diff options
author | Isidro Henoch <imhenoch@protonmail.com> | 2021-12-08 02:09:47 -0600 |
---|---|---|
committer | Isidro Henoch <imhenoch@protonmail.com> | 2021-12-08 02:09:47 -0600 |
commit | d2ee6a21355c390a4aaefc6ea847060c8e47c6ae (patch) | |
tree | 3a4000d6c933109a91add937827168ab0a18c1b7 /androidApp/src/main | |
parent | c80ece3087b862e1849ad5c2972b9b13fec2eb3f (diff) | |
download | etbsa-trackermap-mobile-d2ee6a21355c390a4aaefc6ea847060c8e47c6ae.tar.gz etbsa-trackermap-mobile-d2ee6a21355c390a4aaefc6ea847060c8e47c6ae.tar.bz2 etbsa-trackermap-mobile-d2ee6a21355c390a4aaefc6ea847060c8e47c6ae.zip |
WIP: Starts implementing the main activity
- Removes the MainActivity and the shared code it was using
- Adds the UnitsActivity
- Implements the Map/List toggle functionality
Diffstat (limited to 'androidApp/src/main')
12 files changed, 243 insertions, 48 deletions
diff --git a/androidApp/src/main/AndroidManifest.xml b/androidApp/src/main/AndroidManifest.xml index 718fc5d..889342f 100644 --- a/androidApp/src/main/AndroidManifest.xml +++ b/androidApp/src/main/AndroidManifest.xml @@ -1,14 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" +<manifest + xmlns:android="http://schemas.android.com/apk/res/android" package="mx.trackermap.TrackerMap.android"> + <uses-permission android:name="android.permission.INTERNET" /> + <application - android:label="@string/app_name" + android:name=".TrackerApp" android:allowBackup="false" - android:supportsRtl="true" - android:theme="@style/AppTheme" android:icon="@mipmap/ic_launcher" - android:name=".TrackerApp"> + android:label="@string/app_name" + android:supportsRtl="true" + android:theme="@style/AppTheme"> <activity android:name=".session.LoginActivity" android:exported="true"> @@ -17,5 +20,8 @@ <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> + <activity + android:name=".units.UnitsActivity" + android:exported="false"/> </application> </manifest>
\ No newline at end of file diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/MainActivity.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/MainActivity.kt deleted file mode 100644 index e7d1b5e..0000000 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/MainActivity.kt +++ /dev/null @@ -1,20 +0,0 @@ -package mx.trackermap.TrackerMap.android - -import androidx.appcompat.app.AppCompatActivity -import android.os.Bundle -import mx.trackermap.TrackerMap.Greeting -import android.widget.TextView - -fun greet(): String { - return Greeting().greeting() -} - -class MainActivity : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) - - val tv: TextView = findViewById(R.id.text_view) - tv.text = greet() - } -} diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt index 9331dcc..b236577 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt @@ -2,6 +2,9 @@ package mx.trackermap.TrackerMap.android import android.app.Application import mx.trackermap.TrackerMap.android.session.LoginViewModel +import mx.trackermap.TrackerMap.android.units.UnitsViewModel +import mx.trackermap.TrackerMap.client.apis.DevicesApi +import mx.trackermap.TrackerMap.client.apis.PositionsApi import mx.trackermap.TrackerMap.client.apis.SessionApi import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidLogger @@ -10,15 +13,19 @@ import org.koin.core.context.startKoin import org.koin.core.logger.Level import org.koin.dsl.module -class TrackerApp: Application() { +class TrackerApp : Application() { + override fun onCreate() { super.onCreate() val appModule = module { single { "https://etbsa.net/api" } single { SessionApi(get()) } + single { DevicesApi(get()) } + single { PositionsApi(get()) } viewModel { LoginViewModel(get(), get()) } + viewModel { UnitsViewModel() } } startKoin { diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesFragment.kt new file mode 100644 index 0000000..7e09b17 --- /dev/null +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesFragment.kt @@ -0,0 +1,27 @@ +package mx.trackermap.TrackerMap.android.devices + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import mx.trackermap.TrackerMap.android.databinding.DevicesFragmentBinding + +class DevicesFragment: Fragment() { + private var _binding: DevicesFragmentBinding? = null + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = DevicesFragmentBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +}
\ No newline at end of file diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MapFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MapFragment.kt new file mode 100644 index 0000000..0d4d91a --- /dev/null +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MapFragment.kt @@ -0,0 +1,27 @@ +package mx.trackermap.TrackerMap.android.map + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import mx.trackermap.TrackerMap.android.databinding.MapFragmentBinding + +class MapFragment: Fragment() { + private var _binding: MapFragmentBinding? = null + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = MapFragmentBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +}
\ 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 index 82d11d1..cc84f06 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginFragment.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginFragment.kt @@ -1,5 +1,6 @@ package mx.trackermap.TrackerMap.android.session +import android.content.Intent import android.os.Bundle import android.util.Log import android.view.LayoutInflater @@ -10,10 +11,10 @@ import androidx.core.widget.doAfterTextChanged import androidx.fragment.app.Fragment import com.zhuinden.liveevent.observe import mx.trackermap.TrackerMap.android.databinding.LoginBinding +import mx.trackermap.TrackerMap.android.units.UnitsActivity 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() @@ -53,23 +54,27 @@ class LoginFragment : Fragment() { } private fun setupObservers() { - loginViewModel.loginResult.observe(this) { result -> + loginViewModel.loginState.observe(this) { result -> Log.d("LoginFragment", result.toString()) when (result) { - LoginViewModel.LoginResult.Loading -> { + LoginViewModel.LoginState.Loading -> { Toast.makeText(context, "Loading...", Toast.LENGTH_SHORT).show() } - LoginViewModel.LoginResult.EmailMissing -> { + LoginViewModel.LoginState.EmailMissing -> { Toast.makeText(context, "Email is missing", Toast.LENGTH_SHORT).show() } - LoginViewModel.LoginResult.PasswordMissing -> { + LoginViewModel.LoginState.PasswordMissing -> { Toast.makeText(context, "Password is missing", Toast.LENGTH_SHORT).show() } - LoginViewModel.LoginResult.Failure -> { + LoginViewModel.LoginState.Failure -> { Toast.makeText(context, "Failed login", Toast.LENGTH_SHORT).show() } - LoginViewModel.LoginResult.Success -> { - Toast.makeText(context, "Success", Toast.LENGTH_SHORT).show() + LoginViewModel.LoginState.Success -> { + val activity = requireActivity() + val intent = Intent(activity.applicationContext, UnitsActivity::class.java) + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + startActivity(intent) + activity.finish() } } } 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 index 82c5bf9..8f53b7e 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginViewModel.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginViewModel.kt @@ -15,26 +15,27 @@ class LoginViewModel( savedStateHandle: SavedStateHandle ) : ViewModel() { - sealed class LoginResult { - object Loading: LoginResult() - object EmailMissing : LoginResult() - object PasswordMissing : LoginResult() - object Failure : LoginResult() - object Success : LoginResult() + sealed class LoginState { + object Loading: LoginState() + object EmailMissing : LoginState() + object PasswordMissing : LoginState() + object Failure : LoginState() + object Success : LoginState() } val email: MutableLiveData<String> = savedStateHandle.getLiveData("user", "") val password: MutableLiveData<String> = savedStateHandle.getLiveData("password", "") - private val loginResultEmitter = EventEmitter<LoginResult>() - val loginResult: EventSource<LoginResult> = loginResultEmitter + private val loginStateEmitter = EventEmitter<LoginState>() + val loginState: EventSource<LoginState> = loginStateEmitter fun restoreSession() { + loginStateEmitter.emit(LoginState.Loading); viewModelScope.launch { try { val user = sessionApi.sessionGet() Log.d("LoginViewModel", user.toString()) - loginResultEmitter.emit(LoginResult.Success) + loginStateEmitter.emit(LoginState.Success) } catch (e: Exception) { Log.d("LoginViewModel", "No session") } @@ -46,23 +47,23 @@ class LoginViewModel( val password = password.value!!.toString().trim() if (email.isEmpty()) { - loginResultEmitter.emit(LoginResult.EmailMissing) + loginStateEmitter.emit(LoginState.EmailMissing) return } if (password.isEmpty()) { - loginResultEmitter.emit(LoginResult.PasswordMissing) + loginStateEmitter.emit(LoginState.PasswordMissing) return } - loginResultEmitter.emit(LoginResult.Loading) + loginStateEmitter.emit(LoginState.Loading) viewModelScope.launch { try { val user = sessionApi.sessionPost(email, password) Log.d("LoginViewModel", user.toString()) - loginResultEmitter.emit(LoginResult.Success) + loginStateEmitter.emit(LoginState.Success) } catch (e: Exception) { - loginResultEmitter.emit(LoginResult.Failure) + loginStateEmitter.emit(LoginState.Failure) } } } diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt new file mode 100644 index 0000000..6e9bc83 --- /dev/null +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt @@ -0,0 +1,52 @@ +package mx.trackermap.TrackerMap.android.units + +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.commit +import mx.trackermap.TrackerMap.android.R +import mx.trackermap.TrackerMap.android.databinding.UnitsActivityBinding +import mx.trackermap.TrackerMap.android.devices.DevicesFragment +import mx.trackermap.TrackerMap.android.map.MapFragment +import org.koin.androidx.viewmodel.ext.android.viewModel + +class UnitsActivity : AppCompatActivity() { + + private var _binding: UnitsActivityBinding? = null + private val binding get() = _binding!! + + private val unitsViewModel: UnitsViewModel by viewModel() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + _binding = UnitsActivityBinding.inflate(layoutInflater) + setContentView(binding.root) + + setupEvents() + setupObservers() + } + + override fun onDestroy() { + super.onDestroy() + _binding = null + } + + private fun setupEvents() { + binding.displayModeToggle.setOnClickListener { + unitsViewModel.toggleDisplayMode() + } + } + + private fun setupObservers() { + unitsViewModel.unitsDisplayMode.observe(this) { displayMode -> + val newFragment = + when (displayMode) { + UnitsViewModel.UnitsDisplayMode.LIST -> DevicesFragment() + UnitsViewModel.UnitsDisplayMode.MAP -> MapFragment() + } + supportFragmentManager.commit { + replace(R.id.displayContainer, newFragment) + } + } + } +}
\ No newline at end of file diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsViewModel.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsViewModel.kt new file mode 100644 index 0000000..11df89b --- /dev/null +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsViewModel.kt @@ -0,0 +1,25 @@ +package mx.trackermap.TrackerMap.android.units + +import android.util.Log +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel + +class UnitsViewModel : ViewModel() { + + enum class UnitsDisplayMode { + MAP, LIST + } + + var unitsDisplayMode = MutableLiveData<UnitsDisplayMode>(UnitsDisplayMode.MAP) + + fun toggleDisplayMode() { + Log.d("UnitsViewModel", "Toggling Display mode") + val newDisplayMode = + if (unitsDisplayMode.value == UnitsDisplayMode.MAP) { + UnitsDisplayMode.LIST + } else { + UnitsDisplayMode.MAP + } + unitsDisplayMode.postValue(newDisplayMode) + } +}
\ No newline at end of file diff --git a/androidApp/src/main/res/layout/devices_fragment.xml b/androidApp/src/main/res/layout/devices_fragment.xml new file mode 100644 index 0000000..579afc2 --- /dev/null +++ b/androidApp/src/main/res/layout/devices_fragment.xml @@ -0,0 +1,17 @@ +<?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"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="DEVICES LIST" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintBottom_toBottomOf="parent"/> + +</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/androidApp/src/main/res/layout/map_fragment.xml b/androidApp/src/main/res/layout/map_fragment.xml new file mode 100644 index 0000000..8d36fc1 --- /dev/null +++ b/androidApp/src/main/res/layout/map_fragment.xml @@ -0,0 +1,17 @@ +<?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"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="MAP" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintBottom_toBottomOf="parent"/> + +</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/androidApp/src/main/res/layout/units_activity.xml b/androidApp/src/main/res/layout/units_activity.xml new file mode 100644 index 0000000..fa98bfc --- /dev/null +++ b/androidApp/src/main/res/layout/units_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"> + + <FrameLayout + android:id="@+id/displayContainer" + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_marginTop="16dp" + app:layout_constraintTop_toBottomOf="@id/displayModeToggle" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + android:background="@color/colorPrimary"/> + + <com.google.android.material.floatingactionbutton.FloatingActionButton + android:id="@+id/displayModeToggle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintEnd_toEndOf="parent" + android:backgroundTint="@android:color/white" + app:borderWidth="0dp" + app:fabSize="mini" + android:layout_marginEnd="16dp" + android:layout_marginTop="16dp"/> + +</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file |