type of game step done!

This commit is contained in:
OnlyPapy98
2025-10-31 16:17:15 +01:00
parent bd3d8a3d3f
commit 159837bd6f
30 changed files with 789 additions and 172 deletions

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -38,6 +38,9 @@ android {
dependencies { dependencies {
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar")))) 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.hilt.android) implementation(libs.hilt.android)
annotationProcessor(libs.hilt.compiler) annotationProcessor(libs.hilt.compiler)
implementation(libs.rxjava) implementation(libs.rxjava)

View File

@@ -2,10 +2,35 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.BLUETOOTH"/> <!-- ✅ Bluetooth Permissions (Handle Both Legacy and Modern) -->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- ✅ Required for Android 12+ -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<!-- ✅ Location Permissions -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- ✅ Storage and Network -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" />
<!-- ✅ USB and Hardware -->
<uses-feature android:name="android.hardware.usb.host" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<application <application
android:name=".PmuHorseBetting" android:name=".PmuHorseBetting"

Binary file not shown.

After

Width:  |  Height:  |  Size: 974 KiB

View File

@@ -12,19 +12,27 @@ import android.view.Gravity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.GridLayout; import android.widget.GridLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.example.quiz.data.model.Horse; 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.databinding.FragmentBetValidationBinding; import com.example.quiz.databinding.FragmentBetValidationBinding;
import com.example.quiz.utils.HPRTPrinterUtil; import com.example.quiz.utils.HPRTPrinterUtil;
import com.example.quiz.viewModel.BetViewModel; import com.example.quiz.viewModel.BetViewModel;
import com.example.quiz.viewModel.SharedViewModel; 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.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import dagger.hilt.android.AndroidEntryPoint; import dagger.hilt.android.AndroidEntryPoint;
@@ -47,9 +55,9 @@ public class BetValidation extends Fragment {
private HPRTPrinterUtil printer; private HPRTPrinterUtil printer;
private Integer id; private TypeOfBet typeOfBet;
private String typeOfBet; private Reunion reunion;
private List<Horse> selectedHorses = new ArrayList<Horse>(); private List<Horse> selectedHorses = new ArrayList<Horse>();
@@ -83,7 +91,7 @@ public class BetValidation extends Fragment {
} }
private void setupNumberGrid(GridLayout grid) { private void setupNumberGrid(GridLayout grid) {
binding.gridNumbers.removeAllViews();
int columns = 4; int columns = 4;
grid.setColumnCount(columns); grid.setColumnCount(columns);
@@ -133,28 +141,92 @@ public class BetValidation extends Fragment {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class); shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
viewModel = new ViewModelProvider(this).get(BetViewModel.class); viewModel = new ViewModelProvider(this).get(BetViewModel.class);
shared.betId.observe(getViewLifecycleOwner(), id ->{ viewModel.getBetNameById(shared.betId.getValue() - 1);
this.id = id; viewModel.betName.observe(getViewLifecycleOwner(), name ->{
viewModel.getBetNameById(id - 1); binding.horseName.setText(name);
viewModel.betName.observe(getViewLifecycleOwner(), name ->{ });
binding.horseName.setText(name); viewModel.loadHorses(shared.betId.getValue() - 1);
}); viewModel.horses.observe(getViewLifecycleOwner(), h->{
viewModel.loadHorses(id - 1); this.totalHorses = h;
viewModel.horses.observe(getViewLifecycleOwner(), h->{ setupNumberGrid(binding.gridNumbers);
this.totalHorses = h;
setupNumberGrid(binding.gridNumbers);
});
}); });
shared.typeOfBet.observe(getViewLifecycleOwner(), type ->{ shared.typeOfBet.observe(getViewLifecycleOwner(), type ->{
this.typeOfBet = type; this.typeOfBet = type;
}); });
binding.btnValidate.setOnClickListener(v->{ viewModel.loadReunionById(shared.betId.getValue() - 1);
//Toast.makeText(getContext(), "L'id de bet: "+this.id+" et le type est: "+this.typeOfBet, Toast.LENGTH_SHORT).show(); reunion = viewModel.reunion.getValue();
printer = new HPRTPrinterUtil(getContext()); binding.paymentType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
boolean ok = printer.connectBluetooth("02:03:00:00:00:00"); @Override
if (ok) { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
printer.printText("Bonjour"); String selected = binding.paymentType.getSelectedItem().toString();
if (selected.equals("Orange Money")) {
binding.phoneNumber.setVisibility(View.VISIBLE);
} else {
binding.phoneNumber.setVisibility(View.GONE); // ou GONE
binding.phoneNumber.setText(""); // vider le champ si non utilisé
}
} }
@Override
public void onNothingSelected(AdapterView<?> parent) {
binding.phoneNumber.setVisibility(View.INVISIBLE);
}
});
binding.betValidateBtn.setOnClickListener(v->{
if(binding.paymentType.getSelectedItem().toString().equals("Orange Money") && binding.phoneNumber.getText().toString().isEmpty()){
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){
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();
return;
}
printer = new HPRTPrinterUtil(getContext());
boolean ok = printer.autoConnectBluetoothByName();
if(ok){
StringBuilder tspl = new StringBuilder();
tspl.append("PARIS HIPPIQUE (PMU MALI)\n");
tspl.append(typeOfBet.getName()+"\n");
tspl.append("Tel: 555-1234\n");
tspl.append("----------------------------\n");
tspl.append(reunion.getName()+"/"+reunion.getAddress());
tspl.append("----------------------------\n");
String combinationText = selectedHorses.stream()
.map(h -> String.valueOf(h.getNumber()))
.collect(Collectors.joining("-"));
tspl.append("COMBINAISON : "+combinationText);
tspl.append("\n----------------------------\n");
int mise = 300;
int total = mise * selectedHorses.size();
tspl.append("TOTAL MISE: ").append(total).append(" Fcfa\n");
tspl.append("----------------------------\n");
tspl.append("Bonne chance !\n\n\n");
printer.printText(tspl);
}
});
binding.backBtn.setOnClickListener(v->{
getActivity().onBackPressed();
});
binding.deleteBtn.setOnClickListener(v->{
selectedHorses.clear();
binding.combination.setText(getString(R.string.combination,""));
setupNumberGrid(binding.gridNumbers);
}); });
} }

View File

@@ -6,19 +6,30 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; 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.Button;
import android.widget.LinearLayout;
import android.widget.RadioButton; import android.widget.RadioButton;
import android.widget.RadioGroup; import android.widget.RadioGroup;
import android.widget.Toast; import android.widget.Toast;
import com.example.quiz.data.adapter.TypeOfBetAdapter;
import com.example.quiz.databinding.FragmentListOfTypeOfBetsBinding; import com.example.quiz.databinding.FragmentListOfTypeOfBetsBinding;
import com.example.quiz.viewModel.BetViewModel;
import com.example.quiz.viewModel.SharedViewModel; import com.example.quiz.viewModel.SharedViewModel;
import java.util.ArrayList;
import dagger.hilt.android.AndroidEntryPoint; import dagger.hilt.android.AndroidEntryPoint;
/** /**
@@ -34,6 +45,10 @@ public class ListOfTypeOfBets extends Fragment {
private SharedViewModel shared; private SharedViewModel shared;
private BetViewModel viewModel;
private TypeOfBetAdapter adapter;
public ListOfTypeOfBets() { public ListOfTypeOfBets() {
// Required empty public constructor // Required empty public constructor
} }
@@ -58,20 +73,33 @@ public class ListOfTypeOfBets extends Fragment {
@Override @Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); LayoutAnimationController controller = AnimationUtils.loadLayoutAnimation(
getContext(),
R.anim.layout_fad_in
);
binding.typeOfBetRecyclerView.setLayoutAnimation(controller);
binding.typeOfBetRecyclerView.scheduleLayoutAnimation();
binding.typeOfBetRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
// ViewModels
viewModel = new ViewModelProvider(this).get(BetViewModel.class);
shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
RadioGroup types = binding.optionsGroup; // ⚡ 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);
// Observer les résultats
viewModel.types.observe(getViewLifecycleOwner(), types -> {
if (types != null) {
adapter.setTypes(types);
}
});
Button btnValidate = binding.btnValidate; Button btnValidate = binding.btnValidate;
btnValidate.setOnClickListener(v->{ btnValidate.setOnClickListener(v->{
int selectedId = types.getCheckedRadioButtonId();
if (selectedId == -1) {
Toast.makeText(requireContext(), "Veuillez sélectionner une option", Toast.LENGTH_SHORT).show();
return;
}
RadioButton selectedButton = view.findViewById(selectedId);
String selectedType = selectedButton.getText().toString();
shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
shared.setTypeOfBet(selectedType);
FragmentManager fragmentManager = getParentFragmentManager(); FragmentManager fragmentManager = getParentFragmentManager();
BetValidation betValidation = BetValidation.newInstance(); BetValidation betValidation = BetValidation.newInstance();
fragmentManager.beginTransaction() fragmentManager.beginTransaction()

View File

@@ -2,6 +2,8 @@ package com.example.quiz.data;
import com.example.quiz.data.model.Bet; import com.example.quiz.data.model.Bet;
import com.example.quiz.data.model.Horse; 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.time.LocalDate;
import java.util.Arrays; import java.util.Arrays;
@@ -13,6 +15,16 @@ public class BetsBank {
new Bet( new Bet(
1, 1,
"Course de chevaux", "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), LocalDate.of(2025,10,1),
Arrays.asList( Arrays.asList(
new Horse(1), new Horse(1),
@@ -21,20 +33,45 @@ public class BetsBank {
new Horse(4) new Horse(4)
) )
), ),
new Bet( new Bet(
2, 2,
"Course de chevaux 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), LocalDate.of(2025,10,1),
Arrays.asList( Arrays.asList(
new Horse(4), new Horse(4),
new Horse(5), new Horse(5),
new Horse(7), new Horse(7),
new Horse(6) new Horse(6),
new Horse(8),
new Horse(9),
new Horse(10),
new Horse(11)
) )
), ),
new Bet( new Bet(
3, 3,
"Course de chevaux 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), LocalDate.of(2025,10,1),
Arrays.asList( Arrays.asList(
new Horse(10), new Horse(10),
@@ -46,6 +83,16 @@ public class BetsBank {
new Bet( new Bet(
4, 4,
"Course de chevaux 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), LocalDate.of(2025,10,1),
Arrays.asList( Arrays.asList(
new Horse(5), new Horse(5),

View File

@@ -0,0 +1,80 @@
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.TypeOfBet;
import java.util.List;
public class TypeOfBetAdapter extends RecyclerView.Adapter<TypeOfBetAdapter.TypeOfBetViewHolder> {
private List<TypeOfBet> types;
private onItemClickListener listener;
private int selectedPosition = -1;
public interface onItemClickListener{
void onItemClick(TypeOfBet type);
}
public void setOnItemClickListener(TypeOfBetAdapter.onItemClickListener listener){
this.listener = listener;
}
public TypeOfBetAdapter(List<TypeOfBet> types){
this.types = types;
}
public void setTypes(List<TypeOfBet> types){
this.types = types;
notifyDataSetChanged();
}
@NonNull
@Override
public TypeOfBetViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.type_of_bet_item, parent, false);
return new TypeOfBetViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull TypeOfBetViewHolder holder, int position) {
TypeOfBet type = types.get(position);
holder.type_of_bet_name.setText(type.getName());
if(selectedPosition != position){
holder.itemView.setBackgroundResource(R.drawable.item_gradient_bg);
}else{
holder.itemView.setBackgroundResource(R.drawable.item_gradient_bg_selected);
}
holder.itemView.setOnClickListener(v->{
if(listener != null){
listener.onItemClick(type);
}
int previousPosition = selectedPosition;
selectedPosition = holder.getAdapterPosition();
notifyItemChanged(previousPosition);
notifyItemChanged(selectedPosition);
});
}
@Override
public int getItemCount() {
return types.size();
}
public class TypeOfBetViewHolder extends RecyclerView.ViewHolder {
TextView type_of_bet_name;
public TypeOfBetViewHolder(@NonNull View itemView) {
super(itemView);
type_of_bet_name = itemView.findViewById(R.id.type_of_bet_name);
}
}
}

View File

@@ -8,8 +8,28 @@ public class Bet {
private String name; private String name;
private LocalDate date; private LocalDate date;
private Reunion reunion;
List<TypeOfBet> types;
private List<Horse> horses; 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() { public List<Horse> getHorses() {
return horses; return horses;
} }
@@ -43,9 +63,11 @@ public class Bet {
} }
public Bet(int id, String name, LocalDate date, List<Horse> horses) { public Bet(int id, String name, Reunion reunion, List<TypeOfBet> types, LocalDate date, List<Horse> horses) {
this.id = id; this.id = id;
this.name = name; this.name = name;
this.reunion = reunion;
this.types = types;
this.date = date; this.date = date;
this.horses = horses; this.horses = horses;
} }

View File

@@ -0,0 +1,50 @@
package com.example.quiz.data.model;
import java.time.LocalDate;
public class Reunion {
private int id;
private String name;
private LocalDate date;
private String address;
public Reunion(int id, String name,LocalDate date, String address) {
this.id = id;
this.name = name;
this.date = date;
this.address = address;
}
public void setId(int id) {
this.id = id;
}
public LocalDate getDate() {
return date;
}
public void setDate(LocalDate date) {
this.date = date;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}

View File

@@ -0,0 +1,37 @@
package com.example.quiz.data.model;
public class TypeOfBet {
private int id;
private String name;
private String numberOfHorse;
public TypeOfBet(int id, String name, String numberOfHorse) {
this.id = id;
this.name = name;
this.numberOfHorse = numberOfHorse;
}
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 String getNumberOfHorse() {
return numberOfHorse;
}
public void setNumberOfHorse(String numberOfHorse) {
this.numberOfHorse = numberOfHorse;
}
}

View File

@@ -3,6 +3,8 @@ package com.example.quiz.data.repository;
import com.example.quiz.data.BetsBank; import com.example.quiz.data.BetsBank;
import com.example.quiz.data.model.Bet; import com.example.quiz.data.model.Bet;
import com.example.quiz.data.model.Horse; 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 java.util.List;
@@ -43,4 +45,11 @@ public class BetRepository {
return getBetById(id).getName(); 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

@@ -1,9 +1,17 @@
package com.example.quiz.utils; package com.example.quiz.utils;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log; import android.util.Log;
import android.widget.Toast; import android.widget.Toast;
import java.io.InputStream;
import java.util.Set;
import tspl.HPRTPrinterHelper; import tspl.HPRTPrinterHelper;
public class HPRTPrinterUtil { public class HPRTPrinterUtil {
@@ -11,15 +19,55 @@ public class HPRTPrinterUtil {
private static final String TAG = "HPRTPrinterUtil"; private static final String TAG = "HPRTPrinterUtil";
private Context context; private Context context;
BluetoothAdapter mBluetoothAdapter;
public HPRTPrinterUtil(Context context) { public HPRTPrinterUtil(Context context) {
this.context = context; this.context = context;
} }
/**
* Connecte une imprimante Bluetooth
* @param btAddress adresse MAC Bluetooth de l'imprimante @SuppressLint("MissingPermission")
* @return true si connecté, false sinon public boolean autoConnectBluetoothByName() {
*/ try {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
Toast.makeText(context, "Bluetooth désactivé ou non disponible", Toast.LENGTH_LONG).show();
return false;
}
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
if (pairedDevices != null) {
for (BluetoothDevice device : pairedDevices) {
if (device.getName() != null && device.getName().contains("MP4P Printer")) {
String btAddress = device.getAddress();
// Connexion via ton SDK HPRT
int result = HPRTPrinterHelper.PortOpen("Bluetooth," + btAddress);
if (result == 0) {
Toast.makeText(context, "Imprimante connectée : " + device.getName(), Toast.LENGTH_SHORT).show();
Log.d(TAG, "Connexion réussie : " + device.getName() + " - " + btAddress);
return true;
} else {
Toast.makeText(context, "Erreur connexion imprimante: " + result, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Erreur connexion imprimante: " + result);
return false;
}
}
}
}
Toast.makeText(context, "Imprimante non trouvée. Veuillez appairer d'abord.", Toast.LENGTH_LONG).show();
return false;
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(context, "Erreur auto-connexion : " + e.getMessage(), Toast.LENGTH_LONG).show();
return false;
}
}
public boolean connectBluetooth(String btAddress) { public boolean connectBluetooth(String btAddress) {
try { try {
HPRTPrinterHelper.PortClose(); // ferme toute connexion existante HPRTPrinterHelper.PortClose(); // ferme toute connexion existante
@@ -39,7 +87,7 @@ public class HPRTPrinterUtil {
} }
} }
public void printText(String text) { public void printText(StringBuilder text) {
try { try {
if (!HPRTPrinterHelper.IsOpened()) { if (!HPRTPrinterHelper.IsOpened()) {
Toast.makeText(context, "Imprimante non connectée", Toast.LENGTH_SHORT).show(); Toast.makeText(context, "Imprimante non connectée", Toast.LENGTH_SHORT).show();

View File

@@ -5,6 +5,8 @@ import androidx.lifecycle.ViewModel;
import com.example.quiz.data.model.Bet; import com.example.quiz.data.model.Bet;
import com.example.quiz.data.model.Horse; 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 com.example.quiz.data.repository.BetRepository;
import java.util.List; import java.util.List;
@@ -24,6 +26,10 @@ public class BetViewModel extends ViewModel {
public MutableLiveData<List<Horse>> horses = new MutableLiveData<>(); public MutableLiveData<List<Horse>> horses = new MutableLiveData<>();
public MutableLiveData<List<TypeOfBet>> types = new MutableLiveData<>();
public MutableLiveData<Reunion> reunion = new MutableLiveData<Reunion>();
@Inject @Inject
@@ -43,4 +49,13 @@ public class BetViewModel extends ViewModel {
betName.setValue(betRepository.getBetNameById(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

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

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:delay="15%"
android:animationOrder="normal"
android:animation="@anim/layout_fad_in" />

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<solid android:color="#FFD700"/>
</shape>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient
android:startColor="@color/green_opacity_30"
android:endColor="@color/primary_green"
android:angle="45"/>
<corners android:radius="16dp"/>
</shape>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- Gradient vibrant pour la sélection -->
<gradient
android:startColor="#4CAF50"
android:endColor="#81C784"
android:angle="45"/>
<corners android:radius="16dp"/>
</shape>

View File

@@ -0,0 +1,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="400dp" android:viewportHeight="1024" android:viewportWidth="1024" android:width="400dp">
<path android:fillColor="#0F1F3C" android:pathData="M951.9,253.9c0,-82.2 -110.1,-144.1 -256,-144.1s-256,62 -256,144.1c0,0.7 0.2,1.4 0.2,2.1h-0.2v109.7h73.1v-9.1c45.8,25.8 109.8,41.3 182.9,41.3 67.4,0 126.9,-13.3 171.7,-35.6 6.9,7.2 11.1,14.3 11.1,20.6 0,28.3 -72.9,71 -182.9,71h-73.1v73.1h73.1c67.4,0 127,-13.3 171.7,-35.7 6.9,7.2 11.1,14.3 11.1,20.6 0,28.3 -72.9,71 -182.9,71l-25.9,0.1c-15.9,0.1 -31.3,0.3 -46.3,-0.1l-1.8,73.1c8,0.2 16.2,0.3 24.5,0.3 7.9,0 16,-0.1 24.2,-0.1l25.3,-0.1c67.4,0 127,-13.4 171.8,-35.7 7,7.2 11,14.4 11,20.6 0,28.3 -72.9,71 -182.9,71h-73.1v73.1h73.1c67.4,0 127,-13.4 171.8,-35.7 7,7.2 11.1,14.4 11.1,20.6 0,28.3 -72.9,71 -182.9,71h-73.1v73.1h73.1c145.9,0 256,-62 256,-144.1 0,-0.7 -0.1,-1.5 -0.1,-2.1h0.1L951.9,256h-0.2c0,-0.7 0.2,-1.4 0.2,-2.1zM513,253.9c0,-28.3 72.9,-71 182.9,-71s182.9,42.7 182.9,71c0,28.3 -72.9,71 -182.9,71s-182.9,-42.7 -182.9,-71z"/>
<path android:fillColor="#0F1F3C" android:pathData="M330.1,365.7c-145.9,0 -256,62 -256,144.1 0,0.7 0.2,1.4 0.2,2.1h-0.2v256c0,82.2 110.1,144.1 256,144.1s256,-62 256,-144.1L586.2,512h-0.2c0,-0.7 0.2,-1.4 0.2,-2.1 0,-82.2 -110.1,-144.1 -256,-144.1zM147.3,638.9c0,-6.3 4.1,-13.4 11.1,-20.6 44.8,22.3 104.4,35.7 171.8,35.7 67.4,0 126.9,-13.3 171.7,-35.6 6.9,7.2 11.1,14.3 11.1,20.6 0,28.3 -72.9,71 -182.9,71s-182.9,-42.7 -182.9,-71zM330.1,438.9c109.9,0 182.9,42.7 182.9,71 0,28.3 -72.9,71 -182.9,71s-182.9,-42.7 -182.9,-71c0,-28.3 72.9,-71 182.9,-71zM330.1,839c-109.9,0 -182.9,-42.7 -182.9,-71 0,-6.3 4.2,-13.4 11.1,-20.6 44.8,22.3 104.3,35.7 171.8,35.7 67.4,0 127,-13.3 171.7,-35.7 6.9,7.2 11.1,14.3 11.1,20.6 0,28.3 -72.9,71 -182.9,71z"/>
</vector>

View File

@@ -0,0 +1,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke android:color="@color/text_light_grey"></stroke>
<corners android:radius="5dp"></corners>
</shape>

View File

@@ -0,0 +1,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/transparent"></solid>
<stroke android:color="@color/text_color"></stroke>
<corners android:radius="4dp"></corners>
</shape>

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_main" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginEnd="@dimen/fab_margin"
android:layout_marginBottom="16dp"
app:srcCompat="@android:drawable/ic_dialog_email" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -1,69 +1,158 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:paddingHorizontal="15dp" android:paddingHorizontal="15dp"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:orientation="vertical"> android:orientation="vertical">
<TextView
android:text="@string/hors_choice"
android:textStyle="bold"
android:textSize="25sp"
android:layout_marginTop="35dp"
android:textColor="@color/text_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/horseName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="17sp"
android:textColor="@color/primary_green"
android:layout_marginTop="15dp"
android:layout_marginBottom="40dp"
android:textFontWeight="300"
>
</TextView>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:paddingHorizontal="15dp"
android:gravity="center_horizontal" android:gravity="center_horizontal"
> android:orientation="vertical"
<GridLayout tools:ignore="UselessParent">
android:id="@+id/grid_numbers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:useDefaultMargins="true"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="30dp"
android:orientation="horizontal"
android:gravity="start">
<TextView <TextView
android:id="@+id/combination" android:text="@string/hors_choice"
android:textStyle="bold"
android:textSize="25sp"
android:layout_marginTop="35dp"
android:textColor="@color/text_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/horseName"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="5dp" android:textSize="17sp"
android:textSize="21sp" android:textColor="@color/primary_green"
android:text="@string/combination" android:layout_marginTop="15dp"
android:textColor="@color/primary_green"> android:layout_marginBottom="25dp"
</TextView> android:textFontWeight="300"
</LinearLayout> >
<Button </TextView>
android:id="@+id/btn_validate"
android:text="Valider" <View
android:paddingVertical="8dp" android:id="@+id/divider2"
android:paddingHorizontal="13dp" android:layout_width="match_parent"
android:background="@color/primary_green" android:layout_height="1dp"
android:backgroundTint="@color/primary_green" android:background="?android:attr/listDivider" />
android:layout_width="wrap_content"
android:layout_height="wrap_content" <LinearLayout
android:layout_marginTop="10dp" /> android:layout_width="match_parent"
</LinearLayout> android:layout_height="wrap_content"
android:paddingVertical="8dp"
android:orientation="horizontal"
android:gravity="start">
<TextView
android:id="@+id/combination"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:textFontWeight="800"
android:textSize="18sp"
android:text="@string/combination"
android:textColor="@color/primary_green">
</TextView>
</LinearLayout>
<View
android:id="@+id/divider3"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:attr/listDivider" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="13dp"
android:orientation="horizontal"
android:gravity="center_horizontal"
>
<GridLayout
android:id="@+id/grid_numbers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:useDefaultMargins="true"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Spinner
android:id="@+id/paymentType"
android:layout_width="match_parent"
android:background="@drawable/edittext_border"
android:layout_height="wrap_content"
android:padding="15dp"
android:scrollbarSize="10dp"
android:defaultFocusHighlightEnabled="true"
android:entries="@array/paymentType">
</Spinner>
<EditText
android:id="@+id/phoneNumber"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:drawableStart="@android:drawable/stat_sys_vp_phone_call"
android:padding="10dp"
android:background="@drawable/edittext_border"
android:inputType="phone"
android:visibility="gone"
>
</EditText>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:padding="5dp"
android:weightSum="3">
<Button
android:id="@+id/backBtn"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="10dp"
android:backgroundTint="@color/primary_red"
android:text="@string/cancel"
android:textColor="@color/white"
android:layout_margin="4dp"
/>
<Button
android:id="@+id/deleteBtn"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="10dp"
android:backgroundTint="@android:color/holo_blue_dark"
android:text="@string/delete"
android:textColor="@color/white"
android:layout_margin="4dp"
/>
<Button
android:id="@+id/betValidateBtn"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="10dp"
android:backgroundTint="@color/primary_green"
android:text="@string/validate"
android:textColor="@color/white"
android:layout_margin="4dp"
/>
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@@ -3,53 +3,52 @@
android:orientation="vertical" android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:padding="20dp"> android:padding="10dp"
android:background="@color/text_hint_color"
>
<TextView <LinearLayout
android:id="@+id/title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/bet_type_title" android:orientation="horizontal"
android:textSize="18sp" android:gravity="center"
android:textStyle="bold" >
android:paddingBottom="12dp" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="monospace"
android:paddingBottom="12dp"
android:text="@string/bet_type_title"
android:textFontWeight="400"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:attr/listDivider" />
<!-- Les options statiques --> <!-- Les options statiques -->
<RadioGroup <androidx.recyclerview.widget.RecyclerView
android:id="@+id/optionsGroup" android:layout_marginVertical="30dp"
android:id="@+id/typeOfBetRecyclerView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
</androidx.recyclerview.widget.RecyclerView>
<RadioButton
android:id="@+id/option1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/couplet" />
<RadioButton
android:id="@+id/option2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/tierce" />
<RadioButton
android:id="@+id/option3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/quarte" />
<RadioButton
android:id="@+id/option4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/quinte" />
</RadioGroup>
<!-- Bouton valider -->
<Button <Button
android:id="@+id/btnValidate" android:id="@+id/btnValidate"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp" android:paddingVertical="2dp"
android:background="@drawable/rounded_button_green" android:background="@drawable/rounded_button_green"
android:text="Valider" /> android:textAllCaps="false"
android:text="@string/validate"
>
</Button>
</LinearLayout> </LinearLayout>

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="2dp"
xmlns:app="http://schemas.android.com/tools"
android:layout_marginVertical="10dp"
android:layout_marginHorizontal="10dp"
card_view:cardCornerRadius="16dp"
card_view:cardElevation="6dp"
android:foreground="?attr/selectableItemBackground"
app:ignore="NamespaceTypo">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="16dp"
android:gravity="center_vertical"
android:background="@drawable/item_gradient_bg">
<!-- Icône ou cercle coloré -->
<View
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_marginEnd="16dp"
android:background="@drawable/circle_primary"/>
<!-- Texte principal -->
<TextView
android:id="@+id/type_of_bet_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="@android:color/white"
android:textSize="18sp"
android:fontFamily="sans-serif-medium"
android:text="Type de pari"
android:ellipsize="end"
android:singleLine="true"/>
<!-- Flèche / icône à droite -->
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_arrow_right"
app:tint="@color/white"
/>
</LinearLayout>
</androidx.cardview.widget.CardView>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="paymentType">
<item>Espèce</item>
<item>Orange Money</item>
</string-array>
</resources>

View File

@@ -22,6 +22,9 @@
<string name="tierce">Tierce</string> <string name="tierce">Tierce</string>
<string name="quarte">Quarte</string> <string name="quarte">Quarte</string>
<string name="quinte">Quinte</string> <string name="quinte">Quinte</string>
<string name="validate">Valider</string>
<string name="cancel">Annuler</string>
<string name="delete">Supprimer</string>
<string name="lorem_ipsum"> <string name="lorem_ipsum">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam in scelerisque sem. Mauris Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam in scelerisque sem. Mauris

View File

@@ -1,14 +1,23 @@
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. --> <!-- Base application theme -->
<style name="Base.Theme.Quiz" parent="Theme.Material3.DayNight.NoActionBar"> <style name="Base.Theme.Quiz" parent="Theme.Material3.DayNight.NoActionBar">
<!-- Customize your light theme here. --> <!-- Colors -->
<item name="primaryGreen">@color/primary_green</item> <item name="primaryGreen">@color/primary_green</item>
<item name="primaryYellow">@color/primary_yellow</item> <item name="primaryYellow">@color/primary_yellow</item>
<item name="primaryRed">@color/primary_red</item> <item name="primaryRed">@color/primary_red</item>
<item name="textGrey">@color/text_grey</item> <item name="textGrey">@color/text_grey</item>
<item name="greenOpacity30">@color/green_opacity_30</item> <item name="greenOpacity30">@color/green_opacity_30</item>
<item name="redOpacity10">@color/red_opacity_10</item> <item name="redOpacity10">@color/red_opacity_10</item>
<!-- Apply custom button style -->
<item name="materialButtonStyle">@style/CustomButton</item>
</style> </style>
<!-- Custom button style -->
<style name="CustomButton" parent="Widget.MaterialComponents.Button">
<item name="backgroundTint">@null</item>
</style>
<!-- Theme alias -->
<style name="Theme.Quiz" parent="Base.Theme.Quiz" /> <style name="Theme.Quiz" parent="Base.Theme.Quiz" />
</resources> </resources>