aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsidro Henoch <imhenoch@protonmail.com>2021-12-06 01:04:55 -0600
committerIsidro Henoch <imhenoch@protonmail.com>2021-12-06 01:04:55 -0600
commit93c204bcd190b242f1dea49e52f28c795e4d0b92 (patch)
tree7fc0b2908afa4a63a1f144bc2d2718d91500333d
parente51f039b61b0a653b02f5d4d577bfe8f83286a16 (diff)
downloadetbsa-trackermap-mobile-93c204bcd190b242f1dea49e52f28c795e4d0b92.tar.gz
etbsa-trackermap-mobile-93c204bcd190b242f1dea49e52f28c795e4d0b92.tar.bz2
etbsa-trackermap-mobile-93c204bcd190b242f1dea49e52f28c795e4d0b92.zip
WIP: Implements the Login functionality
- Adds multiple android dependencies, for DI and some utilities - Updates colors and styles - Adds an Application - Adds the Login Fragment and ViewModel
-rw-r--r--androidApp/build.gradle.kts8
-rw-r--r--androidApp/src/main/AndroidManifest.xml5
-rw-r--r--androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt30
-rw-r--r--androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginActivity.kt14
-rw-r--r--androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginFragment.kt76
-rw-r--r--androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginViewModel.kt57
-rw-r--r--androidApp/src/main/res/layout/login.xml74
-rw-r--r--androidApp/src/main/res/layout/login_activity.xml31
-rw-r--r--androidApp/src/main/res/values/colors.xml6
-rw-r--r--androidApp/src/main/res/values/styles.xml2
-rw-r--r--build.gradle.kts2
11 files changed, 299 insertions, 6 deletions
diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts
index ccbc6c8..669b5cb 100644
--- a/androidApp/build.gradle.kts
+++ b/androidApp/build.gradle.kts
@@ -17,6 +17,9 @@ android {
isMinifyEnabled = false
}
}
+ buildFeatures {
+ viewBinding = true
+ }
}
dependencies {
@@ -25,5 +28,10 @@ dependencies {
implementation("androidx.appcompat:appcompat:1.4.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.2")
implementation("com.squareup.okhttp3:okhttp:3.14.2")
+ implementation("com.github.Zhuinden:live-event:1.2.0")
+ implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0")
+ implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:2.4.0")
+ implementation("io.insert-koin:koin-android:3.1.4")
+ implementation("androidx.core:core-ktx:1.7.0")
implementation(group = "", name = "WhirlyGlobeMaply", ext = "aar")
} \ No newline at end of file
diff --git a/androidApp/src/main/AndroidManifest.xml b/androidApp/src/main/AndroidManifest.xml
index 3d1df5c..142700c 100644
--- a/androidApp/src/main/AndroidManifest.xml
+++ b/androidApp/src/main/AndroidManifest.xml
@@ -7,9 +7,10 @@
android:allowBackup="false"
android:supportsRtl="true"
android:theme="@style/AppTheme"
- android:icon="@mipmap/ic_launcher">
+ android:icon="@mipmap/ic_launcher"
+ android:name=".TrackerApp">
<activity
- android:name=".MainActivity"
+ android:name=".session.LoginActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt
new file mode 100644
index 0000000..a8efbf2
--- /dev/null
+++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt
@@ -0,0 +1,30 @@
+package mx.trackermap.TrackerMap.android
+
+import android.app.Application
+import mx.trackermap.TrackerMap.android.session.LoginViewModel
+import mx.trackermap.TrackerMap.client.apis.SessionApi
+import org.koin.android.ext.koin.androidContext
+import org.koin.android.ext.koin.androidLogger
+import org.koin.androidx.viewmodel.dsl.viewModel
+import org.koin.core.context.startKoin
+import org.koin.core.logger.Level
+import org.koin.dsl.module
+
+class TrackerApp: Application() {
+ override fun onCreate() {
+ super.onCreate()
+
+ val appModule = module {
+ single { "https://etbsa.net/api/" }
+ single { SessionApi(get()) }
+
+ viewModel { LoginViewModel(get(), get()) }
+ }
+
+ startKoin {
+ androidLogger(Level.ERROR)
+ androidContext(this@TrackerApp)
+ modules(appModule)
+ }
+ }
+} \ No newline at end of file
diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginActivity.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginActivity.kt
new file mode 100644
index 0000000..3aec7b8
--- /dev/null
+++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginActivity.kt
@@ -0,0 +1,14 @@
+package mx.trackermap.TrackerMap.android.session
+
+import android.os.Bundle
+import android.os.PersistableBundle
+import android.util.Log
+import androidx.appcompat.app.AppCompatActivity
+import mx.trackermap.TrackerMap.android.R
+
+class LoginActivity: AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.login_activity)
+ }
+} \ No newline at end of file
diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginFragment.kt
new file mode 100644
index 0000000..5039a7c
--- /dev/null
+++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginFragment.kt
@@ -0,0 +1,76 @@
+package mx.trackermap.TrackerMap.android.session
+
+import android.os.Bundle
+import android.util.Log
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Toast
+import androidx.core.widget.doAfterTextChanged
+import androidx.fragment.app.Fragment
+import com.zhuinden.liveevent.observe
+import mx.trackermap.TrackerMap.android.databinding.LoginBinding
+import org.koin.androidx.viewmodel.ext.android.viewModel
+
+class LoginFragment : Fragment() {
+
+ private var _binding: LoginBinding? = null
+ private val binding get() = _binding!!
+ private val loginViewModel: LoginViewModel by viewModel()
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ _binding = LoginBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ setupEvents()
+ setupObservers()
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+
+ private fun setupEvents() {
+ binding.usernameEditText.doAfterTextChanged {
+ loginViewModel.email.value = it.toString()
+ }
+ binding.passwordEditText.doAfterTextChanged {
+ loginViewModel.password.value = it.toString()
+ }
+ binding.signinButton.setOnClickListener {
+ loginViewModel.login()
+ }
+ }
+
+ private fun setupObservers() {
+ loginViewModel.loginResult.observe(this) { result ->
+ Log.d("LoginFragment", result.toString())
+ when (result) {
+ LoginViewModel.LoginResult.Loading -> {
+ Toast.makeText(context, "Loading...", Toast.LENGTH_SHORT).show()
+ }
+ LoginViewModel.LoginResult.EmailMissing -> {
+ Toast.makeText(context, "Email is missing", Toast.LENGTH_SHORT).show()
+ }
+ LoginViewModel.LoginResult.PasswordMissing -> {
+ Toast.makeText(context, "Password is missing", Toast.LENGTH_SHORT).show()
+ }
+ LoginViewModel.LoginResult.Failure -> {
+ Toast.makeText(context, "Failed login", Toast.LENGTH_SHORT).show()
+ }
+ LoginViewModel.LoginResult.Success -> {
+ Toast.makeText(context, "Success", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginViewModel.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginViewModel.kt
new file mode 100644
index 0000000..9df78aa
--- /dev/null
+++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginViewModel.kt
@@ -0,0 +1,57 @@
+package mx.trackermap.TrackerMap.android.session
+
+import android.util.Log
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.SavedStateHandle
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import com.zhuinden.eventemitter.EventEmitter
+import com.zhuinden.eventemitter.EventSource
+import kotlinx.coroutines.launch
+import mx.trackermap.TrackerMap.client.apis.SessionApi
+
+class LoginViewModel(
+ private val sessionApi: SessionApi,
+ savedStateHandle: SavedStateHandle
+) : ViewModel() {
+
+ sealed class LoginResult {
+ object Loading: LoginResult()
+ object EmailMissing : LoginResult()
+ object PasswordMissing : LoginResult()
+ object Failure : LoginResult()
+ object Success : LoginResult()
+ }
+
+ val email: MutableLiveData<String> = savedStateHandle.getLiveData("user", "")
+ val password: MutableLiveData<String> = savedStateHandle.getLiveData("password", "")
+
+ private val loginResultEmitter = EventEmitter<LoginResult>()
+ val loginResult: EventSource<LoginResult> = loginResultEmitter
+
+ fun login() {
+ val email = email.value!!.toString().trim()
+ val password = password.value!!.toString().trim()
+
+ if (email.isEmpty()) {
+ loginResultEmitter.emit(LoginResult.EmailMissing)
+ return
+ }
+
+ if (password.isEmpty()) {
+ loginResultEmitter.emit(LoginResult.PasswordMissing)
+ return
+ }
+
+ loginResultEmitter.emit(LoginResult.Loading)
+ viewModelScope.launch {
+ try {
+ val user = sessionApi.sessionPost(email, password)
+ Log.d("LoginViewModel", user.toString())
+ loginResultEmitter.emit(LoginResult.Success)
+ } catch (e: Exception) {
+ loginResultEmitter.emit(LoginResult.Failure)
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/androidApp/src/main/res/layout/login.xml b/androidApp/src/main/res/layout/login.xml
new file mode 100644
index 0000000..0a5f07a
--- /dev/null
+++ b/androidApp/src/main/res/layout/login.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.cardview.widget.CardView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:name="mx.trackermap.TrackerMap.android.session.LoginFragment"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:cardCornerRadius="20dp"
+ app:cardElevation="5dp"
+ app:cardUseCompatPadding="true">
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingVertical="32dp"
+ android:paddingHorizontal="16dp">
+
+ <com.google.android.material.textfield.TextInputLayout
+ android:id="@+id/usernameInputLayout"
+ style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:hint="Username"
+ app:layout_constraintBottom_toTopOf="@+id/passwordInputLayout"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="0.5"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent">
+
+ <com.google.android.material.textfield.TextInputEditText
+ android:id="@+id/usernameEditText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="textEmailAddress"/>
+
+ </com.google.android.material.textfield.TextInputLayout>
+
+ <com.google.android.material.textfield.TextInputLayout
+ android:id="@+id/passwordInputLayout"
+ style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:hint="Password"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="0.5"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/usernameInputLayout"
+ app:layout_constraintBottom_toTopOf="@id/signinButton"
+ android:layout_marginTop="24dp">
+
+ <com.google.android.material.textfield.TextInputEditText
+ android:id="@+id/passwordEditText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="textPassword"/>
+
+ </com.google.android.material.textfield.TextInputLayout>
+
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/signinButton"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ app:layout_constraintWidth_percent="0.5"
+ app:layout_constraintTop_toBottomOf="@id/passwordInputLayout"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintHorizontal_bias="0.5"
+ android:layout_marginTop="40dp"
+ android:text="Log in"/>
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+</androidx.cardview.widget.CardView> \ No newline at end of file
diff --git a/androidApp/src/main/res/layout/login_activity.xml b/androidApp/src/main/res/layout/login_activity.xml
new file mode 100644
index 0000000..f1df817
--- /dev/null
+++ b/androidApp/src/main/res/layout/login_activity.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+
+ <androidx.appcompat.widget.AppCompatImageView
+ android:id="@+id/bannerImage"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ app:layout_constraintWidth_percent="0.7"
+ app:layout_constraintDimensionRatio="1"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:srcCompat="@drawable/ic_launcher_foreground" />
+
+ <fragment
+ android:id="@+id/loginFragment"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:name="mx.trackermap.TrackerMap.android.session.LoginFragment"
+ app:layout_constraintTop_toBottomOf="@id/bannerImage"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ android:layout_marginStart="16dp"
+ android:layout_marginEnd="16dp"
+ android:layout_marginBottom="16dp"/>
+
+</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/androidApp/src/main/res/values/colors.xml b/androidApp/src/main/res/values/colors.xml
index 4faecfa..8fb5f28 100644
--- a/androidApp/src/main/res/values/colors.xml
+++ b/androidApp/src/main/res/values/colors.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <color name="colorPrimary">#6200EE</color>
- <color name="colorPrimaryDark">#3700B3</color>
- <color name="colorAccent">#03DAC5</color>
+ <color name="colorPrimary">#656A74</color>
+ <color name="colorPrimaryDark">#43474E</color>
+ <color name="colorAccent">#EB473E</color>
</resources> \ No newline at end of file
diff --git a/androidApp/src/main/res/values/styles.xml b/androidApp/src/main/res/values/styles.xml
index 1971a0a..4a51239 100644
--- a/androidApp/src/main/res/values/styles.xml
+++ b/androidApp/src/main/res/values/styles.xml
@@ -1,6 +1,6 @@
<resources>
- <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
+ <style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
diff --git a/build.gradle.kts b/build.gradle.kts
index 4602dde..411be83 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -3,6 +3,7 @@ buildscript {
gradlePluginPortal()
google()
mavenCentral()
+ maven("https://jitpack.io")
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0")
@@ -15,6 +16,7 @@ allprojects {
repositories {
google()
mavenCentral()
+ maven("https://jitpack.io")
flatDir {
dirs("libs")
}