feat: Added history (RecyclerView) and fixed bugs

This commit is contained in:
SunZar 2025-02-20 10:53:37 +03:00
parent 8f683c1f0c
commit 04b26f8eaf
9 changed files with 206 additions and 95 deletions

View File

@ -63,12 +63,12 @@ public class UserRepositoryImpl implements UserRepository, SignUserRepository {
ArrayList<HistoryEntity> result1 = new ArrayList<>(historiesDto.size());
for (HistoryDto history : historiesDto) {
final Integer id1 = history.id;
final Integer idUser = history.idUser;
final String username1 = history.username;
final Long time = history.time;
final String nameReader = history.nameReader;
final String type = history.type;
if (idUser != null && id1 != null){
result1.add(new HistoryEntity(id1, idUser, time, nameReader, type));
final Integer code = history.code;
if (username1 != null && id1 != null){
result1.add(new HistoryEntity(id1, username1, time, type, code));
}
}
return result1;

View File

@ -10,21 +10,19 @@ public class HistoryDto {
public Integer id;
@Nullable
@SerializedName("idUser")
public Integer idUser;
@SerializedName("username")
public String username;
@Nullable
@SerializedName("time")
public Long time;
@Nullable
@SerializedName("nameReader")
public String nameReader;
@Nullable
@SerializedName("type")
public String type;
@Nullable
@SerializedName("code")
public Integer code;
}

View File

@ -19,12 +19,12 @@ public class HistoryEntity {
}
@Nullable
public Integer getIdUser() {
return idUser;
public String getUsername() {
return username;
}
public void setIdUser(@Nullable Integer idUser) {
this.idUser = idUser;
public void setUsername(@Nullable String username) {
this.username = username;
}
@Nullable
@ -36,15 +36,6 @@ public class HistoryEntity {
this.time = time;
}
@Nullable
public String getNameReader() {
return nameReader;
}
public void setNameReader(@Nullable String nameReader) {
this.nameReader = nameReader;
}
@Nullable
public String getType() {
return type;
@ -54,28 +45,37 @@ public class HistoryEntity {
this.type = type;
}
public HistoryEntity(@Nullable Integer id, @Nullable Integer idUser, @Nullable Long time, @Nullable String nameReader, @Nullable String type) {
@Nullable
public Integer getCode() {
return code;
}
public void setCode(@Nullable Integer code) {
this.code = code;
}
public HistoryEntity(@Nullable Integer id, @Nullable String username, @Nullable Long time, @Nullable String type, @Nullable Integer code) {
this.id = id;
this.idUser = idUser;
this.username = username;
this.time = time;
this.nameReader = nameReader;
this.type = type;
this.code = code;
}
@Nullable
@SerializedName("idUser")
public Integer idUser;
@SerializedName("username")
public String username;
@Nullable
@SerializedName("time")
public Long time;
@Nullable
@SerializedName("nameReader")
public String nameReader;
@Nullable
@SerializedName("type")
public String type;
@Nullable
@SerializedName("code")
public Integer code;
}

View File

@ -11,11 +11,12 @@ import java.util.ArrayList;
import java.util.List;
import ru.myitschool.work.databinding.ItemHistoryBinding;
import ru.myitschool.work.domain.entities.HistoryEntity;
import ru.myitschool.work.ui.History;
public class HistoryAdapter extends RecyclerView.Adapter<HistoryAdapter.ViewHolder> {
private final List<History> data = new ArrayList<>();
private final List<HistoryEntity> data = new ArrayList<>();
@NonNull
@Override
@ -40,7 +41,7 @@ public class HistoryAdapter extends RecyclerView.Adapter<HistoryAdapter.ViewHold
return data.size();
}
public void updateData(List<History> newData) {
public void updateData(List<HistoryEntity> newData) {
data.clear();
data.addAll(newData);
notifyDataSetChanged();
@ -54,11 +55,11 @@ public class HistoryAdapter extends RecyclerView.Adapter<HistoryAdapter.ViewHold
binding = ItemHistoryBinding.bind(itemView);
}
public void bind(History item) {
public void bind(HistoryEntity item) {
binding.time.setText(item.getTime().toString().substring(0, 10) + " "
+ item.getTime().toString().substring(11, 16));
binding.nameReader.setText(item.getNameReader());
if (item.getPassageType() == 1){
if (item.getType() == 1){
binding.type.setText("QR-code");
}
else{

View File

@ -6,15 +6,19 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.Navigation;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
@ -23,16 +27,23 @@ import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import ru.myitschool.work.R;
import ru.myitschool.work.databinding.FragmentInformationBinding;
import ru.myitschool.work.domain.entities.HistoryEntity;
import ru.myitschool.work.domain.entities.UserEntity;
import ru.myitschool.work.utils.Constants;
import ru.myitschool.work.ui.History;
import ru.myitschool.work.ui.StoreAPI;
import ru.myitschool.work.ui.User;
import ru.myitschool.work.ui.qr.scan.QrScanDestination;
import ru.myitschool.work.utils.PreferenceManager;
import ru.myitschool.work.utils.Utils;
public class InformationFragment extends Fragment {
FragmentInformationBinding binding;
SharedPreferences sharedPreferences;
ArrayList<History> history = new ArrayList<>();
PreferenceManager preferenceManager;
InformationViewModel viewModel;
List<HistoryEntity> history = new ArrayList<>();
private boolean loadingHistory;
private String username;
@Nullable
@Override
@ -45,9 +56,11 @@ public class InformationFragment extends Fragment {
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
sharedPreferences = getContext().getSharedPreferences(getString(R.string.app_name), Context.MODE_PRIVATE);
getInformation();
//sharedPreferences = getContext().getSharedPreferences(getString(R.string.app_name), Context.MODE_PRIVATE);
preferenceManager = new PreferenceManager(this.getContext());
username = preferenceManager.getString(Constants.KEY_USER_USERNAME);
viewModel = new ViewModelProvider(this).get(InformationViewModel.class);
//getInformation();
binding.scan.setOnClickListener(view1 -> {
onClickScan(view);
@ -58,12 +71,13 @@ public class InformationFragment extends Fragment {
});
binding.refreshLayout.setOnRefreshListener(() -> {
onClickRefresh();
viewModel.load();
});
//TODO: SERVER ZAGRUZKA LISTAAAAAAAAAAAAAAA
HistoryAdapter adapter = new HistoryAdapter();
binding.historylist.setAdapter(adapter);
adapter.updateData(history);
subscribe(viewModel, adapter, view);
//getParentFragmentManager()
requireActivity().getSupportFragmentManager().setFragmentResultListener(QrScanDestination.REQUEST_KEY, getViewLifecycleOwner(), (requestKey, result) -> {
@ -79,11 +93,14 @@ public class InformationFragment extends Fragment {
Navigation.findNavController(view).navigate(R.id.action_informationFragment_to_resultFragment);
//getFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, resFragment).commit();
});
viewModel.changeSelectedUsername(username);
viewModel.load();
}
private void onClickRefresh() {
/*private void onClickRefresh() {
getInformation();
}
}*/
private void onClickScan(View view) {
Navigation.findNavController(view).navigate(R.id.action_informationFragment_to_qrScanFragment);
@ -91,11 +108,101 @@ public class InformationFragment extends Fragment {
}
private void onClickLogout(View view) {
sharedPreferences.edit().clear().apply();
preferenceManager.clear();
Navigation.findNavController(view).navigate(R.id.action_informationFragment_to_loginFragment);
//getFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new LoginFragment()).commit();
}
private void subscribe(final InformationViewModel viewModel, final HistoryAdapter historyAdapter, View view) {
viewModel.stateAllUserHistoryLiveData.observe(getViewLifecycleOwner(), state -> {
loadingHistory = state.isLoading();
//Toast.makeText(this.getContext(), "Zashol", Toast.LENGTH_SHORT).show();
binding.loading.setVisibility(Utils.visibleOrGone(loadingHistory));
if (state.isLoading() == false) {
if (state.getItemsHistory() != null) {
history = state.getItemsHistory();
//TODO: BINDING
//binding.address.setText(history.getAddress());
//binding.countVolunteers.setText("Количество волонтёров: " + history.getUsers().size());
//List<ItemUserEntity> itemUserEntities = new ArrayList<>();
//for (FullUserEntity el : volunteerCenter.getUsers()) {
// UserEntity user = new ItemUserEntity(el.getId(), el.getLastName(), el.getFirstName());
// itemUserEntities.add(user);
//}
historyAdapter.updateData(history);
historyAdapter.notifyDataSetChanged();
binding.refreshLayout.setRefreshing(false);
}
} else {
Toast.makeText(this.getContext(), "Error", Toast.LENGTH_SHORT).show();
takeError();
}
binding.refreshLayout.setRefreshing(false);
});
/*
viewModel.stateHistoryLiveData.observe(getViewLifecycleOwner(), state -> {
loadingHistory = state.isLoading();
//Toast.makeText(this.getContext(), "vse", Toast.LENGTH_SHORT).show();
binding.loading.setVisibility(Utils.visibleOrGone(loadingHistory));
if (state.isLoading() == false) {
if (state.getItemsHistory() != null) {
volunteerCenters = state.getItemsVolunteerCenters();
List<String> volunteerCentersString = new ArrayList<String>();
for (ItemVolunteerCenterEntity el : volunteerCenters) {
volunteerCentersString.add(el.getAddress());
}
ArrayAdapter<String> spinnerAdapter;
spinnerAdapter = new ArrayAdapter<String>(this.getContext(), android.R.layout.simple_spinner_item, volunteerCentersString);
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
binding.spinner.setAdapter(spinnerAdapter);
//binding.spinner.setPromptId(R.string.chooseday);
//binding.spinner.setSelection(1, true);
String volunteerCenterId = preferenceManager.getString(Constants.KEY_VOLUNTEER_CENTER_ID);
if (volunteerCenterId != null) {
//Toast.makeText(this.getContext(), volunteerCenterId, Toast.LENGTH_SHORT).show();
binding.spinner.setSelection(Integer.parseInt(volunteerCenterId) - 1, true);
}
} else {
Toast.makeText(this.getContext(), "Error", Toast.LENGTH_SHORT).show();
}
}
/*boolean isSuccess = !state.isLoading()
&& state.getErrorMessage() == null
&& state.getItems() != null;
//binding.refresh.setEnabled(!state.isLoading());
//if (!state.isLoading()) //binding.refresh.setRefreshing(false);
binding.recycler.setVisibility(Utils.visibleOrGone(isSuccess));
binding.error.setVisibility(Utils.visibleOrGone(state.getErrorMessage() != null));
binding.loading.setVisibility(Utils.visibleOrGone(state.isLoading()));
binding.error.setText(state.getErrorMessage());
if (isSuccess) {
listAdapter.updateData(state.getItems());
}
});
*/
}
/*private void getInformation() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ru.myitschool.work.core.Constants.SERVER_ADDRESS)

View File

@ -12,23 +12,17 @@ import java.util.List;
import ru.myitschool.work.data.UserRepositoryImpl;
import ru.myitschool.work.domain.GetAllUserHistoryUseCase;
import ru.myitschool.work.domain.sign.IsUserExistUseCase;
import ru.sicampus.bootcamp2025.data.UserRepositoryImpl;
import ru.sicampus.bootcamp2025.domain.GetUsersListUseCase;
import ru.sicampus.bootcamp2025.domain.GetVolunteerCenterByIdUseCase;
import ru.sicampus.bootcamp2025.domain.GetVolunteerCentersListUseCase;
import ru.sicampus.bootcamp2025.domain.entites.FullVolunteerCenterEntity;
import ru.sicampus.bootcamp2025.domain.entites.ItemVolunteerCenterEntity;
import ru.sicampus.bootcamp2025.domain.entites.Status;
import ru.myitschool.work.domain.entities.HistoryEntity;
import ru.myitschool.work.domain.entities.Status;
public class InformationViewModel extends ViewModel {
private final MutableLiveData<State> mutableStateCentersLiveData = new MutableLiveData<>();
private final MutableLiveData<State> mutableStateHistoryLiveData = new MutableLiveData<>();
public final LiveData<State> stateCentersLiveData = mutableStateCentersLiveData;
public final LiveData<State> stateHistoryLiveData = mutableStateHistoryLiveData;
private final MutableLiveData<State> mutableStateVolunteerCenterLiveData = new MutableLiveData<>();
private final MutableLiveData<State> mutableStateAllUserHistoryLiveData = new MutableLiveData<>();
public final LiveData<State> stateVolunteerCenterLiveData = mutableStateVolunteerCenterLiveData;
public final LiveData<State> stateAllUserHistoryLiveData = mutableStateAllUserHistoryLiveData;
public final GetAllUserHistoryUseCase getAllUserHistoryUseCase = new GetAllUserHistoryUseCase(
UserRepositoryImpl.getInstance()
@ -38,26 +32,26 @@ public class InformationViewModel extends ViewModel {
update();
}*/
private Integer volunteerCenterId;
private String username;
public void changeSelectedVCId(@NonNull Integer volunteerCenterId) {
this.volunteerCenterId = volunteerCenterId;
public void changeSelectedUsername(@NonNull String username) {
this.username = this.username;
}
public void load() {
mutableStateCentersLiveData.setValue(new ListViewModel.State(null, null, null, true));
getAllUserHistoryUseCase.execute(status -> {
mutableStateCentersLiveData.postValue(fromStatus(status));
});
mutableStateAllUserHistoryLiveData.setValue(new InformationViewModel.State(null, null, false));
getHistById(username);
/*getAllUserHistoryUseCase.execute(username, status -> {
mutableStateHistoryLiveData.postValue(fromStatus(status));
});*/
}
public void getVCById() {
getVolunteerCenterByIdUseCase.execute(volunteerCenterId, status -> {
Log.d("taggis", status.getStatusCode() + " " + status.getErrors());
public void getHistById() {
getAllUserHistoryUseCase.execute(username, status -> {
//Log.d("taggis", status.getStatusCode() + " " + status.getErrors());
if (status.getStatusCode() == 200 && status.getErrors() == null) {
mutableStateVolunteerCenterLiveData.postValue(new ListViewModel.State(
mutableStateAllUserHistoryLiveData.postValue(new InformationViewModel.State(
status.getErrors() != null ? status.getErrors().getLocalizedMessage() : null,
null,
status.getValue(),
false
));
@ -67,11 +61,10 @@ public class InformationViewModel extends ViewModel {
});
}
private ListViewModel.State fromStatus(Status<List<ItemVolunteerCenterEntity>> status) {
return new ListViewModel.State(
private InformationViewModel.State fromStatus(Status<List<HistoryEntity>> status) {
return new InformationViewModel.State(
status.getErrors() != null ? status.getErrors().getLocalizedMessage() : null,
status.getValue(),
null,
false
);
}
@ -81,17 +74,13 @@ public class InformationViewModel extends ViewModel {
private final String errorMessage;
@Nullable
private final List<ItemVolunteerCenterEntity> itemsVolunteerCenters;
@Nullable
private final FullVolunteerCenterEntity volunteerCenter;
private final List<HistoryEntity> itemsHistory;
private final boolean isLoading;
public State(@Nullable String errorMessage, @Nullable List<ItemVolunteerCenterEntity> itemsVolunteerCenters, FullVolunteerCenterEntity volunteerCenter, boolean isLoading) {
public State(@Nullable String errorMessage, @Nullable List<HistoryEntity> itemsHistory, boolean isLoading) {
this.errorMessage = errorMessage;
this.itemsVolunteerCenters = itemsVolunteerCenters;
this.volunteerCenter = volunteerCenter;
this.itemsHistory = itemsHistory;
this.isLoading = isLoading;
}
@ -101,13 +90,8 @@ public class InformationViewModel extends ViewModel {
}
@Nullable
public List<ItemVolunteerCenterEntity> getItemsVolunteerCenters() {
return itemsVolunteerCenters;
}
@Nullable
public FullVolunteerCenterEntity getVolunteerCenter() {
return volunteerCenter;
public List<HistoryEntity> getItemsHistory() {
return itemsHistory;
}
public boolean isLoading() {

View File

@ -13,6 +13,7 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.setFragmentResult
import androidx.fragment.app.viewModels
import androidx.navigation.NavController
import androidx.navigation.Navigation.findNavController
import androidx.navigation.fragment.findNavController
import com.google.mlkit.vision.barcode.BarcodeScanner
import com.google.mlkit.vision.barcode.BarcodeScannerOptions
@ -40,7 +41,7 @@ class QrScanFragment : Fragment(R.layout.fragment_qr_scan) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentQrScanBinding.bind(view)
sendResult(bundleOf())
subscribe()
subscribe(view)
initCallback()
}
@ -48,7 +49,7 @@ class QrScanFragment : Fragment(R.layout.fragment_qr_scan) {
binding.close.setOnClickListener { viewModel.close() }
}
private fun subscribe() {
private fun subscribe(view: View) {
viewModel.state.collectWhenStarted(this) { state ->
binding.loading.visibleOrGone(state is QrScanViewModel.State.Loading)
binding.viewFinder.visibleOrGone(state is QrScanViewModel.State.Scan)
@ -62,11 +63,11 @@ class QrScanFragment : Fragment(R.layout.fragment_qr_scan) {
when (action) {
is QrScanViewModel.Action.RequestPermission -> requestPermission(action.permission)
is QrScanViewModel.Action.CloseWithCancel -> {
goBack()
goBack(view)
}
is QrScanViewModel.Action.CloseWithResult -> {
sendResult(QrScanDestination.packToBundle(action.result))
goBack()
goBack(view)
}
}
}
@ -113,9 +114,10 @@ class QrScanFragment : Fragment(R.layout.fragment_qr_scan) {
super.onDestroyView()
}
private fun goBack() {
findNavControllerOrNull()?.popBackStack()
?: requireActivity().onBackPressedDispatcher.onBackPressed()
private fun goBack(view: View) {
findNavController(view).navigate<Any>(R.id.action_qrScanFragment_to_informationFragment)
/*findNavControllerOrNull()?.popBackStack()
?: requireActivity().onBackPressedDispatcher.onBackPressed()*/
}
private fun sendResult(bundle: Bundle) {

View File

@ -0,0 +1,9 @@
package ru.myitschool.work.utils;
import android.view.View;
public class Utils {
public static int visibleOrGone(boolean isVisible) {
return isVisible ? View.VISIBLE : View.GONE;
}
}

View File

@ -86,6 +86,16 @@
android:layout_gravity="center"
/>
<ProgressBar
android:id="@+id/loading"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>