From d2ee6a21355c390a4aaefc6ea847060c8e47c6ae Mon Sep 17 00:00:00 2001 From: Isidro Henoch Date: Wed, 8 Dec 2021 02:09:47 -0600 Subject: 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 --- androidApp/build.gradle.kts | 1 + androidApp/src/main/AndroidManifest.xml | 16 ++++--- .../trackermap/TrackerMap/android/MainActivity.kt | 20 --------- .../mx/trackermap/TrackerMap/android/TrackerApp.kt | 9 +++- .../TrackerMap/android/devices/DevicesFragment.kt | 27 +++++++++++ .../TrackerMap/android/map/MapFragment.kt | 27 +++++++++++ .../TrackerMap/android/session/LoginFragment.kt | 21 +++++---- .../TrackerMap/android/session/LoginViewModel.kt | 29 ++++++------ .../TrackerMap/android/units/UnitsActivity.kt | 52 ++++++++++++++++++++++ .../TrackerMap/android/units/UnitsViewModel.kt | 25 +++++++++++ .../src/main/res/layout/devices_fragment.xml | 17 +++++++ androidApp/src/main/res/layout/map_fragment.xml | 17 +++++++ androidApp/src/main/res/layout/units_activity.xml | 31 +++++++++++++ .../kotlin/mx/trackermap/TrackerMap/Platform.kt | 5 --- .../kotlin/mx/trackermap/TrackerMap/Greeting.kt | 7 --- .../kotlin/mx/trackermap/TrackerMap/Platform.kt | 5 --- .../kotlin/mx/trackermap/TrackerMap/Platform.kt | 7 --- 17 files changed, 244 insertions(+), 72 deletions(-) delete mode 100644 androidApp/src/main/java/mx/trackermap/TrackerMap/android/MainActivity.kt create mode 100644 androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesFragment.kt create mode 100644 androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MapFragment.kt create mode 100644 androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt create mode 100644 androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsViewModel.kt create mode 100644 androidApp/src/main/res/layout/devices_fragment.xml create mode 100644 androidApp/src/main/res/layout/map_fragment.xml create mode 100644 androidApp/src/main/res/layout/units_activity.xml delete mode 100644 shared/src/androidMain/kotlin/mx/trackermap/TrackerMap/Platform.kt delete mode 100644 shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/Greeting.kt delete mode 100644 shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/Platform.kt delete mode 100644 shared/src/iosMain/kotlin/mx/trackermap/TrackerMap/Platform.kt diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts index 669b5cb..6292a1e 100644 --- a/androidApp/build.gradle.kts +++ b/androidApp/build.gradle.kts @@ -33,5 +33,6 @@ dependencies { 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("androidx.fragment:fragment-ktx:1.4.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 718fc5d..889342f 100644 --- a/androidApp/src/main/AndroidManifest.xml +++ b/androidApp/src/main/AndroidManifest.xml @@ -1,14 +1,17 @@ - + + + android:label="@string/app_name" + android:supportsRtl="true" + android:theme="@style/AppTheme"> @@ -17,5 +20,8 @@ + \ 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 = savedStateHandle.getLiveData("user", "") val password: MutableLiveData = savedStateHandle.getLiveData("password", "") - private val loginResultEmitter = EventEmitter() - val loginResult: EventSource = loginResultEmitter + private val loginStateEmitter = EventEmitter() + val loginState: EventSource = 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.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 @@ + + + + + + \ 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 @@ + + + + + + \ 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 @@ + + + + + + + + \ No newline at end of file diff --git a/shared/src/androidMain/kotlin/mx/trackermap/TrackerMap/Platform.kt b/shared/src/androidMain/kotlin/mx/trackermap/TrackerMap/Platform.kt deleted file mode 100644 index 8a30a29..0000000 --- a/shared/src/androidMain/kotlin/mx/trackermap/TrackerMap/Platform.kt +++ /dev/null @@ -1,5 +0,0 @@ -package mx.trackermap.TrackerMap - -actual class Platform actual constructor() { - actual val platform: String = "Android ${android.os.Build.VERSION.SDK_INT}" -} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/Greeting.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/Greeting.kt deleted file mode 100644 index 68b4100..0000000 --- a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/Greeting.kt +++ /dev/null @@ -1,7 +0,0 @@ -package mx.trackermap.TrackerMap - -class Greeting { - fun greeting(): String { - return "Hello, ${Platform().platform}!" - } -} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/Platform.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/Platform.kt deleted file mode 100644 index 9f39005..0000000 --- a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/Platform.kt +++ /dev/null @@ -1,5 +0,0 @@ -package mx.trackermap.TrackerMap - -expect class Platform() { - val platform: String -} \ No newline at end of file diff --git a/shared/src/iosMain/kotlin/mx/trackermap/TrackerMap/Platform.kt b/shared/src/iosMain/kotlin/mx/trackermap/TrackerMap/Platform.kt deleted file mode 100644 index 4c557dd..0000000 --- a/shared/src/iosMain/kotlin/mx/trackermap/TrackerMap/Platform.kt +++ /dev/null @@ -1,7 +0,0 @@ -package mx.trackermap.TrackerMap - -import platform.UIKit.UIDevice - -actual class Platform actual constructor() { - actual val platform: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion -} \ No newline at end of file -- cgit v1.2.3