diff --git a/app/src/main/java/com/example/bondoman/LoginActivity.kt b/app/src/main/java/com/example/bondoman/LoginActivity.kt index 0b07382716725d6866e1f53f5b133343e9b2a0f6..3d1ac63ac0df379fc9521c057223fba276b77d3b 100644 --- a/app/src/main/java/com/example/bondoman/LoginActivity.kt +++ b/app/src/main/java/com/example/bondoman/LoginActivity.kt @@ -32,6 +32,7 @@ class LoginActivity : AppCompatActivity() { private fun replaceFragment(fragment: Fragment){ val fragmentManager = supportFragmentManager val fragmentTransaction = fragmentManager.beginTransaction() + fragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out) fragmentTransaction.replace(R.id.login_layout,fragment) fragmentTransaction.commit() } diff --git a/app/src/main/java/com/example/bondoman/MainActivity.kt b/app/src/main/java/com/example/bondoman/MainActivity.kt index 7229152a018354814f6062b8061c789facd4de60..3fdd64c4b967ea76060c2d26dce2f1542c77ac3e 100644 --- a/app/src/main/java/com/example/bondoman/MainActivity.kt +++ b/app/src/main/java/com/example/bondoman/MainActivity.kt @@ -4,6 +4,7 @@ import android.Manifest.permission.ACCESS_COARSE_LOCATION import android.Manifest.permission.ACCESS_FINE_LOCATION import android.app.AlertDialog import android.content.Context +import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.os.Handler @@ -27,8 +28,10 @@ import com.example.bondoman.models.TransactionViewModel import com.example.bondoman.room.BondomanDatabase import android.os.Build import android.util.Log.w +import android.widget.Toast import androidx.appcompat.widget.Toolbar import com.example.bondoman.ui.nointernet.NoInternetFragment +import kotlinx.coroutines.withContext import retrofit2.HttpException class MainActivity : AppCompatActivity() { @@ -75,19 +78,19 @@ class MainActivity : AppCompatActivity() { binding.bottomNavigationView.setOnItemSelectedListener { when(it.itemId){ R.id.bottom_nav_chart -> { - replaceFragment(ChartFragment(), NoInternetFragment(), "Chart") + replaceFragment(ChartFragment(), ChartFragment(), "Chart") } R.id.bottom_nav_scan -> { replaceFragment(ScanFragment(), NoInternetFragment(), "Scan") } R.id.bottom_nav_cart -> { - replaceFragment(CartFragment(), NoInternetFragment(),"Cart") + replaceFragment(CartFragment(), CartFragment(),"Cart") } R.id.bottom_nav_twibbon -> { - replaceFragment(TwibbonFragment(), NoInternetFragment(),"Twibbon") + replaceFragment(TwibbonFragment(), TwibbonFragment(),"Twibbon") } R.id.bottom_nav_settings -> { - replaceFragment(SettingsFragment(), NoInternetFragment(),"Settings") + replaceFragment(SettingsFragment(),SettingsFragment(),"Settings") } else -> { @@ -124,13 +127,20 @@ class MainActivity : AppCompatActivity() { private fun backgroundWorker(){ println("excuting background worker") val service = RetrofitClient.createRetrofitService(this) + val context = this@MainActivity CoroutineScope(Dispatchers.IO).launch { try { val response = service.checkToken() if (response.isSuccessful) { - println(response) + println("token still valid") } else { - println("Error: ${response.code()}") + clearToken() + withContext(Dispatchers.Main) { + Toast.makeText(context, "Your Session Has Expired", Toast.LENGTH_LONG).show() + } + + startActivity(Intent(context, LoginActivity::class.java)) + finish() } } catch (e: HttpException) { println("Exception ${e.message}") @@ -140,6 +150,13 @@ class MainActivity : AppCompatActivity() { } } + + private fun clearToken() { + val sharedPreferences = getSharedPreferences("BondoMan", Context.MODE_PRIVATE) + val editor = sharedPreferences.edit() + editor.clear().apply() + } + private fun isNetworkConnected(context: Context): Boolean { val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val network = connectivityManager.activeNetwork ?: return false @@ -147,15 +164,8 @@ class MainActivity : AppCompatActivity() { return networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) } - private fun showNoInternetDialog(context: Context) { - val builder = AlertDialog.Builder(context) - builder.setTitle("No Internet Connection") - .setMessage("Please check your internet connection and try again.") - .setPositiveButton("OK") { dialog, _ -> dialog.dismiss() } - val dialog = builder.create() - dialog.show() - } + private fun replaceFragment(fragment: Fragment, noInternetFragment: Fragment, headerTitle : String){ val fragmentManager = supportFragmentManager @@ -163,7 +173,7 @@ class MainActivity : AppCompatActivity() { if (this.isNetworkConnected(this)){ fragmentTransaction.replace(R.id.main_frame_layout,fragment) }else{ - showNoInternetDialog(this) + Toast.makeText(this, "Network Has Been Disconnected", Toast.LENGTH_LONG).show() fragmentTransaction.replace(R.id.main_frame_layout,noInternetFragment) } setTitle(headerTitle) diff --git a/app/src/main/java/com/example/bondoman/services/RetrofitInstance.kt b/app/src/main/java/com/example/bondoman/services/RetrofitInstance.kt index f7abcc7a544270da5c3eca0f5dfd5f0b373c12a9..48f1e06e0e686f387050f99f6f8ea17b16077496 100644 --- a/app/src/main/java/com/example/bondoman/services/RetrofitInstance.kt +++ b/app/src/main/java/com/example/bondoman/services/RetrofitInstance.kt @@ -24,7 +24,6 @@ object RetrofitClient { val originalRequest: Request = chain.request() val requestBuilder: Request.Builder = originalRequest.newBuilder() if (!authToken.isNullOrEmpty()) { - println(authToken) requestBuilder.header("Authorization", "Bearer $authToken") // Add authorization header here } val request: Request = requestBuilder.build() diff --git a/app/src/main/java/com/example/bondoman/ui/login/LoginFragment.kt b/app/src/main/java/com/example/bondoman/ui/login/LoginFragment.kt index b4bebcc4e98708ebf8d7398c03ca0d76203effec..bd759b9ee8d60eb2c6c7fea2d5e8b67fdf6b199e 100644 --- a/app/src/main/java/com/example/bondoman/ui/login/LoginFragment.kt +++ b/app/src/main/java/com/example/bondoman/ui/login/LoginFragment.kt @@ -17,6 +17,10 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.withContext import retrofit2.HttpException import android.content.Context +import android.content.SharedPreferences +import android.net.ConnectivityManager +import android.net.NetworkCapabilities +import android.widget.Toast // TODO: Rename parameter arguments, choose names that match @@ -60,41 +64,56 @@ class LoginFragment : Fragment() { val email = binding.emailInput.text.toString() val password = binding.passwordInput.text.toString() - apiCall(email, password) + login(email, password) } } - private fun apiCall(email: String, password: String) { + private fun login(email: String, password: String) { val loginRequest = LoginRequest(email, password) val service = RetrofitClient.createRetrofitService(requireContext()) - - CoroutineScope(Dispatchers.IO).launch { - val response = service.login(loginRequest) - withContext(Dispatchers.Main) { - try { - if (response.isSuccessful) { - val token = response.body()?.token - if(!token.isNullOrEmpty()){ - val sharedPreferences = requireActivity().getSharedPreferences("BondoMan", Context.MODE_PRIVATE) - val editor = sharedPreferences.edit() - editor.putString("token", token) - editor.apply() - startActivity(Intent(activity, MainActivity::class.java)) - activity?.finish() + if (!isNetworkConnected(requireContext())){ + Toast.makeText(requireContext(), "Network is Disconnected Unable To Login", Toast.LENGTH_LONG).show() + } + else { + CoroutineScope(Dispatchers.IO).launch { + val response = service.login(loginRequest) + withContext(Dispatchers.Main) { + try { + if (response.isSuccessful) { + val token = response.body()?.token + if (!token.isNullOrEmpty()) { + val sharedPreferences = requireActivity().getSharedPreferences( + "BondoMan", + Context.MODE_PRIVATE + ) + val editor = sharedPreferences.edit() + editor.putString("token", token) + editor.putString("email", email) + editor.apply() + startActivity(Intent(activity, MainActivity::class.java)) + activity?.finish() + } + } else { + println("Error: ${response.code()}") } - } else { - println("Error: ${response.code()}") + } catch (e: HttpException) { + println("Exception ${e.message}") + } catch (e: Throwable) { + println(e) } - } catch (e: HttpException) { - println("Exception ${e.message}") - } catch (e: Throwable) { - println(e) } } } } + private fun isNetworkConnected(context: Context): Boolean { + val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val network = connectivityManager.activeNetwork ?: return false + val networkCapabilities = connectivityManager.getNetworkCapabilities(network) ?: return false + return networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + } + companion object { /** * Use this factory method to create a new instance of diff --git a/app/src/main/java/com/example/bondoman/ui/twibbon/TwibbonFragment.kt b/app/src/main/java/com/example/bondoman/ui/twibbon/TwibbonFragment.kt index 4d2e39e84bd1c78088f4405d0e168c0221fcb686..c52485de8a0681e6d091385997746b8cedfa3563 100644 --- a/app/src/main/java/com/example/bondoman/ui/twibbon/TwibbonFragment.kt +++ b/app/src/main/java/com/example/bondoman/ui/twibbon/TwibbonFragment.kt @@ -18,6 +18,7 @@ import java.util.concurrent.Executors import android.content.Context import android.content.Intent import android.graphics.BitmapFactory +import android.net.Uri import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts import androidx.camera.lifecycle.ProcessCameraProvider @@ -52,6 +53,8 @@ class TwibbonFragment : Fragment() { private var previewFrozen: Boolean = false + private val PICK_IMAGE_REQUEST = 1 + private val activityResultLauncher = registerForActivityResult( ActivityResultContracts.RequestMultiplePermissions()) @@ -94,6 +97,7 @@ class TwibbonFragment : Fragment() { } viewBinding.twibbonCaptureButton.setOnClickListener { takePhoto() } + viewBinding.changeTwibbonButton.setOnClickListener { pickTwibbonFromGallery() } cameraExecutor = Executors.newSingleThreadExecutor() } @@ -152,6 +156,21 @@ class TwibbonFragment : Fragment() { startCamera() } + private fun pickTwibbonFromGallery() { + val intent = Intent(Intent.ACTION_PICK) + intent.type = "image/png" + startActivityForResult(intent, PICK_IMAGE_REQUEST) + } + + @Deprecated("Deprecated in Java") + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (requestCode == PICK_IMAGE_REQUEST && resultCode == Activity.RESULT_OK && data != null) { + val imageUri: Uri? = data.data + viewBinding.twibbonOverlay.setImageURI(imageUri) + } + } + override fun onDestroy() { super.onDestroy() diff --git a/app/src/main/res/layout/fragment_twibbon.xml b/app/src/main/res/layout/fragment_twibbon.xml index 94ad224df90a1aa08d77013916b01f921b0f40f4..ea8bc086dd0ac0738863ea8022af79c80cf8c163 100644 --- a/app/src/main/res/layout/fragment_twibbon.xml +++ b/app/src/main/res/layout/fragment_twibbon.xml @@ -26,7 +26,7 @@ android:layout_marginTop="43dp" /> <ImageView - android:id="@+id/imageView3" + android:id="@+id/twibbonOverlay" android:layout_width="wrap_content" android:layout_height="369dp" android:src="@drawable/bondoman_logo" @@ -37,14 +37,27 @@ <Button android:id="@+id/twibbonCaptureButton" android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="16dp" + android:layout_height="60dp" android:fontFamily="sans-serif" - android:text="capture" + android:text="Capture" + app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.498" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/textView2" /> + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="0.743" /> + + <ImageView + android:id="@+id/changeTwibbonButton" + android:layout_width="60dp" + android:layout_height="60dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.15" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="0.743" + app:srcCompat="@android:drawable/ic_menu_gallery" /> <TextView android:id="@+id/textView2"