commit bd3d8a3d3f37450e5616362990e919fead5d9ffd Author: OnlyPapy98 Date: Tue Oct 28 17:31:54 2025 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..eaf91e2 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..fab62c0 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +Quiz \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..8b3f102 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..a93fd78 --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,18 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..863b1be --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml new file mode 100644 index 0000000..48052b2 --- /dev/null +++ b/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..b2c751a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..5bd6771 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 0000000..ee5896a --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,56 @@ +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.google.android.libraries.mapsplatform.secrets.gradle.plugin) + id("com.google.dagger.hilt.android") +} + +android { + namespace = "com.example.quiz" + compileSdk = 34 + + defaultConfig { + applicationId = "com.example.quiz" + minSdk = 29 + targetSdk = 34 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + buildFeatures { + viewBinding = true + } +} + +dependencies { + implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar")))) + implementation(libs.hilt.android) + annotationProcessor(libs.hilt.compiler) + implementation(libs.rxjava) + implementation(libs.rxandroid) + implementation(libs.recyclerview.v7) + implementation(libs.appcompat) + implementation(libs.material) + implementation(libs.constraintlayout) + implementation(libs.navigation.fragment) + implementation(libs.navigation.ui) + implementation(libs.play.services.maps) + + testImplementation(libs.junit) + androidTestImplementation(libs.ext.junit) + androidTestImplementation(libs.espresso.core) +} diff --git a/app/libs/BaseRecyclerViewAdapterHelper-2.9.50.aar b/app/libs/BaseRecyclerViewAdapterHelper-2.9.50.aar new file mode 100644 index 0000000..2480264 Binary files /dev/null and b/app/libs/BaseRecyclerViewAdapterHelper-2.9.50.aar differ diff --git a/app/libs/TSPL_V1.21.jar b/app/libs/TSPL_V1.21.jar new file mode 100644 index 0000000..4b8c151 Binary files /dev/null and b/app/libs/TSPL_V1.21.jar differ diff --git a/app/libs/arm64-v8a/libLZO.so b/app/libs/arm64-v8a/libLZO.so new file mode 100644 index 0000000..a8b7a72 Binary files /dev/null and b/app/libs/arm64-v8a/libLZO.so differ diff --git a/app/libs/armeabi-v7a/libLZO.so b/app/libs/armeabi-v7a/libLZO.so new file mode 100644 index 0000000..ffd0aeb Binary files /dev/null and b/app/libs/armeabi-v7a/libLZO.so differ diff --git a/app/libs/armeabi/libLZO.so b/app/libs/armeabi/libLZO.so new file mode 100644 index 0000000..53cee5a Binary files /dev/null and b/app/libs/armeabi/libLZO.so differ diff --git a/app/libs/lfilepickerlibrary-1.7.0.aar b/app/libs/lfilepickerlibrary-1.7.0.aar new file mode 100644 index 0000000..e220056 Binary files /dev/null and b/app/libs/lfilepickerlibrary-1.7.0.aar differ diff --git a/app/libs/lzo_V1.0.jar b/app/libs/lzo_V1.0.jar new file mode 100644 index 0000000..0065b04 Binary files /dev/null and b/app/libs/lzo_V1.0.jar differ diff --git a/app/libs/material-spinner-1.0.5.aar b/app/libs/material-spinner-1.0.5.aar new file mode 100644 index 0000000..95db7c1 Binary files /dev/null and b/app/libs/material-spinner-1.0.5.aar differ diff --git a/app/libs/mips/libLZO.so b/app/libs/mips/libLZO.so new file mode 100644 index 0000000..02c3838 Binary files /dev/null and b/app/libs/mips/libLZO.so differ diff --git a/app/libs/mips64/libLZO.so b/app/libs/mips64/libLZO.so new file mode 100644 index 0000000..2896f0b Binary files /dev/null and b/app/libs/mips64/libLZO.so differ diff --git a/app/libs/rxpermissions-0.12.aar b/app/libs/rxpermissions-0.12.aar new file mode 100644 index 0000000..3167a85 Binary files /dev/null and b/app/libs/rxpermissions-0.12.aar differ diff --git a/app/libs/rxpermissions-0.9.3.aar b/app/libs/rxpermissions-0.9.3.aar new file mode 100644 index 0000000..2dcabd7 Binary files /dev/null and b/app/libs/rxpermissions-0.9.3.aar differ diff --git a/app/libs/x86/libLZO.so b/app/libs/x86/libLZO.so new file mode 100644 index 0000000..4f13511 Binary files /dev/null and b/app/libs/x86/libLZO.so differ diff --git a/app/libs/x86_64/libLZO.so b/app/libs/x86_64/libLZO.so new file mode 100644 index 0000000..c8abbd3 Binary files /dev/null and b/app/libs/x86_64/libLZO.so differ diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/com/example/quiz/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/example/quiz/ExampleInstrumentedTest.java new file mode 100644 index 0000000..427c549 --- /dev/null +++ b/app/src/androidTest/java/com/example/quiz/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.example.quiz; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.example.quiz", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..48bca8e --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/quiz/AppModule.java b/app/src/main/java/com/example/quiz/AppModule.java new file mode 100644 index 0000000..a2dd9f7 --- /dev/null +++ b/app/src/main/java/com/example/quiz/AppModule.java @@ -0,0 +1,27 @@ +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(); + } +} diff --git a/app/src/main/java/com/example/quiz/BetValidation.java b/app/src/main/java/com/example/quiz/BetValidation.java new file mode 100644 index 0000000..5e8094b --- /dev/null +++ b/app/src/main/java/com/example/quiz/BetValidation.java @@ -0,0 +1,166 @@ +package com.example.quiz; + +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; + +import android.util.Log; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.GridLayout; +import android.widget.TextView; +import android.widget.Toast; + +import com.example.quiz.data.model.Horse; +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.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import dagger.hilt.android.AndroidEntryPoint; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link BetValidation#newInstance} factory method to + * create an instance of this fragment. + */ + +@AndroidEntryPoint +public class BetValidation extends Fragment { + + FragmentBetValidationBinding binding; + + SharedViewModel shared; + + BetViewModel viewModel; + + + private HPRTPrinterUtil printer; + + private Integer id; + + private String typeOfBet; + + private List selectedHorses = new ArrayList(); + + private List totalHorses; + + + + + public BetValidation() { + // Required empty public constructor + } + + public static BetValidation newInstance() { + BetValidation fragment = new BetValidation(); + Bundle args = new Bundle(); + 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 = FragmentBetValidationBinding.inflate(inflater, container, false); + binding.combination.setText(getString(R.string.combination,"")); + return binding.getRoot(); + } + + private void setupNumberGrid(GridLayout grid) { + + int columns = 4; + + grid.setColumnCount(columns); + + if(totalHorses != null){ + totalHorses.stream() + .map(this::createNumberItem) + .forEach(grid::addView); + } + } + + private TextView createNumberItem(Horse horse) { + TextView textView = new TextView(requireContext()); + textView.setText(String.valueOf(horse.getNumber())); + textView.setTextColor(getResources().getColor(R.color.white)); + GridLayout.LayoutParams params = new GridLayout.LayoutParams(); + params.setMargins(10, 10, 10, 10); + textView.setLayoutParams(params); + textView.setTextSize(21); + textView.setWidth(130); + textView.setHeight(130); + textView.setGravity(Gravity.CENTER); + textView.setBackgroundResource(R.drawable.number_background); + textView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); + + textView.setOnClickListener(v -> { + if (selectedHorses.contains(horse)) { + selectedHorses.remove(horse); + v.setSelected(false); + v.setBackgroundResource(R.drawable.number_background); + } else { + selectedHorses.add(horse); + v.setSelected(true); + v.setBackgroundResource(R.drawable.number_selected_background); + } + String combinationText = selectedHorses.stream() + .map(h -> String.valueOf(h.getNumber())) + .collect(Collectors.joining("-")); + binding.combination.setText(getString(R.string.combination, combinationText)); + }); + + return textView; + } + + @Override + 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); + shared.betId.observe(getViewLifecycleOwner(), id ->{ + this.id = id; + viewModel.getBetNameById(id - 1); + viewModel.betName.observe(getViewLifecycleOwner(), name ->{ + binding.horseName.setText(name); + }); + viewModel.loadHorses(id - 1); + viewModel.horses.observe(getViewLifecycleOwner(), h->{ + this.totalHorses = h; + setupNumberGrid(binding.gridNumbers); + }); + }); + shared.typeOfBet.observe(getViewLifecycleOwner(), type ->{ + this.typeOfBet = type; + }); + binding.btnValidate.setOnClickListener(v->{ + //Toast.makeText(getContext(), "L'id de bet: "+this.id+" et le type est: "+this.typeOfBet, Toast.LENGTH_SHORT).show(); + printer = new HPRTPrinterUtil(getContext()); + boolean ok = printer.connectBluetooth("02:03:00:00:00:00"); + if (ok) { + printer.printText("Bonjour"); + } + }); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/quiz/First2Fragment.java b/app/src/main/java/com/example/quiz/First2Fragment.java new file mode 100644 index 0000000..fdcbb51 --- /dev/null +++ b/app/src/main/java/com/example/quiz/First2Fragment.java @@ -0,0 +1,44 @@ +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.FragmentFirst2Binding; + +public class First2Fragment extends Fragment { + + private FragmentFirst2Binding binding; + + @Override + public View onCreateView( + @NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState + ) { + + binding = FragmentFirst2Binding.inflate(inflater, container, false); + return binding.getRoot(); + + } + + public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + binding.buttonFirst.setOnClickListener(v -> + NavHostFragment.findNavController(First2Fragment.this) + .navigate(R.id.action_First2Fragment_to_Second2Fragment) + ); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/quiz/FirstFragment.java b/app/src/main/java/com/example/quiz/FirstFragment.java new file mode 100644 index 0000000..e5f474b --- /dev/null +++ b/app/src/main/java/com/example/quiz/FirstFragment.java @@ -0,0 +1,44 @@ +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.FragmentFirstBinding; + +public class FirstFragment extends Fragment { + + private FragmentFirstBinding binding; + + @Override + public View onCreateView( + @NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState + ) { + + binding = FragmentFirstBinding.inflate(inflater, container, false); + return binding.getRoot(); + + } + + public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + binding.buttonFirst.setOnClickListener(v -> + NavHostFragment.findNavController(FirstFragment.this) + .navigate(R.id.action_FirstFragment_to_SecondFragment) + ); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/quiz/ListOFBets.java b/app/src/main/java/com/example/quiz/ListOFBets.java new file mode 100644 index 0000000..b1ad722 --- /dev/null +++ b/app/src/main/java/com/example/quiz/ListOFBets.java @@ -0,0 +1,127 @@ +package com.example.quiz; + +import android.annotation.SuppressLint; +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.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.databinding.FragmentListOFBettingBinding; +import com.example.quiz.viewModel.BetViewModel; +import com.example.quiz.viewModel.SharedViewModel; + +import dagger.hilt.android.AndroidEntryPoint; +import dagger.hilt.android.internal.lifecycle.HiltViewModelFactory; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link ListOFBets#newInstance} factory method to + * create an instance of this fragment. + */ + +@AndroidEntryPoint +public class ListOFBets extends Fragment { + private String username; + + private View view; + + FragmentListOFBettingBinding binding; + + private BetViewModel viewModel; + + private SharedViewModel shared; + + private BetsAdapter adapter; + + private AppCompatActivity activity; + + + public static ListOFBets newInstance(String username) { + ListOFBets fragment = new ListOFBets(); + Bundle args = new Bundle(); + args.putString("ARG_USERNAME", username); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if(getArguments() != null){ + username = getArguments().getString("ARG_USERNAME"); + } + } + + @Override + 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); + shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class); + + + + viewModel.bets.observe(getViewLifecycleOwner(), bets -> { + adapter.setBets(bets); + adapter.setOnItemClickListener(position -> { + shared.setBetId(position); + FragmentManager fragmentManager = getParentFragmentManager(); + ListOfTypeOfBets typeOfBets = ListOfTypeOfBets.newInstance(); + fragmentManager.beginTransaction() + .replace(R.id.nav_host_fragment_content_main, typeOfBets) + .addToBackStack(null) + .commit(); + }); + }); + + viewModel.loadBets(); + return binding.getRoot(); + } + + @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); + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/quiz/ListOfTypeOfBets.java b/app/src/main/java/com/example/quiz/ListOfTypeOfBets.java new file mode 100644 index 0000000..83c5fe4 --- /dev/null +++ b/app/src/main/java/com/example/quiz/ListOfTypeOfBets.java @@ -0,0 +1,84 @@ +package com.example.quiz; + +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.ViewModelProvider; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.RadioButton; +import android.widget.RadioGroup; +import android.widget.Toast; + +import com.example.quiz.databinding.FragmentListOfTypeOfBetsBinding; +import com.example.quiz.viewModel.SharedViewModel; + +import dagger.hilt.android.AndroidEntryPoint; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link ListOfTypeOfBets#newInstance} factory method to + * create an instance of this fragment. + */ + +@AndroidEntryPoint +public class ListOfTypeOfBets extends Fragment { + + private FragmentListOfTypeOfBetsBinding binding; + + private SharedViewModel shared; + + public ListOfTypeOfBets() { + // Required empty public constructor + } + public static ListOfTypeOfBets newInstance() { + ListOfTypeOfBets fragment = new ListOfTypeOfBets(); + Bundle args = new Bundle(); + 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 = FragmentListOfTypeOfBetsBinding.inflate(inflater, container, false); + return binding.getRoot(); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + RadioGroup types = binding.optionsGroup; + Button btnValidate = binding.btnValidate; + 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(); + BetValidation betValidation = BetValidation.newInstance(); + fragmentManager.beginTransaction() + .replace(R.id.nav_host_fragment_content_main, betValidation) + .addToBackStack(null) + .commit(); + }); + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/quiz/Login.java b/app/src/main/java/com/example/quiz/Login.java new file mode 100644 index 0000000..698bc24 --- /dev/null +++ b/app/src/main/java/com/example/quiz/Login.java @@ -0,0 +1,106 @@ +package com.example.quiz; + +import android.app.Activity; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentTransaction; + +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; +import android.widget.Toolbar; + +import com.example.quiz.databinding.FragmentLoginBinding; +import com.example.quiz.utils.SharedPrefsHelper; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link Login#newInstance} factory method to + * create an instance of this fragment. + */ +public class Login extends Fragment { + + private SharedPrefsHelper prefsHelper; + public Login() { + // Required empty public constructor + } + public static Login newInstance() { + Login fragment = new Login(); + Bundle args = new Bundle(); + fragment.setArguments(args); + return fragment; + } + + private FragmentLoginBinding binding; + + + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + binding = FragmentLoginBinding.inflate(inflater, container, false); + return binding.getRoot(); + } + + @Override + public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + AppCompatActivity activity = (AppCompatActivity) getActivity(); + if(activity != null){ + activity.getSupportActionBar().hide(); + } + + } + + public void onStart(){ + super.onStart(); + binding.loginButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(binding.userNameInput.getText().toString().isEmpty()){ + binding.userNameInput.setError("Le nom d'utilisateur est obligatoire"); + binding.userNameInput.requestFocus(); + return; + } + if(binding.passwordInput.getText().toString().isEmpty()){ + binding.passwordInput.setError("Le mot de passe est obligatoire"); + binding.passwordInput.requestFocus(); + return; + } + if(binding.passwordInput.getText().toString().length() < 6){ + binding.passwordInput.setError("Le mot de passe doit contenir au moins 6 caractères "); + binding.passwordInput.requestFocus(); + return; + } + prefsHelper = SharedPrefsHelper.getInstance(getContext()); + prefsHelper.save("username", binding.userNameInput.getText().toString()); + FragmentManager fragmentManager = getParentFragmentManager(); + ListOFBets bets = ListOFBets.newInstance(binding.userNameInput.getText().toString()); + fragmentManager.beginTransaction() + .replace(R.id.nav_host_fragment_content_main, bets) + .commit(); + } + }); + + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/quiz/MainActivity.java b/app/src/main/java/com/example/quiz/MainActivity.java new file mode 100644 index 0000000..e69de29 diff --git a/app/src/main/java/com/example/quiz/MapsFragment.java b/app/src/main/java/com/example/quiz/MapsFragment.java new file mode 100644 index 0000000..440a7b5 --- /dev/null +++ b/app/src/main/java/com/example/quiz/MapsFragment.java @@ -0,0 +1,57 @@ +package com.example.quiz; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.google.android.gms.maps.CameraUpdateFactory; +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.OnMapReadyCallback; +import com.google.android.gms.maps.SupportMapFragment; +import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.MarkerOptions; + +public class MapsFragment extends Fragment { + + private OnMapReadyCallback callback = new OnMapReadyCallback() { + + /** + * Manipulates the map once available. + * This callback is triggered when the map is ready to be used. + * This is where we can add markers or lines, add listeners or move the camera. + * In this case, we just add a marker near Sydney, Australia. + * If Google Play services is not installed on the device, the user will be prompted to + * install it inside the SupportMapFragment. This method will only be triggered once the + * user has installed Google Play services and returned to the app. + */ + @Override + public void onMapReady(GoogleMap googleMap) { + LatLng sydney = new LatLng(-34, 151); + googleMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney")); + googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney)); + } + }; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_maps, container, false); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + SupportMapFragment mapFragment = + (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map); + if (mapFragment != null) { + mapFragment.getMapAsync(callback); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/quiz/PageQuiz.java b/app/src/main/java/com/example/quiz/PageQuiz.java new file mode 100644 index 0000000..6a8efa9 --- /dev/null +++ b/app/src/main/java/com/example/quiz/PageQuiz.java @@ -0,0 +1,71 @@ +package com.example.quiz; + +import android.graphics.Color; +import android.os.Bundle; + +import com.example.quiz.utils.SharedPrefsHelper; +import com.google.android.material.snackbar.Snackbar; + +import androidx.appcompat.app.AppCompatActivity; + +import android.view.View; + +import androidx.fragment.app.FragmentManager; +import androidx.navigation.NavController; +import androidx.navigation.Navigation; +import androidx.navigation.ui.AppBarConfiguration; +import androidx.navigation.ui.NavigationUI; + +import com.example.quiz.databinding.ActivityPageQuizBinding; + +import dagger.hilt.android.AndroidEntryPoint; + +@AndroidEntryPoint +public class PageQuiz extends AppCompatActivity { + + private AppBarConfiguration appBarConfiguration; + private ActivityPageQuizBinding binding; + + private SharedPrefsHelper prefsHelper; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + binding = ActivityPageQuizBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + setSupportActionBar(binding.toolbar); + binding.toolbar.setBackgroundColor(Color.parseColor("#501C5A29")); + binding.fab.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) + .setAnchorView(R.id.fab) + .setAction("Action", null).show(); + } + }); + prefsHelper = SharedPrefsHelper.getInstance(getApplicationContext()); + FragmentManager fragmentManager = getSupportFragmentManager(); + + if(prefsHelper.get("username") != null){ + ListOFBets bets = ListOFBets.newInstance(prefsHelper.get("username")); + fragmentManager + .beginTransaction() + .replace(R.id.nav_host_fragment_content_main, bets) + .commit(); + }else{ + Login login = Login.newInstance(); + fragmentManager + .beginTransaction() + .replace(R.id.nav_host_fragment_content_main, login) + .commit(); + } + } + + @Override + public boolean onSupportNavigateUp() { + NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_page_quiz); + return NavigationUI.navigateUp(navController, appBarConfiguration) + || super.onSupportNavigateUp(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/quiz/PmuHorseBetting.java b/app/src/main/java/com/example/quiz/PmuHorseBetting.java new file mode 100644 index 0000000..a643d8c --- /dev/null +++ b/app/src/main/java/com/example/quiz/PmuHorseBetting.java @@ -0,0 +1,11 @@ +package com.example.quiz; + +import android.app.Application; + +import com.example.quiz.utils.SharedPrefsHelper; + +import dagger.hilt.android.HiltAndroidApp; + +@HiltAndroidApp +public class PmuHorseBetting extends Application { +} diff --git a/app/src/main/java/com/example/quiz/Questions.java b/app/src/main/java/com/example/quiz/Questions.java new file mode 100644 index 0000000..975c6e0 --- /dev/null +++ b/app/src/main/java/com/example/quiz/Questions.java @@ -0,0 +1,80 @@ +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() { + @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(); + } + }); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/quiz/Second2Fragment.java b/app/src/main/java/com/example/quiz/Second2Fragment.java new file mode 100644 index 0000000..eceb1f8 --- /dev/null +++ b/app/src/main/java/com/example/quiz/Second2Fragment.java @@ -0,0 +1,44 @@ +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; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/quiz/SecondFragment.java b/app/src/main/java/com/example/quiz/SecondFragment.java new file mode 100644 index 0000000..918b95c --- /dev/null +++ b/app/src/main/java/com/example/quiz/SecondFragment.java @@ -0,0 +1,44 @@ +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; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/quiz/data/BetsBank.java b/app/src/main/java/com/example/quiz/data/BetsBank.java new file mode 100644 index 0000000..9b035bb --- /dev/null +++ b/app/src/main/java/com/example/quiz/data/BetsBank.java @@ -0,0 +1,72 @@ +package com.example.quiz.data; + +import com.example.quiz.data.model.Bet; +import com.example.quiz.data.model.Horse; + +import java.time.LocalDate; +import java.util.Arrays; +import java.util.List; + +public class BetsBank { + public List getBet() { + return Arrays.asList( + new Bet( + 1, + "Course de chevaux", + 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", + LocalDate.of(2025,10,1), + Arrays.asList( + new Horse(4), + new Horse(5), + new Horse(7), + new Horse(6) + ) + ), + new Bet( + 3, + "Course de chevaux 3", + 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", + 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; + } +} diff --git a/app/src/main/java/com/example/quiz/data/QuestionsBank.java b/app/src/main/java/com/example/quiz/data/QuestionsBank.java new file mode 100644 index 0000000..3384f21 --- /dev/null +++ b/app/src/main/java/com/example/quiz/data/QuestionsBank.java @@ -0,0 +1,69 @@ +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 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; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/quiz/data/adapter/BetsAdapter.java b/app/src/main/java/com/example/quiz/data/adapter/BetsAdapter.java new file mode 100644 index 0000000..13c5c0e --- /dev/null +++ b/app/src/main/java/com/example/quiz/data/adapter/BetsAdapter.java @@ -0,0 +1,75 @@ +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.Bet; + + +import java.util.ArrayList; +import java.util.List; +public class BetsAdapter extends RecyclerView.Adapter { + private List bets = new ArrayList<>(); + private onItemClickListener listener; + + + public interface onItemClickListener { + void onItemClick(int position); + } + + public void setOnItemClickListener(onItemClickListener listener){ + this.listener = listener; + } + + + + public void setBets(List bets){ + this.bets = bets; + notifyDataSetChanged(); + } + + @NonNull + @Override + public BetViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_bet, parent, false); + return new BetViewHolder(view); + } + + @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())); + holder.itemView.setOnClickListener(v->{ + if(listener != null){ + listener.onItemClick(bet.getId()); + } + }); + } + + + + + @Override + public int getItemCount(){ + return bets.size(); + } + + static class BetViewHolder extends RecyclerView.ViewHolder{ + TextView tvName, tvDate; + public BetViewHolder(@NonNull View itemView) { + super(itemView); + tvName = itemView.findViewById(R.id.tvName); + tvDate = itemView.findViewById(R.id.tvDate); + } + + } + +} diff --git a/app/src/main/java/com/example/quiz/data/model/Bet.java b/app/src/main/java/com/example/quiz/data/model/Bet.java new file mode 100644 index 0000000..7fedfd4 --- /dev/null +++ b/app/src/main/java/com/example/quiz/data/model/Bet.java @@ -0,0 +1,52 @@ +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 List horses; + + public List getHorses() { + return horses; + } + + public void setHorses(List 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, LocalDate date, List horses) { + this.id = id; + this.name = name; + this.date = date; + this.horses = horses; + } +} diff --git a/app/src/main/java/com/example/quiz/data/model/Horse.java b/app/src/main/java/com/example/quiz/data/model/Horse.java new file mode 100644 index 0000000..32c50a1 --- /dev/null +++ b/app/src/main/java/com/example/quiz/data/model/Horse.java @@ -0,0 +1,18 @@ +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; + } +} diff --git a/app/src/main/java/com/example/quiz/data/model/Question.java b/app/src/main/java/com/example/quiz/data/model/Question.java new file mode 100644 index 0000000..ca7ceb2 --- /dev/null +++ b/app/src/main/java/com/example/quiz/data/model/Question.java @@ -0,0 +1,39 @@ +package com.example.quiz.data.model; + +import java.util.List; + +public class Question { + private String question; + private List answers; + private Integer indexAnswer; + + public Question(String question, List answers, int indexAnswer){ + this.question = question; + this.answers = answers; + this.indexAnswer = indexAnswer; + } + + public int getIndexAnswer() { + return indexAnswer; + } + + public void setIndexAnswer(int indexAnswer) { + this.indexAnswer = indexAnswer; + } + + public String getQuestion() { + return question; + } + + public void setQuestion(String question) { + this.question = question; + } + + public List getAnswers() { + return answers; + } + + public void setAnswers(List answers) { + this.answers = answers; + } +} diff --git a/app/src/main/java/com/example/quiz/data/repository/BetRepository.java b/app/src/main/java/com/example/quiz/data/repository/BetRepository.java new file mode 100644 index 0000000..1492a7e --- /dev/null +++ b/app/src/main/java/com/example/quiz/data/repository/BetRepository.java @@ -0,0 +1,46 @@ +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 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 getAllBets(){ + return betsBank.getBet(); + } + + public Bet getBetById(int id){ + return betsBank.getBet().get(id); + } + + public List getHorsesById(int id){ + return getBetById(id).getHorses(); + } + + public BetRepository getInstance(){ + return new BetRepository(); + } + + public String getBetNameById(int id){ + return getBetById(id).getName(); + } + +} diff --git a/app/src/main/java/com/example/quiz/data/repository/QuestionRepository.java b/app/src/main/java/com/example/quiz/data/repository/QuestionRepository.java new file mode 100644 index 0000000..ff0e2e4 --- /dev/null +++ b/app/src/main/java/com/example/quiz/data/repository/QuestionRepository.java @@ -0,0 +1,31 @@ +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 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(); + } +} diff --git a/app/src/main/java/com/example/quiz/injection/QuestionViewModelFactory.java b/app/src/main/java/com/example/quiz/injection/QuestionViewModelFactory.java new file mode 100644 index 0000000..bf32e14 --- /dev/null +++ b/app/src/main/java/com/example/quiz/injection/QuestionViewModelFactory.java @@ -0,0 +1,38 @@ +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 create(@NonNull Class modelClass){ + if(modelClass.isAssignableFrom(QuestionViewModel.class)){ + return (T) new QuestionViewModel(questionRepository); + } + throw new IllegalArgumentException("Unknown ViewModel class"); + } + +} diff --git a/app/src/main/java/com/example/quiz/utils/HPRTPrinterUtil.java b/app/src/main/java/com/example/quiz/utils/HPRTPrinterUtil.java new file mode 100644 index 0000000..b5f3624 --- /dev/null +++ b/app/src/main/java/com/example/quiz/utils/HPRTPrinterUtil.java @@ -0,0 +1,91 @@ +package com.example.quiz.utils; + +import android.content.Context; +import android.util.Log; +import android.widget.Toast; + +import tspl.HPRTPrinterHelper; + +public class HPRTPrinterUtil { + + private static final String TAG = "HPRTPrinterUtil"; + private Context context; + + public HPRTPrinterUtil(Context context) { + this.context = context; + } + + /** + * Connecte une imprimante Bluetooth + * @param btAddress adresse MAC Bluetooth de l'imprimante + * @return true si connecté, false sinon + */ + public boolean connectBluetooth(String btAddress) { + try { + HPRTPrinterHelper.PortClose(); // ferme toute connexion existante + int result = HPRTPrinterHelper.PortOpen("Bluetooth," + btAddress); + if (result == 0) { + Log.d(TAG, "Connexion réussie"); + Toast.makeText(context, "Imprimante connectée", Toast.LENGTH_SHORT).show(); + return true; + } else { + Log.e(TAG, "Erreur connexion: " + result); + Toast.makeText(context, "Erreur connexion imprimante: " + result, Toast.LENGTH_SHORT).show(); + return false; + } + } catch (Exception e) { + Log.e(TAG, "Erreur connexion: " + e.getMessage()); + return false; + } + } + + public void printText(String text) { + try { + if (!HPRTPrinterHelper.IsOpened()) { + Toast.makeText(context, "Imprimante non connectée", Toast.LENGTH_SHORT).show(); + return; + } + + // TSPL pur pour texte simple + String tspl = ""+ text + "\r\n"; + + // Envoi à l'imprimante + HPRTPrinterHelper.PrintData(tspl); + + Log.d(TAG, "Texte imprimé sur ticket"); // on log seulement le succès + + } catch (Exception e) { + Log.e(TAG, "Erreur impression TSPL: " + e.getMessage()); + Toast.makeText(context, "Erreur impression TSPL", Toast.LENGTH_SHORT).show(); + } + } + + + + public void printTSPLTemplate(String tsplTemplate) { + try { + if (!HPRTPrinterHelper.IsOpened()) { + Toast.makeText(context, "Imprimante non connectée", Toast.LENGTH_SHORT).show(); + return; + } + + HPRTPrinterHelper.PrintData(tsplTemplate); + Log.d(TAG, "Template imprimé"); + } catch (Exception e) { + Log.e(TAG, "Erreur impression TSPL: " + e.getMessage()); + Toast.makeText(context, "Erreur impression TSPL", Toast.LENGTH_SHORT).show(); + } + } + + /** + * Déconnecte l'imprimante + */ + public void disconnect() { + try { + HPRTPrinterHelper.PortClose(); + Toast.makeText(context, "Imprimante déconnectée", Toast.LENGTH_SHORT).show(); + } catch (Exception e) { + Log.e(TAG, "Erreur déconnexion: " + e.getMessage()); + } + } +} diff --git a/app/src/main/java/com/example/quiz/utils/SharedPrefsHelper.java b/app/src/main/java/com/example/quiz/utils/SharedPrefsHelper.java new file mode 100644 index 0000000..7fddf33 --- /dev/null +++ b/app/src/main/java/com/example/quiz/utils/SharedPrefsHelper.java @@ -0,0 +1,34 @@ +package com.example.quiz.utils; + +import android.content.Context; +import android.content.SharedPreferences; + +public class SharedPrefsHelper { + + private static final String PREF_NAME = "quiz_prefs"; + private static SharedPrefsHelper instance; + private SharedPreferences prefs; + + private SharedPrefsHelper(Context context) { + prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); + } + + public static SharedPrefsHelper getInstance(Context context) { + if (instance == null) { + instance = new SharedPrefsHelper(context.getApplicationContext()); + } + return instance; + } + + public void save(String key, String value) { + prefs.edit().putString(key, value).apply(); + } + + public String get(String key) { + return prefs.getString(key, null); + } + + public void clear() { + prefs.edit().clear().apply(); + } +} diff --git a/app/src/main/java/com/example/quiz/viewModel/BetViewModel.java b/app/src/main/java/com/example/quiz/viewModel/BetViewModel.java new file mode 100644 index 0000000..acc86fe --- /dev/null +++ b/app/src/main/java/com/example/quiz/viewModel/BetViewModel.java @@ -0,0 +1,46 @@ +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.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> bets = new MutableLiveData>(); + + public MutableLiveData betName = new MutableLiveData(); + + public MutableLiveData> horses = new MutableLiveData<>(); + + + + @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)); + } + +} diff --git a/app/src/main/java/com/example/quiz/viewModel/QuestionViewModel.java b/app/src/main/java/com/example/quiz/viewModel/QuestionViewModel.java new file mode 100644 index 0000000..f750228 --- /dev/null +++ b/app/src/main/java/com/example/quiz/viewModel/QuestionViewModel.java @@ -0,0 +1,41 @@ +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 currentQuestion = new MutableLiveData(); + public MutableLiveData score = new MutableLiveData(); + public MutableLiveData isLastQuestion = new MutableLiveData(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)); + } + } + +} diff --git a/app/src/main/java/com/example/quiz/viewModel/SharedViewModel.java b/app/src/main/java/com/example/quiz/viewModel/SharedViewModel.java new file mode 100644 index 0000000..4db3b73 --- /dev/null +++ b/app/src/main/java/com/example/quiz/viewModel/SharedViewModel.java @@ -0,0 +1,22 @@ +package com.example.quiz.viewModel; + +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; + +import javax.inject.Inject; + +import dagger.hilt.android.lifecycle.HiltViewModel; + + +public class SharedViewModel extends ViewModel { + + public MutableLiveData betId = new MutableLiveData(); + public MutableLiveData typeOfBet = new MutableLiveData(); + + public void setBetId(int id){ + betId.setValue(id); + } + public void setTypeOfBet(String type){ + typeOfBet.setValue(type); + } +} diff --git a/app/src/main/res/anim/item_fad_in.xml b/app/src/main/res/anim/item_fad_in.xml new file mode 100644 index 0000000..d4f1e18 --- /dev/null +++ b/app/src/main/res/anim/item_fad_in.xml @@ -0,0 +1,5 @@ + + diff --git a/app/src/main/res/anim/layout_fad_in.xml b/app/src/main/res/anim/layout_fad_in.xml new file mode 100644 index 0000000..6f5f8dd --- /dev/null +++ b/app/src/main/res/anim/layout_fad_in.xml @@ -0,0 +1,5 @@ + + diff --git a/app/src/main/res/drawable/bet_item_icon.xml b/app/src/main/res/drawable/bet_item_icon.xml new file mode 100644 index 0000000..10231ee --- /dev/null +++ b/app/src/main/res/drawable/bet_item_icon.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_gradient.xml b/app/src/main/res/drawable/bg_gradient.xml new file mode 100644 index 0000000..6c63b7f --- /dev/null +++ b/app/src/main/res/drawable/bg_gradient.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/course_item_border.xml b/app/src/main/res/drawable/course_item_border.xml new file mode 100644 index 0000000..7fdc8f6 --- /dev/null +++ b/app/src/main/res/drawable/course_item_border.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/drawable/edittext_border.xml b/app/src/main/res/drawable/edittext_border.xml new file mode 100644 index 0000000..46e54c1 --- /dev/null +++ b/app/src/main/res/drawable/edittext_border.xml @@ -0,0 +1,10 @@ + + + + + + diff --git a/app/src/main/res/drawable/horse_face_svgrepo_com.xml b/app/src/main/res/drawable/horse_face_svgrepo_com.xml new file mode 100644 index 0000000..8d439ef --- /dev/null +++ b/app/src/main/res/drawable/horse_face_svgrepo_com.xml @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_arrow_right.xml b/app/src/main/res/drawable/ic_arrow_right.xml new file mode 100644 index 0000000..5321bd5 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_right.xml @@ -0,0 +1,16 @@ + + + + diff --git a/app/src/main/res/drawable/ic_chevron_right.xml b/app/src/main/res/drawable/ic_chevron_right.xml new file mode 100644 index 0000000..fa6ad85 --- /dev/null +++ b/app/src/main/res/drawable/ic_chevron_right.xml @@ -0,0 +1,16 @@ + + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/item_box.xml b/app/src/main/res/drawable/item_box.xml new file mode 100644 index 0000000..f3cb893 --- /dev/null +++ b/app/src/main/res/drawable/item_box.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/number_background.xml b/app/src/main/res/drawable/number_background.xml new file mode 100644 index 0000000..d816546 --- /dev/null +++ b/app/src/main/res/drawable/number_background.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/number_selected_background.xml b/app/src/main/res/drawable/number_selected_background.xml new file mode 100644 index 0000000..d772656 --- /dev/null +++ b/app/src/main/res/drawable/number_selected_background.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/pmu_logo.png b/app/src/main/res/drawable/pmu_logo.png new file mode 100644 index 0000000..f7d0c62 Binary files /dev/null and b/app/src/main/res/drawable/pmu_logo.png differ diff --git a/app/src/main/res/drawable/rounded_button_green.xml b/app/src/main/res/drawable/rounded_button_green.xml new file mode 100644 index 0000000..b4b634d --- /dev/null +++ b/app/src/main/res/drawable/rounded_button_green.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..16313e0 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_page_quiz.xml b/app/src/main/res/layout/activity_page_quiz.xml new file mode 100644 index 0000000..b26f10b --- /dev/null +++ b/app/src/main/res/layout/activity_page_quiz.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml new file mode 100644 index 0000000..0f12ea1 --- /dev/null +++ b/app/src/main/res/layout/content_main.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/content_page_quiz.xml b/app/src/main/res/layout/content_page_quiz.xml new file mode 100644 index 0000000..d9ff9b3 --- /dev/null +++ b/app/src/main/res/layout/content_page_quiz.xml @@ -0,0 +1,19 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_bet_validation.xml b/app/src/main/res/layout/fragment_bet_validation.xml new file mode 100644 index 0000000..42bc1ef --- /dev/null +++ b/app/src/main/res/layout/fragment_bet_validation.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + +