Implemented login functionality at the school's request

This commit is contained in:
Deniz Düzgören
2019-09-20 15:49:09 +02:00
parent 8aec4ec4cd
commit 8684e763b1
21 changed files with 580 additions and 65 deletions
+2 -2
View File
@@ -10,8 +10,8 @@ android {
applicationId "com.denizd.substitutionplan" applicationId "com.denizd.substitutionplan"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 28 targetSdkVersion 28
versionCode 37 versionCode 38
versionName "2.2.14" versionName "2.3.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
buildTypes { buildTypes {
+7
View File
@@ -18,6 +18,13 @@
android:supportsRtl="true" android:supportsRtl="true"
tools:ignore="GoogleAppIndexingWarning"> tools:ignore="GoogleAppIndexingWarning">
<activity
android:name=".activities.Login"
android:label="Login"
android:screenOrientation="portrait"
android:theme="@style/AppTheme0.Launcher"
android:windowSoftInputMode="adjustPan"/>
<activity <activity
android:name=".activities.FirstTime" android:name=".activities.FirstTime"
android:label="First Time" android:label="First Time"
@@ -1,5 +1,6 @@
package com.denizd.substitutionplan.activities package com.denizd.substitutionplan.activities
import android.animation.LayoutTransition
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@@ -18,7 +19,7 @@ import android.widget.*
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat
import com.denizd.substitutionplan.R import com.denizd.substitutionplan.R
@@ -38,6 +39,9 @@ internal class FirstTime : AppCompatActivity(R.layout.activity_first_time) {
val window = this.window val window = this.window
context = this context = this
val parentLayout = findViewById<ConstraintLayout>(R.id.coordinatorLayout)
parentLayout.layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
val barColour = when { val barColour = when {
Build.VERSION.SDK_INT < Build.VERSION_CODES.M -> ContextCompat.getColor(context, R.color.legacyBlack) 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) 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) .putBoolean("colourTransferred", true)
.apply() .apply()
val cLayout = findViewById<CoordinatorLayout>(R.id.coordinatorLayout)
val linearInflation = findViewById<LinearLayout>(R.id.linearInflation) val linearInflation = findViewById<LinearLayout>(R.id.linearInflation)
val x: Int = fab.right - fab.width / 2 val x: Int = fab.right - fab.width / 2
val y: Int = fab.bottom- fab.height / 2 val y: Int = fab.bottom - fab.height / 2
val endRadius = hypot(cLayout.width.toDouble(), cLayout.height.toDouble()).toInt() val endRadius = hypot(parentLayout.width.toDouble(), parentLayout.height.toDouble()).toInt()
inflater.inflate(R.layout.welcome_screen, linearInflation, true) inflater.inflate(R.layout.welcome_screen, linearInflation, true)
val anim = ViewAnimationUtils.createCircularReveal(linearInflation, x, y, 0F, endRadius.toFloat()) val anim = ViewAnimationUtils.createCircularReveal(linearInflation, x, y, 0F, endRadius.toFloat())
val handler = Handler() val handler = Handler()
@@ -147,11 +150,11 @@ internal class FirstTime : AppCompatActivity(R.layout.activity_first_time) {
val mImgCheck = findViewById<ImageView>(R.id.imageView).drawable as AnimatedVectorDrawableCompat val mImgCheck = findViewById<ImageView>(R.id.imageView).drawable as AnimatedVectorDrawableCompat
mImgCheck.start() mImgCheck.start()
} }
}, 1000) }, 600)
handler.postDelayed({ handler.postDelayed({
startActivity(mainActivity) startActivity(mainActivity)
finish() finish()
}, 2000) }, 3000)
} }
} }
@@ -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<TextView>(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<LinearLayout>(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<WebView>(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<LinearLayout>(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<LinearLayout>(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<ImageView>(R.id.imageView).drawable as AnimatedVectorDrawable
mImgCheck.start()
} else {
val mImgCheck = findViewById<ImageView>(R.id.imageView).drawable as AnimatedVectorDrawableCompat
mImgCheck.start()
}
}, 600)
handler.postDelayed({
val main = Intent(this, Main::class.java)
startActivity(main)
finish()
}, 3000)
}
}
@@ -43,13 +43,17 @@ internal class Main : AppCompatActivity(R.layout.app_bar_main) {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
context = this context = this
prefs = PreferenceManager.getDefaultSharedPreferences(context) as SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context)
val edit = prefs.edit() val edit = prefs.edit()
val firstTime = Intent(context, FirstTime::class.java) val firstTime = Intent(context, FirstTime::class.java)
val login = Intent(context, Login::class.java)
Crashlytics.setUserIdentifier(prefs.getString("username", "") ?: "") Crashlytics.setUserIdentifier(prefs.getString("username", "") ?: "")
if (prefs.getBoolean("firstTime", true)) { if (!prefs.getBoolean("successful_login", false)) {
// if (true) { startActivity(login)
finish()
} else if (prefs.getBoolean("firstTime", true)) {
// } else if (true) {
startActivity(firstTime) startActivity(firstTime)
finish() finish()
} else { } else {
@@ -238,10 +242,10 @@ internal class Main : AppCompatActivity(R.layout.app_bar_main) {
} }
private fun personalPlanTitle(): String { 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) getString(R.string.yourPlan)
} else { } else {
val user = prefs.getString("username", "") ?: ""
if (user.endsWith("s", true) || user.endsWith("x", true) || user.endsWith("z", true)) { if (user.endsWith("s", true) || user.endsWith("x", true) || user.endsWith("z", true)) {
"$user${getString(R.string.noSPlan)}" "$user${getString(R.string.noSPlan)}"
} else { } else {
@@ -29,10 +29,7 @@ internal class ColourAdapter(private var mColours: List<Colour>, onClickListener
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ColourViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ColourViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false) val v = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
return ColourViewHolder( return ColourViewHolder(v, mOnClickListener)
v,
mOnClickListener
)
} }
override fun onBindViewHolder(holder: ColourViewHolder, position: Int) { override fun onBindViewHolder(holder: ColourViewHolder, position: Int) {
@@ -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)
}
}
@@ -47,7 +47,6 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
private lateinit var prefs: SharedPreferences private lateinit var prefs: SharedPreferences
private val builder = CustomTabsIntent.Builder() private val builder = CustomTabsIntent.Builder()
private val customTabsIntent = builder.build() as CustomTabsIntent private val customTabsIntent = builder.build() as CustomTabsIntent
private var cs: Int = 7
private var window: Window? = null private var window: Window? = null
private lateinit var colourRecycler: RecyclerView private lateinit var colourRecycler: RecyclerView
private lateinit var ringtoneCustomiserDialog: AlertDialog private lateinit var ringtoneCustomiserDialog: AlertDialog
@@ -253,19 +252,6 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
"\n---\n" + "\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.") "\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 -> { R.id.btnForceRefresh -> {
DataFetcher( DataFetcher(
isPlan = true, isPlan = true,
@@ -25,6 +25,7 @@ internal class FBPingService : JobService() {
private fun doBackgroundWork(params: JobParameters) { private fun doBackgroundWork(params: JobParameters) {
val prefs = PreferenceManager.getDefaultSharedPreferences(context) val prefs = PreferenceManager.getDefaultSharedPreferences(context)
FirebaseApp.initializeApp(context) FirebaseApp.initializeApp(context)
if (!prefs.getBoolean("firstTime", true)) {
FirebaseMessaging.getInstance().apply { FirebaseMessaging.getInstance().apply {
if (prefs.getBoolean("notif", true)) { if (prefs.getBoolean("notif", true)) {
subscribeToTopic(Topic.ANDROID.tag) subscribeToTopic(Topic.ANDROID.tag)
@@ -48,6 +49,7 @@ internal class FBPingService : JobService() {
prefs.edit().putInt("pingFB", prefs.getInt("pingFB", 0) + 1).apply() prefs.edit().putInt("pingFB", prefs.getInt("pingFB", 0) + 1).apply()
} }
}
jobFinished(params, false) jobFinished(params, false)
} }
} }
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
android:ordering="sequentially"
android:shareInterpolator="false">
<!-- Step 1 -->
<objectAnimator
android:duration="@android:integer/config_mediumAnimTime"
android:propertyName="pathData"
android:valueFrom="M 12 17 C 13.1 17 14 16.1 14 15 C 14 13.9 13.1 13 12 13 C 10.9 13 10 13.9 10 15 C 10 16.1 10.9 17 12 17 Z M 18 8 L 17 8 L 17 6 C 17 3.24 14.76 1 12 1 C 9.24 1 7 3 7 8 L 8.9 8 C 8.6 4 10.29 2.9 12 2.9 C 13.71 2.9 15.1 4.29 15.1 6 L 15.1 8 L 6 8 C 4.9 8 4 8.9 4 10 L 4 20 C 4 21.1 4.9 22 6 22 L 18 22 C 19.1 22 20 21.1 20 20 L 20 10 C 20 8.9 19.1 8 18 8 Z M 18 20 L 6 20 L 6 10 L 18 10 L 18 20 Z"
android:valueTo="M 12 17 C 13.1 17 14 16.1 14 15 C 14 13.9 13.1 13 12 13 C 10.9 13 10 13.9 10 15 C 10 16.1 10.9 17 12 17 Z M 18 8 L 17 8 L 17 6 C 17 3.24 14.76 1 12 1 C 9.24 1 7 3.24 7 6 L 8.9 6 C 8.9 4.29 10.29 2.9 12 2.9 C 13.71 2.9 15.1 4.29 15.1 6 L 15.1 8 L 6 8 C 4.9 8 4 8.9 4 10 L 4 20 C 4 21.1 4.9 22 6 22 L 18 22 C 19.1 22 20 21.1 20 20 L 20 10 C 20 8.9 19.1 8 18 8 Z M 18 20 L 6 20 L 6 10 L 18 10 L 18 20 Z"
android:valueType="pathType" />
</set>
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_closed_lock">
<target
android:name="lock"
android:animation="@animator/unlock_animation" />
</animated-vector>
+8 -8
View File
@@ -3,18 +3,18 @@
android:height="24dp" android:height="24dp"
android:viewportHeight="24.0" android:viewportHeight="24.0"
android:viewportWidth="24.0"> android:viewportWidth="24.0">
<group android:name="background"> <!-- <group android:name="background">-->
<path <!-- <path-->
android:name="circle" <!-- android:name="circle"-->
android:fillColor="@color/colorAccent" <!-- android:fillColor="@color/colorAccent"-->
android:pathData="M12,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0" /> <!-- android:pathData="M12,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0" />-->
</group> <!-- </group>-->
<group android:name="check"> <group android:name="check">
<path <path
android:name="tick" android:name="tick"
android:pathData="M6.5,12 l0,0 l0,0" android:pathData="M6.5,12 l0,0 l0,0"
android:strokeColor="@color/colorBackground" android:strokeColor="@color/colorAccent"
android:strokeWidth="1" /> android:strokeWidth="2" />
</group> </group>
</vector> </vector>
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:name="lock"
android:fillColor="@color/colorAccent"
android:pathData="M 12 17 C 13.1 17 14 16.1 14 15 C 14 13.9 13.1 13 12 13 C 10.9 13 10 13.9 10 15 C 10 16.1 10.9 17 12 17 Z M 18 8 L 17 8 L 17 6 C 17 3.24 14.76 1 12 1 C 9.24 1 7 3 7 8 L 8.9 8 C 8.6 4 10.29 2.9 12 2.9 C 13.71 2.9 15.1 4.29 15.1 6 L 15.1 8 L 6 8 C 4.9 8 4 8.9 4 10 L 4 20 C 4 21.1 4.9 22 6 22 L 18 22 C 19.1 22 20 21.1 20 20 L 20 10 C 20 8.9 19.1 8 18 8 Z M 18 20 L 6 20 L 6 10 L 18 10 L 18 20 Z" />
</vector>
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:name="lock"
android:fillColor="@color/colorAccent"
android:pathData="M12,17c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6h1.9c0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0 3.1,1.39 3.1,3.1v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM18,20L6,20L6,10h12v10z" />
</vector>
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/coordinatorLayout" android:id="@+id/coordinatorLayout"
@@ -7,7 +7,8 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/colorBackground" android:background="@color/colorBackground"
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
tools:context=".activities.FirstTime"> tools:context=".activities.FirstTime"
android:animateLayoutChanges="true">
<androidx.core.widget.NestedScrollView <androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -25,7 +26,7 @@
android:layout_marginTop="56dp" android:layout_marginTop="56dp"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:text="@string/welcome" android:text="@string/welcome"
android:textAlignment="center" android:textAlignment="viewStart"
android:textColor="@color/colorAccent" android:textColor="@color/colorAccent"
android:fontFamily="@font/manrope_extrabold" android:fontFamily="@font/manrope_extrabold"
android:textSize="28sp" android:textSize="28sp"
@@ -282,7 +283,19 @@
app:icon="@drawable/ic_tick" app:icon="@drawable/ic_tick"
app:iconTint="@color/colorBackground" app:iconTint="@color/colorBackground"
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"
android:translationZ="-1dp"/> android:translationZ="-1dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@+id/snackBarLayout"/>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/snackBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<LinearLayout <LinearLayout
android:id="@+id/linearInflation" android:id="@+id/linearInflation"
@@ -296,4 +309,4 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/> app:layout_constraintTop_toTopOf="parent"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.constraintlayout.widget.ConstraintLayout>
+140
View File
@@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="@color/colorBackground"
android:animateLayoutChanges="true">
<TextView
android:id="@+id/txtWelcome"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="56dp"
android:layout_marginStart="16dp"
android:text="@string/hello"
android:textAlignment="viewStart"
android:textColor="@color/colorAccent"
android:fontFamily="@font/manrope_extrabold"
android:textSize="28sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView android:id="@+id/loginRequiredText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/login_required"
android:textSize="14sp"
android:textColor="@color/colorText"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/txtWelcome"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/usernameTextLayout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="16dp"
android:hint="@string/username"
android:importantForAutofill="no"
android:textColorHint="@color/colorHint"
app:boxStrokeColor="@color/colorAccent"
app:boxStrokeWidth="1dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/loginRequiredText">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/usernameText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:animateLayoutChanges="true"
android:ems="10"
android:gravity="start"
android:imeOptions="flagNoExtractUi"
android:inputType="textNoSuggestions"
android:singleLine="true"
android:textColor="@color/colorText"
android:textSize="16sp" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/passwordTextLayout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
app:boxStrokeColor="@color/colorAccent"
app:boxStrokeWidth="1dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:hint="@string/password"
android:textColorHint="@color/colorHint"
android:importantForAutofill="no"
app:layout_constraintTop_toBottomOf="@+id/usernameTextLayout"
app:layout_constraintStart_toStartOf="@+id/usernameTextLayout"
app:layout_constraintEnd_toEndOf="@+id/usernameTextLayout">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/passwordText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:animateLayoutChanges="true"
android:ems="10"
android:gravity="start"
android:imeOptions="flagNoExtractUi"
android:inputType="textPassword"
android:singleLine="true"
android:textColor="@color/colorText"
android:textSize="16sp"/>
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/temporary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="subst plan"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/loginFab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:backgroundTint="@color/colorAccent"
android:text="@string/login"
android:textColor="@color/colorBackground"
app:icon="@drawable/ic_tick"
app:iconTint="@color/colorBackground"
android:layout_gravity="bottom|end"
android:translationZ="-1dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@+id/snackBarLayout"/>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/snackBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:clickable="false"
android:focusable="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="@color/colorBackground"
android:animateLayoutChanges="true">
<TextView
android:id="@+id/txtWelcome"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="56dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@string/hello"
android:textAlignment="viewStart"
android:textColor="@color/colorAccent"
android:fontFamily="@font/manrope_extrabold"
android:textSize="28sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@id/txtWelcome"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<TextView android:id="@+id/loginRequiredText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/login_required"
android:textSize="14sp"
android:textColor="@color/colorText"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"/>
</LinearLayout>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/loginFab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:backgroundTint="@color/colorAccent"
android:text="@string/login"
android:textColor="@color/colorBackground"
app:icon="@drawable/ic_open_lock"
app:iconTint="@color/colorBackground"
android:layout_gravity="bottom|end"
android:translationZ="-1dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<LinearLayout
android:id="@+id/layoutAfterCircleReveal"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/colorBackground"
android:orientation="vertical"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
+46
View File
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/animated_lock" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="@string/logged_in"
android:textAlignment="center"
android:textSize="30sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
<LinearLayout
android:id="@+id/colourLayout"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:background="@color/colorAccent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<WebView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
+8
View File
@@ -150,4 +150,12 @@
<item quantity="one">,\nund %d weitere Nachricht</item> <item quantity="one">,\nund %d weitere Nachricht</item>
<item quantity="other">,\nund %d weitere Nachrichten</item> <item quantity="other">,\nund %d weitere Nachrichten</item>
</plurals> </plurals>
<string name="login_required">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.</string>
<string name="hello">Hallo!</string>
<string name="username">Dein Nutzername</string>
<string name="password">Dein Password</string>
<string name="login">Einloggen</string>
<string name="logging_in">Einloggen…</string>
<string name="load_page_again">Lade Login-Seite erneut</string>
<string name="logged_in">Du bist eingeloggt!</string>
</resources> </resources>
+8
View File
@@ -163,4 +163,12 @@
<item quantity="one">,\nand %d more message</item> <item quantity="one">,\nand %d more message</item>
<item quantity="other">,\nand %d more messages</item> <item quantity="other">,\nand %d more messages</item>
</plurals> </plurals>
<string name="login_required">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.</string>
<string name="hello">Hello there!</string>
<string name="username">Your username</string>
<string name="password">Your password</string>
<string name="login">Log in</string>
<string name="logging_in">Logging in…</string>
<string name="load_page_again">Load login page again</string>
<string name="logged_in">You have been logged in!</string>
</resources> </resources>