http request call done

This commit is contained in:
OnlyPapy98
2025-11-12 16:52:48 +01:00
parent 159837bd6f
commit b1ce91ef20
53 changed files with 1109 additions and 1045 deletions

View File

@@ -2,6 +2,7 @@ plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.google.android.libraries.mapsplatform.secrets.gradle.plugin)
id("com.google.dagger.hilt.android")
alias(libs.plugins.kotlin.android)
}
android {
@@ -34,13 +35,18 @@ android {
buildFeatures {
viewBinding = true
}
kotlinOptions {
jvmTarget = "11"
}
}
dependencies {
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar"))))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1")
implementation("com.squareup.retrofit2:converter-gson:2.11.0")
implementation("com.squareup.retrofit2:retrofit:2.11.0")
implementation(libs.retrofit)
implementation(libs.okhttp)
implementation(libs.logging.interceptor)
implementation(libs.kotlinx.coroutines.android)
implementation(libs.converter.gson)
implementation(libs.hilt.android)
annotationProcessor(libs.hilt.compiler)
implementation(libs.rxjava)

View File

@@ -1,27 +0,0 @@
package com.example.quiz;
import com.example.quiz.data.BetsBank;
import com.example.quiz.data.repository.BetRepository;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import dagger.hilt.InstallIn;
import dagger.hilt.components.SingletonComponent;
@Module
@InstallIn(SingletonComponent.class)
public class AppModule {
@Provides
@Singleton
public BetsBank provideApiService(){
return BetsBank.getInstance();
}
@Provides
@Singleton
public BetRepository provideBetRepository() {
return new BetRepository();
}
}

View File

@@ -17,24 +17,14 @@ import android.widget.GridLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.example.quiz.data.model.Horse;
import com.example.quiz.data.model.Course;
import com.example.quiz.data.model.Reunion;
import com.example.quiz.data.model.TypeOfBet;
import com.example.quiz.databinding.FragmentBetValidationBinding;
import com.example.quiz.utils.HPRTPrinterUtil;
import com.example.quiz.viewModel.BetViewModel;
import com.example.quiz.viewModel.SharedViewModel;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import dagger.hilt.android.AndroidEntryPoint;
/**
@@ -50,18 +40,18 @@ public class BetValidation extends Fragment {
SharedViewModel shared;
BetViewModel viewModel;
private HPRTPrinterUtil printer;
private TypeOfBet typeOfBet;
private String typeOfBet;
private Reunion reunion;
private List<Horse> selectedHorses = new ArrayList<Horse>();
private Course course;
private List<String> selectedHorses = new ArrayList<String>();
private List<Horse> totalHorses;
@@ -92,27 +82,28 @@ public class BetValidation extends Fragment {
private void setupNumberGrid(GridLayout grid) {
binding.gridNumbers.removeAllViews();
int columns = 4;
int columns = 7;
grid.setColumnCount(columns);
if(totalHorses != null){
totalHorses.stream()
.map(this::createNumberItem)
.forEach(grid::addView);
if(shared.selectedCourse.getValue() != null){
for (int i = 1; i <= shared.selectedCourse.getValue().getNombreChevauxInscrits(); i++) {
createNumberItem(String.valueOf(i));
grid.addView(createNumberItem(String.valueOf(i)));
}
}
createNumberItem("X");
grid.addView(createNumberItem("X"));
}
private TextView createNumberItem(Horse horse) {
private TextView createNumberItem(String horse) {
TextView textView = new TextView(requireContext());
textView.setText(String.valueOf(horse.getNumber()));
textView.setText(horse);
textView.setTextColor(getResources().getColor(R.color.white));
GridLayout.LayoutParams params = new GridLayout.LayoutParams();
params.setMargins(10, 10, 10, 10);
params.setMargins(1, 1, 1, 1);
textView.setLayoutParams(params);
textView.setTextSize(21);
textView.setWidth(130);
textView.setHeight(130);
textView.setTextSize(10);
textView.setWidth(80);
textView.setHeight(100);
textView.setGravity(Gravity.CENTER);
textView.setBackgroundResource(R.drawable.number_background);
textView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
@@ -128,7 +119,7 @@ public class BetValidation extends Fragment {
v.setBackgroundResource(R.drawable.number_selected_background);
}
String combinationText = selectedHorses.stream()
.map(h -> String.valueOf(h.getNumber()))
.map(h -> h)
.collect(Collectors.joining("-"));
binding.combination.setText(getString(R.string.combination, combinationText));
});
@@ -140,21 +131,17 @@ public class BetValidation extends Fragment {
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
viewModel = new ViewModelProvider(this).get(BetViewModel.class);
/*viewModel = new ViewModelProvider(this).get(BetViewModel.class);
viewModel.getBetNameById(shared.betId.getValue() - 1);
viewModel.betName.observe(getViewLifecycleOwner(), name ->{
binding.horseName.setText(name);
});
viewModel.loadHorses(shared.betId.getValue() - 1);
viewModel.horses.observe(getViewLifecycleOwner(), h->{
this.totalHorses = h;
setupNumberGrid(binding.gridNumbers);
});
shared.typeOfBet.observe(getViewLifecycleOwner(), type ->{
this.typeOfBet = type;
});
viewModel.loadReunionById(shared.betId.getValue() - 1);
reunion = viewModel.reunion.getValue();
if(viewModel.partant.getValue() != null){
this.totalHorses = viewModel.partant.getValue();
}*/
setupNumberGrid(binding.gridNumbers);
binding.paymentType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
@@ -180,13 +167,34 @@ public class BetValidation extends Fragment {
Toast.makeText(getContext(), "Veuillez entrer un numéro de téléphone", Toast.LENGTH_SHORT).show();
return;
}
Integer required = Integer.parseInt(typeOfBet.getNumberOfHorse());
if(required == null){
if(shared.typeOfBet == null || shared.selectedReunion.getValue() == null || shared.selectedCourse == null){
return;
}
typeOfBet = shared.typeOfBet.getValue();
reunion = shared.selectedReunion.getValue();
course = shared.selectedCourse.getValue();
int required = 0;
if(typeOfBet.toLowerCase().contains("couple")){
required = 2;
}
if(typeOfBet.toLowerCase().contains("tierce")){
required = 3;
}
if(typeOfBet.toLowerCase().contains("quarte")){
required = 4;
}
if(typeOfBet.toLowerCase().contains("quinte")){
required = 5;
}
if(required == 0){
Toast.makeText(getContext(), "Erreur de type de pari", Toast.LENGTH_SHORT).show();
return;
}
if(selectedHorses.size() != required){
Toast.makeText(getContext(), "Veuillez sélectionner "+required+" chevaux", Toast.LENGTH_SHORT).show();
if(selectedHorses.size() < required){
Toast.makeText(getContext(), "Veuillez sélectionner au moins"+required+" chevaux", Toast.LENGTH_SHORT).show();
return;
}
printer = new HPRTPrinterUtil(getContext());
@@ -195,16 +203,16 @@ public class BetValidation extends Fragment {
StringBuilder tspl = new StringBuilder();
tspl.append("PARIS HIPPIQUE (PMU MALI)\n");
tspl.append(typeOfBet.getName()+"\n");
tspl.append(typeOfBet).append("\n");
tspl.append("Tel: 555-1234\n");
tspl.append("----------------------------\n");
tspl.append(reunion.getName()+"/"+reunion.getAddress());
tspl.append(reunion.getNom()).append("/").append(course.getLieu());
tspl.append("----------------------------\n");
String combinationText = selectedHorses.stream()
.map(h -> String.valueOf(h.getNumber()))
.map(String::valueOf)
.collect(Collectors.joining("-"));
tspl.append("COMBINAISON : "+combinationText);
tspl.append("COMBINAISON : ").append(combinationText);
tspl.append("\n----------------------------\n");
@@ -216,7 +224,9 @@ public class BetValidation extends Fragment {
printer.printText(tspl);
}
selectedHorses = List.of();
binding.combination.setText(getString(R.string.combination,""));
setupNumberGrid(binding.gridNumbers);
});
binding.backBtn.setOnClickListener(v->{

View File

@@ -6,31 +6,29 @@ import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.app.ComponentActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import android.service.controls.Control;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.LayoutAnimationController;
import android.widget.Toast;
import com.example.quiz.data.adapter.BetsAdapter;
import com.example.quiz.data.model.Course;
import com.example.quiz.databinding.FragmentListOFBettingBinding;
import com.example.quiz.viewModel.BetViewModel;
import com.example.quiz.utils.Result;
import com.example.quiz.viewModel.CourseViewModel;
import com.example.quiz.viewModel.SharedViewModel;
import com.google.android.material.appbar.MaterialToolbar;
import java.util.List;
import dagger.hilt.android.AndroidEntryPoint;
import dagger.hilt.android.internal.lifecycle.HiltViewModelFactory;
/**
* A simple {@link Fragment} subclass.
@@ -40,25 +38,21 @@ import dagger.hilt.android.internal.lifecycle.HiltViewModelFactory;
@AndroidEntryPoint
public class ListOFBets extends Fragment {
private String username;
private View view;
FragmentListOFBettingBinding binding;
private BetViewModel viewModel;
private SharedViewModel shared;
private CourseViewModel viewModel;
private BetsAdapter adapter;
private AppCompatActivity activity;
public static ListOFBets newInstance(String username) {
public static ListOFBets newInstance() {
ListOFBets fragment = new ListOFBets();
Bundle args = new Bundle();
args.putString("ARG_USERNAME", username);
fragment.setArguments(args);
return fragment;
}
@@ -66,8 +60,13 @@ public class ListOFBets extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(getArguments() != null){
username = getArguments().getString("ARG_USERNAME");
AppCompatActivity activity = (AppCompatActivity) getActivity();
if(activity != null){
MaterialToolbar toolbar = activity.findViewById(R.id.toolbar);
activity.setSupportActionBar(toolbar);
if(activity.getSupportActionBar() != null){
activity.getSupportActionBar().setTitle("Liste des courses");
}
}
}
@@ -75,24 +74,15 @@ public class ListOFBets extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentListOFBettingBinding.inflate(inflater, container, false);
activity = (AppCompatActivity) getActivity();
if(activity != null){
if(activity.getSupportActionBar() != null){
activity.getSupportActionBar().show();
activity.getSupportActionBar().setTitle("Liste des paris");
}
}
adapter = new BetsAdapter();
binding.recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
binding.recyclerView.setAdapter(adapter);
LayoutAnimationController controller = AnimationUtils.loadLayoutAnimation(getContext(), R.anim.layout_fad_in);
binding.recyclerView.setLayoutAnimation(controller);
viewModel = new ViewModelProvider(this).get(BetViewModel.class);
viewModel = new ViewModelProvider(this).get(CourseViewModel.class);
shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
viewModel.bets.observe(getViewLifecycleOwner(), bets -> {
/*viewModel.bets.observe(getViewLifecycleOwner(), bets -> {
adapter.setBets(bets);
adapter.setOnItemClickListener(position -> {
shared.setBetId(position);
@@ -103,25 +93,42 @@ public class ListOFBets extends Fragment {
.addToBackStack(null)
.commit();
});
});
});*/
viewModel.loadBets();
//viewModel.loadBets();
observe();
return binding.getRoot();
}
public void observe(){
viewModel.getCourses().observe(getViewLifecycleOwner(), new Observer<Result<List<Course>>>() {
@Override
public void onChanged(Result<List<Course>> result) {
switch (result.status){
case LOADING:
Toast.makeText(getContext(), "Loading", Toast.LENGTH_SHORT).show();
break;
case SUCCESS:
adapter.setBets(result.data);
adapter.setOnItemClickListener(course ->{
shared.setSelectedCourse(course);
FragmentManager fragmentManager = getParentFragmentManager();
ListOfTypeOfBets typeOfBets = ListOfTypeOfBets.newInstance();
fragmentManager.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, typeOfBets)
.addToBackStack(null)
.commit();
});
case ERROR:
break;
}
}
});
}
@SuppressLint("UseSupportActionBar")
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
AppCompatActivity activity = (AppCompatActivity) getActivity();
if(activity!=null){
Toolbar toolbar = activity.findViewById(R.id.toolbar);
toolbar.setBackgroundColor(getResources().getColor(R.color.primary_green));
toolbar.setTitleTextColor(getResources().getColor(R.color.text_light_grey));
activity.setSupportActionBar(toolbar);
if(activity.getSupportActionBar() != null){
activity.getSupportActionBar().setTitle(username);
}
}
}
}

View File

@@ -0,0 +1,126 @@
package com.example.quiz;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import android.widget.Toolbar;
import com.example.quiz.data.adapter.ReunionAdapter;
import com.example.quiz.data.model.Reunion;
import com.example.quiz.databinding.FragmentListOfReunionsBinding;
import com.example.quiz.utils.Result;
import com.example.quiz.viewModel.ReunionViewModel;
import com.example.quiz.viewModel.SharedViewModel;
import com.google.android.material.appbar.MaterialToolbar;
import java.util.List;
import dagger.hilt.android.AndroidEntryPoint;
/**
* A simple {@link Fragment} subclass.
* Use the {@link ListOfReunions#newInstance} factory method to
* create an instance of this fragment.
*/
@AndroidEntryPoint
public class ListOfReunions extends Fragment {
FragmentListOfReunionsBinding binding;
SharedViewModel shared;
ReunionAdapter adapter;
ReunionViewModel reunionViewModel;
public ListOfReunions() {
// Required empty public constructor
}
public static ListOfReunions newInstance(String username) {
ListOfReunions fragment = new ListOfReunions();
Bundle args = new Bundle();
args.putString("USER_NAME", username);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentListOfReunionsBinding.inflate(inflater, container, false);
adapter = new ReunionAdapter();
binding.reunionsList.setLayoutManager(new LinearLayoutManager(getContext()));
binding.reunionsList.setAdapter(adapter);
reunionViewModel = new ViewModelProvider(this).get(ReunionViewModel.class);
shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
observeReunions();
return binding.getRoot();
}
public void observeReunions(){
reunionViewModel.getReunions().observe(getViewLifecycleOwner(), new Observer<Result<List<Reunion>>>() {
@Override
public void onChanged(Result<List<Reunion>> result) {
switch (result.status) {
case LOADING:
Toast.makeText(getContext(), "Loading", Toast.LENGTH_SHORT).show();
break;
case SUCCESS:
adapter.setReunions(result.data);
adapter.setOnItemClickListener(reunion->{
shared.setSelectedReunion(reunion);
FragmentManager fragmentManager = getParentFragmentManager();
ListOFBets bets = ListOFBets.newInstance();
fragmentManager.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, bets)
.addToBackStack(null)
.commit();
});
break;
case ERROR:
Toast.makeText(getContext(), result.message, Toast.LENGTH_SHORT).show();
}
}
});
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
AppCompatActivity activity = (AppCompatActivity) getActivity();
if (activity != null) {
MaterialToolbar toolbar = activity.findViewById(R.id.toolbar);
activity.setSupportActionBar(toolbar);
if (activity.getSupportActionBar() != null) {
activity.getSupportActionBar().show();
activity.getSupportActionBar().setTitle("Liste des réunions");
}
toolbar.setBackgroundColor(getResources().getColor(R.color.primary_green, null));
toolbar.setTitleTextColor(getResources().getColor(R.color.white, null));
}
}
}

View File

@@ -4,6 +4,7 @@ import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.ViewModel;
@@ -14,21 +15,16 @@ import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.view.animation.LayoutAnimationController;
import android.widget.Adapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;
import com.example.quiz.data.adapter.TypeOfBetAdapter;
import com.example.quiz.databinding.FragmentListOfTypeOfBetsBinding;
import com.example.quiz.viewModel.BetViewModel;
import com.example.quiz.viewModel.SharedViewModel;
import com.google.android.material.appbar.MaterialToolbar;
import java.util.ArrayList;
import java.util.List;
import dagger.hilt.android.AndroidEntryPoint;
@@ -45,8 +41,6 @@ public class ListOfTypeOfBets extends Fragment {
private SharedViewModel shared;
private BetViewModel viewModel;
private TypeOfBetAdapter adapter;
public ListOfTypeOfBets() {
@@ -62,6 +56,14 @@ public class ListOfTypeOfBets extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AppCompatActivity activity = (AppCompatActivity) getActivity();
if(activity != null){
MaterialToolbar toolbar = activity.findViewById(R.id.toolbar);
activity.setSupportActionBar(toolbar);
if(activity.getSupportActionBar() != null){
activity.getSupportActionBar().setTitle("Liste des jeux");
}
}
}
@Override
@@ -73,33 +75,45 @@ public class ListOfTypeOfBets extends Fragment {
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
LayoutAnimationController controller = AnimationUtils.loadLayoutAnimation(
getContext(),
R.anim.layout_fad_in
);
binding.typeOfBetRecyclerView.setLayoutAnimation(controller);
binding.typeOfBetRecyclerView.scheduleLayoutAnimation();
super.onViewCreated(view, savedInstanceState);
binding.typeOfBetRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
// ViewModels
viewModel = new ViewModelProvider(this).get(BetViewModel.class);
//viewModel = new ViewModelProvider(this).get(BetViewModel.class);
shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
// ⚡ Initialiser ladapter UNE SEULE FOIS
adapter = new TypeOfBetAdapter(new ArrayList<>());
adapter.setOnItemClickListener(type -> shared.setTypeOfBet(type));
binding.typeOfBetRecyclerView.setAdapter(adapter);
// Charger les données
viewModel.loadTypes(shared.betId.getValue()-1);
List<String> types = List.of("Couple Gagnant", "Couple Place", "Tierce", "Quinte");
// Observer les résultats
viewModel.types.observe(getViewLifecycleOwner(), types -> {
if (types != null) {
adapter.setTypes(types);
/*viewModel.types.observe(getViewLifecycleOwner(), type -> {
List<String> types = List.of();
if(type == null){
return;
}
switch (type){
case TIERCE:
types = List.of("Couple Gagnant", "Couple Place", "Tierce");
case QUARTE:
types = List.of("Couple Gagnant", "Couple Place", "Tierce", "Quarte");
case QUINTE:
types = List.of("Couple Gagnant", "Couple Place", "Tierce", "Quinte");
break;
}
adapter.setTypes(types);
});*/
adapter.setTypes(types);
adapter.setOnItemClickListener(type -> {
shared.setTypeOfBet(type);
});
Button btnValidate = binding.btnValidate;
btnValidate.setOnClickListener(v->{
if(shared.typeOfBet == null){
Toast.makeText(getContext(),"Aucun Type de jeu choisi", Toast.LENGTH_SHORT).show();
return;
}
FragmentManager fragmentManager = getParentFragmentManager();
BetValidation betValidation = BetValidation.newInstance();
fragmentManager.beginTransaction()
@@ -107,6 +121,5 @@ public class ListOfTypeOfBets extends Fragment {
.addToBackStack(null)
.commit();
});
}
}

View File

@@ -89,9 +89,9 @@ public class Login extends Fragment {
prefsHelper = SharedPrefsHelper.getInstance(getContext());
prefsHelper.save("username", binding.userNameInput.getText().toString());
FragmentManager fragmentManager = getParentFragmentManager();
ListOFBets bets = ListOFBets.newInstance(binding.userNameInput.getText().toString());
ListOfReunions reunions = ListOfReunions.newInstance(binding.userNameInput.getText().toString());
fragmentManager.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, bets)
.replace(R.id.nav_host_fragment_content_main, reunions)
.commit();
}
});

View File

@@ -48,10 +48,10 @@ public class PageQuiz extends AppCompatActivity {
FragmentManager fragmentManager = getSupportFragmentManager();
if(prefsHelper.get("username") != null){
ListOFBets bets = ListOFBets.newInstance(prefsHelper.get("username"));
ListOfReunions reunions = ListOfReunions.newInstance(prefsHelper.get("username"));
fragmentManager
.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, bets)
.replace(R.id.nav_host_fragment_content_main, reunions)
.commit();
}else{
Login login = Login.newInstance();

View File

@@ -1,80 +0,0 @@
package com.example.quiz;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.quiz.data.model.Question;
import com.example.quiz.databinding.FragmentQuestionsBinding;
import com.example.quiz.injection.QuestionViewModelFactory;
import com.example.quiz.viewModel.QuestionViewModel;
public class Questions extends Fragment {
private FragmentQuestionsBinding binding;
private QuestionViewModel viewModel;
public Questions() {
// Required empty public constructor
}
public static Questions newInstance(String username) {
Questions fragment = new Questions();
Bundle args = new Bundle();
args.putString("ARG_USERNAME", username);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewModel = new ViewModelProvider(this, QuestionViewModelFactory.getInstance()).get(QuestionViewModel.class);
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentQuestionsBinding.inflate(inflater, container, false);
// Inflate the layout for this fragment
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
viewModel.startQuiz();
viewModel.currentQuestion.observe(getViewLifecycleOwner(), new Observer<Question>() {
@Override
public void onChanged(Question question) {
binding.questionText.setText(question.getQuestion());
binding.answer1.setText(question.getAnswers().get(0));
binding.answer2.setText(question.getAnswers().get(1));
binding.answer3.setText(question.getAnswers().get(2));
binding.answer4.setText(question.getAnswers().get(3));
}
});
}
@Override
public void onStart() {
super.onStart();
binding.nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
viewModel.nextQuestion();
}
});
}
}

View File

@@ -1,44 +0,0 @@
package com.example.quiz;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.example.quiz.databinding.FragmentSecond2Binding;
public class Second2Fragment extends Fragment {
private FragmentSecond2Binding binding;
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
binding = FragmentSecond2Binding.inflate(inflater, container, false);
return binding.getRoot();
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.buttonSecond.setOnClickListener(v ->
NavHostFragment.findNavController(Second2Fragment.this)
.navigate(R.id.action_Second2Fragment_to_First2Fragment)
);
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

View File

@@ -1,44 +0,0 @@
package com.example.quiz;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.example.quiz.databinding.FragmentSecondBinding;
public class SecondFragment extends Fragment {
private FragmentSecondBinding binding;
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
binding = FragmentSecondBinding.inflate(inflater, container, false);
return binding.getRoot();
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.buttonSecond.setOnClickListener(v ->
NavHostFragment.findNavController(SecondFragment.this)
.navigate(R.id.action_SecondFragment_to_FirstFragment)
);
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

View File

@@ -1,119 +0,0 @@
package com.example.quiz.data;
import com.example.quiz.data.model.Bet;
import com.example.quiz.data.model.Horse;
import com.example.quiz.data.model.Reunion;
import com.example.quiz.data.model.TypeOfBet;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
public class BetsBank {
public List<Bet> getBet() {
return Arrays.asList(
new Bet(
1,
"Course de chevaux",
new Reunion(1,
"Réunion ",
LocalDate.of(2025,10,1),
"Hippodrome Verssaille"
),
Arrays.asList(
new TypeOfBet(1, "Couplet", "2"),
new TypeOfBet(2, "Tierce", "3"),
new TypeOfBet(3, "Place", "1")
),
LocalDate.of(2025,10,1),
Arrays.asList(
new Horse(1),
new Horse(2),
new Horse(3),
new Horse(4)
)
),
new Bet(
2,
"Course de chevaux 2",
new Reunion(2,
"Réunion 2",
LocalDate.of(2025,10,1),
"Hippodrome Bordeaux"
),
Arrays.asList(
new TypeOfBet(1, "Quarte", "4"),
new TypeOfBet(2, "Quinte", "5"),
new TypeOfBet(3, "Placé", "1")
),
LocalDate.of(2025,10,1),
Arrays.asList(
new Horse(4),
new Horse(5),
new Horse(7),
new Horse(6),
new Horse(8),
new Horse(9),
new Horse(10),
new Horse(11)
)
),
new Bet(
3,
"Course de chevaux 3",
new Reunion(2,
"Réunion 2",
LocalDate.of(2025,10,1),
"Hippodrome Bordeaux"
),
Arrays.asList(
new TypeOfBet(1, "Quarte", "4"),
new TypeOfBet(2, "Quinte", "5"),
new TypeOfBet(3, "Placé", "1")
),
LocalDate.of(2025,10,1),
Arrays.asList(
new Horse(10),
new Horse(90),
new Horse(45),
new Horse(9)
)
),
new Bet(
4,
"Course de chevaux 4",
new Reunion(2,
"Réunion 2",
LocalDate.of(2025,10,1),
"Hippodrome Bordeaux"
),
Arrays.asList(
new TypeOfBet(1, "Couple", "2"),
new TypeOfBet(2, "Tierce", "3"),
new TypeOfBet(3, "Quarte", "4")
),
LocalDate.of(2025,10,1),
Arrays.asList(
new Horse(5),
new Horse(33),
new Horse(26),
new Horse(99),
new Horse(100),
new Horse(101),
new Horse(102),
new Horse(103),
new Horse(104),
new Horse(105)
)
)
);
}
public static BetsBank instance;
public static BetsBank getInstance(){
if(instance == null){
instance = new BetsBank();
}
return instance;
}
}

View File

@@ -1,69 +0,0 @@
package com.example.quiz.data;
import com.example.quiz.data.model.Question;
import java.util.Arrays;
import java.util.List;
public class QuestionsBank {
public List<Question> getQuestions() {
return Arrays.asList(
new Question(
"Who is the creator of Android?",
Arrays.asList(
"Andy Rubin",
"Steve Wozniak",
"Jake Wharton",
"Paul Smith"
),
0
),
new Question(
"When did the first man land on the moon?",
Arrays.asList(
"1958",
"1962",
"1967",
"1969"
),
3
),
new Question(
"What is the house number of The Simpsons?",
Arrays.asList(
"42",
"101",
"666",
"742"
),
3
),
new Question(
"Who painteddid the Mona Lisa paint?",
Arrays.asList(
"Michelangelo",
"Leonardo Da Vinci",
"Raphael",
"Caravaggio"
),
1
),
new Question(
"What is the country top-level domain of Belgium?",
Arrays.asList(
".bg",
".bm",
".bl",
".be"
),
3
)
);
}
private static QuestionsBank instance;
public static QuestionsBank getInstance() {
if (instance == null) {
instance = new QuestionsBank();
}
return instance;
}
}

View File

@@ -10,18 +10,19 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.quiz.R;
import com.example.quiz.data.model.Bet;
import com.example.quiz.data.model.Course;
import com.example.quiz.viewModel.SharedViewModel;
import java.util.ArrayList;
import java.util.List;
public class BetsAdapter extends RecyclerView.Adapter<BetsAdapter.BetViewHolder> {
private List<Bet> bets = new ArrayList<>();
private List<Course> bets = new ArrayList<>();
private onItemClickListener listener;
public interface onItemClickListener {
void onItemClick(int position);
void onItemClick(Course bet);
}
public void setOnItemClickListener(onItemClickListener listener){
@@ -30,7 +31,7 @@ public class BetsAdapter extends RecyclerView.Adapter<BetsAdapter.BetViewHolder>
public void setBets(List<Bet> bets){
public void setBets(List<Course> bets){
this.bets = bets;
notifyDataSetChanged();
}
@@ -44,12 +45,13 @@ public class BetsAdapter extends RecyclerView.Adapter<BetsAdapter.BetViewHolder>
@Override
public void onBindViewHolder(@NonNull BetViewHolder holder, int position) {
Bet bet = bets.get(position);
holder.tvDate.setText(String.valueOf(bet.getDate()));
holder.tvName.setText(String.valueOf(bet.getName()));
Course bet = bets.get(position);
holder.tvDate.setText(String.valueOf(bet.getDateDepartCourse()));
holder.tvName.setText(String.valueOf(bet.getLieu()));
holder.tvReunion.setText("Nom de la réunion");
holder.itemView.setOnClickListener(v->{
if(listener != null){
listener.onItemClick(bet.getId());
listener.onItemClick(bet);
}
});
}
@@ -63,11 +65,12 @@ public class BetsAdapter extends RecyclerView.Adapter<BetsAdapter.BetViewHolder>
}
static class BetViewHolder extends RecyclerView.ViewHolder{
TextView tvName, tvDate;
TextView tvName, tvDate, tvReunion;
public BetViewHolder(@NonNull View itemView) {
super(itemView);
tvName = itemView.findViewById(R.id.tvName);
tvDate = itemView.findViewById(R.id.tvDate);
tvReunion = itemView.findViewById(R.id.tvReunion);
}
}

View File

@@ -0,0 +1,72 @@
package com.example.quiz.data.adapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.quiz.R;
import com.example.quiz.data.model.Reunion;
import java.util.ArrayList;
import java.util.List;
public class ReunionAdapter extends RecyclerView.Adapter<ReunionAdapter.ReunionViewHolder> {
private List<Reunion> reunions = List.of();
private onItemClickListener listener;
public interface onItemClickListener {
void onItemClick(Reunion reunion);
}
public void setOnItemClickListener(onItemClickListener listener){
this.listener = listener;
}
public void setReunions(List<Reunion> reunions){
this.reunions = reunions;
notifyDataSetChanged();
}
@NonNull
@Override
public ReunionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_reunion, parent, false);
return new ReunionViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ReunionViewHolder holder, int position){
Reunion reunion = reunions.get(position);
holder.reunionName.setText(String.valueOf(reunion.getNom()));
holder.reunionDate.setText(String.valueOf(reunion.getDate()));
holder.itemView.setOnClickListener(v -> {
if(listener != null){
listener.onItemClick(reunion);
}
});
}
@Override
public int getItemCount() {
return reunions.size();
}
static class ReunionViewHolder extends RecyclerView.ViewHolder {
TextView reunionName, reunionDate;
public ReunionViewHolder(View itemView){
super(itemView);
reunionName = itemView.findViewById(R.id.reunionName);
reunionDate = itemView.findViewById(R.id.reunionDate);
}
}
}

View File

@@ -14,24 +14,24 @@ import com.example.quiz.data.model.TypeOfBet;
import java.util.List;
public class TypeOfBetAdapter extends RecyclerView.Adapter<TypeOfBetAdapter.TypeOfBetViewHolder> {
private List<TypeOfBet> types;
private List<String> types;
private onItemClickListener listener;
private int selectedPosition = -1;
public interface onItemClickListener{
void onItemClick(TypeOfBet type);
void onItemClick(String type);
}
public void setOnItemClickListener(TypeOfBetAdapter.onItemClickListener listener){
this.listener = listener;
}
public TypeOfBetAdapter(List<TypeOfBet> types){
public TypeOfBetAdapter(List<String> types){
this.types = types;
}
public void setTypes(List<TypeOfBet> types){
public void setTypes(List<String> types){
this.types = types;
notifyDataSetChanged();
}
@@ -46,8 +46,8 @@ public class TypeOfBetAdapter extends RecyclerView.Adapter<TypeOfBetAdapter.Type
@Override
public void onBindViewHolder(@NonNull TypeOfBetViewHolder holder, int position) {
TypeOfBet type = types.get(position);
holder.type_of_bet_name.setText(type.getName());
String type = types.get(position);
holder.type_of_bet_name.setText(type);
if(selectedPosition != position){
holder.itemView.setBackgroundResource(R.drawable.item_gradient_bg);
}else{

View File

@@ -1,74 +0,0 @@
package com.example.quiz.data.model;
import java.time.LocalDate;
import java.util.List;
public class Bet {
private int id;
private String name;
private LocalDate date;
private Reunion reunion;
List<TypeOfBet> types;
private List<Horse> horses;
public Reunion getReunion() {
return reunion;
}
public void setReunion(Reunion reunion) {
this.reunion = reunion;
}
public List<TypeOfBet> getTypes() {
return types;
}
public void setTypes(List<TypeOfBet> types) {
this.types = types;
}
public List<Horse> getHorses() {
return horses;
}
public void setHorses(List<Horse> horses) {
this.horses = horses;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public LocalDate getDate() {
return date;
}
public void setDate(LocalDate date) {
this.date = date;
}
public Bet(int id, String name, Reunion reunion, List<TypeOfBet> types, LocalDate date, List<Horse> horses) {
this.id = id;
this.name = name;
this.reunion = reunion;
this.types = types;
this.date = date;
this.horses = horses;
}
}

View File

@@ -0,0 +1,57 @@
package com.example.quiz.data.model;
public class Cheval {
private int number;
private String nom;
private String numero;
private boolean nonPartant;
private boolean nonEcurie;
public Cheval(int number, String nom, String numero, boolean nonPartant, boolean nonEcurie) {
this.number = number;
this.nom = nom;
this.numero = numero;
this.nonPartant = nonPartant;
this.nonEcurie = nonEcurie;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getNumero() {
return numero;
}
public void setNumero(String numero) {
this.numero = numero;
}
public boolean isNonPartant() {
return nonPartant;
}
public void setNonPartant(boolean nonPartant) {
this.nonPartant = nonPartant;
}
public boolean isNonEcurie() {
return nonEcurie;
}
public void setNonEcurie(boolean nonEcurie) {
this.nonEcurie = nonEcurie;
}
}

View File

@@ -0,0 +1,95 @@
package com.example.quiz.data.model;
import com.example.quiz.data.model.enums.CourseType;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
public class Course {
private int id;
private String numero;
private String nom;
private String lieu;
private LocalDateTime dateDepartCourse;
private String reunion;
private int nombreChevauxInscrits;
private List<Cheval> chevaux;
public Course(int id, String numero, String nom, String lieu, LocalDateTime dateDepartCourse, String reunion, int nombreChevauxInscrits, List<Cheval> chevaux) {
this.id = id;
this.numero = numero;
this.nom = nom;
this.lieu = lieu;
this.dateDepartCourse = dateDepartCourse;
this.reunion = reunion;
this.nombreChevauxInscrits = nombreChevauxInscrits;
this.chevaux = chevaux;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNumero() {
return numero;
}
public void setNumero(String numero) {
this.numero = numero;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getLieu() {
return lieu;
}
public void setLieu(String lieu) {
this.lieu = lieu;
}
public LocalDateTime getDateDepartCourse() {
return dateDepartCourse;
}
public void setDateDepartCourse(LocalDateTime dateDepartCourse) {
this.dateDepartCourse = dateDepartCourse;
}
public String getReunion() {
return reunion;
}
public void setReunion(String reunion) {
this.reunion = reunion;
}
public int getNombreChevauxInscrits() {
return nombreChevauxInscrits;
}
public void setNombreChevauxInscrits(int nombreChevauxInscrits) {
this.nombreChevauxInscrits = nombreChevauxInscrits;
}
public List<Cheval> getChevaux() {
return chevaux;
}
public void setChevaux(List<Cheval> chevaux) {
this.chevaux = chevaux;
}
}

View File

@@ -0,0 +1,67 @@
package com.example.quiz.data.model;
public class Hippodrome {
private int id;
private String nom;
private String ville;
private String pays;
private int capacite;
private String description;
public Hippodrome(int id, String nom, String ville, String pays, int capacite, String description) {
this.id = id;
this.nom = nom;
this.ville = ville;
this.pays = pays;
this.capacite = capacite;
this.description = description;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getVille() {
return ville;
}
public void setVille(String ville) {
this.ville = ville;
}
public String getPays() {
return pays;
}
public void setPays(String pays) {
this.pays = pays;
}
public int getCapacite() {
return capacite;
}
public void setCapacite(int capacite) {
this.capacite = capacite;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

View File

@@ -1,18 +0,0 @@
package com.example.quiz.data.model;
public class Horse {
private Integer number;
public Horse(Integer number) {
this.number = number;
}
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
}

View File

@@ -4,22 +4,47 @@ import java.time.LocalDate;
public class Reunion {
private int id;
private String name;
private String code;
private String nom;
private LocalDate date;
private String address;
private int numero;
private Hippodrome hippodrome;
private int totalCourses;
public Reunion(int id, String name,LocalDate date, String address) {
public Reunion(int id, String code, String nom, LocalDate date, int numero, Hippodrome hippodrome, int totalCourses) {
this.id = id;
this.name = name;
this.code = code;
this.nom = nom;
this.date = date;
this.address = address;
this.numero = numero;
this.hippodrome = hippodrome;
this.totalCourses = totalCourses;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public LocalDate getDate() {
return date;
}
@@ -28,23 +53,27 @@ public class Reunion {
this.date = date;
}
public int getId() {
return id;
public int getNumero() {
return numero;
}
public String getName() {
return name;
public void setNumero(int numero) {
this.numero = numero;
}
public void setName(String name) {
this.name = name;
public Hippodrome getHippodrome() {
return hippodrome;
}
public String getAddress() {
return address;
public void setHippodrome(Hippodrome hippodrome) {
this.hippodrome = hippodrome;
}
public void setAddress(String address) {
this.address = address;
public int getTotalCourses() {
return totalCourses;
}
public void setTotalCourses(int totalCourses) {
this.totalCourses = totalCourses;
}
}

View File

@@ -0,0 +1,7 @@
package com.example.quiz.data.model.enums;
public enum CourseType {
TIERCE,
QUARTE,
QUINTE
}

View File

@@ -0,0 +1,63 @@
package com.example.quiz.data.remote;
import android.util.Log;
import androidx.annotation.NonNull;
import java.util.concurrent.TimeUnit;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import dagger.hilt.InstallIn;
import dagger.hilt.components.SingletonComponent;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
@Module
@InstallIn(SingletonComponent.class)
public class ApiClient {
private static final String BASE_URL = "https://api.pmu.ml/api/v1/";
@Provides
@Singleton
public HttpLoggingInterceptor provideLoggingInterceptor(){
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(@NonNull String s) {
Log.d("OkHttp", "log: "+s);
}
});
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
return loggingInterceptor;
}
@Provides
@Singleton
public OkHttpClient provideOkHttpClient(HttpLoggingInterceptor loggingInterceptor){
return new OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.connectTimeout(240, TimeUnit.SECONDS)
.readTimeout(240, TimeUnit.SECONDS)
.build();
}
@Provides
@Singleton
public Retrofit provideRetrofit(OkHttpClient okHttpClient){
return new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
@Provides
@Singleton
public ApiService provideApiService(Retrofit retrofit){
return retrofit.create(ApiService.class);
}
}

View File

@@ -0,0 +1,17 @@
package com.example.quiz.data.remote;
import com.example.quiz.data.model.Course;
import com.example.quiz.data.model.Reunion;
import java.util.List;
import retrofit2.Call;
import retrofit2.http.GET;
public interface ApiService {
@GET("reunions")
Call<List<Reunion>> getReunions();
@GET("course/avenir")
Call<List<Course>> getCourses();
}

View File

@@ -1,55 +0,0 @@
package com.example.quiz.data.repository;
import com.example.quiz.data.BetsBank;
import com.example.quiz.data.model.Bet;
import com.example.quiz.data.model.Horse;
import com.example.quiz.data.model.Reunion;
import com.example.quiz.data.model.TypeOfBet;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
@Singleton
public class BetRepository {
private BetsBank betsBank;
@Inject
public BetRepository(BetsBank betsBank){
this.betsBank = betsBank;
}
public BetRepository(){
this.betsBank = BetsBank.getInstance();
}
public List<Bet> getAllBets(){
return betsBank.getBet();
}
public Bet getBetById(int id){
return betsBank.getBet().get(id);
}
public List<Horse> getHorsesById(int id){
return getBetById(id).getHorses();
}
public BetRepository getInstance(){
return new BetRepository();
}
public String getBetNameById(int id){
return getBetById(id).getName();
}
public List<TypeOfBet> getTypeOfBetByBetId(int id){
return getBetById(id).getTypes();
}
public Reunion getReunionByHorseId(int id){
return getBetById(id).getReunion();
}
}

View File

@@ -0,0 +1,46 @@
package com.example.quiz.data.repository;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import com.example.quiz.data.model.Course;
import com.example.quiz.data.remote.ApiService;
import com.example.quiz.utils.Result;
import java.util.List;
import javax.inject.Inject;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class CourseRepository {
private ApiService apiService;
@Inject
public CourseRepository(ApiService apiService) {
this.apiService = apiService;
}
public LiveData<Result<List<Course>>> getCourses() {
MutableLiveData<Result<List<Course>>> liveCourses = new MutableLiveData<Result<List<Course>>>();
liveCourses.setValue(Result.loading());
apiService.getCourses().enqueue(new Callback<List<Course>>() {
@Override
public void onResponse(Call<List<Course>> call, Response<List<Course>> response) {
if(response.isSuccessful()){
liveCourses.postValue(Result.success(response.body()));
}else{
liveCourses.postValue(Result.error(response.message()));
}
}
@Override
public void onFailure(Call<List<Course>> call, Throwable throwable) {
liveCourses.postValue(Result.error(throwable.getMessage()));
}
});
return liveCourses;
}
}

View File

@@ -1,31 +0,0 @@
package com.example.quiz.data.repository;
import com.example.quiz.data.QuestionsBank;
import com.example.quiz.data.model.Question;
import java.util.List;
import java.util.Map;
public class QuestionRepository {
private QuestionsBank questionsBank;
public QuestionRepository(){
this.questionsBank = QuestionsBank.getInstance();
}
public List<Question> getQuestions(){
return questionsBank.getQuestions();
}
public Object updateQuestionById(int id, Question question){
Question myQuestion = questionsBank.getQuestions().get(id);
if(question == null) return Map.of("error", "Cette question n'existe pas!");
myQuestion.setQuestion(question.getQuestion()!=null?question.getQuestion():myQuestion.getQuestion());
myQuestion.setAnswers(!question.getAnswers().isEmpty()?question.getAnswers():myQuestion.getAnswers());
myQuestion.setIndexAnswer(question.getIndexAnswer() > 3?question.getIndexAnswer():myQuestion.getIndexAnswer());
return Map.of("success", true);
}
public QuestionRepository getInstance(){
return new QuestionRepository();
}
}

View File

@@ -0,0 +1,49 @@
package com.example.quiz.data.repository;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import com.example.quiz.data.model.Reunion;
import com.example.quiz.data.remote.ApiClient;
import com.example.quiz.data.remote.ApiService;
import com.example.quiz.utils.Result;
import com.google.android.gms.common.api.Api;
import java.util.List;
import javax.inject.Inject;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class ReunionRepository {
private ApiService apiService;
@Inject
public ReunionRepository(ApiService apiService) {
this.apiService = apiService;
}
public LiveData<Result<List<Reunion>>> getReunions(){
MutableLiveData<Result<List<Reunion>>> liveReunionsData = new MutableLiveData<>();
liveReunionsData.setValue(Result.loading());
apiService.getReunions().enqueue(new Callback<List<Reunion>>() {
@Override
public void onResponse(Call<List<Reunion>> call, Response<List<Reunion>> response) {
if(response.isSuccessful()){
liveReunionsData.postValue(Result.success(response.body()));
}else{
liveReunionsData.postValue(Result.error(response.message()));
}
}
@Override
public void onFailure(Call<List<Reunion>> call, Throwable throwable) {
liveReunionsData.postValue(Result.error(throwable.getMessage()));
}
});
return liveReunionsData;
}
}

View File

@@ -0,0 +1,29 @@
package com.example.quiz.data.repository.module;
import com.example.quiz.data.remote.ApiService;
import com.example.quiz.data.repository.CourseRepository;
import com.example.quiz.data.repository.ReunionRepository;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import dagger.hilt.InstallIn;
import dagger.hilt.components.SingletonComponent;
@Module
@InstallIn(SingletonComponent.class)
public class RepositoryModule {
@Provides
@Singleton
public ReunionRepository provideReunionRepository(ApiService apiService){
return new ReunionRepository(apiService);
}
@Provides
@Singleton
public CourseRepository provideCourseRepository(ApiService apiService){
return new CourseRepository(apiService);
}
}

View File

@@ -1,38 +0,0 @@
package com.example.quiz.injection;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import com.example.quiz.data.repository.QuestionRepository;
import com.example.quiz.viewModel.QuestionViewModel;
public class QuestionViewModelFactory implements ViewModelProvider.Factory {
private QuestionRepository questionRepository;
private static QuestionViewModelFactory factory;
public static QuestionViewModelFactory getInstance(){
if(factory == null){
synchronized (QuestionViewModel.class){
if(factory == null){
factory = new QuestionViewModelFactory();
}
}
}
return factory;
}
private QuestionViewModelFactory(){
this.questionRepository = new QuestionRepository();
}
@Override
@NonNull
public <T extends ViewModel> T create(@NonNull Class<T> modelClass){
if(modelClass.isAssignableFrom(QuestionViewModel.class)){
return (T) new QuestionViewModel(questionRepository);
}
throw new IllegalArgumentException("Unknown ViewModel class");
}
}

View File

@@ -0,0 +1,28 @@
package com.example.quiz.utils;
public class Result<T> {
public enum Status { SUCCESS, ERROR, LOADING }
public final Status status;
public final T data;
public final String message;
private Result(Status status, T data, String message) {
this.status = status;
this.data = data;
this.message = message;
}
public static <T> Result<T> success(T data) {
return new Result<>(Status.SUCCESS, data, null);
}
public static <T> Result<T> error(String msg) {
return new Result<>(Status.ERROR, null, msg);
}
public static <T> Result<T> loading() {
return new Result<>(Status.LOADING, null, null);
}
}

View File

@@ -1,61 +0,0 @@
package com.example.quiz.viewModel;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.example.quiz.data.model.Bet;
import com.example.quiz.data.model.Horse;
import com.example.quiz.data.model.Reunion;
import com.example.quiz.data.model.TypeOfBet;
import com.example.quiz.data.repository.BetRepository;
import java.util.List;
import javax.inject.Inject;
import dagger.hilt.android.lifecycle.HiltViewModel;
@HiltViewModel
public class BetViewModel extends ViewModel {
private BetRepository betRepository;
public MutableLiveData<List<Bet>> bets = new MutableLiveData<List<Bet>>();
public MutableLiveData<String> betName = new MutableLiveData<String>();
public MutableLiveData<List<Horse>> horses = new MutableLiveData<>();
public MutableLiveData<List<TypeOfBet>> types = new MutableLiveData<>();
public MutableLiveData<Reunion> reunion = new MutableLiveData<Reunion>();
@Inject
public BetViewModel(BetRepository betRepository){
this.betRepository = betRepository;
}
public void loadBets(){
bets.setValue(betRepository.getAllBets());
}
public void loadHorses(int id){
horses.setValue(betRepository.getHorsesById(id));
}
public void getBetNameById(int id){
betName.setValue(betRepository.getBetNameById(id));
}
public void loadTypes(int id){
types.setValue(betRepository.getBetById(id).getTypes());
}
public void loadReunionById(int id){
reunion.setValue(betRepository.getReunionByHorseId(id));
}
}

View File

@@ -0,0 +1,33 @@
package com.example.quiz.viewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModel;
import com.example.quiz.data.model.Course;
import com.example.quiz.data.repository.CourseRepository;
import com.example.quiz.utils.Result;
import java.util.List;
import javax.inject.Inject;
import dagger.hilt.android.lifecycle.HiltViewModel;
@HiltViewModel
public class CourseViewModel extends ViewModel {
private final CourseRepository courseRepository;
private LiveData<Result<List<Course>>> courses;
@Inject
public CourseViewModel(CourseRepository courseRepository){
this.courseRepository = courseRepository;
}
public LiveData<Result<List<Course>>> getCourses(){
if(courses == null){
courses = courseRepository.getCourses();
}
return courses;
}
}

View File

@@ -1,41 +0,0 @@
package com.example.quiz.viewModel;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.example.quiz.data.model.Question;
import com.example.quiz.data.repository.QuestionRepository;
import java.util.Objects;
public class QuestionViewModel extends ViewModel {
private QuestionRepository questionRepository;
public MutableLiveData<Question> currentQuestion = new MutableLiveData<Question>();
public MutableLiveData<Integer> score = new MutableLiveData<Integer>();
public MutableLiveData<Boolean> isLastQuestion = new MutableLiveData<Boolean>(false);
public QuestionViewModel(QuestionRepository questionRepository){
this.questionRepository = questionRepository;
}
public void startQuiz(){
currentQuestion.setValue(questionRepository.getQuestions().get(0));
score.setValue(0);
}
public Boolean isAnswerValid(int answerIndex){
return answerIndex == Objects.requireNonNull(currentQuestion.getValue()).getIndexAnswer();
}
public void nextQuestion(){
int currentQuestionIndex = questionRepository.getQuestions().indexOf(currentQuestion.getValue());
if(currentQuestionIndex == questionRepository.getQuestions().size()-1){
isLastQuestion.setValue(true);
}else{
currentQuestion.setValue(questionRepository.getQuestions().get(currentQuestionIndex+1));
}
}
}

View File

@@ -0,0 +1,33 @@
package com.example.quiz.viewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModel;
import com.example.quiz.data.model.Reunion;
import com.example.quiz.data.repository.ReunionRepository;
import com.example.quiz.utils.Result;
import java.util.List;
import javax.inject.Inject;
import dagger.hilt.android.lifecycle.HiltViewModel;
@HiltViewModel
public class ReunionViewModel extends ViewModel {
private final ReunionRepository reunionRepository;
private LiveData<Result<List<Reunion>>> reunions;
@Inject
public ReunionViewModel(ReunionRepository reunionRepository) {
this.reunionRepository = reunionRepository;
}
public LiveData<Result<List<Reunion>>> getReunions() {
if (reunions == null) {
reunions = reunionRepository.getReunions();
}
return reunions;
}
}

View File

@@ -3,6 +3,8 @@ package com.example.quiz.viewModel;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.example.quiz.data.model.Course;
import com.example.quiz.data.model.Reunion;
import com.example.quiz.data.model.TypeOfBet;
import javax.inject.Inject;
@@ -12,13 +14,19 @@ import dagger.hilt.android.lifecycle.HiltViewModel;
public class SharedViewModel extends ViewModel {
public MutableLiveData<Integer> betId = new MutableLiveData<Integer>();
public MutableLiveData<TypeOfBet> typeOfBet = new MutableLiveData<TypeOfBet>();
public MutableLiveData<Reunion> selectedReunion = new MutableLiveData<Reunion>();
public MutableLiveData<Course> selectedCourse = new MutableLiveData<Course>();
public MutableLiveData<String> typeOfBet = new MutableLiveData<String>();
public void setBetId(int id){
betId.setValue(id);
public void setSelectedReunion(Reunion reunion){
selectedReunion.setValue(reunion);
}
public void setTypeOfBet(TypeOfBet type){
public void setSelectedCourse(Course course){
selectedCourse.setValue(course);
}
public void setTypeOfBet(String type){
typeOfBet.setValue(type);
}
}

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/green_opacity_30"/>
<solid android:color="@color/primary_green"/>
<stroke android:width="2dp" android:color="#2E7D32"/>
<corners android:radius="12dp"/>
</shape>

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
android:shape="rectangle">
<solid android:color="@color/primary_green" />
<stroke android:width="2dp" android:color="@color/primary_green" />
</shape>

View File

@@ -1,5 +1,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
android:shape="rectangle">
<solid android:color="#4CAF50" />
<stroke android:width="2dp" android:color="#2E7D32" />
</shape>

View File

@@ -9,37 +9,12 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="8dp"
android:padding="10dp"
android:background="@color/white">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sélectionnez la course"
android:textSize="22sp"
android:textColor="#333333"
android:layout_marginBottom="16dp"
android:layout_gravity="center_horizontal"
android:fontFamily="sans-serif-medium"/>
<!-- History button -->
<Button
android:id="@+id/btnHistory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Voir l'historique"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="16dp"
android:padding="12dp"
android:backgroundTint="#4CAF50"
android:textColor="#FFFFFF"
android:textAllCaps="false"/>
<androidx.recyclerview.widget.RecyclerView
android:paddingTop="40dp"
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
</FrameLayout>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ListOfReunions">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingTop="15dp"
android:paddingHorizontal="20dp"
tools:ignore="UselessParent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/reunionsList"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
</FrameLayout>

View File

@@ -12,17 +12,19 @@
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:paddingTop="10dp"
>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="monospace"
android:fontFamily="@string/LItem"
android:paddingBottom="12dp"
android:text="@string/bet_type_title"
android:textFontWeight="400"
android:textSize="18sp"
android:textColor="@color/primary_green"
android:textSize="22sp"
android:textStyle="bold" />
</LinearLayout>

View File

@@ -1,67 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
android:background="@color/cardview_shadow_start_color">
<!-- Question -->
<TextView
android:id="@+id/questionText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/cardview_light_background"
android:gravity="center"
android:paddingBottom="24dp" />
<!-- Réponses -->
<RadioGroup
android:id="@+id/answersGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="32dp">
<RadioButton
android:id="@+id/answer1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:padding="8dp" />
<RadioButton
android:id="@+id/answer2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:padding="8dp" />
<RadioButton
android:id="@+id/answer3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:padding="8dp" />
<RadioButton
android:id="@+id/answer4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:padding="8dp" />
</RadioGroup>
<!-- Bouton Suivant -->
<Button
android:id="@+id/nextButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Question suivante"
android:backgroundTint="@color/purple"
android:textColor="@android:color/white"
android:padding="12dp" />
</LinearLayout>

View File

@@ -1,35 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SecondFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<Button
android:id="@+id/button_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/previous"
app:layout_constraintBottom_toTopOf="@id/textview_second"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textview_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/lorem_ipsum"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_second" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>

View File

@@ -1,35 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Second2Fragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<Button
android:id="@+id/button_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/previous"
app:layout_constraintBottom_toTopOf="@id/textview_second"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textview_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/lorem_ipsum"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_second" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
<androidx.cardview.widget.CardView xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15dp"
@@ -12,24 +12,50 @@
android:orientation="vertical"
android:padding="18dp"
android:background="@drawable/course_item_border">
<TextView
android:id="@+id/tvName"
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_gravity="center_vertical">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
app:srcCompat="@drawable/horse_with_creative_hair_raising_feet_right_side_view_svgrepo_com">
</ImageView>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="@color/text_color"
android:fontFamily="sans-serif-medium">
</TextView>
<TextView
android:id="@+id/tvDate"
android:layout_width="wrap_content"
android:layout_marginTop="5dp"
android:textFontWeight="400"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="@color/text_color"
android:fontFamily="sans-serif-medium">
</TextView>
android:orientation="vertical">
<TextView
android:id="@+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="@color/white"
android:textFontWeight="500"
android:fontFamily="sans-serif-medium">
</TextView>
<TextView
android:id="@+id/tvReunion"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textSize="13sp"
android:textFontWeight="300"
>
</TextView>
<TextView
android:id="@+id/tvDate"
android:layout_width="wrap_content"
android:layout_marginTop="5dp"
android:textFontWeight="400"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="@color/white"
android:fontFamily="sans-serif-medium">
</TextView>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/primary_green"
android:layout_marginVertical="3dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="75dp"
android:paddingHorizontal="10dp"
android:orientation="horizontal"
tools:ignore="MissingConstraints">
<LinearLayout
android:layout_width="45dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginEnd="10dp"
android:gravity="center">
<ImageView
android:layout_width="45dp"
android:layout_height="45dp"
android:contentDescription="Horse"
android:src="@drawable/horse_with_creative_hair_raising_feet_right_side_view_svgrepo_com">
</ImageView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_vertical">
<TextView
android:id="@+id/reunionName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textFontWeight="400"
android:layout_marginBottom="6dp"
android:textSize="15sp"
android:textColor="@color/white">
</TextView>
<TextView
android:id="@+id/reunionDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textFontWeight="700"
android:textSize="13sp"
android:textColor="@color/white">
</TextView>
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -14,7 +14,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="70dp"
android:orientation="horizontal"
android:padding="16dp"
android:gravity="center_vertical"
@@ -22,8 +22,8 @@
<!-- Icône ou cercle coloré -->
<View
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginEnd="16dp"
android:background="@drawable/circle_primary"/>