diff --git a/app/build.gradle b/app/build.gradle
index c8d87ab..80e301f 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -10,8 +10,8 @@ android {
applicationId "com.denizd.substitutionplan"
minSdkVersion 21
targetSdkVersion 28
- versionCode 37
- versionName "2.2.14"
+ versionCode 38
+ versionName "2.3.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 46b3b8c..0f37854 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -18,6 +18,13 @@
android:supportsRtl="true"
tools:ignore="GoogleAppIndexingWarning">
+
+
(R.id.coordinatorLayout)
+ parentLayout.layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
+
val barColour = when {
Build.VERSION.SDK_INT < Build.VERSION_CODES.M -> ContextCompat.getColor(context, R.color.legacyBlack)
Build.VERSION.SDK_INT <= Build.VERSION_CODES.P -> ContextCompat.getColor(context, R.color.colorBackground)
@@ -111,12 +115,11 @@ internal class FirstTime : AppCompatActivity(R.layout.activity_first_time) {
.putBoolean("colourTransferred", true)
.apply()
- val cLayout = findViewById(R.id.coordinatorLayout)
val linearInflation = findViewById(R.id.linearInflation)
val x: Int = fab.right - fab.width / 2
- val y: Int = fab.bottom- fab.height / 2
- val endRadius = hypot(cLayout.width.toDouble(), cLayout.height.toDouble()).toInt()
+ val y: Int = fab.bottom - fab.height / 2
+ val endRadius = hypot(parentLayout.width.toDouble(), parentLayout.height.toDouble()).toInt()
inflater.inflate(R.layout.welcome_screen, linearInflation, true)
val anim = ViewAnimationUtils.createCircularReveal(linearInflation, x, y, 0F, endRadius.toFloat())
val handler = Handler()
@@ -147,11 +150,11 @@ internal class FirstTime : AppCompatActivity(R.layout.activity_first_time) {
val mImgCheck = findViewById(R.id.imageView).drawable as AnimatedVectorDrawableCompat
mImgCheck.start()
}
- }, 1000)
+ }, 600)
handler.postDelayed({
startActivity(mainActivity)
finish()
- }, 2000)
+ }, 3000)
}
}
diff --git a/app/src/main/java/com/denizd/substitutionplan/activities/Login.kt b/app/src/main/java/com/denizd/substitutionplan/activities/Login.kt
new file mode 100644
index 0000000..e5f725a
--- /dev/null
+++ b/app/src/main/java/com/denizd/substitutionplan/activities/Login.kt
@@ -0,0 +1,132 @@
+package com.denizd.substitutionplan.activities
+
+import android.animation.LayoutTransition
+import android.annotation.SuppressLint
+import android.content.Intent
+import android.content.SharedPreferences
+import android.graphics.drawable.AnimatedVectorDrawable
+import android.os.Build
+import android.os.Bundle
+import android.os.Handler
+import android.preference.PreferenceManager
+import android.view.View
+import android.view.ViewAnimationUtils
+import android.view.animation.Animation
+import android.view.animation.AnimationUtils
+import android.webkit.WebView
+import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.TextView
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.app.AppCompatDelegate
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.content.ContextCompat
+import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat
+import com.denizd.substitutionplan.R
+import com.denizd.substitutionplan.data.LoginWebViewClient
+import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
+import kotlin.math.hypot
+
+internal class Login : AppCompatActivity(R.layout.activity_login_webview), LoginWebViewClient.OnLoginSuccessListener {
+
+ private lateinit var prefs: SharedPreferences
+ private lateinit var parentLayout: ConstraintLayout
+ private lateinit var logInButton: ExtendedFloatingActionButton
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setTheme(R.style.AppTheme0)
+ parentLayout = findViewById(R.id.constraintLayout)
+ parentLayout.layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
+ val title = findViewById(R.id.txtWelcome)
+ prefs = PreferenceManager.getDefaultSharedPreferences(this)
+
+ val barColour = when {
+ Build.VERSION.SDK_INT < Build.VERSION_CODES.M -> ContextCompat.getColor(this, R.color.legacyBlack)
+ Build.VERSION.SDK_INT <= Build.VERSION_CODES.P -> ContextCompat.getColor(this, R.color.colorBackground)
+ else -> 0
+ }
+ if (barColour != 0) {
+ window.navigationBarColor = barColour
+ window.statusBarColor = barColour
+ }
+ if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_NO) {
+ if (Build.VERSION.SDK_INT in 23..28) {
+ @SuppressLint("InlinedApi")
+ window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
+ }
+ }
+
+ logInButton = findViewById(R.id.loginFab)
+ logInButton.setOnClickListener {
+ findViewById(R.id.linearLayout).apply {
+ logInButton.hide()
+ removeAllViews()
+ title.text = getString(R.string.logging_in)
+ val view = View.inflate(this@Login, R.layout.webview, null)
+ addView(view)
+ val webView = view.findViewById(R.id.webView)
+ webView.webViewClient = LoginWebViewClient(this@Login)
+ openLoginPage(webView)
+ handler.postDelayed({
+ webView.scrollY = -4000
+ }, 2000)
+ }
+ }
+ }
+
+ override fun onLoginSucceeded(success: Boolean) {
+ if (success) {
+ success()
+ }
+ }
+
+ private fun openLoginPage(webView: WebView) {
+ webView.loadUrl("https://307.joomla.schule.bremen.de/index.php/component/users/#top")
+ }
+
+ private fun success() {
+ prefs.edit().putBoolean("successful_login", true).apply()
+
+ val layoutAfterCircleReveal = findViewById(R.id.layoutAfterCircleReveal)
+
+ val x: Int = logInButton.right - logInButton.width / 2
+ val y: Int = logInButton.bottom - logInButton.height / 2
+ val endRadius = hypot(parentLayout.width.toDouble(), parentLayout.height.toDouble()).toInt()
+ View.inflate(this, R.layout.unlock_screen, layoutAfterCircleReveal)
+ val anim = ViewAnimationUtils.createCircularReveal(layoutAfterCircleReveal, x, y, 0F, endRadius.toFloat())
+ val handler = Handler()
+ val animOut = AnimationUtils.loadAnimation(this, R.anim.fade_out_short)
+ anim.duration = 600
+ val colour = findViewById(R.id.colourLayout)
+ layoutAfterCircleReveal.visibility = View.VISIBLE
+ anim.start()
+ logInButton.hide()
+
+ handler.postDelayed({
+ colour.startAnimation(animOut)
+ }, 400)
+ animOut.setAnimationListener(object: Animation.AnimationListener {
+ override fun onAnimationStart(arg0: Animation) {}
+ override fun onAnimationRepeat(arg0: Animation) {}
+ override fun onAnimationEnd(arg0: Animation) {
+ colour.visibility = View.GONE
+ }
+ })
+ handler.postDelayed({
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
+ val mImgCheck = findViewById(R.id.imageView).drawable as AnimatedVectorDrawable
+ mImgCheck.start()
+ } else {
+ val mImgCheck = findViewById(R.id.imageView).drawable as AnimatedVectorDrawableCompat
+ mImgCheck.start()
+ }
+ }, 600)
+ handler.postDelayed({
+ val main = Intent(this, Main::class.java)
+ startActivity(main)
+ finish()
+ }, 3000)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/substitutionplan/activities/Main.kt b/app/src/main/java/com/denizd/substitutionplan/activities/Main.kt
index 035674c..7dee1a2 100644
--- a/app/src/main/java/com/denizd/substitutionplan/activities/Main.kt
+++ b/app/src/main/java/com/denizd/substitutionplan/activities/Main.kt
@@ -43,13 +43,17 @@ internal class Main : AppCompatActivity(R.layout.app_bar_main) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
context = this
- prefs = PreferenceManager.getDefaultSharedPreferences(context) as SharedPreferences
+ prefs = PreferenceManager.getDefaultSharedPreferences(context)
val edit = prefs.edit()
val firstTime = Intent(context, FirstTime::class.java)
+ val login = Intent(context, Login::class.java)
Crashlytics.setUserIdentifier(prefs.getString("username", "") ?: "")
- if (prefs.getBoolean("firstTime", true)) {
-// if (true) {
+ if (!prefs.getBoolean("successful_login", false)) {
+ startActivity(login)
+ finish()
+ } else if (prefs.getBoolean("firstTime", true)) {
+// } else if (true) {
startActivity(firstTime)
finish()
} else {
@@ -238,10 +242,10 @@ internal class Main : AppCompatActivity(R.layout.app_bar_main) {
}
private fun personalPlanTitle(): String {
- return if (prefs.getBoolean("greeting", true)) {
+ val user = prefs.getString("username", "") ?: ""
+ return if (prefs.getBoolean("greeting", true) || user.isEmpty()) {
getString(R.string.yourPlan)
} else {
- val user = prefs.getString("username", "") ?: ""
if (user.endsWith("s", true) || user.endsWith("x", true) || user.endsWith("z", true)) {
"$user${getString(R.string.noSPlan)}"
} else {
diff --git a/app/src/main/java/com/denizd/substitutionplan/adapters/ColourAdapter.kt b/app/src/main/java/com/denizd/substitutionplan/adapters/ColourAdapter.kt
index 8e59358..1206311 100644
--- a/app/src/main/java/com/denizd/substitutionplan/adapters/ColourAdapter.kt
+++ b/app/src/main/java/com/denizd/substitutionplan/adapters/ColourAdapter.kt
@@ -29,10 +29,7 @@ internal class ColourAdapter(private var mColours: List, onClickListener
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ColourViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
- return ColourViewHolder(
- v,
- mOnClickListener
- )
+ return ColourViewHolder(v, mOnClickListener)
}
override fun onBindViewHolder(holder: ColourViewHolder, position: Int) {
diff --git a/app/src/main/java/com/denizd/substitutionplan/data/LoginWebViewClient.kt b/app/src/main/java/com/denizd/substitutionplan/data/LoginWebViewClient.kt
new file mode 100644
index 0000000..5d58cac
--- /dev/null
+++ b/app/src/main/java/com/denizd/substitutionplan/data/LoginWebViewClient.kt
@@ -0,0 +1,46 @@
+package com.denizd.substitutionplan.data
+
+import android.webkit.CookieManager
+import android.webkit.WebView
+import android.webkit.WebViewClient
+
+/**
+ * class that extends WebViewClient to provide a function that checks the webpage's cookies to
+ * verify a login
+ *
+ * @param successListener a reference to the OnLoginSuccessListener implemented in an activity
+ */
+internal class LoginWebViewClient(successListener: OnLoginSuccessListener) : WebViewClient() {
+
+ private val mSuccessListener = successListener
+
+ /**
+ * onPageFinished has been overridden to check if the cookie "joomla_user_state=logged_in"
+ * exists, and returns true to the OnLoginSuccessListener
+ *
+ * @param view a reference to the WebView
+ * @param url a reference to the url of the WebView
+ */
+ override fun onPageFinished(view: WebView?, url: String?) {
+ super.onPageFinished(view, url)
+ val cookies = CookieManager.getInstance().getCookie(url)
+
+ if (cookies.contains("joomla_user_state=logged_in")) {
+ mSuccessListener.onLoginSucceeded(true)
+ }
+ }
+
+ /**
+ * the interface that provides onLoginSucceeded to the activity or fragment that implements it
+ */
+ internal interface OnLoginSuccessListener {
+
+ /**
+ * the function that can be overridden to check whether a successful login has occurred
+ *
+ * @param success boolean value that returns true if the cookie could be found,
+ * false otherwise
+ */
+ fun onLoginSucceeded(success: Boolean)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/substitutionplan/fragments/SettingsFragment.kt b/app/src/main/java/com/denizd/substitutionplan/fragments/SettingsFragment.kt
index 14bbb14..4f21148 100644
--- a/app/src/main/java/com/denizd/substitutionplan/fragments/SettingsFragment.kt
+++ b/app/src/main/java/com/denizd/substitutionplan/fragments/SettingsFragment.kt
@@ -47,7 +47,6 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
private lateinit var prefs: SharedPreferences
private val builder = CustomTabsIntent.Builder()
private val customTabsIntent = builder.build() as CustomTabsIntent
- private var cs: Int = 7
private var window: Window? = null
private lateinit var colourRecycler: RecyclerView
private lateinit var ringtoneCustomiserDialog: AlertDialog
@@ -253,19 +252,6 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
"\n---\n" +
"\nThis privacy policy was modified upon the template provided by privacypolicytemplate.net and App Privacy Policy Generator. These services are in no way affiliated with AvH Plan or the developer.")
}
- R.id.btnVersion -> {
- if (cs > 0) {
- cs--
- } else {
- try {
- cs = 7
- customTabsIntent.launchUrl(mContext, Uri.parse("http://www.flussufer.de/gerd/person.htm"))
- makeToast(getString(R.string.dontTellHim))
- } catch (e: ActivityNotFoundException) {
- makeToast(getString(R.string.chromeCompatibleNotFound))
- }
- }
- }
R.id.btnForceRefresh -> {
DataFetcher(
isPlan = true,
diff --git a/app/src/main/java/com/denizd/substitutionplan/services/FBPingService.kt b/app/src/main/java/com/denizd/substitutionplan/services/FBPingService.kt
index 656ed68..6b79681 100644
--- a/app/src/main/java/com/denizd/substitutionplan/services/FBPingService.kt
+++ b/app/src/main/java/com/denizd/substitutionplan/services/FBPingService.kt
@@ -25,28 +25,30 @@ internal class FBPingService : JobService() {
private fun doBackgroundWork(params: JobParameters) {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
FirebaseApp.initializeApp(context)
- FirebaseMessaging.getInstance().apply {
- if (prefs.getBoolean("notif", true)) {
- subscribeToTopic(Topic.ANDROID.tag)
- } else {
- unsubscribeFromTopic(Topic.ANDROID.tag)
+ if (!prefs.getBoolean("firstTime", true)) {
+ FirebaseMessaging.getInstance().apply {
+ if (prefs.getBoolean("notif", true)) {
+ subscribeToTopic(Topic.ANDROID.tag)
+ } else {
+ unsubscribeFromTopic(Topic.ANDROID.tag)
+ }
+
+ if (prefs.getBoolean("subscribedToFBDebugChannel", false)) {
+ subscribeToTopic(Topic.DEVELOPMENT.tag)
+ } else {
+ unsubscribeFromTopic(Topic.DEVELOPMENT.tag)
+ }
+
+ if (prefs.getBoolean("subscribedToiOSChannel", false)) {
+ subscribeToTopic(Topic.IOS.tag)
+ } else {
+ unsubscribeFromTopic(Topic.IOS.tag)
+ }
+
+ subscribeToTopic(Topic.BROADCAST.tag)
+
+ prefs.edit().putInt("pingFB", prefs.getInt("pingFB", 0) + 1).apply()
}
-
- if (prefs.getBoolean("subscribedToFBDebugChannel", false)) {
- subscribeToTopic(Topic.DEVELOPMENT.tag)
- } else {
- unsubscribeFromTopic(Topic.DEVELOPMENT.tag)
- }
-
- if (prefs.getBoolean("subscribedToiOSChannel", false)) {
- subscribeToTopic(Topic.IOS.tag)
- } else {
- unsubscribeFromTopic(Topic.IOS.tag)
- }
-
- subscribeToTopic(Topic.BROADCAST.tag)
-
- prefs.edit().putInt("pingFB", prefs.getInt("pingFB", 0) + 1).apply()
}
jobFinished(params, false)
}
diff --git a/app/src/main/res/animator/unlock_animation.xml b/app/src/main/res/animator/unlock_animation.xml
new file mode 100644
index 0000000..feda24f
--- /dev/null
+++ b/app/src/main/res/animator/unlock_animation.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/animated_lock.xml b/app/src/main/res/drawable/animated_lock.xml
new file mode 100644
index 0000000..49e9937
--- /dev/null
+++ b/app/src/main/res/drawable/animated_lock.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/check_mark.xml b/app/src/main/res/drawable/check_mark.xml
index 95337e7..8ebbbf9 100644
--- a/app/src/main/res/drawable/check_mark.xml
+++ b/app/src/main/res/drawable/check_mark.xml
@@ -3,18 +3,18 @@
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
-
-
-
+
+
+
+
+
+
+ android:strokeColor="@color/colorAccent"
+ android:strokeWidth="2" />
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_closed_lock.xml b/app/src/main/res/drawable/ic_closed_lock.xml
new file mode 100644
index 0000000..6a19fca
--- /dev/null
+++ b/app/src/main/res/drawable/ic_closed_lock.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_open_lock.xml b/app/src/main/res/drawable/ic_open_lock.xml
new file mode 100644
index 0000000..9fafe85
--- /dev/null
+++ b/app/src/main/res/drawable/ic_open_lock.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_first_time.xml b/app/src/main/res/layout/activity_first_time.xml
index 5ad70ef..d16eee0 100644
--- a/app/src/main/res/layout/activity_first_time.xml
+++ b/app/src/main/res/layout/activity_first_time.xml
@@ -1,5 +1,5 @@
-
+ tools:context=".activities.FirstTime"
+ android:animateLayoutChanges="true">
+ android:translationZ="-1dp"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toTopOf="@+id/snackBarLayout"/>
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
new file mode 100644
index 0000000..33315b0
--- /dev/null
+++ b/app/src/main/res/layout/activity_login.xml
@@ -0,0 +1,140 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_login_webview.xml b/app/src/main/res/layout/activity_login_webview.xml
new file mode 100644
index 0000000..3f1d48b
--- /dev/null
+++ b/app/src/main/res/layout/activity_login_webview.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/unlock_screen.xml b/app/src/main/res/layout/unlock_screen.xml
new file mode 100644
index 0000000..fe2a77b
--- /dev/null
+++ b/app/src/main/res/layout/unlock_screen.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/webview.xml b/app/src/main/res/layout/webview.xml
new file mode 100644
index 0000000..442d863
--- /dev/null
+++ b/app/src/main/res/layout/webview.xml
@@ -0,0 +1,6 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 76ecaa7..6a42361 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -150,4 +150,12 @@
- ,\nund %d weitere Nachricht
- ,\nund %d weitere Nachrichten
+ Bitte klicke die Schaltfäche unten und gib deinen Nutzernamen und dein Passwort ein, um zu zeigen, dass du am Alexander-von-Humboldt-Gymnasium beschäftigt bist.\n\nDieser Login ist nur einmalig und deine Informationen werden nicht mit anderen geteilt.
+ Hallo!
+ Dein Nutzername
+ Dein Password
+ Einloggen
+ Einloggen…
+ Lade Login-Seite erneut
+ Du bist eingeloggt!
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 6db86f5..4db2d9d 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -163,4 +163,12 @@
- ,\nand %d more message
- ,\nand %d more messages
+ Please click the button below to enter your username and password to verify that you\'re occupied at the Alexander-von-Humboldt-Gymnasium.\n\nThis login is only required once and your information will not be shared with anybody.
+ Hello there!
+ Your username
+ Your password
+ Log in
+ Logging in…
+ Load login page again
+ You have been logged in!