integrated Jetpack navigation to project so we dont have to manually code the functionallities of loading to different fragments

This commit is contained in:
Alex
2026-04-04 20:08:40 -06:00
parent e25a02fe1f
commit be79de7c82
33 changed files with 508 additions and 455 deletions

View File

@@ -3,6 +3,7 @@ import java.util.Properties
plugins { plugins {
alias(libs.plugins.android.application) alias(libs.plugins.android.application)
alias(libs.plugins.hilt) alias(libs.plugins.hilt)
alias(libs.plugins.navigation.safeargs)
} }
val localProperties = Properties().apply { val localProperties = Properties().apply {
@@ -64,6 +65,9 @@ dependencies {
implementation(libs.hilt.android) implementation(libs.hilt.android)
annotationProcessor(libs.hilt.compiler) annotationProcessor(libs.hilt.compiler)
implementation(libs.navigation.fragment)
implementation(libs.navigation.ui)
implementation("com.squareup.retrofit2:retrofit:2.9.0") implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0") implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.12.0") implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")

View File

@@ -15,12 +15,11 @@ import androidx.core.content.ContextCompat;
import androidx.core.graphics.Insets; import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.Fragment; import androidx.navigation.NavController;
import androidx.navigation.fragment.NavHostFragment;
import androidx.navigation.ui.NavigationUI;
import com.example.petstoremobile.R; import com.example.petstoremobile.R;
import com.example.petstoremobile.fragments.ChatFragment;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.ProfileFragment;
import com.example.petstoremobile.services.ChatNotificationService; import com.example.petstoremobile.services.ChatNotificationService;
import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.bottomnavigation.BottomNavigationView;
@@ -29,6 +28,7 @@ import dagger.hilt.android.AndroidEntryPoint;
@AndroidEntryPoint @AndroidEntryPoint
public class HomeActivity extends AppCompatActivity { public class HomeActivity extends AppCompatActivity {
private BottomNavigationView bottomNav; private BottomNavigationView bottomNav;
private NavController navController;
// Launcher to ask for notification permission // Launcher to ask for notification permission
private final ActivityResultLauncher<String> requestPermissionLauncher = private final ActivityResultLauncher<String> requestPermissionLauncher =
@@ -52,66 +52,52 @@ public class HomeActivity extends AppCompatActivity {
//get the bottom navbar from the layout //get the bottom navbar from the layout
bottomNav = findViewById(R.id.bottom_navigation); bottomNav = findViewById(R.id.bottom_navigation);
// Initialize Navigation Component
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager()
.findFragmentById(R.id.nav_host_fragment);
if (navHostFragment != null) {
navController = navHostFragment.getNavController();
NavigationUI.setupWithNavController(bottomNav, navController);
}
//load the list fragment by default if it's a fresh start //load the list fragment by default if it's a fresh start
if (savedInstanceState == null) { if (savedInstanceState == null) {
handleIntent(getIntent()); handleIntent(getIntent());
} }
//when an item in the bottom bar is selected, load the corresponding fragment
bottomNav.setOnItemSelectedListener(item -> {
if (item.getItemId() == R.id.nav_list) {
loadFragment(new ListFragment());
return true;
} else if (item.getItemId() == R.id.nav_chat) {
loadFragment(new ChatFragment());
return true;
} else if (item.getItemId() == R.id.nav_profile) {
loadFragment(new ProfileFragment());
return true;
}
return false;
});
// Start the notification service and request for notification permission // Start the notification service and request for notification permission
startNotificationService(); startNotificationService();
requestNotificationPermission(); requestNotificationPermission();
} }
// Handle new intents when the activity is already running,
// like clicking a notification while the app is in use
@Override @Override
protected void onNewIntent(Intent intent) { protected void onNewIntent(Intent intent) {
super.onNewIntent(intent); super.onNewIntent(intent);
handleIntent(intent); handleIntent(intent);
} }
// Helper function to process intents for navigation.
// like clicking a notification or just launching the app from a fresh start
private void handleIntent(Intent intent) { private void handleIntent(Intent intent) {
if (intent != null && "chat".equals(intent.getStringExtra("navigate_to"))) { if (intent != null && "chat".equals(intent.getStringExtra("navigate_to"))) {
ChatFragment chatFragment = new ChatFragment(); Bundle args = new Bundle();
if (intent.hasExtra("conversation_id")) { if (intent.hasExtra("conversation_id")) {
Bundle args = new Bundle();
args.putLong("conversation_id", intent.getLongExtra("conversation_id", -1)); args.putLong("conversation_id", intent.getLongExtra("conversation_id", -1));
chatFragment.setArguments(args);
} }
loadFragment(chatFragment); // Use NavController to navigate
bottomNav.setSelectedItemId(R.id.nav_chat); if (navController != null) {
} else { navController.navigate(R.id.nav_chat, args);
loadFragment(new ListFragment()); }
bottomNav.setSelectedItemId(R.id.nav_list);
} }
} }
// Helper function to start the notification service in the background // Function to start the notification service in the background
// to receive notifications when a new conversation is created // to receive notifications when a new conversation is created
private void startNotificationService() { private void startNotificationService() {
Intent serviceIntent = new Intent(this, ChatNotificationService.class); Intent serviceIntent = new Intent(this, ChatNotificationService.class);
startService(serviceIntent); startService(serviceIntent);
} }
//Helper function to request for notification permission //Function to request for notification permission
private void requestNotificationPermission() { private void requestNotificationPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
@@ -119,12 +105,4 @@ public class HomeActivity extends AppCompatActivity {
} }
} }
} }
//Helper function to load a fragment
private void loadFragment(Fragment fragment) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, fragment)
.commit();
}
} }

View File

@@ -11,6 +11,8 @@ import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.LazyHeaders;
import com.example.petstoremobile.R; import com.example.petstoremobile.R;
import com.example.petstoremobile.api.PetApi; import com.example.petstoremobile.api.PetApi;
import com.example.petstoremobile.dtos.PetDTO; import com.example.petstoremobile.dtos.PetDTO;
@@ -21,6 +23,7 @@ public class PetAdapter extends RecyclerView.Adapter<PetAdapter.PetViewHolder> {
private List<PetDTO> petList; private List<PetDTO> petList;
private OnPetClickListener petClickListener; private OnPetClickListener petClickListener;
private String baseUrl; private String baseUrl;
private String token;
// Interface for pet click on recycler view // Interface for pet click on recycler view
public interface OnPetClickListener { public interface OnPetClickListener {
@@ -37,6 +40,10 @@ public class PetAdapter extends RecyclerView.Adapter<PetAdapter.PetViewHolder> {
this.baseUrl = baseUrl; this.baseUrl = baseUrl;
} }
public void setToken(String token) {
this.token = token;
}
// Get the controls of each row in recycler view // Get the controls of each row in recycler view
public static class PetViewHolder extends RecyclerView.ViewHolder { public static class PetViewHolder extends RecyclerView.ViewHolder {
TextView tvPetName, tvPetSpeciesBreed, tvPetAge, tvPetPrice, tvPetStatus; TextView tvPetName, tvPetSpeciesBreed, tvPetAge, tvPetPrice, tvPetStatus;
@@ -89,11 +96,18 @@ public class PetAdapter extends RecyclerView.Adapter<PetAdapter.PetViewHolder> {
// Load pet image using Glide with circle crop // Load pet image using Glide with circle crop
if (baseUrl != null) { if (baseUrl != null) {
String imageUrl = baseUrl + String.format(PetApi.PET_IMAGE_PATH, pet.getPetId()); String imageUrl = baseUrl + String.format(PetApi.PET_IMAGE_PATH, pet.getPetId());
Object loadTarget = imageUrl;
if (token != null) {
loadTarget = new GlideUrl(imageUrl, new LazyHeaders.Builder()
.addHeader("Authorization", "Bearer " + token)
.build());
}
Glide.with(holder.itemView.getContext()) Glide.with(holder.itemView.getContext())
.load(imageUrl) .load(loadTarget)
.circleCrop() .circleCrop()
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.ALL) // Changed to ALL for better performance
.skipMemoryCache(true)
.placeholder(R.drawable.placeholder) .placeholder(R.drawable.placeholder)
.error(R.drawable.placeholder) .error(R.drawable.placeholder)
.into(holder.ivPetProfile); .into(holder.ivPetProfile);

View File

@@ -8,6 +8,8 @@ import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.LazyHeaders;
import com.example.petstoremobile.R; import com.example.petstoremobile.R;
import com.example.petstoremobile.api.ProductApi; import com.example.petstoremobile.api.ProductApi;
import com.example.petstoremobile.dtos.ProductDTO; import com.example.petstoremobile.dtos.ProductDTO;
@@ -18,6 +20,7 @@ public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductV
private List<ProductDTO> productList; private List<ProductDTO> productList;
private OnProductClickListener listener; private OnProductClickListener listener;
private String baseUrl; private String baseUrl;
private String token;
public interface OnProductClickListener { public interface OnProductClickListener {
void onProductClick(int position); void onProductClick(int position);
@@ -32,6 +35,10 @@ public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductV
this.baseUrl = baseUrl; this.baseUrl = baseUrl;
} }
public void setToken(String token) {
this.token = token;
}
public static class ProductViewHolder extends RecyclerView.ViewHolder { public static class ProductViewHolder extends RecyclerView.ViewHolder {
TextView tvName, tvCategory, tvDesc, tvPrice; TextView tvName, tvCategory, tvDesc, tvPrice;
ImageView ivProductImage; ImageView ivProductImage;
@@ -65,11 +72,18 @@ public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductV
// Load product image using Glide // Load product image using Glide
if (baseUrl != null) { if (baseUrl != null) {
String imageUrl = baseUrl + String.format(ProductApi.PRODUCT_IMAGE_PATH, p.getProdId()); String imageUrl = baseUrl + String.format(ProductApi.PRODUCT_IMAGE_PATH, p.getProdId());
Object loadTarget = imageUrl;
if (token != null) {
loadTarget = new GlideUrl(imageUrl, new LazyHeaders.Builder()
.addHeader("Authorization", "Bearer " + token)
.build());
}
Glide.with(holder.itemView.getContext()) Glide.with(holder.itemView.getContext())
.load(imageUrl) .load(loadTarget)
.circleCrop() .circleCrop()
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.ALL)
.skipMemoryCache(true)
.placeholder(R.drawable.placeholder) .placeholder(R.drawable.placeholder)
.error(R.drawable.placeholder) .error(R.drawable.placeholder)
.into(holder.ivProductImage); .into(holder.ivProductImage);

View File

@@ -178,6 +178,7 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
String role = tokenManager.getRole(); String role = tokenManager.getRole();
messageAdapter.setCurrentUserId(currentUserId); messageAdapter.setCurrentUserId(currentUserId);
messageAdapter.setToken(token);
// if token exist then connect to websocket // if token exist then connect to websocket
if (token != null) { if (token != null) {

View File

@@ -2,9 +2,13 @@ package com.example.petstoremobile.fragments;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.GravityCompat; import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout; import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.fragment.NavHostFragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@@ -15,16 +19,6 @@ import android.widget.LinearLayout;
import com.example.petstoremobile.R; import com.example.petstoremobile.R;
import com.example.petstoremobile.api.auth.TokenManager; import com.example.petstoremobile.api.auth.TokenManager;
import com.example.petstoremobile.fragments.listfragments.PetFragment;
import com.example.petstoremobile.fragments.listfragments.ServiceFragment;
import com.example.petstoremobile.fragments.listfragments.SupplierFragment;
import com.example.petstoremobile.fragments.listfragments.AdoptionFragment;
import com.example.petstoremobile.fragments.listfragments.AppointmentFragment;
import com.example.petstoremobile.fragments.listfragments.InventoryFragment;
import com.example.petstoremobile.fragments.listfragments.ProductFragment;
import com.example.petstoremobile.fragments.listfragments.ProductSupplierFragment;
import com.example.petstoremobile.fragments.listfragments.PurchaseOrderFragment;
import com.example.petstoremobile.fragments.listfragments.SaleFragment;
import javax.inject.Inject; import javax.inject.Inject;
@@ -38,10 +32,10 @@ public class ListFragment extends Fragment {
private LinearLayout drawerPets, drawerServices, drawerSuppliers; private LinearLayout drawerPets, drawerServices, drawerSuppliers;
private View touchBlocker; private View touchBlocker;
// Adoptions, Appointments, Inventory, Products
private LinearLayout drawerAdoptions, drawerAppointments, drawerInventory, drawerProducts, drawerProductSupplier, drawerPurchaseOrderView, drawerSale; private LinearLayout drawerAdoptions, drawerAppointments, drawerInventory, drawerProducts, drawerProductSupplier, drawerPurchaseOrderView, drawerSale;
private NavController innerNavController;
@Inject TokenManager tokenManager; @Inject TokenManager tokenManager;
@Override @Override
@@ -62,7 +56,6 @@ public class ListFragment extends Fragment {
drawerSale=view.findViewById(R.id.drawerSale); drawerSale=view.findViewById(R.id.drawerSale);
drawerPurchaseOrderView=view.findViewById(R.id.drawerPurchaseOrderView); drawerPurchaseOrderView=view.findViewById(R.id.drawerPurchaseOrderView);
// Check user role and restrict access for STAFF // Check user role and restrict access for STAFF
String role = tokenManager.getRole(); String role = tokenManager.getRole();
if ("STAFF".equalsIgnoreCase(role)) { if ("STAFF".equalsIgnoreCase(role)) {
@@ -73,11 +66,6 @@ public class ListFragment extends Fragment {
//needed to disable touches on the innerContainer while the drawer is open //needed to disable touches on the innerContainer while the drawer is open
touchBlocker = view.findViewById(R.id.touchBlocker); touchBlocker = view.findViewById(R.id.touchBlocker);
//Display pets fragment by default
if (savedInstanceState == null) {
loadFragment(new PetFragment());
}
//add Listeners to the drawer so user won't be able to interact with the innerContainer (the list fragments) //add Listeners to the drawer so user won't be able to interact with the innerContainer (the list fragments)
//while the drawer is open //while the drawer is open
drawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() { drawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
@@ -104,84 +92,39 @@ public class ListFragment extends Fragment {
}); });
// Click listeners for each drawer // Click listeners for each drawer
//Pets drawerPets.setOnClickListener(v -> navigateTo(R.id.nav_pet));
drawerPets.setOnClickListener(v -> { drawerServices.setOnClickListener(v -> navigateTo(R.id.nav_service));
loadFragment(new PetFragment()); drawerSuppliers.setOnClickListener(v -> navigateTo(R.id.nav_supplier));
drawerLayout.closeDrawers(); drawerAdoptions.setOnClickListener(v -> navigateTo(R.id.nav_adoption));
}); drawerAppointments.setOnClickListener(v -> navigateTo(R.id.nav_appointment));
drawerInventory.setOnClickListener(v -> navigateTo(R.id.nav_inventory));
//Services drawerProducts.setOnClickListener(v -> navigateTo(R.id.nav_product));
drawerServices.setOnClickListener(v -> { drawerProductSupplier.setOnClickListener(v -> navigateTo(R.id.nav_product_supplier));
loadFragment(new ServiceFragment()); drawerPurchaseOrderView.setOnClickListener(v -> navigateTo(R.id.nav_purchase_order));
drawerLayout.closeDrawers(); drawerSale.setOnClickListener(v -> navigateTo(R.id.nav_sale));
});
//Suppliers
drawerSuppliers.setOnClickListener(v -> {
loadFragment(new SupplierFragment());
drawerLayout.closeDrawers();
});
//Adoptions
drawerAdoptions.setOnClickListener(v -> {
loadFragment(new AdoptionFragment());
drawerLayout.closeDrawers();
});
//Appointment
drawerAppointments.setOnClickListener(v -> {
loadFragment(new AppointmentFragment());
drawerLayout.closeDrawers();
});
//Inventory
drawerInventory.setOnClickListener(v -> {
loadFragment(new InventoryFragment());
drawerLayout.closeDrawers();
});
//Products
drawerProducts.setOnClickListener(v -> {
loadFragment(new ProductFragment());
drawerLayout.closeDrawers();
});
//ProductSupplier
drawerProductSupplier.setOnClickListener(v -> {
loadFragment(new ProductSupplierFragment());
drawerLayout.closeDrawers();
});
//Purchase
drawerPurchaseOrderView.setOnClickListener(v -> {
loadFragment(new PurchaseOrderFragment());
drawerLayout.closeDrawers();
});
//Sale
drawerSale.setOnClickListener(v -> {
loadFragment(new SaleFragment());
drawerLayout.closeDrawers();
});
return view; return view;
} }
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
NavHostFragment navHostFragment = (NavHostFragment) getChildFragmentManager()
.findFragmentById(R.id.inner_nav_host_fragment);
if (navHostFragment != null) {
innerNavController = navHostFragment.getNavController();
}
}
private void navigateTo(int destinationId) {
if (innerNavController != null) {
innerNavController.navigate(destinationId);
}
drawerLayout.closeDrawers();
}
//helper function to open the drawer //helper function to open the drawer
public void openDrawer() { public void openDrawer() {
drawerLayout.openDrawer(GravityCompat.START); drawerLayout.openDrawer(GravityCompat.START);
} }
}
// helper function to load the fragment into the display
public void loadFragment(Fragment fragment) {
getChildFragmentManager()
.beginTransaction()
.replace(R.id.inner_fragment_container, fragment)
.addToBackStack(null)
.commit();
}
}

View File

@@ -8,6 +8,7 @@ import android.view.*;
import android.widget.*; import android.widget.*;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -17,7 +18,6 @@ import com.example.petstoremobile.api.AdoptionApi;
import com.example.petstoremobile.dtos.AdoptionDTO; import com.example.petstoremobile.dtos.AdoptionDTO;
import com.example.petstoremobile.dtos.PageResponse; import com.example.petstoremobile.dtos.PageResponse;
import com.example.petstoremobile.fragments.ListFragment; import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.AdoptionDetailFragment;
import com.example.petstoremobile.utils.EventDecorator; import com.example.petstoremobile.utils.EventDecorator;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.prolificinteractive.materialcalendarview.CalendarDay; import com.prolificinteractive.materialcalendarview.CalendarDay;
@@ -68,8 +68,13 @@ public class AdoptionFragment extends Fragment implements AdoptionAdapter.OnAdop
fab.setOnClickListener(v -> openDetail(-1)); fab.setOnClickListener(v -> openDetail(-1));
hamburger.setOnClickListener(v -> { hamburger.setOnClickListener(v -> {
ListFragment lf = (ListFragment) getParentFragment(); Fragment parent = getParentFragment();
if (lf != null) lf.openDrawer(); if (parent != null) {
Fragment grandParent = parent.getParentFragment();
if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
}
}); });
btnToggleCalendarMode.setOnClickListener(v -> toggleCalendarMode()); btnToggleCalendarMode.setOnClickListener(v -> toggleCalendarMode());
@@ -197,7 +202,6 @@ public class AdoptionFragment extends Fragment implements AdoptionAdapter.OnAdop
} }
private void openDetail(int position) { private void openDetail(int position) {
AdoptionDetailFragment detail = new AdoptionDetailFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
if (position != -1) { if (position != -1) {
@@ -209,11 +213,9 @@ public class AdoptionFragment extends Fragment implements AdoptionAdapter.OnAdop
args.putString("adoptionStatus", a.getAdoptionStatus()); args.putString("adoptionStatus", a.getAdoptionStatus());
} }
detail.setArguments(args); NavHostFragment.findNavController(this).navigate(R.id.nav_adoption_detail, args);
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null) lf.loadFragment(detail);
} }
@Override @Override
public void onAdoptionClick(int position) { openDetail(position); } public void onAdoptionClick(int position) { openDetail(position); }
} }

View File

@@ -5,6 +5,7 @@ import android.os.Bundle;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -28,7 +29,6 @@ import com.example.petstoremobile.dtos.ServiceDTO;
import com.example.petstoremobile.dtos.PageResponse; import com.example.petstoremobile.dtos.PageResponse;
import com.example.petstoremobile.dtos.PetDTO; import com.example.petstoremobile.dtos.PetDTO;
import com.example.petstoremobile.fragments.ListFragment; import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.AppointmentDetailFragment;
import com.example.petstoremobile.utils.EventDecorator; import com.example.petstoremobile.utils.EventDecorator;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.prolificinteractive.materialcalendarview.CalendarDay; import com.prolificinteractive.materialcalendarview.CalendarDay;
@@ -96,9 +96,13 @@ public class AppointmentFragment extends Fragment implements AppointmentAdapter.
fabAdd.setOnClickListener(v -> openAppointmentDetails(-1)); fabAdd.setOnClickListener(v -> openAppointmentDetails(-1));
hamburger.setOnClickListener(v -> { hamburger.setOnClickListener(v -> {
ListFragment listFragment = (ListFragment) getParentFragment(); Fragment parent = getParentFragment();
if (listFragment != null) if (parent != null) {
listFragment.openDrawer(); Fragment grandParent = parent.getParentFragment();
if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
}
}); });
btnToggleCalendarMode.setOnClickListener(v -> toggleCalendarMode()); btnToggleCalendarMode.setOnClickListener(v -> toggleCalendarMode());
@@ -205,7 +209,6 @@ public class AppointmentFragment extends Fragment implements AppointmentAdapter.
} }
private void openAppointmentDetails(int position) { private void openAppointmentDetails(int position) {
AppointmentDetailFragment detailFragment = new AppointmentDetailFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
if (position != -1) { if (position != -1) {
@@ -221,9 +224,7 @@ public class AppointmentFragment extends Fragment implements AppointmentAdapter.
if (a.getStoreId() != null) args.putLong("storeId", a.getStoreId()); if (a.getStoreId() != null) args.putLong("storeId", a.getStoreId());
} }
detailFragment.setArguments(args); NavHostFragment.findNavController(this).navigate(R.id.nav_appointment_detail, args);
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null) lf.loadFragment(detailFragment);
} }
public void onAppointmentSaved(int position, AppointmentDTO appointment) { public void onAppointmentSaved(int position, AppointmentDTO appointment) {
loadAppointmentData(); loadAppointmentData();
@@ -333,4 +334,4 @@ public class AppointmentFragment extends Fragment implements AppointmentAdapter.
recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter); recyclerView.setAdapter(adapter);
} }
} }

View File

@@ -17,7 +17,10 @@ import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -32,8 +35,6 @@ import com.example.petstoremobile.dtos.CategoryDTO;
import com.example.petstoremobile.dtos.InventoryDTO; import com.example.petstoremobile.dtos.InventoryDTO;
import com.example.petstoremobile.dtos.PageResponse; import com.example.petstoremobile.dtos.PageResponse;
import com.example.petstoremobile.fragments.ListFragment; import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.InventoryDetailFragment;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -100,9 +101,13 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
.setOnClickListener(v -> openDetail(null)); .setOnClickListener(v -> openDetail(null));
hamburger.setOnClickListener(v -> { hamburger.setOnClickListener(v -> {
ListFragment lf = (ListFragment) getParentFragment(); Fragment parent = getParentFragment();
if (lf != null) if (parent != null) {
lf.openDrawer(); Fragment grandParent = parent.getParentFragment();
if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
}
}); });
btnBulkDelete.setOnClickListener(v -> confirmBulkDelete()); btnBulkDelete.setOnClickListener(v -> confirmBulkDelete());
@@ -174,7 +179,8 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
private void setupSearch(View view) { private void setupSearch(View view) {
etSearch = view.findViewById(R.id.etSearchInventory); etSearch = view.findViewById(R.id.etSearchInventory);
etSearch.addTextChangedListener(new TextWatcher() { etSearch.addTextChangedListener(new TextWatcher() {
@Override public void beforeTextChanged(CharSequence s, int i, int i1, int i2) { @Override
public void beforeTextChanged(CharSequence s, int i, int i1, int i2) {
} }
@Override @Override
@@ -332,7 +338,6 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
// Navigation // Navigation
private void openDetail(InventoryDTO inv) { private void openDetail(InventoryDTO inv) {
InventoryDetailFragment detail = new InventoryDetailFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
if (inv != null) { if (inv != null) {
@@ -343,12 +348,7 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
args.putInt("quantity", inv.getQuantity() != null ? inv.getQuantity() : 0); args.putInt("quantity", inv.getQuantity() != null ? inv.getQuantity() : 0);
} }
detail.setArguments(args); NavHostFragment.findNavController(this).navigate(R.id.nav_inventory_detail, args);
detail.setInventoryFragment(this);
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null)
lf.loadFragment(detail);
} }
public void onInventoryChanged() { public void onInventoryChanged() {

View File

@@ -2,7 +2,10 @@ package com.example.petstoremobile.fragments.listfragments;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -26,8 +29,6 @@ import com.example.petstoremobile.api.PetApi;
import com.example.petstoremobile.dtos.PageResponse; import com.example.petstoremobile.dtos.PageResponse;
import com.example.petstoremobile.dtos.PetDTO; import com.example.petstoremobile.dtos.PetDTO;
import com.example.petstoremobile.fragments.ListFragment; import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.PetDetailFragment;
import com.example.petstoremobile.fragments.listfragments.listprofilefragments.PetProfileFragment;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList; import java.util.ArrayList;
@@ -73,10 +74,12 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
//Make the hamburger button open the drawer from listFragment //Make the hamburger button open the drawer from listFragment
hamburger.setOnClickListener(v -> { hamburger.setOnClickListener(v -> {
ListFragment listFragment = (ListFragment) getParentFragment(); Fragment parent = getParentFragment();
//if list fragment is found then use its helper function to open the drawer if (parent != null) {
if (listFragment != null) { Fragment grandParent = parent.getParentFragment();
listFragment.openDrawer(); if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
} }
}); });
@@ -150,8 +153,6 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
//Open pet profile //Open pet profile
private void openPetProfile(int position) { private void openPetProfile(int position) {
PetProfileFragment profileFragment = new PetProfileFragment();
//Make a bundle to pass data to the profile fragment //Make a bundle to pass data to the profile fragment
Bundle args = new Bundle(); Bundle args = new Bundle();
PetDTO pet = filteredList.get(position); PetDTO pet = filteredList.get(position);
@@ -168,25 +169,12 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
args.putDouble("petPrice", 0.0); args.putDouble("petPrice", 0.0);
} }
//send the bundle to the profile fragment to display NavHostFragment.findNavController(this).navigate(R.id.nav_pet_profile, args);
profileFragment.setArguments(args);
//get ListFragment to load the the pet profile view
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null) {
listFragment.loadFragment(profileFragment);
}
} }
//Open the pet detail view for adding //Open the pet detail view for adding
private void openPetDetails(int position) { private void openPetDetails(int position) {
PetDetailFragment detailFragment = new PetDetailFragment(); NavHostFragment.findNavController(this).navigate(R.id.nav_pet_detail);
//get ListFragment to load the detail view
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null) {
listFragment.loadFragment(detailFragment);
}
} }
// Called by PetAdapter when a row is clicked to open the details view // Called by PetAdapter when a row is clicked to open the details view
@@ -236,4 +224,4 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter); recyclerView.setAdapter(adapter);
} }
} }

View File

@@ -6,20 +6,22 @@ import android.util.Log;
import android.view.*; import android.view.*;
import android.widget.*; import android.widget.*;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.example.petstoremobile.R; import com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.ProductAdapter; import com.example.petstoremobile.adapters.ProductAdapter;
import com.example.petstoremobile.api.ProductApi; import com.example.petstoremobile.api.ProductApi;
import com.example.petstoremobile.api.auth.TokenManager;
import com.example.petstoremobile.dtos.PageResponse; import com.example.petstoremobile.dtos.PageResponse;
import com.example.petstoremobile.dtos.ProductDTO; import com.example.petstoremobile.dtos.ProductDTO;
import com.example.petstoremobile.fragments.ListFragment; import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.ProductDetailFragment;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.*; import java.util.*;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;
import dagger.hilt.android.AndroidEntryPoint; import dagger.hilt.android.AndroidEntryPoint;
import retrofit2.*; import retrofit2.*;
@@ -34,6 +36,8 @@ public class ProductFragment extends Fragment implements ProductAdapter.OnProduc
private EditText etSearch; private EditText etSearch;
@Inject ProductApi api; @Inject ProductApi api;
@Inject @Named("baseUrl") String baseUrl;
@Inject TokenManager tokenManager;
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -51,8 +55,13 @@ public class ProductFragment extends Fragment implements ProductAdapter.OnProduc
ImageButton hamburger = view.findViewById(R.id.btnHamburgerProduct); ImageButton hamburger = view.findViewById(R.id.btnHamburgerProduct);
hamburger.setOnClickListener(v -> { hamburger.setOnClickListener(v -> {
ListFragment lf = (ListFragment) getParentFragment(); Fragment parent = getParentFragment();
if (lf != null) lf.openDrawer(); if (parent != null) {
Fragment grandParent = parent.getParentFragment();
if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
}
}); });
return view; return view;
@@ -61,6 +70,8 @@ public class ProductFragment extends Fragment implements ProductAdapter.OnProduc
private void setupRecyclerView(View view) { private void setupRecyclerView(View view) {
RecyclerView rv = view.findViewById(R.id.recyclerViewProducts); RecyclerView rv = view.findViewById(R.id.recyclerViewProducts);
adapter = new ProductAdapter(filteredList, this); adapter = new ProductAdapter(filteredList, this);
adapter.setBaseUrl(baseUrl);
adapter.setToken(tokenManager.getToken());
rv.setLayoutManager(new LinearLayoutManager(getContext())); rv.setLayoutManager(new LinearLayoutManager(getContext()));
rv.setAdapter(adapter); rv.setAdapter(adapter);
} }
@@ -122,7 +133,6 @@ public class ProductFragment extends Fragment implements ProductAdapter.OnProduc
} }
private void openDetail(int position) { private void openDetail(int position) {
ProductDetailFragment detail = new ProductDetailFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
if (position != -1) { if (position != -1) {
ProductDTO p = filteredList.get(position); ProductDTO p = filteredList.get(position);
@@ -132,11 +142,9 @@ public class ProductFragment extends Fragment implements ProductAdapter.OnProduc
args.putString("prodPrice", p.getProdPrice() != null ? p.getProdPrice().toString() : ""); args.putString("prodPrice", p.getProdPrice() != null ? p.getProdPrice().toString() : "");
args.putLong("categoryId", p.getCategoryId() != null ? p.getCategoryId() : -1); args.putLong("categoryId", p.getCategoryId() != null ? p.getCategoryId() : -1);
} }
detail.setArguments(args); NavHostFragment.findNavController(this).navigate(R.id.nav_product_detail, args);
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null) lf.loadFragment(detail);
} }
@Override @Override
public void onProductClick(int position) { openDetail(position); } public void onProductClick(int position) { openDetail(position); }
} }

View File

@@ -6,6 +6,7 @@ import android.util.Log;
import android.view.*; import android.view.*;
import android.widget.*; import android.widget.*;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -51,8 +52,13 @@ public class ProductSupplierFragment extends Fragment
ImageButton hamburger = view.findViewById(R.id.btnHamburgerPS); ImageButton hamburger = view.findViewById(R.id.btnHamburgerPS);
hamburger.setOnClickListener(v -> { hamburger.setOnClickListener(v -> {
ListFragment lf = (ListFragment) getParentFragment(); Fragment parent = getParentFragment();
if (lf != null) lf.openDrawer(); if (parent != null) {
Fragment grandParent = parent.getParentFragment();
if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
}
}); });
return view; return view;
@@ -121,7 +127,6 @@ public class ProductSupplierFragment extends Fragment
} }
private void openDetail(int position) { private void openDetail(int position) {
ProductSupplierDetailFragment detail = new ProductSupplierDetailFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
if (position != -1) { if (position != -1) {
ProductSupplierDTO ps = filteredList.get(position); ProductSupplierDTO ps = filteredList.get(position);
@@ -131,9 +136,7 @@ public class ProductSupplierFragment extends Fragment
args.putString("supplierName", ps.getSupplierName()); args.putString("supplierName", ps.getSupplierName());
args.putString("cost", ps.getCost() != null ? ps.getCost().toString() : ""); args.putString("cost", ps.getCost() != null ? ps.getCost().toString() : "");
} }
detail.setArguments(args); NavHostFragment.findNavController(this).navigate(R.id.nav_product_supplier_detail, args);
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null) lf.loadFragment(detail);
} }
@Override @Override

View File

@@ -6,6 +6,7 @@ import android.util.Log;
import android.view.*; import android.view.*;
import android.widget.*; import android.widget.*;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -15,7 +16,6 @@ import com.example.petstoremobile.api.PurchaseOrderApi;
import com.example.petstoremobile.dtos.PageResponse; import com.example.petstoremobile.dtos.PageResponse;
import com.example.petstoremobile.dtos.PurchaseOrderDTO; import com.example.petstoremobile.dtos.PurchaseOrderDTO;
import com.example.petstoremobile.fragments.ListFragment; import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.PurchaseOrderDetailFragment;
import java.util.*; import java.util.*;
import javax.inject.Inject; import javax.inject.Inject;
@@ -47,9 +47,13 @@ public class PurchaseOrderFragment extends Fragment
ImageButton hamburger = view.findViewById(R.id.btnHamburgerPO); ImageButton hamburger = view.findViewById(R.id.btnHamburgerPO);
hamburger.setOnClickListener(v -> { hamburger.setOnClickListener(v -> {
ListFragment lf = (ListFragment) getParentFragment(); Fragment parent = getParentFragment();
if (lf != null) if (parent != null) {
lf.openDrawer(); Fragment grandParent = parent.getParentFragment();
if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
}
}); });
return view; return view;
@@ -126,17 +130,13 @@ public class PurchaseOrderFragment extends Fragment
} }
private void openDetail(int position) { private void openDetail(int position) {
PurchaseOrderDetailFragment detail = new PurchaseOrderDetailFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
PurchaseOrderDTO po = filteredList.get(position); PurchaseOrderDTO po = filteredList.get(position);
args.putLong("purchaseOrderId", po.getPurchaseOrderId()); args.putLong("purchaseOrderId", po.getPurchaseOrderId());
args.putString("supplierName", po.getSupplierName()); args.putString("supplierName", po.getSupplierName());
args.putString("orderDate", po.getOrderDate()); args.putString("orderDate", po.getOrderDate());
args.putString("status", po.getStatus()); args.putString("status", po.getStatus());
detail.setArguments(args); NavHostFragment.findNavController(this).navigate(R.id.nav_purchase_order_detail, args);
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null)
lf.loadFragment(detail);
} }
@Override @Override

View File

@@ -2,6 +2,7 @@ package com.example.petstoremobile.fragments.listfragments;
import android.os.Bundle; import android.os.Bundle;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -17,7 +18,6 @@ import com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.SaleAdapter; import com.example.petstoremobile.adapters.SaleAdapter;
import com.example.petstoremobile.api.SaleApi; import com.example.petstoremobile.api.SaleApi;
import com.example.petstoremobile.fragments.ListFragment; import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.RefundDetailFragment;
import com.example.petstoremobile.models.Sale; import com.example.petstoremobile.models.Sale;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -53,9 +53,12 @@ public class SaleFragment extends Fragment implements SaleAdapter.OnSaleClickLis
// Make the hamburger button open the drawer from listFragment // Make the hamburger button open the drawer from listFragment
if (btnHamburger != null) { if (btnHamburger != null) {
btnHamburger.setOnClickListener(v -> { btnHamburger.setOnClickListener(v -> {
ListFragment listFragment = (ListFragment) getParentFragment(); Fragment parent = getParentFragment();
if (listFragment != null) { if (parent != null) {
listFragment.openDrawer(); Fragment grandParent = parent.getParentFragment();
if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
} }
}); });
} }
@@ -111,19 +114,14 @@ public class SaleFragment extends Fragment implements SaleAdapter.OnSaleClickLis
@Override @Override
public void onSaleClick(int position) { public void onSaleClick(int position) {
Sale sale = filteredList.get(position); Sale sale = filteredList.get(position);
RefundDetailFragment refundFragment = new RefundDetailFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putInt("saleId", sale.getSaleId()); args.putInt("saleId", sale.getSaleId());
args.putString("saleDate", sale.getSaleDate()); args.putString("saleDate", sale.getSaleDate());
args.putString("employeeName", sale.getEmployeeName()); args.putString("employeeName", sale.getEmployeeName());
args.putDouble("total", sale.getTotal()); args.putDouble("total", sale.getTotal());
args.putString("paymentMethod", sale.getPaymentMethod()); args.putString("paymentMethod", sale.getPaymentMethod());
refundFragment.setArguments(args);
refundFragment.setSaleFragment(this); NavHostFragment.findNavController(this).navigate(R.id.nav_refund_detail, args);
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null)
listFragment.loadFragment(refundFragment);
} }
public void reloadSales() { public void reloadSales() {
@@ -149,4 +147,4 @@ public class SaleFragment extends Fragment implements SaleAdapter.OnSaleClickLis
recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter); recyclerView.setAdapter(adapter);
} }
} }

View File

@@ -2,7 +2,10 @@ package com.example.petstoremobile.fragments.listfragments;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -23,7 +26,6 @@ import com.example.petstoremobile.api.ServiceApi;
import com.example.petstoremobile.dtos.PageResponse; import com.example.petstoremobile.dtos.PageResponse;
import com.example.petstoremobile.dtos.ServiceDTO; import com.example.petstoremobile.dtos.ServiceDTO;
import com.example.petstoremobile.fragments.ListFragment; import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.ServiceDetailFragment;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList; import java.util.ArrayList;
@@ -66,10 +68,12 @@ public class ServiceFragment extends Fragment implements ServiceAdapter.OnServic
//Make the hamburger button open the drawer from listFragment //Make the hamburger button open the drawer from listFragment
hamburger.setOnClickListener(v -> { hamburger.setOnClickListener(v -> {
ListFragment listFragment = (ListFragment) getParentFragment(); Fragment parent = getParentFragment();
//if list fragment is found then use its helper function to open the drawer if (parent != null) {
if (listFragment != null) { Fragment grandParent = parent.getParentFragment();
listFragment.openDrawer(); if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
} }
}); });
@@ -112,8 +116,6 @@ public class ServiceFragment extends Fragment implements ServiceAdapter.OnServic
//Open the service detail view depending on the mode //Open the service detail view depending on the mode
private void openServiceDetails(int position) { private void openServiceDetails(int position) {
ServiceDetailFragment detailFragment = new ServiceDetailFragment();
//Make a bundle to pass data to the detail fragment //Make a bundle to pass data to the detail fragment
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putInt("position", position); args.putInt("position", position);
@@ -128,16 +130,7 @@ public class ServiceFragment extends Fragment implements ServiceAdapter.OnServic
args.putDouble("servicePrice", service.getServicePrice()); args.putDouble("servicePrice", service.getServicePrice());
} }
//send the bundle to the detail fragment to display NavHostFragment.findNavController(this).navigate(R.id.nav_service_detail, args);
detailFragment.setArguments(args);
//set the service fragment to the parent so we refer back to service view when save or delete is done
detailFragment.setServiceFragment(this);
//get ListFragment to load the the detail view
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null) {
listFragment.loadFragment(detailFragment);
}
} }
// Called by ServiceAdapter when a row is clicked to open the details view // Called by ServiceAdapter when a row is clicked to open the details view
@@ -188,4 +181,4 @@ public class ServiceFragment extends Fragment implements ServiceAdapter.OnServic
recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter); recyclerView.setAdapter(adapter);
} }
} }

View File

@@ -2,7 +2,10 @@ package com.example.petstoremobile.fragments.listfragments;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -23,7 +26,6 @@ import com.example.petstoremobile.api.SupplierApi;
import com.example.petstoremobile.dtos.PageResponse; import com.example.petstoremobile.dtos.PageResponse;
import com.example.petstoremobile.dtos.SupplierDTO; import com.example.petstoremobile.dtos.SupplierDTO;
import com.example.petstoremobile.fragments.ListFragment; import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.SupplierDetailFragment;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList; import java.util.ArrayList;
@@ -66,10 +68,12 @@ public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupp
//Make the hamburger button open the drawer from listFragment //Make the hamburger button open the drawer from listFragment
hamburger.setOnClickListener(v -> { hamburger.setOnClickListener(v -> {
ListFragment listFragment = (ListFragment) getParentFragment(); Fragment parent = getParentFragment();
//if list fragment is found then use its helper function to open the drawer if (parent != null) {
if (listFragment != null) { Fragment grandParent = parent.getParentFragment();
listFragment.openDrawer(); if (grandParent instanceof ListFragment) {
((ListFragment) grandParent).openDrawer();
}
} }
}); });
@@ -113,8 +117,6 @@ public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupp
//Open the supplier detail view depending on the mode //Open the supplier detail view depending on the mode
private void openSupplierDetails(int position) { private void openSupplierDetails(int position) {
SupplierDetailFragment detailFragment = new SupplierDetailFragment();
//Make a bundle to pass data to the detail fragment //Make a bundle to pass data to the detail fragment
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putInt("position", position); args.putInt("position", position);
@@ -130,16 +132,7 @@ public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupp
args.putString("supPhone", supplier.getSupPhone()); args.putString("supPhone", supplier.getSupPhone());
} }
//send the bundle to the detail fragment to display NavHostFragment.findNavController(this).navigate(R.id.nav_supplier_detail, args);
detailFragment.setArguments(args);
//set the supplier fragment to the parent so we refer back to supplier view when save or delete is done
detailFragment.setSupplierFragment(this);
//get ListFragment to load the the detail view
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null) {
listFragment.loadFragment(detailFragment);
}
} }

View File

@@ -8,6 +8,8 @@ import android.widget.*;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.example.petstoremobile.R; import com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.BlackTextArrayAdapter; import com.example.petstoremobile.adapters.BlackTextArrayAdapter;
import com.example.petstoremobile.api.*; import com.example.petstoremobile.api.*;
@@ -259,7 +261,6 @@ public class AdoptionDetailFragment extends Fragment {
} }
private void navigateBack() { private void navigateBack() {
ListFragment lf = (ListFragment) getParentFragment(); NavHostFragment.findNavController(this).popBackStack();
if (lf != null) lf.getChildFragmentManager().popBackStack();
} }
} }

View File

@@ -8,6 +8,8 @@ import android.widget.*;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.example.petstoremobile.R; import com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.BlackTextArrayAdapter; import com.example.petstoremobile.adapters.BlackTextArrayAdapter;
import com.example.petstoremobile.api.*; import com.example.petstoremobile.api.*;
@@ -447,7 +449,6 @@ public class AppointmentDetailFragment extends Fragment {
} }
private void navigateBack() { private void navigateBack() {
ListFragment lf = (ListFragment) getParentFragment(); NavHostFragment.findNavController(this).popBackStack();
if (lf != null) lf.getChildFragmentManager().popBackStack();
} }
} }

View File

@@ -16,6 +16,7 @@ import android.widget.Toast;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.example.petstoremobile.R; import com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.BlackTextArrayAdapter; import com.example.petstoremobile.adapters.BlackTextArrayAdapter;
@@ -327,9 +328,7 @@ public class InventoryDetailFragment extends Fragment {
} }
private void navigateBack() { private void navigateBack() {
ListFragment lf = (ListFragment) getParentFragment(); NavHostFragment.findNavController(this).popBackStack();
if (lf != null)
lf.getChildFragmentManager().popBackStack();
} }
private void setButtonsEnabled(boolean enabled) { private void setButtonsEnabled(boolean enabled) {
@@ -337,4 +336,4 @@ public class InventoryDetailFragment extends Fragment {
btnDelete.setEnabled(enabled); btnDelete.setEnabled(enabled);
btnBack.setEnabled(enabled); btnBack.setEnabled(enabled);
} }
} }

View File

@@ -7,6 +7,7 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@@ -44,15 +45,9 @@ public class PetDetailFragment extends Fragment {
private Button btnSavePet, btnDeletePet, btnBack; private Button btnSavePet, btnDeletePet, btnBack;
private int petId; private int petId;
private boolean isEditing = false; private boolean isEditing = false;
private PetFragment petFragment;
@Inject PetApi petApi; @Inject PetApi petApi;
//set the pet fragment to the parent so we refer back to pet view when save or delete is done
public void setPetFragment(PetFragment fragment) {
this.petFragment = fragment;
}
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
@@ -178,14 +173,7 @@ public class PetDetailFragment extends Fragment {
//Helper method to navigate back to the list //Helper method to navigate back to the list
private void navigateBack() { private void navigateBack() {
ListFragment listFragment = (ListFragment) getParentFragment(); NavHostFragment.findNavController(this).popBackStack();
if (listFragment != null) {
// If editing pop back twice to get back to PetDetail Fragment instead of PetProfileFragment
if (isEditing) {
listFragment.getChildFragmentManager().popBackStack();
}
listFragment.getChildFragmentManager().popBackStack();
}
} }
//helper function to check if pet is being edited or added and show the view accordingly //helper function to check if pet is being edited or added and show the view accordingly
@@ -244,4 +232,4 @@ public class PetDetailFragment extends Fragment {
spinnerPetStatus.setAdapter(adapter); spinnerPetStatus.setAdapter(adapter);
} }
} }

View File

@@ -17,13 +17,17 @@ import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider; import androidx.core.content.FileProvider;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.LazyHeaders;
import com.example.petstoremobile.R; import com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.BlackTextArrayAdapter; import com.example.petstoremobile.adapters.BlackTextArrayAdapter;
import com.example.petstoremobile.api.*; import com.example.petstoremobile.api.*;
import com.example.petstoremobile.api.auth.TokenManager;
import com.example.petstoremobile.dtos.*; import com.example.petstoremobile.dtos.*;
import com.example.petstoremobile.fragments.ListFragment;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.InputStream; import java.io.InputStream;
@@ -59,6 +63,7 @@ public class ProductDetailFragment extends Fragment {
@Inject ProductApi productApi; @Inject ProductApi productApi;
@Inject CategoryApi categoryApi; @Inject CategoryApi categoryApi;
@Inject @Named("baseUrl") String baseUrl; @Inject @Named("baseUrl") String baseUrl;
@Inject TokenManager tokenManager;
private ActivityResultLauncher<Intent> galleryLauncher; private ActivityResultLauncher<Intent> galleryLauncher;
private ActivityResultLauncher<Uri> cameraLauncher; private ActivityResultLauncher<Uri> cameraLauncher;
@@ -254,10 +259,18 @@ public class ProductDetailFragment extends Fragment {
//load the product image from the backend //load the product image from the backend
private void loadProductImage() { private void loadProductImage() {
String imageUrl = baseUrl + String.format(Locale.US, ProductApi.PRODUCT_IMAGE_PATH, prodId); String imageUrl = baseUrl + String.format(Locale.US, ProductApi.PRODUCT_IMAGE_PATH, prodId);
String token = tokenManager.getToken();
Object loadTarget = imageUrl;
if (token != null) {
loadTarget = new GlideUrl(imageUrl, new LazyHeaders.Builder()
.addHeader("Authorization", "Bearer " + token)
.build());
}
Glide.with(this) Glide.with(this)
.load(imageUrl) .load(loadTarget)
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.ALL)
.skipMemoryCache(true)
.placeholder(R.drawable.placeholder2) .placeholder(R.drawable.placeholder2)
.error(R.drawable.placeholder2) .error(R.drawable.placeholder2)
.into(ivProductImage); .into(ivProductImage);
@@ -398,7 +411,6 @@ public class ProductDetailFragment extends Fragment {
} }
private void navigateBack() { private void navigateBack() {
ListFragment lf = (ListFragment) getParentFragment(); NavHostFragment.findNavController(this).popBackStack();
if (lf != null) lf.getChildFragmentManager().popBackStack();
} }
} }

View File

@@ -7,6 +7,8 @@ import android.widget.*;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.example.petstoremobile.R; import com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.BlackTextArrayAdapter; import com.example.petstoremobile.adapters.BlackTextArrayAdapter;
import com.example.petstoremobile.api.*; import com.example.petstoremobile.api.*;
@@ -222,7 +224,6 @@ public class ProductSupplierDetailFragment extends Fragment {
} }
private void navigateBack() { private void navigateBack() {
ListFragment lf = (ListFragment) getParentFragment(); NavHostFragment.findNavController(this).popBackStack();
if (lf != null) lf.getChildFragmentManager().popBackStack();
} }
} }

View File

@@ -6,6 +6,8 @@ import android.view.*;
import android.widget.*; import android.widget.*;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.example.petstoremobile.R; import com.example.petstoremobile.R;
import com.example.petstoremobile.fragments.ListFragment; import com.example.petstoremobile.fragments.ListFragment;
@@ -49,8 +51,7 @@ public class PurchaseOrderDetailFragment extends Fragment {
} }
btnBack.setOnClickListener(v -> { btnBack.setOnClickListener(v -> {
ListFragment lf = (ListFragment) getParentFragment(); NavHostFragment.findNavController(this).popBackStack();
if (lf != null) lf.getChildFragmentManager().popBackStack();
}); });
return view; return view;

View File

@@ -2,6 +2,8 @@ package com.example.petstoremobile.fragments.listfragments.detailfragments;
import android.os.Bundle; import android.os.Bundle;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -14,7 +16,6 @@ import android.widget.Toast;
import com.example.petstoremobile.R; import com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.BlackTextArrayAdapter; import com.example.petstoremobile.adapters.BlackTextArrayAdapter;
import com.example.petstoremobile.api.SaleApi; import com.example.petstoremobile.api.SaleApi;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.SaleFragment; import com.example.petstoremobile.fragments.listfragments.SaleFragment;
import com.example.petstoremobile.utils.ActivityLogger; import com.example.petstoremobile.utils.ActivityLogger;
import com.example.petstoremobile.utils.InputValidator; import com.example.petstoremobile.utils.InputValidator;
@@ -119,9 +120,7 @@ public class RefundDetailFragment extends Fragment {
} }
private void goBack() { private void goBack() {
ListFragment listFragment = (ListFragment) getParentFragment(); NavHostFragment.findNavController(this).popBackStack();
if (listFragment != null)
listFragment.getChildFragmentManager().popBackStack();
} }
private void initViews(View view) { private void initViews(View view) {
@@ -141,4 +140,4 @@ public class RefundDetailFragment extends Fragment {
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerRefundPayment.setAdapter(adapter); spinnerRefundPayment.setAdapter(adapter);
} }
} }

View File

@@ -4,6 +4,7 @@ import android.os.Bundle;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@@ -17,7 +18,6 @@ import android.widget.Toast;
import com.example.petstoremobile.R; import com.example.petstoremobile.R;
import com.example.petstoremobile.api.ServiceApi; import com.example.petstoremobile.api.ServiceApi;
import com.example.petstoremobile.dtos.ServiceDTO; import com.example.petstoremobile.dtos.ServiceDTO;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.ServiceFragment; import com.example.petstoremobile.fragments.listfragments.ServiceFragment;
import com.example.petstoremobile.utils.ActivityLogger; import com.example.petstoremobile.utils.ActivityLogger;
import com.example.petstoremobile.utils.InputValidator; import com.example.petstoremobile.utils.InputValidator;
@@ -164,10 +164,7 @@ public class ServiceDetailFragment extends Fragment {
//Helper method to navigate back to the list //Helper method to navigate back to the list
private void navigateBack() { private void navigateBack() {
ListFragment listFragment = (ListFragment) getParentFragment(); NavHostFragment.findNavController(this).popBackStack();
if (listFragment != null) {
listFragment.getChildFragmentManager().popBackStack();
}
} }
//helper function to check if service is being edited or added and show the view accordingly //helper function to check if service is being edited or added and show the view accordingly

View File

@@ -4,6 +4,7 @@ import android.os.Bundle;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@@ -17,8 +18,6 @@ import android.widget.Toast;
import com.example.petstoremobile.R; import com.example.petstoremobile.R;
import com.example.petstoremobile.api.SupplierApi; import com.example.petstoremobile.api.SupplierApi;
import com.example.petstoremobile.dtos.SupplierDTO; import com.example.petstoremobile.dtos.SupplierDTO;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.SupplierFragment;
import com.example.petstoremobile.utils.ActivityLogger; import com.example.petstoremobile.utils.ActivityLogger;
import com.example.petstoremobile.utils.InputValidator; import com.example.petstoremobile.utils.InputValidator;
@@ -37,15 +36,9 @@ public class SupplierDetailFragment extends Fragment {
private Button btnSaveSupplier, btnDeleteSupplier, btnBack; private Button btnSaveSupplier, btnDeleteSupplier, btnBack;
private int supId; private int supId;
private boolean isEditing = false; private boolean isEditing = false;
private SupplierFragment supplierFragment;
@Inject SupplierApi supplierApi; @Inject SupplierApi supplierApi;
//set the supplier fragment to the parent so we refer back to supplier view when save or delete is done
public void setSupplierFragment(SupplierFragment fragment) {
this.supplierFragment = fragment;
}
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
@@ -167,10 +160,7 @@ public class SupplierDetailFragment extends Fragment {
//Helper method to navigate back to the list //Helper method to navigate back to the list
private void navigateBack() { private void navigateBack() {
ListFragment listFragment = (ListFragment) getParentFragment(); NavHostFragment.findNavController(this).popBackStack();
if (listFragment != null) {
listFragment.getChildFragmentManager().popBackStack();
}
} }
//helper function to check if supplier is being edited or added and show the view accordingly //helper function to check if supplier is being edited or added and show the view accordingly
@@ -217,4 +207,4 @@ public class SupplierDetailFragment extends Fragment {
btnDeleteSupplier = view.findViewById(R.id.btnDeleteSupplier); btnDeleteSupplier = view.findViewById(R.id.btnDeleteSupplier);
btnBack = view.findViewById(R.id.btnBack); btnBack = view.findViewById(R.id.btnBack);
} }
} }

View File

@@ -14,6 +14,7 @@ import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider; import androidx.core.content.FileProvider;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.util.Log; import android.util.Log;
@@ -27,8 +28,11 @@ import android.widget.Toast;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.LazyHeaders;
import com.example.petstoremobile.R; import com.example.petstoremobile.R;
import com.example.petstoremobile.api.PetApi; import com.example.petstoremobile.api.PetApi;
import com.example.petstoremobile.api.auth.TokenManager;
import com.example.petstoremobile.fragments.ListFragment; import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.PetDetailFragment; import com.example.petstoremobile.fragments.listfragments.detailfragments.PetDetailFragment;
@@ -62,6 +66,7 @@ public class PetProfileFragment extends Fragment {
@Inject PetApi petApi; @Inject PetApi petApi;
@Inject @Named("baseUrl") String baseUrl; @Inject @Named("baseUrl") String baseUrl;
@Inject TokenManager tokenManager;
// launchers for camera and gallery // launchers for camera and gallery
private ActivityResultLauncher<Intent> galleryLauncher; private ActivityResultLauncher<Intent> galleryLauncher;
@@ -148,26 +153,13 @@ public class PetProfileFragment extends Fragment {
//set button click listeners //set button click listeners
btnBack.setOnClickListener(v -> { btnBack.setOnClickListener(v -> {
//get the list fragment and pop the back stack to return to the previous view (PetFragment) NavHostFragment.findNavController(this).popBackStack();
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null) {
listFragment.getChildFragmentManager().popBackStack();
}
}); });
//Make the edit button go to the pet detail view //Make the edit button go to the pet detail view
btnEditPet.setOnClickListener(v -> { btnEditPet.setOnClickListener(v -> {
if (getArguments() == null) return; if (getArguments() == null) return;
NavHostFragment.findNavController(this).navigate(R.id.nav_pet_detail, getArguments());
PetDetailFragment detailFragment = new PetDetailFragment();
//send the bundle to the pet detail fragment
detailFragment.setArguments(getArguments());
//get ListFragment to load the the detail view
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null) {
listFragment.loadFragment(detailFragment);
}
}); });
//Make change photo button ask user to select a new photo //Make change photo button ask user to select a new photo
@@ -209,11 +201,18 @@ public class PetProfileFragment extends Fragment {
// Helper function to load pet image from backend // Helper function to load pet image from backend
private void loadPetImage(int petId) { private void loadPetImage(int petId) {
String imageUrl = baseUrl + String.format(Locale.US, PetApi.PET_IMAGE_PATH, petId); String imageUrl = baseUrl + String.format(Locale.US, PetApi.PET_IMAGE_PATH, petId);
String token = tokenManager.getToken();
Object loadTarget = imageUrl;
if (token != null) {
loadTarget = new GlideUrl(imageUrl, new LazyHeaders.Builder()
.addHeader("Authorization", "Bearer " + token)
.build());
}
Glide.with(this) Glide.with(this)
.load(imageUrl) .load(loadTarget)
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.ALL)
.skipMemoryCache(true)
.placeholder(R.drawable.placeholder) .placeholder(R.drawable.placeholder)
.error(R.drawable.placeholder) .error(R.drawable.placeholder)
.listener(new com.bumptech.glide.request.RequestListener<android.graphics.drawable.Drawable>() { .listener(new com.bumptech.glide.request.RequestListener<android.graphics.drawable.Drawable>() {

View File

@@ -7,12 +7,14 @@
android:orientation="vertical" android:orientation="vertical"
android:background="@color/primary_dark"> android:background="@color/primary_dark">
<FrameLayout <androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container" android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_weight="1" android:layout_weight="1"
android:background="@color/background_grey"/> app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
<com.google.android.material.bottomnavigation.BottomNavigationView <com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation" android:id="@+id/bottom_navigation"

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout <androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawerLayout" android:id="@+id/drawerLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
@@ -10,10 +11,13 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/background_grey"> android:background="@color/background_grey">
<FrameLayout <androidx.fragment.app.FragmentContainerView
android:id="@+id/inner_fragment_container" android:id="@+id/inner_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"/> android:layout_height="match_parent"
app:defaultNavHost="false"
app:navGraph="@navigation/list_nav_graph" />
<View <View
android:id="@+id/touchBlocker" android:id="@+id/touchBlocker"
@@ -33,8 +37,6 @@
android:orientation="vertical" android:orientation="vertical"
android:background="@color/primary_dark"> android:background="@color/primary_dark">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -87,14 +89,12 @@
android:paddingStart="16dp" android:paddingStart="16dp"
android:paddingEnd="16dp" android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground"> android:background="?attr/selectableItemBackground">
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Pets" android:text="Pets"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="15sp"/> android:textSize="15sp"/>
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
@@ -106,14 +106,12 @@
android:paddingStart="16dp" android:paddingStart="16dp"
android:paddingEnd="16dp" android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground"> android:background="?attr/selectableItemBackground">
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Services" android:text="Services"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="15sp"/> android:textSize="15sp"/>
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
@@ -125,39 +123,30 @@
android:paddingStart="16dp" android:paddingStart="16dp"
android:paddingEnd="16dp" android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground"> android:background="?attr/selectableItemBackground">
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Suppliers" android:text="Suppliers"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="15sp"/> android:textSize="15sp"/>
</LinearLayout> </LinearLayout>
<LinearLayout
<!-- Appointments --> android:id="@+id/drawerAppointments"
<LinearLayout
android:id="@+id/drawerAppointments"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="48dp"
android:text="Appointments" android:orientation="horizontal"
android:textColor="@color/white" android:gravity="center_vertical"
android:textSize="15sp"/> android:paddingStart="16dp"
android:paddingEnd="16dp"
</LinearLayout> android:background="?attr/selectableItemBackground">
<TextView
<!-- Adoptions --> android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Appointments"
android:textColor="@color/white"
android:textSize="15sp"/>
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/drawerAdoptions" android:id="@+id/drawerAdoptions"
@@ -168,19 +157,14 @@
android:paddingStart="16dp" android:paddingStart="16dp"
android:paddingEnd="16dp" android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground"> android:background="?attr/selectableItemBackground">
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Adoptions" android:text="Adoptions"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="15sp"/> android:textSize="15sp"/>
</LinearLayout> </LinearLayout>
<!-- Inventory -->
<LinearLayout <LinearLayout
android:id="@+id/drawerInventory" android:id="@+id/drawerInventory"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -190,19 +174,14 @@
android:paddingStart="16dp" android:paddingStart="16dp"
android:paddingEnd="16dp" android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground"> android:background="?attr/selectableItemBackground">
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Inventory" android:text="Inventory"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="15sp"/> android:textSize="15sp"/>
</LinearLayout> </LinearLayout>
<!-- Product -->
<LinearLayout <LinearLayout
android:id="@+id/drawerProducts" android:id="@+id/drawerProducts"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -212,88 +191,65 @@
android:paddingStart="16dp" android:paddingStart="16dp"
android:paddingEnd="16dp" android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground"> android:background="?attr/selectableItemBackground">
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Products" android:text="Products"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="15sp"/> android:textSize="15sp"/>
</LinearLayout> </LinearLayout>
<LinearLayout
<!-- Sale --> android:id="@+id/drawerSale"
<LinearLayout
android:id="@+id/drawerSale"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="48dp"
android:text="Sale" android:orientation="horizontal"
android:textColor="@color/white" android:gravity="center_vertical"
android:textSize="15sp"/> android:paddingStart="16dp"
android:paddingEnd="16dp"
</LinearLayout> android:background="?attr/selectableItemBackground">
<TextView
<!-- PurchaseOrder -->
<LinearLayout
android:id="@+id/drawerPurchaseOrderView"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="PurchaseOrder"
android:textColor="@color/white"
android:textSize="15sp"/>
</LinearLayout>
<!-- ProductSupplier -->
<LinearLayout
android:id="@+id/drawerProductSupplier"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="48dp" android:layout_height="wrap_content"
android:orientation="horizontal" android:text="Sale"
android:gravity="center_vertical" android:textColor="@color/white"
android:paddingStart="16dp" android:textSize="15sp"/>
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ProductSupplier"
android:textColor="@color/white"
android:textSize="15sp"/>
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/drawerPurchaseOrderView"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="PurchaseOrder"
android:textColor="@color/white"
android:textSize="15sp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/drawerProductSupplier"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:background="?attr/selectableItemBackground">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ProductSupplier"
android:textColor="@color/white"
android:textSize="15sp"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</androidx.drawerlayout.widget.DrawerLayout> </androidx.drawerlayout.widget.DrawerLayout>

View File

@@ -0,0 +1,136 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/list_nav_graph"
app:startDestination="@id/nav_pet">
<!-- List Screens -->
<fragment
android:id="@+id/nav_pet"
android:name="com.example.petstoremobile.fragments.listfragments.PetFragment"
android:label="Pets"
tools:layout="@layout/fragment_pet" />
<fragment
android:id="@+id/nav_service"
android:name="com.example.petstoremobile.fragments.listfragments.ServiceFragment"
android:label="Services"
tools:layout="@layout/fragment_service" />
<fragment
android:id="@+id/nav_supplier"
android:name="com.example.petstoremobile.fragments.listfragments.SupplierFragment"
android:label="Suppliers"
tools:layout="@layout/fragment_supplier" />
<fragment
android:id="@+id/nav_adoption"
android:name="com.example.petstoremobile.fragments.listfragments.AdoptionFragment"
android:label="Adoptions"
tools:layout="@layout/fragment_adoption" />
<fragment
android:id="@+id/nav_appointment"
android:name="com.example.petstoremobile.fragments.listfragments.AppointmentFragment"
android:label="Appointments"
tools:layout="@layout/fragment_appointment" />
<fragment
android:id="@+id/nav_inventory"
android:name="com.example.petstoremobile.fragments.listfragments.InventoryFragment"
android:label="Inventory"
tools:layout="@layout/fragment_inventory" />
<fragment
android:id="@+id/nav_product"
android:name="com.example.petstoremobile.fragments.listfragments.ProductFragment"
android:label="Products"
tools:layout="@layout/fragment_product" />
<fragment
android:id="@+id/nav_product_supplier"
android:name="com.example.petstoremobile.fragments.listfragments.ProductSupplierFragment"
android:label="Product Suppliers"
tools:layout="@layout/fragment_product_supplier" />
<fragment
android:id="@+id/nav_purchase_order"
android:name="com.example.petstoremobile.fragments.listfragments.PurchaseOrderFragment"
android:label="Purchase Orders"
tools:layout="@layout/fragment_purchase_order" />
<fragment
android:id="@+id/nav_sale"
android:name="com.example.petstoremobile.fragments.listfragments.SaleFragment"
android:label="Sales"
tools:layout="@layout/fragment_sale" />
<!-- Detail Screens -->
<fragment
android:id="@+id/nav_pet_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.PetDetailFragment"
android:label="Pet Details"
tools:layout="@layout/fragment_pet_detail" />
<fragment
android:id="@+id/nav_pet_profile"
android:name="com.example.petstoremobile.fragments.listfragments.listprofilefragments.PetProfileFragment"
android:label="Pet Profile"
tools:layout="@layout/fragment_pet_profile" />
<fragment
android:id="@+id/nav_adoption_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.AdoptionDetailFragment"
android:label="Adoption Details"
tools:layout="@layout/fragment_adoption_detail" />
<fragment
android:id="@+id/nav_service_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.ServiceDetailFragment"
android:label="Service Details"
tools:layout="@layout/fragment_service_detail" />
<fragment
android:id="@+id/nav_supplier_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.SupplierDetailFragment"
android:label="Supplier Details"
tools:layout="@layout/fragment_supplier_detail" />
<fragment
android:id="@+id/nav_inventory_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.InventoryDetailFragment"
android:label="Inventory Details"
tools:layout="@layout/fragment_inventory_detail" />
<fragment
android:id="@+id/nav_appointment_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.AppointmentDetailFragment"
android:label="Appointment Details"
tools:layout="@layout/fragment_appointment_detail" />
<fragment
android:id="@+id/nav_purchase_order_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.PurchaseOrderDetailFragment"
android:label="Purchase Order Details"
tools:layout="@layout/fragment_purchase_order_detail" />
<fragment
android:id="@+id/nav_product_supplier_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.ProductSupplierDetailFragment"
android:label="Product Supplier Details"
tools:layout="@layout/fragment_product_supplier_detail" />
<fragment
android:id="@+id/nav_product_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.ProductDetailFragment"
android:label="Product Details"
tools:layout="@layout/fragment_product_detail" />
<fragment
android:id="@+id/nav_refund_detail"
android:name="com.example.petstoremobile.fragments.listfragments.detailfragments.RefundDetailFragment"
android:label="Refund Details"
tools:layout="@layout/fragment_refund_detail" />
</navigation>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/nav_graph"
app:startDestination="@id/nav_list">
<fragment
android:id="@+id/nav_list"
android:name="com.example.petstoremobile.fragments.ListFragment"
android:label="List"
tools:layout="@layout/fragment_list" />
<fragment
android:id="@+id/nav_chat"
android:name="com.example.petstoremobile.fragments.ChatFragment"
android:label="Chat"
tools:layout="@layout/fragment_chat" />
<fragment
android:id="@+id/nav_profile"
android:name="com.example.petstoremobile.fragments.ProfileFragment"
android:label="Profile"
tools:layout="@layout/fragment_profile" />
</navigation>

View File

@@ -2,4 +2,5 @@
plugins { plugins {
alias(libs.plugins.android.application) apply false alias(libs.plugins.android.application) apply false
alias(libs.plugins.hilt) apply false alias(libs.plugins.hilt) apply false
alias(libs.plugins.navigation.safeargs) apply false
} }

View File

@@ -9,6 +9,7 @@ activity = "1.12.4"
constraintlayout = "2.2.1" constraintlayout = "2.2.1"
swiperefreshlayout = "1.2.0" swiperefreshlayout = "1.2.0"
hilt = "2.51.1" hilt = "2.51.1"
navigation = "2.8.8"
[libraries] [libraries]
junit = { group = "junit", name = "junit", version.ref = "junit" } junit = { group = "junit", name = "junit", version.ref = "junit" }
@@ -21,7 +22,10 @@ constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayo
swiperefreshlayout = { group = "androidx.swiperefreshlayout", name = "swiperefreshlayout", version.ref = "swiperefreshlayout" } swiperefreshlayout = { group = "androidx.swiperefreshlayout", name = "swiperefreshlayout", version.ref = "swiperefreshlayout" }
hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" } hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" } hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" }
navigation-fragment = { group = "androidx.navigation", name = "navigation-fragment", version.ref = "navigation" }
navigation-ui = { group = "androidx.navigation", name = "navigation-ui", version.ref = "navigation" }
[plugins] [plugins]
android-application = { id = "com.android.application", version.ref = "agp" } android-application = { id = "com.android.application", version.ref = "agp" }
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
navigation-safeargs = { id = "androidx.navigation.safeargs", version.ref = "navigation" }