Added small hints to FetcherActivity.kt to help out the user

This commit is contained in:
denizk0461
2023-05-05 11:53:44 +02:00
parent e17a81e604
commit 8a416b30fd
13 changed files with 104 additions and 65 deletions
@@ -2,6 +2,7 @@ package com.denizk0461.studip.activity
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.os.Bundle import android.os.Bundle
import android.view.View
import android.webkit.WebResourceRequest import android.webkit.WebResourceRequest
import android.webkit.WebView import android.webkit.WebView
import android.webkit.WebViewClient import android.webkit.WebViewClient
@@ -28,6 +29,9 @@ class FetcherActivity : FragmentActivity() {
// View model // View model
private lateinit var viewModel: FetcherViewModel private lateinit var viewModel: FetcherViewModel
// URL of the schedule
private val scheduleUrl: String = "https://elearning.uni-bremen.de/dispatch.php/calendar/schedule"
/** /**
* Enabling JavaScript is necessary to get the HTML source in this context. As the HTML can only * Enabling JavaScript is necessary to get the HTML source in this context. As the HTML can only
* be accessed once the user has logged in, a simple HTML request would not suffice here. * be accessed once the user has logged in, a simple HTML request would not suffice here.
@@ -44,10 +48,14 @@ class FetcherActivity : FragmentActivity() {
binding = ActivityFetcherBinding.inflate(layoutInflater) binding = ActivityFetcherBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
// Remind the user of the help button
showToast(this, getString(R.string.toast_info_reminder))
// Enabling JavaScript. See comment above lint suppression for reason why this is done. // Enabling JavaScript. See comment above lint suppression for reason why this is done.
binding.webview.settings.apply { binding.webview.settings.apply {
javaScriptEnabled = true javaScriptEnabled = true
} }
binding.webview.webViewClient = object : WebViewClient() { binding.webview.webViewClient = object : WebViewClient() {
// Disallow redirecting to prevent the app from launching Chrome after the user logs in // Disallow redirecting to prevent the app from launching Chrome after the user logs in
override fun shouldOverrideUrlLoading( override fun shouldOverrideUrlLoading(
@@ -56,6 +64,18 @@ class FetcherActivity : FragmentActivity() {
): Boolean { ): Boolean {
return false return false
} }
override fun doUpdateVisitedHistory(view: WebView?, url: String?, isReload: Boolean) {
// Check whether the button to save the timetable should be shown
if (url?.contains(scheduleUrl) == true) {
binding.fab.visibility = View.VISIBLE
} else {
binding.fab.visibility = View.GONE
}
// Super call
super.doUpdateVisitedHistory(view, url, isReload)
}
} }
// Set up bottom app bar for various actions // Set up bottom app bar for various actions
@@ -77,6 +97,7 @@ class FetcherActivity : FragmentActivity() {
val bundle = Bundle() val bundle = Bundle()
bundle.putString("header", getString(R.string.fetch_bar_help_sheet_title)) bundle.putString("header", getString(R.string.fetch_bar_help_sheet_title))
bundle.putString("content", getString(R.string.fetch_bar_help_sheet_content)) bundle.putString("content", getString(R.string.fetch_bar_help_sheet_content))
bundle.putBoolean("isCancellable", true)
sheet.arguments = bundle sheet.arguments = bundle
}.show(supportFragmentManager, TextSheet::class.java.simpleName) }.show(supportFragmentManager, TextSheet::class.java.simpleName)
true true
@@ -96,7 +117,7 @@ class FetcherActivity : FragmentActivity() {
binding.fab.setOnClickListener { binding.fab.setOnClickListener {
if (binding.webview.url?.contains( if (binding.webview.url?.contains(
"https://elearning.uni-bremen.de/dispatch.php/calendar/schedule" scheduleUrl
) == true) { ) == true) {
/* /*
* Retrieve encoded HTML via JavaScript function. Encoding is done as otherwise not all * Retrieve encoded HTML via JavaScript function. Encoding is done as otherwise not all
@@ -39,6 +39,7 @@ class MainActivity : FragmentActivity() {
binding.navHostFragmentContentMain.getFragment<NavHostFragment>().findNavController() binding.navHostFragmentContentMain.getFragment<NavHostFragment>().findNavController()
) )
// Set up navigation component
setNavigationGraph() setNavigationGraph()
} }
@@ -66,7 +66,7 @@ fun Resources.Theme.showErrorSnackBar(view: CoordinatorLayout, text: String, anc
} }
/** /**
* Retrieve a [TextSheet] with text content added as arguments bundle. * Retrieve a cancellable [TextSheet] with text content added as arguments bundle.
* *
* @param header header of the sheet * @param header header of the sheet
* @param content text content of the sheet * @param content text content of the sheet
@@ -76,6 +76,7 @@ fun getTextSheet(header: String, content: String): TextSheet = TextSheet().also
val bundle = Bundle() val bundle = Bundle()
bundle.putString("header", header) bundle.putString("header", header)
bundle.putString("content", content) bundle.putString("content", content)
bundle.putBoolean("isCancellable", true)
sheet.arguments = bundle sheet.arguments = bundle
} }
@@ -37,8 +37,15 @@ class CanteenFragment : AppFragment() {
// View model reference for providing access to the database // View model reference for providing access to the database
private val viewModel: CanteenViewModel by viewModels() 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 = "" private var openingHours = ""
/**
* Locally stored dates to populate the TabLayout with.
*/
private var dates: List<String> = listOf() private var dates: List<String> = listOf()
// Instantiate the view binding // Instantiate the view binding
@@ -65,12 +65,8 @@ class EventFragment : AppFragment() {
// Set the view pager's current page to the current day, if the user chose this option // Set the view pager's current page to the current day, if the user chose this option
if (viewModel.preferenceCurrentDay) { if (viewModel.preferenceCurrentDay) {
/* // Determine the current day and go to the respective page.
* Determine the current day and go to the respective page. binding.viewPager.setCurrentItem(
* BUG: this selects the correct tab and changes the page, but it doesn't highlight
* the tab that has been selected. binding.viewPager.currentPage encounters the same bug
*/
binding.dayTabLayout.getTabAt(
when (Calendar.getInstance().get(Calendar.DAY_OF_WEEK)) { when (Calendar.getInstance().get(Calendar.DAY_OF_WEEK)) {
Calendar.TUESDAY -> 1 Calendar.TUESDAY -> 1
Calendar.WEDNESDAY -> 2 Calendar.WEDNESDAY -> 2
@@ -79,11 +75,16 @@ class EventFragment : AppFragment() {
Calendar.SATURDAY -> 5 Calendar.SATURDAY -> 5
Calendar.SUNDAY -> 6 Calendar.SUNDAY -> 6
else -> 0 // assume Monday else -> 0 // assume Monday
} }, false
)?.select() )
} }
// Set up button for adding a new event
binding.fabAddEvent.setOnClickListener { binding.fabAddEvent.setOnClickListener {
/*
* Open the bottom sheet used for editing an event, but tell the sheet that it will be
* used for creating a new event instead.
*/
openBottomSheet( openBottomSheet(
ScheduleUpdateSheet().also { sheet -> ScheduleUpdateSheet().also { sheet ->
val bundle = Bundle() val bundle = Bundle()
@@ -92,29 +93,17 @@ class EventFragment : AppFragment() {
} }
) )
} }
}
/** // Show the user a little message if they're opening the app for the first time
* Called when the layout changes (e.g. device rotation) but NOT when the fragment is selected if (viewModel.preferenceFirstLaunch) {
* from the bottom navigation view.
*/ // Show toast
// override fun onSaveInstanceState(outState: Bundle) { // showToast(context, getString(R.string.toast_first_launch))
// super.onSaveInstanceState(outState)
// // Remember that the app has been launched before
// outState.putInt( viewModel.preferenceFirstLaunch = false
// "viewPagerCurrentPage", }
// binding.viewPager.currentItem }
// )
// }
//
// override fun onViewStateRestored(savedInstanceState: Bundle?) {
// super.onViewStateRestored(savedInstanceState)
//
// // Retrieve
// val restoredPage = savedInstanceState?.getInt("viewPagerCurrentPage") ?: 0
//
//// binding.viewPager.currentItem = restoredPage
// }
// Invalidate the view binding // Invalidate the view binding
override fun onDestroyView() { override fun onDestroyView() {
@@ -8,6 +8,11 @@ package com.denizk0461.studip.model
*/ */
enum class SettingsPreferences(val key: String) { enum class SettingsPreferences(val key: String) {
/**
* Whether the user is launching this app for the first time.
*/
FIRST_LAUNCH("check_first_launch"),
/** /**
* Which allergens the user wants displayed or hidden. * Which allergens the user wants displayed or hidden.
*/ */
@@ -57,6 +57,7 @@ class DevCodeSheet : AppSheet(R.layout.sheet_dev_code) {
"UE9XRUxM".d64 -> launchLink("aHR0cHM6Ly95b3V0dS5iZS9XUGMtVkVxQlBISQ==".d64) "UE9XRUxM".d64 -> launchLink("aHR0cHM6Ly95b3V0dS5iZS9XUGMtVkVxQlBISQ==".d64)
"Q0FMTE1F".d64 -> launchLink("aHR0cHM6Ly95b3V0dS5iZS8xbTV1WnJNMnktMA==".d64) "Q0FMTE1F".d64 -> launchLink("aHR0cHM6Ly95b3V0dS5iZS8xbTV1WnJNMnktMA==".d64)
"SkFNSVJP".d64 -> launchLink("aHR0cHM6Ly95b3V0dS5iZS9fMVZoT2c0N3ozNA==".d64) "SkFNSVJP".d64 -> launchLink("aHR0cHM6Ly95b3V0dS5iZS9fMVZoT2c0N3ozNA==".d64)
"TE9ORUxZ".d64 -> launchLink("aHR0cHM6Ly95b3V0dS5iZS9uLURFNHNfc3d5Zw==".d64)
"Qk9KQUNL".d64 -> { "Qk9KQUNL".d64 -> {
startActivity(Intent(context, ImageActivity::class.java).also { intent -> startActivity(Intent(context, ImageActivity::class.java).also { intent ->
val bundle = Bundle() val bundle = Bundle()
@@ -23,16 +23,26 @@ class TextSheet : AppSheet(R.layout.sheet_text) {
// Retrieve content for the window // Retrieve content for the window
val content = arguments?.getString("content") ?: "" val content = arguments?.getString("content") ?: ""
// Set whether the sheet should be cancellable by actions such as swiping
val isSheetCancellable = arguments?.getBoolean("isCancellable") == true
// Set text values // Set text values
binding.apply { binding.apply {
textHeader.text = header textHeader.text = header
textContent.text = content textContent.text = content
} }
// Set up close button // Set up an appropriate close button depending on whether the sheet is cancellable
binding.buttonCancel.setOnClickListener { if (isSheetCancellable) {
// Do nothing and dismiss the sheet // Set up a simple X button to be able to close the sheet
dismiss() binding.buttonCancel.visibility = View.VISIBLE
binding.buttonCancel.setOnClickListener {
// Do nothing and dismiss the sheet
dismiss()
}
} else {
// Show a more prominent button to close the sheet
binding.buttonCancel.visibility = View.GONE
} }
} }
} }
@@ -16,6 +16,13 @@ class EventViewModel(app: Application) : AppViewModel(app) {
val preferenceCurrentDay: Boolean val preferenceCurrentDay: Boolean
get() = repo.getBooleanPreference( get() = repo.getBooleanPreference(
SettingsPreferences.CURRENT_DAY, SettingsPreferences.CURRENT_DAY,
defaultValue = true defaultValue = true,
) )
var preferenceFirstLaunch: Boolean
get() = repo.getBooleanPreference(
SettingsPreferences.FIRST_LAUNCH,
defaultValue = true,
)
set(value) { repo.setPreference(SettingsPreferences.FIRST_LAUNCH, value) }
} }
+4 -5
View File
@@ -3,7 +3,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root_view" android:id="@+id/root_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:animateLayoutChanges="true">
<WebView <WebView
android:id="@+id/webview" android:id="@+id/webview"
@@ -24,9 +25,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:srcCompat="@drawable/save" app:srcCompat="@drawable/save"
android:contentDescription="@string/fetch_bar_save_desc" android:contentDescription="@string/fetch_bar_save_desc"
app:layout_anchor="@id/bottom_app_bar"/> app:layout_anchor="@id/bottom_app_bar"
<!-- android:layout_gravity="bottom|end"--> android:visibility="gone"/>
<!-- android:layout_marginEnd="@dimen/fab_margin"-->
<!-- android:layout_marginBottom="@dimen/fab_margin"-->
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
+3 -13
View File
@@ -404,13 +404,14 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<!-- crashlytics opt-in --> <!-- crashlytics opt-in - unused. use for possible future implementation of Crashlytics -->
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_crashlytics" android:id="@+id/layout_crashlytics"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingHorizontal="16dp" android:paddingHorizontal="16dp"
android:paddingVertical="8dp"> android:paddingVertical="8dp"
android:visibility="gone">
<androidx.appcompat.widget.LinearLayoutCompat <androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp" android:layout_width="0dp"
@@ -533,17 +534,6 @@
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="4dp"
android:layout_marginBottom="8dp"
android:text="@string/with_love"
android:textAlignment="center"
android:textSize="8sp"
tools:ignore="SmallSp" />
</androidx.appcompat.widget.LinearLayoutCompat> </androidx.appcompat.widget.LinearLayoutCompat>
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>
+9 -5
View File
@@ -1,6 +1,8 @@
<resources> <resources>
<string name="app_name">Stud.IP Timetable</string> <string name="app_name">Stud.IP Timetable</string>
<string name="toast_first_launch">Hey, danke, dass Du meine App ausprobierst! ~Deniz</string>
<string name="monday">Montag</string> <string name="monday">Montag</string>
<string name="tuesday">Dienstag</string> <string name="tuesday">Dienstag</string>
<string name="wednesday">Mittwoch</string> <string name="wednesday">Mittwoch</string>
@@ -28,6 +30,7 @@
<string name="toast_fetch_finished_one">Dein Stundenplan wurde aktualisiert, doch eine Veranstaltung konnte nicht heruntergeladen werden.</string> <string name="toast_fetch_finished_one">Dein Stundenplan wurde aktualisiert, doch eine Veranstaltung konnte nicht heruntergeladen werden.</string>
<string name="toast_fetch_finished_other">Dein Stundenplan wurde aktualisiert, doch %d Veranstaltungen konnten nicht heruntergeladen werden.</string> <string name="toast_fetch_finished_other">Dein Stundenplan wurde aktualisiert, doch %d Veranstaltungen konnten nicht heruntergeladen werden.</string>
<string name="toast_info_reminder">Klick\' das Info-Icon unten, falls du Hilfe benötigst.</string>
<string name="fetch_bar_close_title">Schließen</string> <string name="fetch_bar_close_title">Schließen</string>
<string name="fetch_bar_close_desc">Schließe die Webseite, ohne etwas zu speichern</string> <string name="fetch_bar_close_desc">Schließe die Webseite, ohne etwas zu speichern</string>
<string name="fetch_bar_refresh_title">Aktualisieren</string> <string name="fetch_bar_refresh_title">Aktualisieren</string>
@@ -35,7 +38,7 @@
<string name="fetch_bar_help_title">Hilfe</string> <string name="fetch_bar_help_title">Hilfe</string>
<string name="fetch_bar_help_desc">Zeige Hilfe</string> <string name="fetch_bar_help_desc">Zeige Hilfe</string>
<string name="fetch_bar_help_sheet_title">Wie Du Deinen Stundenplan in der App speichern kannst</string> <string name="fetch_bar_help_sheet_title">Wie Du Deinen Stundenplan in der App speichern kannst</string>
<string name="fetch_bar_help_sheet_content"> • Logge dich mit deinem Stud.IP-Login ein\n • Öffne deinen Stundenplan (falls er sich nicht automatisch öffnet)\n • Klicke auf den \'Speichern\'-Knopf rechts in der unteren Ecke\n • Fertig!</string> <string name="fetch_bar_help_sheet_content"> • Logge dich mit deinem Stud.IP-Login ein\n • Öffne deinen Stundenplan (falls er sich nicht automatisch öffnet)\n • Klicke auf den \'Speichern\'-Knopf, der unten in der rechten Ecke auftauchen sollte\n • Fertig!</string>
<string name="fetch_bar_save_desc">Speichere den Stundenplan in der App ab</string> <string name="fetch_bar_save_desc">Speichere den Stundenplan in der App ab</string>
<string name="save">Speichern</string> <string name="save">Speichern</string>
@@ -181,8 +184,11 @@
<string name="settings_data_title">Was passiert mit meinen Daten?</string> <string name="settings_data_title">Was passiert mit meinen Daten?</string>
<string name="settings_data_subtitle">Stiehlst du meinen Stud.IP-Login?</string> <string name="settings_data_subtitle">Stiehlst du meinen Stud.IP-Login?</string>
<string name="settings_data_sheet_header">TL;DR: nein, aber Google könnte mir Bescheid geben, falls die App mal abstürzt.</string> <string name="settings_data_sheet_header">TL;DR: nein.</string>
<string name="settings_data_sheet_content">Die App funktioniert standalone, was bedeutet, dass sie sich niemals mit einem Server verbindet, der mir gehört. Sie ist ein Web-Scraper, also ein Programm, welches eine Internetseite öffnet und dann all die Informationen dieser Webseite herunterlädt und analysiert. In diesem Fall sind es die Webseiten der Mensen und Cafeterien des Studierendenwerks Bremen (stw-bremen.de) sowie die Stud.IP-Seite (elearning.uni-bremen.de).\n\nDies funktioniert relativ einfach für die Essenspläne, da diese Pläne öffentlich zugänglich sind. Um jedoch Deinen persönlichen Stud.IP-Stundenplan herunterzuladen, braucht die App Zugriff auf diese Webseite während Dein Account eingeloggt ist. Dies erfolgt, indem die App Dich mit deinem Account einloggen lässt - dies geschieht, wenn Du den Knopf zum Aktualisieren des Plans drückst und die App Dir die Login-Seite zeigt - und Du dann den Knopf klickst, um den Inhalt, den HTML-Quellcode, herunterzuladen. Der HTML-Quellcode beinhält Informationen darüber, was auf einer Webseite angezeigt wird und wie es aussehen soll, aber er kann niemals persönliche Details beinhalten, wie zum Beispiel Passwörter oder andere Daten, die auf Deinem Gerät vorhanden sind.\n\nDer Quellcode wird dann lokal, also auf Deinem Gerät, zu den Daten verarbeitet, die Du dann in der App sehen kannst, ohne, dass jegliche Daten irgendwohin geschickt werden müssten.\n\nEinige Daten welche nichts mit Deinen Stud.IP-Daten zu tun haben könnten jedoch dennoch nach außen geschickt werden. Diese App nutzt \"Crashlytics\" von Google. Dies ist ein Tool, welches Absturzreporte an Google-Server schickt, wenn in der App etwas schief läuft. Diese werden genutzt, um Probleme in der App zu lösen.\n\nDies ist jedoch gemäß europäischer Datenschutz-Grundverordnung Opt-In, was bedeutet, dass Du zustimmen musst, bevor Daten nach außen geschickt werden. Du wurdest danach gefragt, als Du die App zum ersten Mal gestartet hast, und du kannst jederzeit deine Meinung ändern, indem Du den Schalter hierfür in den Einstellungen umstellst. Solltest Du dich entscheiden, keine Daten verschicken zu lassen, wird auch nichts mit Google (und mir) geteilt.\n\nSolltest du dich versichern wollen, dass wirklich keine Daten an irgendwelche Server verschickt wird (abgesehen von den Absturzreports an Google), kannst Du jederzeit das Projekt erkunden, da es Open-Source und auf meinen GitHub-Profil öffentlich zugänglich ist:\nhttps://github.com/denizk0461/studip-timetable/\n\nSchreib mir ansonsten gerne eine E-Mail:\ndenizk0461@gmail.com</string> <string name="settings_data_sheet_content">Die App funktioniert standalone, was bedeutet, dass sie sich niemals mit einem Server verbindet, der mir gehört. Sie ist ein Web-Scraper, also ein Programm, welches eine Internetseite öffnet und dann all die Informationen dieser Webseite herunterlädt und analysiert. In diesem Fall sind es die Webseiten der Mensen und Cafeterien des Studierendenwerks Bremen (stw-bremen.de) sowie die Stud.IP-Seite (elearning.uni-bremen.de).\n\nDies funktioniert relativ einfach für die Essenspläne, da diese Pläne öffentlich zugänglich sind. Um jedoch Deinen persönlichen Stud.IP-Stundenplan herunterzuladen, braucht die App Zugriff auf diese Webseite während Dein Account eingeloggt ist. Dies erfolgt, indem die App Dich mit deinem Account einloggen lässt - dies geschieht, wenn Du den Knopf zum Aktualisieren des Plans drückst und die App Dir die Login-Seite zeigt - und Du dann den Knopf klickst, um den Inhalt, den HTML-Quellcode, herunterzuladen. Der HTML-Quellcode beinhält Informationen darüber, was auf einer Webseite angezeigt wird und wie es aussehen soll, aber er kann niemals persönliche Details beinhalten, wie zum Beispiel Passwörter oder andere Daten, die auf Deinem Gerät vorhanden sind.\n\nDer Quellcode wird dann lokal, also auf Deinem Gerät, zu den Daten verarbeitet, die Du dann in der App sehen kannst, ohne, dass jegliche Daten irgendwohin geschickt werden müssten.\n\nSolltest du dich versichern wollen, dass wirklich keine Daten an irgendwelche Server verschickt wird, kannst Du jederzeit das Projekt erkunden, da es Open-Source und auf meinen GitHub-Profil öffentlich zugänglich ist:\nhttps://github.com/denizk0461/studip-timetable/\n\nSchreib mir ansonsten gerne eine E-Mail:\ndenizk0461@gmail.com\ndeniz7@uni-bremen.de</string>
<!-- unused - use for possible future implementation of Crashlytics -->
<string name="settings_data_sheet_header_crashlytics">TL;DR: nein, aber Google könnte mir Bescheid geben, falls die App mal abstürzt.</string>
<string name="settings_data_sheet_content_crashlytics">Die App funktioniert standalone, was bedeutet, dass sie sich niemals mit einem Server verbindet, der mir gehört. Sie ist ein Web-Scraper, also ein Programm, welches eine Internetseite öffnet und dann all die Informationen dieser Webseite herunterlädt und analysiert. In diesem Fall sind es die Webseiten der Mensen und Cafeterien des Studierendenwerks Bremen (stw-bremen.de) sowie die Stud.IP-Seite (elearning.uni-bremen.de).\n\nDies funktioniert relativ einfach für die Essenspläne, da diese Pläne öffentlich zugänglich sind. Um jedoch Deinen persönlichen Stud.IP-Stundenplan herunterzuladen, braucht die App Zugriff auf diese Webseite während Dein Account eingeloggt ist. Dies erfolgt, indem die App Dich mit deinem Account einloggen lässt - dies geschieht, wenn Du den Knopf zum Aktualisieren des Plans drückst und die App Dir die Login-Seite zeigt - und Du dann den Knopf klickst, um den Inhalt, den HTML-Quellcode, herunterzuladen. Der HTML-Quellcode beinhält Informationen darüber, was auf einer Webseite angezeigt wird und wie es aussehen soll, aber er kann niemals persönliche Details beinhalten, wie zum Beispiel Passwörter oder andere Daten, die auf Deinem Gerät vorhanden sind.\n\nDer Quellcode wird dann lokal, also auf Deinem Gerät, zu den Daten verarbeitet, die Du dann in der App sehen kannst, ohne, dass jegliche Daten irgendwohin geschickt werden müssten.\n\nEinige Daten welche nichts mit Deinen Stud.IP-Daten zu tun haben könnten jedoch dennoch nach außen geschickt werden. Diese App nutzt \"Crashlytics\" von Google. Dies ist ein Tool, welches Absturzreporte an Google-Server schickt, wenn in der App etwas schief läuft. Diese werden genutzt, um Probleme in der App zu lösen.\n\nDies ist jedoch gemäß europäischer Datenschutz-Grundverordnung Opt-In, was bedeutet, dass Du zustimmen musst, bevor Daten nach außen geschickt werden. Du wurdest danach gefragt, als Du die App zum ersten Mal gestartet hast, und du kannst jederzeit deine Meinung ändern, indem Du den Schalter hierfür in den Einstellungen umstellst. Solltest Du dich entscheiden, keine Daten verschicken zu lassen, wird auch nichts mit Google (und mir) geteilt.\n\nSolltest du dich versichern wollen, dass wirklich keine Daten an irgendwelche Server verschickt wird (abgesehen von den Absturzreports an Google), kannst Du jederzeit das Projekt erkunden, da es Open-Source und auf meinen GitHub-Profil öffentlich zugänglich ist:\nhttps://github.com/denizk0461/studip-timetable/\n\nSchreib mir ansonsten gerne eine E-Mail:\ndenizk0461@gmail.com\ndeniz7@uni-bremen.de</string>
<string name="settings_licences_title">Siehe Lizenzen</string> <string name="settings_licences_title">Siehe Lizenzen</string>
<string name="settings_licences_subtitle">Ressourcen, die diese App möglich gemacht haben</string> <string name="settings_licences_subtitle">Ressourcen, die diese App möglich gemacht haben</string>
@@ -191,6 +197,4 @@
<string name="settings_app_version_15">klick weiter</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> <string name="settings_app_version_121">Solltest du nicht für deine Klausuren lernen?</string>
<string name="with_love">mit ♡️ aus Bremen-Osterholz\nvon denizk0461 \\__*</string>
</resources> </resources>
+9 -5
View File
@@ -1,6 +1,8 @@
<resources> <resources>
<string name="app_name">Stud.IP Timetable</string> <string name="app_name">Stud.IP Timetable</string>
<string name="toast_first_launch">Hey, thank you for trying out my app! ~Deniz</string>
<string name="monday">Monday</string> <string name="monday">Monday</string>
<string name="tuesday">Tuesday</string> <string name="tuesday">Tuesday</string>
<string name="wednesday">Wednesday</string> <string name="wednesday">Wednesday</string>
@@ -28,6 +30,7 @@
<string name="toast_fetch_finished_one">Your schedule has been refreshed, but one item could not be saved.</string> <string name="toast_fetch_finished_one">Your schedule has been refreshed, but one item could not be saved.</string>
<string name="toast_fetch_finished_other">Your schedule has been refreshed, but %d items could not be saved.</string> <string name="toast_fetch_finished_other">Your schedule has been refreshed, but %d items could not be saved.</string>
<string name="toast_info_reminder">Click the info icon at the bottom if you need any help here.</string>
<string name="fetch_bar_close_title">Close</string> <string name="fetch_bar_close_title">Close</string>
<string name="fetch_bar_close_desc">Close the website without saving anything</string> <string name="fetch_bar_close_desc">Close the website without saving anything</string>
<string name="fetch_bar_refresh_title">Refresh</string> <string name="fetch_bar_refresh_title">Refresh</string>
@@ -35,7 +38,7 @@
<string name="fetch_bar_help_title">Help</string> <string name="fetch_bar_help_title">Help</string>
<string name="fetch_bar_help_desc">Show help</string> <string name="fetch_bar_help_desc">Show help</string>
<string name="fetch_bar_help_sheet_title">How to save your timetable in the app</string> <string name="fetch_bar_help_sheet_title">How to save your timetable in the app</string>
<string name="fetch_bar_help_sheet_content"> • Log in with your Stud.IP login\n • Open your timetable view (in case it doesn\'t open automatically)\n • Click the \'save\' button in the bottom right corner\n • Done!</string> <string name="fetch_bar_help_sheet_content"> • Log in with your Stud.IP login\n • Open your timetable view (in case it doesn\'t open automatically)\n • Click the \'save\' button that should appear in the bottom right corner\n • Done!</string>
<string name="fetch_bar_save_desc">Save the timetable in the app</string> <string name="fetch_bar_save_desc">Save the timetable in the app</string>
<string name="save">Save</string> <string name="save">Save</string>
@@ -185,8 +188,11 @@
<string name="settings_data_title">What happens with my data?</string> <string name="settings_data_title">What happens with my data?</string>
<string name="settings_data_subtitle">Will you steal my Stud.IP login?</string> <string name="settings_data_subtitle">Will you steal my Stud.IP login?</string>
<string name="settings_data_sheet_header">TL;DR: no, but Google may let me know if the app crashes on your device.</string> <string name="settings_data_sheet_header">TL;DR: no.</string>
<string name="settings_data_sheet_content">This app works standalone, which is to say, it doesn\'t ever connect to a server I own. Instead, it is a web scraper, which means that it opens a website and then downloads and analyses all the data from that website by itself. In this case, those websites are the canteen websites of the Studierendenwerk Bremen (stw-bremen.de) and the Stud.IP page (elearning.uni-bremen.de).\n\nThis works fairly easily for the canteen offers, since the plans are public and anyone can access them. However, to access your personal Stud.IP schedule, the app needs access to that website, with your account logged in. This is done by letting you log into the website by yourself (which happens when you click the button to refresh the schedule and the app opens the login page) and then clicking a button to download the content, the HTML source code, of the website. The HTML source code contains information about which elements are shown on the website and how they look, but it can never contain your personal details such as passwords, or any other sensitive data you may store on your device.\n\nThe HTML source is then processed locally on your device, which means that your device will handle converting the HTML source to the data you will be shown in the app by itself, without needing to send any data anywhere.\n\nHowever, some data which has nothing to do with your Stud.IP data may still be sent outside of your device. This app uses \"Crashlytics\" by Google, which is a tool that sends crash reports to Google servers if something breaks. These are used to fix problems that occur in the app.\n\nThis, in compliance with the European General Data Protection Regulation, is of course opt-in, which means that you need to accept this before any data is sent outside of your device. You have been prompted for this when you first started the app, and you can always change your mind in the app settings by clicking the corresponding switch. Should you choose to not share crash data with Google (and me), no data will be sent outside of your device.\n\nShould you want to reassure yourself that no data is sent to any servers (outside of the crash reports from Google), feel free to explore the project, since it is open-source and documented on my GitHub profile:\nhttps://github.com/denizk0461/studip-timetable/\n\nYou\'re also welcome to send me an email:\ndenizk0461@gmail.com</string> <string name="settings_data_sheet_content">This app works standalone, which is to say, it doesn\'t ever connect to a server I own. Instead, it is a web scraper, which means that it opens a website and then downloads and analyses all the data from that website by itself. In this case, those websites are the canteen websites of the Studierendenwerk Bremen (stw-bremen.de) and the Stud.IP page (elearning.uni-bremen.de).\n\nThis works fairly easily for the canteen offers, since the plans are public and anyone can access them. However, to access your personal Stud.IP schedule, the app needs access to that website, with your account logged in. This is done by letting you log into the website by yourself (which happens when you click the button to refresh the schedule and the app opens the login page) and then clicking a button to download the content, the HTML source code, of the website. The HTML source code contains information about which elements are shown on the website and how they look, but it can never contain your personal details such as passwords, or any other sensitive data you may store on your device.\n\nThe HTML source is then processed locally on your device, which means that your device will handle converting the HTML source to the data you will be shown in the app by itself, without needing to send any data anywhere.\n\nShould you want to reassure yourself that no data is sent to any servers, feel free to explore the project, since it is open-source and documented on my GitHub profile:\nhttps://github.com/denizk0461/studip-timetable/\n\nYou\'re also welcome to send me an email:\ndenizk0461@gmail.com\ndeniz7@uni-bremen.de</string>
<!-- unused - use for possible future implementation of Crashlytics -->
<string name="settings_data_sheet_header_crashlytics">TL;DR: no, but Google may let me know if the app crashes on your device.</string>
<string name="settings_data_sheet_content_crashlytics">This app works standalone, which is to say, it doesn\'t ever connect to a server I own. Instead, it is a web scraper, which means that it opens a website and then downloads and analyses all the data from that website by itself. In this case, those websites are the canteen websites of the Studierendenwerk Bremen (stw-bremen.de) and the Stud.IP page (elearning.uni-bremen.de).\n\nThis works fairly easily for the canteen offers, since the plans are public and anyone can access them. However, to access your personal Stud.IP schedule, the app needs access to that website, with your account logged in. This is done by letting you log into the website by yourself (which happens when you click the button to refresh the schedule and the app opens the login page) and then clicking a button to download the content, the HTML source code, of the website. The HTML source code contains information about which elements are shown on the website and how they look, but it can never contain your personal details such as passwords, or any other sensitive data you may store on your device.\n\nThe HTML source is then processed locally on your device, which means that your device will handle converting the HTML source to the data you will be shown in the app by itself, without needing to send any data anywhere.\n\nHowever, some data which has nothing to do with your Stud.IP data may still be sent outside of your device. This app uses \"Crashlytics\" by Google, which is a tool that sends crash reports to Google servers if something breaks. These are used to fix problems that occur in the app.\n\nThis, in compliance with the European General Data Protection Regulation, is of course opt-in, which means that you need to accept this before any data is sent outside of your device. You have been prompted for this when you first started the app, and you can always change your mind in the app settings by clicking the corresponding switch. Should you choose to not share crash data with Google (and me), no data will be sent outside of your device.\n\nShould you want to reassure yourself that no data is sent to any servers (outside of the crash reports from Google), feel free to explore the project, since it is open-source and documented on my GitHub profile:\nhttps://github.com/denizk0461/studip-timetable/\n\nYou\'re also welcome to send me an email:\ndenizk0461@gmail.com\ndeniz7@uni-bremen.de</string>
<string name="settings_licences_title">View licences</string> <string name="settings_licences_title">View licences</string>
<string name="settings_licences_subtitle">Resources that made this app possible</string> <string name="settings_licences_subtitle">Resources that made this app possible</string>
@@ -203,8 +209,6 @@
<string name="settings_app_version_165" translatable="false">◢◤</string> <string name="settings_app_version_165" translatable="false">◢◤</string>
<string name="settings_app_version_200" translatable="false">\\__*</string> <string name="settings_app_version_200" translatable="false">\\__*</string>
<string name="with_love">with ♡️ from Bremen-Osterholz\nmade by denizk0461 \\__*</string>
<string-array name="cheesy_wisdoms" translatable="false"> <string-array name="cheesy_wisdoms" translatable="false">
<item>it\'s only real when it hurts</item> <item>it\'s only real when it hurts</item>
<item>can\'t go back in time, every second is a new one</item> <item>can\'t go back in time, every second is a new one</item>