From e44ee66c67486264923818307c5f67f57c988460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Laiz=20G=C3=B3mez?= Date: Fri, 26 Jul 2019 20:17:40 +0200 Subject: [PATCH 01/32] v0.4-SNAPSHOT --- app/build.gradle | 4 ++-- app/src/main/res/values/strings.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 35f3b59..fe46cf9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,8 +17,8 @@ android { applicationId 'com.martinlaizg.geofind' minSdkVersion 26 targetSdkVersion 28 - versionCode 7 - versionName 'v0.3.1' + versionCode 8 + versionName 'v0.4-SNAPSHOT' testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e24730b..46ffb31 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -111,7 +111,7 @@ Errors and suggestions App version App developer - v0.3.1 + v0.4-SNAPSHOT Refused permission to location %1$d/%2$d Add image URL From 68068e6aa7d9cb9af05046b65ccdd378d8889579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Laiz=20G=C3=B3mez?= Date: Fri, 2 Aug 2019 17:00:43 +0200 Subject: [PATCH 02/32] Incrementada version room --- .../martinlaizg/geofind/data/access/database/AppDatabase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/martinlaizg/geofind/data/access/database/AppDatabase.java b/app/src/main/java/com/martinlaizg/geofind/data/access/database/AppDatabase.java index 50c5ce3..755127a 100644 --- a/app/src/main/java/com/martinlaizg/geofind/data/access/database/AppDatabase.java +++ b/app/src/main/java/com/martinlaizg/geofind/data/access/database/AppDatabase.java @@ -22,7 +22,7 @@ import com.martinlaizg.geofind.data.access.database.entities.User; @Database(entities = {User.class, Tour.class, Place.class, Play.class, PlacePlay.class}, - version = 6, exportSchema = false) + version = 7, exportSchema = false) @TypeConverters( {DateTypeConverter.class, PlayLevelTypeConverter.class, UserTypeTypeConverter.class}) public abstract class AppDatabase From 1a69dad16e5f0bbd8b59d0c2027e44bf74acdbde Mon Sep 17 00:00:00 2001 From: Martin Laiz Gomez Date: Sat, 3 Aug 2019 11:01:55 +0200 Subject: [PATCH 03/32] =?UTF-8?q?Mejorado=20dialogo=20al=20completar=20un?= =?UTF-8?q?=20sitio.=20Cambiado=20dialogo,=20material=20button=20en=20vez?= =?UTF-8?q?=20de=20Material=20card.=20Creado=20dialogo=20cada=20vez=20que?= =?UTF-8?q?=20se=20llegaa=20un=20sitio,=20as=C3=AD=20las=20respuestas=20es?= =?UTF-8?q?t=C3=A1n=20en=20diferente=20orden?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/repository/PlayRepository.java | 2 +- .../views/fragment/play/PlayTourFragment.java | 72 +++++++++---------- app/src/main/res/layout/question_layout.xml | 52 +++++--------- 3 files changed, 52 insertions(+), 74 deletions(-) diff --git a/app/src/main/java/com/martinlaizg/geofind/data/repository/PlayRepository.java b/app/src/main/java/com/martinlaizg/geofind/data/repository/PlayRepository.java index b3bca5a..c319872 100644 --- a/app/src/main/java/com/martinlaizg/geofind/data/repository/PlayRepository.java +++ b/app/src/main/java/com/martinlaizg/geofind/data/repository/PlayRepository.java @@ -77,7 +77,7 @@ public Play getPlay(int user_id, int tour_id) throws APIException { return null; } } else { - Log.e(TAG, "getPlay: Other error"); + Log.e(TAG, "getPlay: Other error", e); throw e; } } diff --git a/app/src/main/java/com/martinlaizg/geofind/views/fragment/play/PlayTourFragment.java b/app/src/main/java/com/martinlaizg/geofind/views/fragment/play/PlayTourFragment.java index 8589fcd..99dbeb8 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/fragment/play/PlayTourFragment.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/fragment/play/PlayTourFragment.java @@ -1,6 +1,7 @@ package com.martinlaizg.geofind.views.fragment.play; import android.Manifest; +import android.annotation.SuppressLint; import android.content.Context; import android.content.pm.PackageManager; import android.location.Location; @@ -21,7 +22,7 @@ import androidx.lifecycle.ViewModelProviders; import androidx.navigation.Navigation; -import com.google.android.material.card.MaterialCardView; +import com.google.android.material.button.MaterialButton; import com.martinlaizg.geofind.R; import com.martinlaizg.geofind.config.Preferences; import com.martinlaizg.geofind.data.access.api.service.exceptions.APIException; @@ -97,13 +98,6 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat .popBackStack(R.id.navTour, false); return; } - - // If has question build it - if(place.getQuestion() != null && !place.getQuestion().isEmpty()) { - createDialog(place); - } else { - questionDialog = null; - } setPlace(place); }); } @@ -138,6 +132,21 @@ public void onPause() { locationManager.removeUpdates(this); } + private void setPlace(Place nextPlace) { + place = nextPlace; + placeLocation = new Location(""); + placeLocation.setLatitude(place.getLat()); + placeLocation.setLongitude(place.getLon()); + place_name.setText(place.getName()); + place_description.setText(place.getDescription()); + int numCompletedPlaces = viewModel.getPlay().getPlaces().size() + 1; + int numPlaces = viewModel.getPlay().getTour().getPlaces().size(); + place_complete.setText(getResources().getQuantityString(R.plurals.place_number_number, + numCompletedPlaces, + numCompletedPlaces, numPlaces)); + updateView(); + } + abstract void updateView(); @Override @@ -164,7 +173,8 @@ public void onLocationChanged(@NonNull Location location) { Log.d(TAG(), "updateView: user arrive to the place"); // If has question display - if(questionDialog != null && !questionDialog.isShowing()) { + if(place != null && place.getQuestion() != null && !place.getQuestion().isEmpty()) { + createDialog(place); questionDialog.show(); } else { completePlace(); @@ -193,6 +203,7 @@ public void onProviderDisabled(String provider) { private void completePlace() { // hide question dialog if exist and is showing if(questionDialog != null && questionDialog.isShowing()) questionDialog.dismiss(); + locationManager.removeUpdates(this); viewModel.completePlace(place.getId()).observe(this, place -> { if(place == null) { if(viewModel.tourIsCompleted()) { @@ -231,55 +242,42 @@ PackageManager.PERMISSION_GRANTED && requireActivity() }); } - private void setPlace(Place nextPlace) { - place = nextPlace; - placeLocation = new Location(""); - placeLocation.setLatitude(place.getLat()); - placeLocation.setLongitude(place.getLon()); - place_name.setText(place.getName()); - place_description.setText(place.getDescription()); - int numCompletedPlaces = viewModel.getPlay().getPlaces().size() + 1; - int numPlaces = viewModel.getPlay().getTour().getPlaces().size(); - place_complete.setText(getResources().getQuantityString(R.plurals.place_number_number, - numCompletedPlaces, - numCompletedPlaces, numPlaces)); - updateView(); - } - + @SuppressLint("MissingPermission") private void createDialog(Place place) { AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(requireContext()); View dialogView = getLayoutInflater() .inflate(R.layout.question_layout, new ConstraintLayout(requireContext()), false); TextView question = dialogView.findViewById(R.id.question); question.setText(place.getQuestion()); - List cards = Arrays.asList(dialogView.findViewById(R.id.answer1_layout), - dialogView.findViewById(R.id.answer2_layout), - dialogView.findViewById(R.id.answer3_layout)); - List texts = Arrays.asList(dialogView.findViewById(R.id.answer1), - dialogView.findViewById(R.id.answer2), - dialogView.findViewById(R.id.answer3)); - + List texts = Arrays.asList(dialogView.findViewById(R.id.answer1), + dialogView.findViewById(R.id.answer2), + dialogView.findViewById(R.id.answer3)); // Get random position to start - int i = new Random().nextInt(cards.size()); + int i = new Random().nextInt(texts.size()); // Set correct answer texts.get(i).setText(place.getAnswer()); - cards.get(i).setOnClickListener(v -> completePlace()); + texts.get(i).setOnClickListener(v -> completePlace()); i++; - i %= cards.size(); + i %= texts.size(); // set second answer texts.get(i).setText(place.getAnswer2()); - cards.get(i).setOnClickListener(v -> showWrongAnswerToast()); + texts.get(i).setOnClickListener(v -> showWrongAnswerToast()); i++; - i %= cards.size(); + i %= texts.size(); texts.get(i).setText(place.getAnswer3()); - cards.get(i).setOnClickListener(v -> showWrongAnswerToast()); + texts.get(i).setOnClickListener(v -> showWrongAnswerToast()); dialogBuilder.setView(dialogView); questionDialog = dialogBuilder.create(); + questionDialog.setOnDismissListener(dialog -> locationManager + .requestLocationUpdates(LocationManager.GPS_PROVIDER, LOC_TIME_REQ, LOC_DIST_REQ, + this)); + ; } private void showWrongAnswerToast() { + if(questionDialog != null && questionDialog.isShowing()) questionDialog.dismiss(); Toast.makeText(requireContext(), getString(R.string.wrong_answer), Toast.LENGTH_SHORT) .show(); } diff --git a/app/src/main/res/layout/question_layout.xml b/app/src/main/res/layout/question_layout.xml index df7235f..b48f1b3 100644 --- a/app/src/main/res/layout/question_layout.xml +++ b/app/src/main/res/layout/question_layout.xml @@ -26,8 +26,8 @@ app:layout_constraintTop_toTopOf="parent" tools:text="@sample/places.json/data/question[0]" /> - + app:layout_constraintTop_toBottomOf="@+id/question" + tools:text="@sample/places.json/data/answer1" /> - - - - - - - + app:layout_constraintEnd_toEndOf="@+id/answer1" + app:layout_constraintStart_toStartOf="@+id/answer1" + app:layout_constraintTop_toBottomOf="@+id/answer1" + tools:text="@sample/places.json/data/answer2[0]" /> - + app:layout_constraintEnd_toEndOf="@+id/answer2" + app:layout_constraintStart_toStartOf="@+id/answer2" + app:layout_constraintTop_toBottomOf="@+id/answer2" + tools:text="@sample/places.json/data/answer3[0]" /> - - \ No newline at end of file From 96b28e46d85ff053f6f74b75ad56e6100b5f3a63 Mon Sep 17 00:00:00 2001 From: Martin Laiz Date: Sat, 3 Aug 2019 12:00:28 +0200 Subject: [PATCH 04/32] =?UTF-8?q?A=C3=B1adido=20JavaDoc=20a=20la=20interfa?= =?UTF-8?q?z=20de=20RetroFit=20(API)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../geofind/data/access/api/RestClient.java | 90 ++++++++++++++++++- 1 file changed, 88 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/martinlaizg/geofind/data/access/api/RestClient.java b/app/src/main/java/com/martinlaizg/geofind/data/access/api/RestClient.java index 66ea514..47740da 100644 --- a/app/src/main/java/com/martinlaizg/geofind/data/access/api/RestClient.java +++ b/app/src/main/java/com/martinlaizg/geofind/data/access/api/RestClient.java @@ -16,40 +16,126 @@ import retrofit2.http.Path; import retrofit2.http.QueryMap; -// TODO add JavaDoc public interface RestClient { + /** + * Get the entier list of {@link Tour} + * + * @param params + * the params to get tours + * @return the list of tours + */ @GET("tours") Call> getTours(@QueryMap java.util.Map params); + /** + * Create the tour + * + * @param tour + * the tour to create + * @return the created tour + */ @POST("tours") Call createTour(@Body Tour tour); + /** + * Get a single tour + * + * @param tour_id + * the id of the tour + * @return the tour + */ @GET("tours/{tour_id}") Call getTour(@Path("tour_id") Integer tour_id); + /** + * Update the tour with the {@code tour_id} with the data in {@code tour} + * + * @param tour_id + * the id of the tour to update + * @param tour + * the new data of the tour + * @return the tour updated + */ @PUT("tours/{tour_id}") - Call update(@Path("tour_id") Integer tour_id, @Body Tour t); + Call update(@Path("tour_id") Integer tour_id, @Body Tour tour); + /** + * Get the {@link Play} by {@code tour_id} and {@code user_id} + * + * @param tour_id + * the id of the tour + * @param user_id + * the id of the user + * @return the play + */ @GET("tours/{tour_id}/users/{user_id}/play") Call getUserPlay(@Path("tour_id") Integer tour_id, @Path("user_id") Integer user_id); + /** + * Create the empty {@link Play} by {@code tour_id} and {@code user_id} + * + * @param tour_id + * the id of the tour + * @param user_id + * the id of the user + * @return the play + */ @POST("tours/{tour_id}/users/{user_id}/play") Call createUserPlay(@Path("tour_id") Integer tour_id, @Path("user_id") Integer user_id); + /** + * Log in the user + * + * @param login + * login data + * @return the logged user + */ @POST("login") Call login(@Body Login login); + /** + * Registry the user + * + * @param login + * the data to registry + * @return the new {@link User} + */ @POST("users") Call registry(@Body Login login); + /** + * Create the play of a place + * + * @param play_id + * the id of the play + * @param place_id + * the id of the place + * @return the new {@link Play} with the place + */ @POST("plays/{play_id}/places/{place_id}") Call createPlacePlay(@Path("play_id") Integer play_id, @Path("place_id") Integer place_id); + /** + * Send a message to support + * + * @param params + * the data (title and message) + * @return nothing + */ @POST("support") Call sendSupportMessage(@QueryMap Map params); + /** + * Update the data of the user + * + * @param user_id + * the id of the user to update + * @param login + * the new data of the user and credentials + * @return the new user + */ @PUT("users/{user_id}") Call updateUser(@Path("user_id") Integer user_id, @Body Login login); } From 7fd9acbbfdef99c82ad61dd3e18d6afcfc89d788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Laiz=20G=C3=B3mez?= Date: Mon, 5 Aug 2019 18:22:30 +0200 Subject: [PATCH 05/32] Refactorizados los Repos y Services para quitar factorias --- app/build.gradle | 4 +- .../data/access/api/RetrofitInstance.java | 10 +-- .../data/access/api/service/PlayService.java | 19 +++-- .../access/api/service/ServiceFactory.java | 34 --------- .../data/access/api/service/TourService.java | 12 +-- .../data/access/api/service/UserService.java | 14 ++-- .../data/repository/PlaceRepository.java | 12 ++- .../data/repository/PlayRepository.java | 27 ++++--- .../data/repository/RepositoryFactory.java | 43 ----------- .../data/repository/TourRepository.java | 16 ++-- .../data/repository/UserRepository.java | 19 ++++- .../geofind/views/activity/MainActivity.java | 10 +++ .../views/viewmodel/CreatorViewModel.java | 3 +- .../views/viewmodel/EditProfileViewModel.java | 3 +- .../views/viewmodel/LoginViewModel.java | 3 +- .../viewmodel/MainFragmentViewModel.java | 3 +- .../views/viewmodel/PlayTourViewModel.java | 3 +- .../views/viewmodel/SettingsViewModel.java | 3 +- .../views/viewmodel/TourListViewModel.java | 3 +- .../views/viewmodel/TourViewModel.java | 5 +- .../data/repository/TourRepositoryTest.java | 74 +++++++++++++++++++ 21 files changed, 178 insertions(+), 142 deletions(-) delete mode 100644 app/src/main/java/com/martinlaizg/geofind/data/access/api/service/ServiceFactory.java delete mode 100644 app/src/main/java/com/martinlaizg/geofind/data/repository/RepositoryFactory.java create mode 100644 app/src/test/java/com/martinlaizg/geofind/data/repository/TourRepositoryTest.java diff --git a/app/build.gradle b/app/build.gradle index fe46cf9..d1bcbe3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -114,6 +114,8 @@ dependencies { // Picasso implementation 'com.squareup.picasso:picasso:2.5.2' - // Tests Junit + // Testing testImplementation 'junit:junit:4.12' + testImplementation 'androidx.test:core:1.2.0' + testImplementation 'org.mockito:mockito-core:2.19.0' } diff --git a/app/src/main/java/com/martinlaizg/geofind/data/access/api/RetrofitInstance.java b/app/src/main/java/com/martinlaizg/geofind/data/access/api/RetrofitInstance.java index b0405db..7e83678 100644 --- a/app/src/main/java/com/martinlaizg/geofind/data/access/api/RetrofitInstance.java +++ b/app/src/main/java/com/martinlaizg/geofind/data/access/api/RetrofitInstance.java @@ -10,7 +10,6 @@ import com.google.gson.GsonBuilder; import com.martinlaizg.geofind.config.Preferences; import com.martinlaizg.geofind.data.access.api.service.exceptions.APIException; -import com.martinlaizg.geofind.data.repository.RepositoryFactory; import com.martinlaizg.geofind.data.repository.UserRepository; import com.martinlaizg.geofind.utils.DateUtils; @@ -22,7 +21,8 @@ public class RetrofitInstance { - private static final String BASE_URL = "https://geofind1.herokuapp.com/api/"; + // private static final String BASE_URL = "https://geofind1.herokuapp.com/api/"; + private static final String BASE_URL = "http://192.168.1.36:8000/api/"; private static final String TAG = RetrofitInstance.class.getSimpleName(); @@ -33,9 +33,6 @@ public class RetrofitInstance { private static UserRepository userRepo; public static RestClient getRestClient(Application application) { - if(userRepo == null) { - userRepo = RepositoryFactory.getUserRepository(application); - } if(sp == null) { sp = PreferenceManager.getDefaultSharedPreferences(application.getApplicationContext()); } @@ -55,6 +52,9 @@ public static Retrofit getRetrofitInstance() { Response response = chain.proceed(newRequest); if(response.code() == 401) { // Code 401 Unauthorized try { + if(userRepo == null) { + userRepo = UserRepository.getInstance(); + } userRepo.reLogin(); } catch(APIException e) { Log.e(TAG, "Fail relogin", e); diff --git a/app/src/main/java/com/martinlaizg/geofind/data/access/api/service/PlayService.java b/app/src/main/java/com/martinlaizg/geofind/data/access/api/service/PlayService.java index b4b146e..103aac7 100644 --- a/app/src/main/java/com/martinlaizg/geofind/data/access/api/service/PlayService.java +++ b/app/src/main/java/com/martinlaizg/geofind/data/access/api/service/PlayService.java @@ -18,19 +18,18 @@ public class PlayService { - private static RestClient restClient; + private static final String TAG = PlayService.class.getSimpleName(); + private static PlayService instance; - private static PlayService playService; + private RestClient restClient; - private final String TAG = PlayService.class.getSimpleName(); + private PlayService(Application application) { + restClient = RetrofitInstance.getRestClient(application); + } - void instantiate(Application application) { - if(restClient == null) { - restClient = RetrofitInstance.getRestClient(application); - } - if(playService == null) { - playService = new PlayService(); - } + public static PlayService getInstance(Application application) { + if(instance == null) instance = new PlayService(application); + return instance; } /** diff --git a/app/src/main/java/com/martinlaizg/geofind/data/access/api/service/ServiceFactory.java b/app/src/main/java/com/martinlaizg/geofind/data/access/api/service/ServiceFactory.java deleted file mode 100644 index 6b30c2f..0000000 --- a/app/src/main/java/com/martinlaizg/geofind/data/access/api/service/ServiceFactory.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.martinlaizg.geofind.data.access.api.service; - -import android.app.Application; - -public class ServiceFactory { - - private static UserService userService; - private static TourService tourService; - private static PlayService playService; - - public static UserService getUserService(Application application) { - if(userService == null) { - userService = new UserService(); - userService.instantiate(application); - } - return userService; - } - - public static TourService getTourService(Application application) { - if(tourService == null) { - tourService = new TourService(); - tourService.instantiate(application); - } - return tourService; - } - - public static PlayService getPlayService(Application application) { - if(playService == null) { - playService = new PlayService(); - playService.instantiate(application); - } - return playService; - } -} diff --git a/app/src/main/java/com/martinlaizg/geofind/data/access/api/service/TourService.java b/app/src/main/java/com/martinlaizg/geofind/data/access/api/service/TourService.java index ed9dd59..fee64dd 100644 --- a/app/src/main/java/com/martinlaizg/geofind/data/access/api/service/TourService.java +++ b/app/src/main/java/com/martinlaizg/geofind/data/access/api/service/TourService.java @@ -19,17 +19,19 @@ public class TourService { private static RestClient restClient; - private static TourService tourService; + private static TourService instance; private final String TAG = TourService.class.getSimpleName(); - void instantiate(Application application) { + private TourService(Application application) { if(restClient == null) { restClient = RetrofitInstance.getRestClient(application); } - if(tourService == null) { - tourService = new TourService(); - } + } + + public static TourService getInstance(Application application) { + if(instance == null) instance = new TourService(application); + return instance; } /** diff --git a/app/src/main/java/com/martinlaizg/geofind/data/access/api/service/UserService.java b/app/src/main/java/com/martinlaizg/geofind/data/access/api/service/UserService.java index 05b3268..b3221b5 100644 --- a/app/src/main/java/com/martinlaizg/geofind/data/access/api/service/UserService.java +++ b/app/src/main/java/com/martinlaizg/geofind/data/access/api/service/UserService.java @@ -18,14 +18,18 @@ public class UserService { + private static final String TAG = UserService.class.getSimpleName(); + + private static UserService instance; private static RestClient restClient; - private final String TAG = UserService.class.getSimpleName(); + private UserService(Application application) { + restClient = RetrofitInstance.getRestClient(application); + } - void instantiate(Application application) { - if(restClient == null) { - restClient = RetrofitInstance.getRestClient(application); - } + public static UserService getInstance(Application application) { + if(instance == null) instance = new UserService(application); + return instance; } /** diff --git a/app/src/main/java/com/martinlaizg/geofind/data/repository/PlaceRepository.java b/app/src/main/java/com/martinlaizg/geofind/data/repository/PlaceRepository.java index 9f86760..d052e9e 100644 --- a/app/src/main/java/com/martinlaizg/geofind/data/repository/PlaceRepository.java +++ b/app/src/main/java/com/martinlaizg/geofind/data/repository/PlaceRepository.java @@ -10,13 +10,21 @@ public class PlaceRepository { - private static PlaceDAO placeDAO; + private static final String TAG = PlaceRepository.class.getSimpleName(); + private static PlaceRepository instance; - void instantiate(Application application) { + private PlaceDAO placeDAO; + + private PlaceRepository(Application application) { AppDatabase database = AppDatabase.getInstance(application); placeDAO = database.placeDAO(); } + public static PlaceRepository getInstance(Application application) { + if(instance == null) instance = new PlaceRepository(application); + return instance; + } + /** * Insert a List of Place into the database * diff --git a/app/src/main/java/com/martinlaizg/geofind/data/repository/PlayRepository.java b/app/src/main/java/com/martinlaizg/geofind/data/repository/PlayRepository.java index c319872..9566e76 100644 --- a/app/src/main/java/com/martinlaizg/geofind/data/repository/PlayRepository.java +++ b/app/src/main/java/com/martinlaizg/geofind/data/repository/PlayRepository.java @@ -5,7 +5,6 @@ import com.martinlaizg.geofind.data.access.api.error.ErrorType; import com.martinlaizg.geofind.data.access.api.service.PlayService; -import com.martinlaizg.geofind.data.access.api.service.ServiceFactory; import com.martinlaizg.geofind.data.access.api.service.exceptions.APIException; import com.martinlaizg.geofind.data.access.database.AppDatabase; import com.martinlaizg.geofind.data.access.database.dao.PlayDAO; @@ -19,24 +18,30 @@ public class PlayRepository { private static final String TAG = PlayRepository.class.getSimpleName(); + private static PlayRepository instance; - private static PlayDAO playDAO; - private static PlayService playService; + private PlayDAO playDAO; + private PlayService playService; - private static TourRepository tourRepo; - private static UserRepository userRepo; + private TourRepository tourRepo; + private UserRepository userRepo; - private static PlacePlayDAO placePlayDAO; + private PlacePlayDAO placePlayDAO; - void instantiate(Application application) { + private PlayRepository(Application application) { AppDatabase database = AppDatabase.getInstance(application); playDAO = database.playDAO(); - playService = ServiceFactory.getPlayService(application); - placePlayDAO = database.playPlaceDAO(); - tourRepo = RepositoryFactory.getTourRepository(application); - userRepo = RepositoryFactory.getUserRepository(application); + playService = PlayService.getInstance(application); + + tourRepo = TourRepository.getInstance(application); + userRepo = UserRepository.getInstance(application); + } + + public static PlayRepository getInstance(Application application) { + if(instance == null) instance = new PlayRepository(application); + return instance; } /** diff --git a/app/src/main/java/com/martinlaizg/geofind/data/repository/RepositoryFactory.java b/app/src/main/java/com/martinlaizg/geofind/data/repository/RepositoryFactory.java deleted file mode 100644 index a2ff355..0000000 --- a/app/src/main/java/com/martinlaizg/geofind/data/repository/RepositoryFactory.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.martinlaizg.geofind.data.repository; - -import android.app.Application; - -public class RepositoryFactory { - - private static UserRepository userRepository; - private static TourRepository tourRepository; - private static PlaceRepository placeRepository; - private static PlayRepository playRepository; - - public static UserRepository getUserRepository(Application application) { - if(userRepository == null) { - userRepository = new UserRepository(); - userRepository.instantiate(application); - } - return userRepository; - } - - public static TourRepository getTourRepository(Application application) { - if(tourRepository == null) { - tourRepository = new TourRepository(); - tourRepository.instantiate(application); - } - return tourRepository; - } - - public static PlaceRepository getPlaceRepository(Application application) { - if(placeRepository == null) { - placeRepository = new PlaceRepository(); - placeRepository.instantiate(application); - } - return placeRepository; - } - - public static PlayRepository getPlayRepository(Application application) { - if(playRepository == null) { - playRepository = new PlayRepository(); - playRepository.instantiate(application); - } - return playRepository; - } -} diff --git a/app/src/main/java/com/martinlaizg/geofind/data/repository/TourRepository.java b/app/src/main/java/com/martinlaizg/geofind/data/repository/TourRepository.java index 1995817..89488ed 100644 --- a/app/src/main/java/com/martinlaizg/geofind/data/repository/TourRepository.java +++ b/app/src/main/java/com/martinlaizg/geofind/data/repository/TourRepository.java @@ -3,7 +3,6 @@ import android.app.Application; import android.util.Log; -import com.martinlaizg.geofind.data.access.api.service.ServiceFactory; import com.martinlaizg.geofind.data.access.api.service.TourService; import com.martinlaizg.geofind.data.access.api.service.exceptions.APIException; import com.martinlaizg.geofind.data.access.database.AppDatabase; @@ -15,6 +14,7 @@ public class TourRepository { private static final String TAG = TourRepository.class.getSimpleName(); + private static TourRepository instance; private static TourService tourService; private static TourDAO tourDAO; @@ -22,12 +22,18 @@ public class TourRepository { private static PlaceRepository placeRepo; private static UserRepository userRepo; - void instantiate(Application application) { + private TourRepository(Application application) { AppDatabase database = AppDatabase.getInstance(application); tourDAO = database.tourDAO(); - tourService = ServiceFactory.getTourService(application); - placeRepo = RepositoryFactory.getPlaceRepository(application); - userRepo = RepositoryFactory.getUserRepository(application); + tourService = TourService.getInstance(application); + + placeRepo = PlaceRepository.getInstance(application); + userRepo = UserRepository.getInstance(application); + } + + public static TourRepository getInstance(Application application) { + if(instance == null) instance = new TourRepository(application); + return instance; } /** diff --git a/app/src/main/java/com/martinlaizg/geofind/data/repository/UserRepository.java b/app/src/main/java/com/martinlaizg/geofind/data/repository/UserRepository.java index 4ca6066..11a9592 100644 --- a/app/src/main/java/com/martinlaizg/geofind/data/repository/UserRepository.java +++ b/app/src/main/java/com/martinlaizg/geofind/data/repository/UserRepository.java @@ -7,7 +7,6 @@ import com.martinlaizg.geofind.config.Preferences; import com.martinlaizg.geofind.data.access.api.entities.Login; -import com.martinlaizg.geofind.data.access.api.service.ServiceFactory; import com.martinlaizg.geofind.data.access.api.service.UserService; import com.martinlaizg.geofind.data.access.api.service.exceptions.APIException; import com.martinlaizg.geofind.data.access.database.AppDatabase; @@ -16,15 +15,23 @@ public class UserRepository { + private static final String TAG = UserRepository.class.getSimpleName(); + private static UserRepository instance; + private static UserDAO userDAO; private static UserService userService; private static SharedPreferences sp; - void instantiate(Application application) { + private UserRepository(Application application) { AppDatabase database = AppDatabase.getInstance(application); userDAO = database.userDAO(); - userService = ServiceFactory.getUserService(application); - sp = PreferenceManager.getDefaultSharedPreferences(application.getApplicationContext()); + userService = UserService.getInstance(application); + sp = PreferenceManager.getDefaultSharedPreferences(application); + } + + public static UserRepository getInstance(Application application) { + if(instance == null) instance = new UserRepository(application); + return instance; } /** @@ -125,4 +132,8 @@ public User login(Login login) throws APIException { } return user; } + + public static UserRepository getInstance() { + return instance; + } } diff --git a/app/src/main/java/com/martinlaizg/geofind/views/activity/MainActivity.java b/app/src/main/java/com/martinlaizg/geofind/views/activity/MainActivity.java index 4f14ffe..e9a8f4c 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/activity/MainActivity.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/activity/MainActivity.java @@ -2,11 +2,13 @@ import android.content.SharedPreferences; import android.os.Bundle; +import android.os.PersistableBundle; import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import androidx.drawerlayout.widget.DrawerLayout; @@ -21,6 +23,7 @@ import com.martinlaizg.geofind.config.Preferences; import com.martinlaizg.geofind.data.access.api.RetrofitInstance; import com.martinlaizg.geofind.data.access.database.entities.User; +import com.martinlaizg.geofind.data.repository.UserRepository; import com.squareup.picasso.Picasso; import java.util.HashSet; @@ -92,6 +95,13 @@ private void setServicesToken(String token) { RetrofitInstance.setToken(token); } + @Override + public void onCreate(@Nullable Bundle savedInstanceState, + @Nullable PersistableBundle persistentState) { + super.onCreate(savedInstanceState, persistentState); + UserRepository.getInstance(getApplication()); + } + @Override protected void onPause() { super.onPause(); diff --git a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/CreatorViewModel.java b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/CreatorViewModel.java index 461db00..d52332b 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/CreatorViewModel.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/CreatorViewModel.java @@ -10,7 +10,6 @@ import com.martinlaizg.geofind.data.access.database.entities.Place; import com.martinlaizg.geofind.data.access.database.entities.Tour; import com.martinlaizg.geofind.data.enums.PlayLevel; -import com.martinlaizg.geofind.data.repository.RepositoryFactory; import com.martinlaizg.geofind.data.repository.TourRepository; import java.util.ArrayList; @@ -25,7 +24,7 @@ public class CreatorViewModel public CreatorViewModel(@NonNull Application application) { super(application); - tourRepo = RepositoryFactory.getTourRepository(application); + tourRepo = TourRepository.getInstance(application); } public MutableLiveData createTour() { diff --git a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/EditProfileViewModel.java b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/EditProfileViewModel.java index 3026100..75224b7 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/EditProfileViewModel.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/EditProfileViewModel.java @@ -8,7 +8,6 @@ import com.martinlaizg.geofind.data.access.api.entities.Login; import com.martinlaizg.geofind.data.access.api.service.exceptions.APIException; import com.martinlaizg.geofind.data.access.database.entities.User; -import com.martinlaizg.geofind.data.repository.RepositoryFactory; import com.martinlaizg.geofind.data.repository.UserRepository; public class EditProfileViewModel @@ -19,7 +18,7 @@ public class EditProfileViewModel public EditProfileViewModel(Application application) { super(application); - userRepo = RepositoryFactory.getUserRepository(application); + userRepo = UserRepository.getInstance(application); } public MutableLiveData updateUser(Login login, User user) { diff --git a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/LoginViewModel.java b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/LoginViewModel.java index 15d039f..487c96b 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/LoginViewModel.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/LoginViewModel.java @@ -8,7 +8,6 @@ import com.martinlaizg.geofind.data.access.api.entities.Login; import com.martinlaizg.geofind.data.access.api.service.exceptions.APIException; import com.martinlaizg.geofind.data.access.database.entities.User; -import com.martinlaizg.geofind.data.repository.RepositoryFactory; import com.martinlaizg.geofind.data.repository.UserRepository; public class LoginViewModel @@ -19,7 +18,7 @@ public class LoginViewModel public LoginViewModel(Application application) { super(application); - userRepo = RepositoryFactory.getUserRepository(application); + userRepo = UserRepository.getInstance(application); } public MutableLiveData login(Login login) { diff --git a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/MainFragmentViewModel.java b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/MainFragmentViewModel.java index 0037199..baac957 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/MainFragmentViewModel.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/MainFragmentViewModel.java @@ -9,7 +9,6 @@ import com.martinlaizg.geofind.data.access.api.service.exceptions.APIException; import com.martinlaizg.geofind.data.access.database.entities.Play; import com.martinlaizg.geofind.data.repository.PlayRepository; -import com.martinlaizg.geofind.data.repository.RepositoryFactory; import java.util.List; @@ -23,7 +22,7 @@ public class MainFragmentViewModel public MainFragmentViewModel(@NonNull Application application) { super(application); - playRepo = RepositoryFactory.getPlayRepository(application); + playRepo = PlayRepository.getInstance(application); } public APIException getError() { diff --git a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/PlayTourViewModel.java b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/PlayTourViewModel.java index 9b27310..398d701 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/PlayTourViewModel.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/PlayTourViewModel.java @@ -10,7 +10,6 @@ import com.martinlaizg.geofind.data.access.database.entities.Place; import com.martinlaizg.geofind.data.access.database.entities.Play; import com.martinlaizg.geofind.data.repository.PlayRepository; -import com.martinlaizg.geofind.data.repository.RepositoryFactory; public class PlayTourViewModel extends AndroidViewModel { @@ -22,7 +21,7 @@ public class PlayTourViewModel public PlayTourViewModel(@NonNull Application application) { super(application); - playRepo = RepositoryFactory.getPlayRepository(application); + playRepo = PlayRepository.getInstance(application); } public MutableLiveData loadPlay(int user_id, int tour_id) { diff --git a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/SettingsViewModel.java b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/SettingsViewModel.java index 09bac90..30a1247 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/SettingsViewModel.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/SettingsViewModel.java @@ -7,7 +7,6 @@ import androidx.lifecycle.MutableLiveData; import com.martinlaizg.geofind.data.access.api.service.exceptions.APIException; -import com.martinlaizg.geofind.data.repository.RepositoryFactory; import com.martinlaizg.geofind.data.repository.UserRepository; public class SettingsViewModel @@ -20,7 +19,7 @@ public class SettingsViewModel public SettingsViewModel(Application application) { super(application); - userRepo = RepositoryFactory.getUserRepository(application); + userRepo = UserRepository.getInstance(application); } public APIException getError() { diff --git a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/TourListViewModel.java b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/TourListViewModel.java index 6f54e23..7575a67 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/TourListViewModel.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/TourListViewModel.java @@ -8,7 +8,6 @@ import com.martinlaizg.geofind.data.access.api.service.exceptions.APIException; import com.martinlaizg.geofind.data.access.database.entities.Tour; -import com.martinlaizg.geofind.data.repository.RepositoryFactory; import com.martinlaizg.geofind.data.repository.TourRepository; import java.util.List; @@ -23,7 +22,7 @@ public class TourListViewModel public TourListViewModel(@NonNull Application application) { super(application); - tourRepo = RepositoryFactory.getTourRepository(application); + tourRepo = TourRepository.getInstance(application); } public MutableLiveData> getTours() { diff --git a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/TourViewModel.java b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/TourViewModel.java index 3477e1c..5b7b2d3 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/TourViewModel.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/TourViewModel.java @@ -11,7 +11,6 @@ import com.martinlaizg.geofind.data.access.database.entities.Play; import com.martinlaizg.geofind.data.access.database.entities.Tour; import com.martinlaizg.geofind.data.repository.PlayRepository; -import com.martinlaizg.geofind.data.repository.RepositoryFactory; import com.martinlaizg.geofind.data.repository.TourRepository; import java.util.ArrayList; @@ -29,8 +28,8 @@ public class TourViewModel public TourViewModel(@NonNull Application application) { super(application); - tourRepo = RepositoryFactory.getTourRepository(application); - playRepo = RepositoryFactory.getPlayRepository(application); + tourRepo = TourRepository.getInstance(application); + playRepo = PlayRepository.getInstance(application); } public MutableLiveData getTour(int tour_id, int user_id) { diff --git a/app/src/test/java/com/martinlaizg/geofind/data/repository/TourRepositoryTest.java b/app/src/test/java/com/martinlaizg/geofind/data/repository/TourRepositoryTest.java new file mode 100644 index 0000000..76036bd --- /dev/null +++ b/app/src/test/java/com/martinlaizg/geofind/data/repository/TourRepositoryTest.java @@ -0,0 +1,74 @@ +package com.martinlaizg.geofind.data.repository; + +import android.app.Application; + +import com.martinlaizg.geofind.data.access.api.service.exceptions.APIException; +import com.martinlaizg.geofind.data.access.database.AppDatabase; +import com.martinlaizg.geofind.data.access.database.dao.TourDAO; +import com.martinlaizg.geofind.data.access.database.entities.Tour; +import com.martinlaizg.geofind.data.enums.PlayLevel; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class TourRepositoryTest { + + @Mock + private TourDAO tourDAO; + @Mock + private AppDatabase appDatabase; + @Mock + private Application application; + + private TourRepository repository; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @Test + public void getTourTest() { + repository = RepositoryFactory.getTourRepository(application); + Integer tour_id = 1; + String tour_name = ""; + String tourDescription = ""; + PlayLevel minLevel = PlayLevel.COMPASS; + Integer creatorId = 1; + Tour expectedTour = new Tour(tour_id, tour_name, tourDescription, minLevel, null, null, + creatorId, null); + when(tourDAO.getTour(tour_id)).thenReturn(expectedTour); + when(appDatabase.tourDAO()).thenReturn(tourDAO); + + Tour actualTour = null; + try { + actualTour = repository.getTour(tour_id); + } catch(APIException e) { + fail("Exception throwed"); + } + assertEquals(expectedTour, actualTour); + } + + // public Tour getTour(Integer id) throws APIException { + // Tour t = tourDAO.getTour(id); + // if(t == null) { + // t = tourService.getTour(id); + // insert(t); + // } else { + // t.setCreator(userRepo.getUser(t.getCreator_id())); + // t.setPlaces(placeRepo.getTourPlaces(id)); + // } + // return t; + // } + +} + From ad4cc6a130c14b3a38fe5a8a3b7fdd2050e506f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Laiz=20G=C3=B3mez?= Date: Mon, 5 Aug 2019 23:34:30 +0200 Subject: [PATCH 06/32] Stage Cambiando orden del del creador de tours --- .../data/access/database/entities/Tour.java | 1 + .../fragment/creator/CreateTourFragment.java | 57 +++++++++------ .../fragment/creator/CreatorFragment.java | 71 ++++++++----------- .../views/fragment/list/TourListFragment.java | 1 - .../views/viewmodel/CreatorViewModel.java | 46 ++++++------ .../main/res/navigation/main_navigation.xml | 8 +-- app/src/main/res/values-en/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 8 files changed, 96 insertions(+), 90 deletions(-) diff --git a/app/src/main/java/com/martinlaizg/geofind/data/access/database/entities/Tour.java b/app/src/main/java/com/martinlaizg/geofind/data/access/database/entities/Tour.java index 9668ad3..4c7e5e0 100644 --- a/app/src/main/java/com/martinlaizg/geofind/data/access/database/entities/Tour.java +++ b/app/src/main/java/com/martinlaizg/geofind/data/access/database/entities/Tour.java @@ -56,6 +56,7 @@ public Tour() { id = 0; name = ""; description = ""; + min_level = PlayLevel.MAP; places = new ArrayList<>(); } diff --git a/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreateTourFragment.java b/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreateTourFragment.java index 365465d..09fc44b 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreateTourFragment.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreateTourFragment.java @@ -22,6 +22,7 @@ import com.google.android.material.textfield.TextInputLayout; import com.martinlaizg.geofind.R; import com.martinlaizg.geofind.config.Preferences; +import com.martinlaizg.geofind.data.access.api.error.ErrorType; import com.martinlaizg.geofind.data.access.database.entities.Tour; import com.martinlaizg.geofind.data.access.database.entities.User; import com.martinlaizg.geofind.data.enums.PlayLevel; @@ -37,7 +38,8 @@ public class CreateTourFragment extends Fragment implements View.OnClickListener { - private final static String TAG = CreateTourFragment.class.getSimpleName(); + public static final String TOUR_ID = "TOUR_ID"; + private static final String TAG = CreateTourFragment.class.getSimpleName(); @BindView(R.id.tour_name_layout) TextInputLayout tour_name_layout; @@ -61,31 +63,19 @@ public View onCreateView(@NonNull final LayoutInflater inflater, final ViewGroup final Bundle savedInstanceState) { final View view = inflater.inflate(R.layout.fragment_create_tour, container, false); ButterKnife.bind(this, view); + viewModel = ViewModelProviders.of(requireActivity()).get(CreatorViewModel.class); return view; } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - viewModel = ViewModelProviders.of(requireActivity()).get(CreatorViewModel.class); - Tour t = viewModel.getTour(); - if(t != null) { - if(!t.getName().isEmpty()) { - Objects.requireNonNull(tour_name_layout.getEditText()).setText(t.getName()); - } - if(!t.getDescription().isEmpty()) { - Objects.requireNonNull(tour_description_layout.getEditText()) - .setText(t.getDescription()); - } - if(t.getMin_level() != null) { - difficulty_spinner.setSelection(t.getMin_level().ordinal()); - } - tour_image_view.setVisibility(View.GONE); - if(t.getImage() != null) image_url = t.getImage(); - if(!image_url.isEmpty()) { - Picasso.with(requireContext()).load(image_url).into(tour_image_view); - tour_image_view.setVisibility(View.VISIBLE); - } + Bundle b = getArguments(); + int tour_id = 0; + if(b != null) { + tour_id = b.getInt(TOUR_ID); } + viewModel.getTour(tour_id).observe(requireActivity(), this::setTour); + done_button.setOnClickListener(this); add_image_button.setOnClickListener(v -> { AlertDialog alertDialog = buildDialog(); @@ -93,6 +83,33 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat }); } + private void setTour(Tour tour) { + if(tour == null) { + ErrorType error = viewModel.getError(); + if(error == ErrorType.EXIST) { + Navigation.findNavController(requireActivity(), R.id.main_fragment_holder) + .popBackStack(); + } + return; + } + Objects.requireNonNull(tour_name_layout.getEditText()).setText(tour.getName()); + + Objects.requireNonNull(tour_description_layout.getEditText()) + .setText(tour.getDescription()); + + difficulty_spinner.setSelection(tour.getMin_level().ordinal()); + + tour_image_view.setVisibility(View.GONE); + if(tour.getImage() != null) image_url = tour.getImage(); + if(!image_url.isEmpty()) { + Picasso.with(requireContext()).load(image_url).into(tour_image_view); + tour_image_view.setVisibility(View.VISIBLE); + } + if(tour.getId() > 0) { + done_button.setText(getString(R.string.update)); + } + } + private AlertDialog buildDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); // Get the layout inflater diff --git a/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatorFragment.java b/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatorFragment.java index be3cf97..d0af7b5 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatorFragment.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatorFragment.java @@ -17,14 +17,12 @@ import com.google.android.material.button.MaterialButton; import com.martinlaizg.geofind.R; -import com.martinlaizg.geofind.data.access.api.service.exceptions.APIException; +import com.martinlaizg.geofind.data.access.api.error.ErrorType; import com.martinlaizg.geofind.data.access.database.entities.Tour; import com.martinlaizg.geofind.views.adapter.CreatorPlacesAdapter; import com.martinlaizg.geofind.views.fragment.single.TourFragment; import com.martinlaizg.geofind.views.viewmodel.CreatorViewModel; -import java.util.Objects; - import butterknife.BindView; import butterknife.ButterKnife; @@ -58,22 +56,22 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_creator, container, false); ButterKnife.bind(this, view); - return view; - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { viewModel = ViewModelProviders.of(requireActivity()).get(CreatorViewModel.class); adapter = new CreatorPlacesAdapter(); places_list.setLayoutManager(new LinearLayoutManager(requireActivity())); places_list.setAdapter(adapter); + return view; + } - // Load tour + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { Bundle b = getArguments(); - int tour_id = Objects.requireNonNull(b).getInt(TOUR_ID); - viewModel.loadTour(tour_id).observe(this, this::setTour); + int tour_id = 0; + if(b != null) { + tour_id = b.getInt(TOUR_ID); + } + viewModel.getTour(tour_id).observe(this, this::setTour); - // set buttons add_place_button.setOnClickListener(v -> { Bundle p = new Bundle(); p.putInt(CreatePlaceFragment.PLACE_POSITION, viewModel.getPlaces().size()); @@ -87,45 +85,34 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat } private void setTour(Tour tour) { - if(tour != null) { - adapter.setPlaces(requireActivity(), tour.getPlaces()); - if(tour.getId() != 0) { - create_tour_button.setText(R.string.update_tour); - } - if(tour.getName().isEmpty()) { - tour_name.setText(getString(R.string.click_edit)); - } else { - tour_name.setText(tour.getName()); - } - if(tour.getDescription().isEmpty()) { - tour_description.setText(getResources().getString(R.string.without_decription)); - } else { - tour_description.setText(tour.getDescription()); - } + if(tour == null) { + ErrorType error = viewModel.getError(); + return; + } + adapter.setPlaces(requireActivity(), tour.getPlaces()); + if(tour.getId() != 0) { + create_tour_button.setText(R.string.update_tour); + } + if(tour.getName().isEmpty()) { + tour_name.setText(getString(R.string.click_edit)); + } else { + tour_name.setText(tour.getName()); + } + if(tour.getDescription().isEmpty()) { + tour_description.setText(getResources().getString(R.string.without_decription)); + } else { + tour_description.setText(tour.getDescription()); } - } - - @Override - public void onDetach() { - super.onDetach(); - // reset the view model - if(viewModel != null) viewModel.reset(); } @Override public void onClick(View v) { - if(viewModel.getTour().getPlaces().isEmpty()) { - Toast.makeText(requireContext(), getString(R.string.at_least_one_place), - Toast.LENGTH_SHORT).show(); - return; - } create_tour_button.setEnabled(false); viewModel.createTour().observe(this, tour -> { create_tour_button.setEnabled(true); if(tour == null) { - APIException err = viewModel.getError(); - Toast.makeText(requireActivity(), err.getType().toString(), Toast.LENGTH_LONG) - .show(); + ErrorType err = viewModel.getError(); + Toast.makeText(requireActivity(), err.toString(), Toast.LENGTH_LONG).show(); Navigation.findNavController(requireActivity(), R.id.main_fragment_holder) .popBackStack(R.id.navTourList, false); return; diff --git a/app/src/main/java/com/martinlaizg/geofind/views/fragment/list/TourListFragment.java b/app/src/main/java/com/martinlaizg/geofind/views/fragment/list/TourListFragment.java index 16e3b7d..a7a0935 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/fragment/list/TourListFragment.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/fragment/list/TourListFragment.java @@ -54,7 +54,6 @@ public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) { final View view = inflater.inflate(R.layout.fragment_tour_list, container, false); ButterKnife.bind(this, view); - tour_list.setLayoutManager(new LinearLayoutManager(requireActivity())); adapter = new TourListAdapter(); tour_list.setAdapter(adapter); diff --git a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/CreatorViewModel.java b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/CreatorViewModel.java index d52332b..0e533d2 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/CreatorViewModel.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/CreatorViewModel.java @@ -6,6 +6,7 @@ import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.MutableLiveData; +import com.martinlaizg.geofind.data.access.api.error.ErrorType; import com.martinlaizg.geofind.data.access.api.service.exceptions.APIException; import com.martinlaizg.geofind.data.access.database.entities.Place; import com.martinlaizg.geofind.data.access.database.entities.Tour; @@ -20,7 +21,7 @@ public class CreatorViewModel private final TourRepository tourRepo; private Tour tour; - private APIException error; + private ErrorType error; public CreatorViewModel(@NonNull Application application) { super(application); @@ -34,7 +35,7 @@ public MutableLiveData createTour() { try { tour = tourRepo.create(tour); } catch(APIException e) { - setError(e); + setError(e.getType()); m.postValue(null); return; } @@ -42,7 +43,7 @@ public MutableLiveData createTour() { try { tour = tourRepo.update(tour); } catch(APIException e) { - setError(e); + setError(e.getType()); m.postValue(null); return; } @@ -62,18 +63,25 @@ public void updateTour(String name, String description, Integer creator_id, Play tour.setImage(image_url); } - public MutableLiveData loadTour(Integer tour_id) { + public MutableLiveData getTour(int tour_id) { + MutableLiveData t = new MutableLiveData<>(); + if(tour == null || tour.getId() != tour_id) { + return loadTour(tour_id); + } + new Thread(() -> t.postValue(tour)); + return t; + } + + private MutableLiveData loadTour(Integer tour_id) { MutableLiveData t = new MutableLiveData<>(); new Thread(() -> { - if(tour == null) { - tour = new Tour(); - if(tour_id > 0) { - try { - tour = tourRepo.getTour(tour_id); - } catch(APIException e) { - setError(e); - tour = null; - } + tour = new Tour(); + if(tour_id > 0) { + try { + tour = tourRepo.getTour(tour_id); + } catch(APIException e) { + setError(e.getType()); + tour = null; } } t.postValue(tour); @@ -81,15 +89,11 @@ public MutableLiveData loadTour(Integer tour_id) { return t; } - public Tour getTour() { - return tour; - } - - public APIException getError() { + public ErrorType getError() { return error; } - private void setError(APIException error) { + private void setError(ErrorType error) { this.error = error; } @@ -115,8 +119,4 @@ public void setPlace(Place place) { } } - public void reset() { - tour = null; - } - } diff --git a/app/src/main/res/navigation/main_navigation.xml b/app/src/main/res/navigation/main_navigation.xml index 73f4e70..9f74f4a 100644 --- a/app/src/main/res/navigation/main_navigation.xml +++ b/app/src/main/res/navigation/main_navigation.xml @@ -32,6 +32,9 @@ android:name="TOUR_ID" android:defaultValue="0" app:argType="integer" /> + - + app:destination="@+id/navCreateTour" /> diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index 15c7568..4c89227 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -107,4 +107,5 @@ App developer Add image URL Image URL + Update \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 46ffb31..6a7f7ce 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -116,4 +116,5 @@ %1$d/%2$d Add image URL Image URL + Update From 28c97904aa50348c5e1a719835467698f01d5ebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Laiz=20G=C3=B3mez?= Date: Thu, 8 Aug 2019 22:24:17 +0200 Subject: [PATCH 07/32] Multiples cambios MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cambiado orden de pantallas de creación de un tour #16 Mostrado dialogo de confirmación al salir del creador sin guardar (solo al darle al botón de atrás) #67 --- app/build.gradle | 9 ++--- .../data/access/api/RetrofitInstance.java | 3 +- .../data/access/database/entities/Place.java | 2 ++ .../fragment/creator/CreatePlaceFragment.java | 28 +++++++++++++++ .../fragment/creator/CreateTourFragment.java | 35 +++++++++++++++++-- .../fragment/creator/CreatorFragment.java | 25 +++++++++++++ .../views/fragment/play/PlayTourFragment.java | 23 ++++++------ .../views/viewmodel/CreatorViewModel.java | 6 +++- .../main/res/layout/fragment_create_tour.xml | 1 + .../main/res/navigation/main_navigation.xml | 5 +-- app/src/main/res/values-en/strings.xml | 2 ++ app/src/main/res/values-es/strings.xml | 3 ++ app/src/main/res/values/strings.xml | 2 ++ 13 files changed, 120 insertions(+), 24 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d1bcbe3..9b2350b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -47,6 +47,7 @@ dependencies { // // AndroidX implementation 'androidx.appcompat:appcompat:1.0.2' + implementation 'androidx.activity:activity:1.1.0-alpha02' testImplementation 'androidx.arch.core:core-testing:2.0.1' implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' @@ -60,9 +61,9 @@ dependencies { implementation 'androidx.lifecycle:lifecycle-reactivestreams:2.0.0' annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.0.0' // Navigation - implementation 'androidx.navigation:navigation-common:2.0.0' - implementation 'androidx.navigation:navigation-fragment:2.0.0' - implementation 'androidx.navigation:navigation-ui:2.0.0' + implementation 'androidx.navigation:navigation-common:2.1.0-beta02' + implementation 'androidx.navigation:navigation-fragment:2.1.0-beta02' + implementation 'androidx.navigation:navigation-ui:2.1.0-beta02' implementation 'androidx.preference:preference:1.0.0' // Room implementation 'androidx.room:room-runtime:2.1.0' @@ -78,7 +79,7 @@ dependencies { // // Google Material - implementation 'com.google.android.material:material:1.0.0' + implementation 'com.google.android.material:material:1.1.0-alpha09' // Android Test androidTestImplementation 'androidx.test:core:1.2.0' diff --git a/app/src/main/java/com/martinlaizg/geofind/data/access/api/RetrofitInstance.java b/app/src/main/java/com/martinlaizg/geofind/data/access/api/RetrofitInstance.java index 7e83678..a9b0c4d 100644 --- a/app/src/main/java/com/martinlaizg/geofind/data/access/api/RetrofitInstance.java +++ b/app/src/main/java/com/martinlaizg/geofind/data/access/api/RetrofitInstance.java @@ -21,8 +21,7 @@ public class RetrofitInstance { - // private static final String BASE_URL = "https://geofind1.herokuapp.com/api/"; - private static final String BASE_URL = "http://192.168.1.36:8000/api/"; + private static final String BASE_URL = "https://geofind1.herokuapp.com/api/"; private static final String TAG = RetrofitInstance.class.getSimpleName(); diff --git a/app/src/main/java/com/martinlaizg/geofind/data/access/database/entities/Place.java b/app/src/main/java/com/martinlaizg/geofind/data/access/database/entities/Place.java index d22f632..2bbc80b 100644 --- a/app/src/main/java/com/martinlaizg/geofind/data/access/database/entities/Place.java +++ b/app/src/main/java/com/martinlaizg/geofind/data/access/database/entities/Place.java @@ -56,6 +56,8 @@ public Place(Integer id, String name, Double lat, Double lon, Integer tour_id, @Ignore public Place() { id = 0; + this.name = ""; + this.description = ""; } public int getId() { diff --git a/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatePlaceFragment.java b/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatePlaceFragment.java index e825635..48d523a 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatePlaceFragment.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatePlaceFragment.java @@ -20,6 +20,7 @@ import android.widget.TextView; import android.widget.Toast; +import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.constraintlayout.widget.ConstraintLayout; @@ -34,6 +35,7 @@ import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MarkerOptions; import com.google.android.material.button.MaterialButton; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.textfield.TextInputLayout; import com.martinlaizg.geofind.R; import com.martinlaizg.geofind.data.access.database.entities.Place; @@ -95,6 +97,14 @@ public class CreatePlaceFragment @Override public void onClick(View v) { + // Hide the keyboard + InputMethodManager editTextInput = (InputMethodManager) requireActivity() + .getSystemService(Context.INPUT_METHOD_SERVICE); + View currentFocus = requireActivity().getCurrentFocus(); + if(currentFocus != null) { + editTextInput.hideSoftInputFromWindow(currentFocus.getWindowToken(), 0); + } + alert_no_place_text.setVisibility(View.INVISIBLE); Place place = getPlace(); if(place == null) return; @@ -293,6 +303,15 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, new_place_map_view.onCreate(savedInstanceState); new_place_map_view.onResume(); new_place_map_view.getMapAsync(this); + + // Back button listener + requireActivity().getOnBackPressedDispatcher() + .addCallback(this, new OnBackPressedCallback(true) { + @Override + public void handleOnBackPressed() { + showExitDialog(); + } + }); return view; } @@ -396,4 +415,13 @@ public void onMapLongClick(LatLng latLng) { marker = m; } + + private void showExitDialog() { + new MaterialAlertDialogBuilder(requireContext()).setTitle(R.string.are_you_sure) + .setMessage(getString(R.string.exit_lose_data_alert)) + .setPositiveButton(getString(R.string.ok), (dialog, which) -> { + Navigation.findNavController(requireActivity(), R.id.main_fragment_holder) + .popBackStack(); + }).show(); + } } diff --git a/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreateTourFragment.java b/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreateTourFragment.java index 09fc44b..84316fe 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreateTourFragment.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreateTourFragment.java @@ -3,6 +3,7 @@ import android.app.AlertDialog; import android.content.Context; import android.os.Bundle; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -11,6 +12,7 @@ import android.widget.LinearLayout; import android.widget.Spinner; +import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; @@ -19,6 +21,7 @@ import androidx.preference.PreferenceManager; import com.google.android.material.button.MaterialButton; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.textfield.TextInputLayout; import com.martinlaizg.geofind.R; import com.martinlaizg.geofind.config.Preferences; @@ -64,9 +67,25 @@ public View onCreateView(@NonNull final LayoutInflater inflater, final ViewGroup final View view = inflater.inflate(R.layout.fragment_create_tour, container, false); ButterKnife.bind(this, view); viewModel = ViewModelProviders.of(requireActivity()).get(CreatorViewModel.class); + OnBackPressedCallback callback = new OnBackPressedCallback(true) { + @Override + public void handleOnBackPressed() { + showExitDialog(); + } + }; + requireActivity().getOnBackPressedDispatcher().addCallback(this, callback); return view; } + private void showExitDialog() { + new MaterialAlertDialogBuilder(requireContext()).setTitle(R.string.are_you_sure) + .setMessage(getString(R.string.exit_lose_data_alert)) + .setPositiveButton(getString(R.string.ok), (dialog, which) -> { + Navigation.findNavController(requireActivity(), R.id.main_fragment_holder) + .popBackStack(); + }).show(); + } + @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { Bundle b = getArguments(); @@ -74,7 +93,8 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat if(b != null) { tour_id = b.getInt(TOUR_ID); } - viewModel.getTour(tour_id).observe(requireActivity(), this::setTour); + Log.i(TAG, "onViewCreated: Get tour with id = " + tour_id); + viewModel.getTour(tour_id).observe(this, this::setTour); done_button.setOnClickListener(this); add_image_button.setOnClickListener(v -> { @@ -86,6 +106,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat private void setTour(Tour tour) { if(tour == null) { ErrorType error = viewModel.getError(); + Log.e(TAG, "setTour: Error getting the tour" + error.toString()); if(error == ErrorType.EXIST) { Navigation.findNavController(requireActivity(), R.id.main_fragment_holder) .popBackStack(); @@ -138,6 +159,14 @@ private AlertDialog buildDialog() { @Override public void onClick(View v) { + // Hide the keyboard + InputMethodManager editTextInput = (InputMethodManager) requireActivity() + .getSystemService(Context.INPUT_METHOD_SERVICE); + View currentFocus = requireActivity().getCurrentFocus(); + if(currentFocus != null) { + editTextInput.hideSoftInputFromWindow(currentFocus.getWindowToken(), 0); + } + tour_name_layout.setError(""); String name = Objects.requireNonNull(tour_name_layout.getEditText()).getText().toString() .trim(); @@ -166,6 +195,8 @@ public void onClick(View v) { User user = Preferences .getLoggedUser(PreferenceManager.getDefaultSharedPreferences(requireContext())); viewModel.updateTour(name, description, user.getId(), pl, image_url); - Navigation.findNavController(requireActivity(), R.id.main_fragment_holder).popBackStack(); + Navigation.findNavController(requireActivity(), R.id.main_fragment_holder) + .navigate(R.id.toEditTour); } + } diff --git a/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatorFragment.java b/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatorFragment.java index d0af7b5..9722f28 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatorFragment.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatorFragment.java @@ -7,6 +7,7 @@ import android.widget.TextView; import android.widget.Toast; +import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; @@ -16,6 +17,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.button.MaterialButton; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.martinlaizg.geofind.R; import com.martinlaizg.geofind.data.access.api.error.ErrorType; import com.martinlaizg.geofind.data.access.database.entities.Tour; @@ -60,9 +62,26 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, adapter = new CreatorPlacesAdapter(); places_list.setLayoutManager(new LinearLayoutManager(requireActivity())); places_list.setAdapter(adapter); + // Back button callback + OnBackPressedCallback callback = new OnBackPressedCallback(true) { + @Override + public void handleOnBackPressed() { + showExitDialog(); + } + }; + requireActivity().getOnBackPressedDispatcher().addCallback(this, callback); return view; } + private void showExitDialog() { + new MaterialAlertDialogBuilder(requireContext()).setTitle(R.string.are_you_sure) + .setMessage(getString(R.string.exit_lose_data_alert)) + .setPositiveButton(getString(R.string.ok), (dialog, which) -> { + Navigation.findNavController(requireActivity(), R.id.main_fragment_holder) + .popBackStack(); + }).show(); + } + @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { Bundle b = getArguments(); @@ -105,6 +124,12 @@ private void setTour(Tour tour) { } } + @Override + public void onDestroy() { + super.onDestroy(); + viewModel.reset(); + } + @Override public void onClick(View v) { create_tour_button.setEnabled(false); diff --git a/app/src/main/java/com/martinlaizg/geofind/views/fragment/play/PlayTourFragment.java b/app/src/main/java/com/martinlaizg/geofind/views/fragment/play/PlayTourFragment.java index 99dbeb8..9945016 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/fragment/play/PlayTourFragment.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/fragment/play/PlayTourFragment.java @@ -23,6 +23,7 @@ import androidx.navigation.Navigation; import com.google.android.material.button.MaterialButton; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.martinlaizg.geofind.R; import com.martinlaizg.geofind.config.Preferences; import com.martinlaizg.geofind.data.access.api.service.exceptions.APIException; @@ -174,7 +175,7 @@ public void onLocationChanged(@NonNull Location location) { // If has question display if(place != null && place.getQuestion() != null && !place.getQuestion().isEmpty()) { - createDialog(place); + showQuestionDialog(place); questionDialog.show(); } else { completePlace(); @@ -207,16 +208,11 @@ private void completePlace() { viewModel.completePlace(place.getId()).observe(this, place -> { if(place == null) { if(viewModel.tourIsCompleted()) { - AlertDialog.Builder questionDialogBuilder = new AlertDialog.Builder( - requireContext()).setTitle(R.string.tour_completed); - questionDialogBuilder.setPositiveButton(R.string.ok, - (dialog, which) -> Navigation - .findNavController( - requireActivity(), - R.id.main_fragment_holder) - .popBackStack(R.id.navTour, - false)); - questionDialogBuilder.show(); + new MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.tour_completed) // + .setPositiveButton(R.string.ok, (dialog, which) -> Navigation + .findNavController(requireActivity(), R.id.main_fragment_holder) + .popBackStack(R.id.navTour, false)).show(); return; } APIException error = viewModel.getError(); @@ -243,8 +239,9 @@ PackageManager.PERMISSION_GRANTED && requireActivity() } @SuppressLint("MissingPermission") - private void createDialog(Place place) { - AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(requireContext()); + private void showQuestionDialog(Place place) { + AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(requireContext()); + View dialogView = getLayoutInflater() .inflate(R.layout.question_layout, new ConstraintLayout(requireContext()), false); TextView question = dialogView.findViewById(R.id.question); diff --git a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/CreatorViewModel.java b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/CreatorViewModel.java index 0e533d2..fdf4011 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/CreatorViewModel.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/CreatorViewModel.java @@ -68,7 +68,7 @@ public MutableLiveData getTour(int tour_id) { if(tour == null || tour.getId() != tour_id) { return loadTour(tour_id); } - new Thread(() -> t.postValue(tour)); + new Thread(() -> t.postValue(tour)).start(); return t; } @@ -119,4 +119,8 @@ public void setPlace(Place place) { } } + public void reset() { + this.tour = null; + this.error = null; + } } diff --git a/app/src/main/res/layout/fragment_create_tour.xml b/app/src/main/res/layout/fragment_create_tour.xml index e2c8656..60f996d 100644 --- a/app/src/main/res/layout/fragment_create_tour.xml +++ b/app/src/main/res/layout/fragment_create_tour.xml @@ -106,6 +106,7 @@ + app:destination="@+id/navCreator" + app:popUpTo="@+id/navCreateTour" + app:popUpToInclusive="true" /> Add image URL Image URL Update + Are you sure? + You will lose the unsaved data \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 8e92c01..18f3059 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -107,4 +107,7 @@ Version de la aplicación Añade URL de imagen URL de la imagen + ¿Estás seguro? + Perderás todos los datos no guardados + Actualizar \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6a7f7ce..cc71236 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -117,4 +117,6 @@ Add image URL Image URL Update + Are you sure? + You will lose the unsaved data From 6e48be085cab699239e2baa3eb2ca494eccddc60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Laiz=20G=C3=B3mez?= Date: Sun, 11 Aug 2019 13:03:45 +0200 Subject: [PATCH 08/32] Quitada sugerecia de nombre de creador de tour --- app/src/main/res/layout/fragment_create_tour.xml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/layout/fragment_create_tour.xml b/app/src/main/res/layout/fragment_create_tour.xml index 60f996d..36c6c78 100644 --- a/app/src/main/res/layout/fragment_create_tour.xml +++ b/app/src/main/res/layout/fragment_create_tour.xml @@ -52,7 +52,8 @@ + android:inputType="textNoSuggestions|textCapSentences" + android:singleLine="true" /> From 49e3b743bc822fc518107d090c422c42ead4879e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Laiz=20G=C3=B3mez?= Date: Mon, 12 Aug 2019 18:41:26 +0200 Subject: [PATCH 09/32] Stage --- .../data/access/database/entities/Place.java | 24 ++ .../fragment/creator/CreatePlaceFragment.java | 292 ++++++++---------- .../creator/CreatePlaceLocationFragment.java | 149 +++++++++ .../fragment/creator/CreatorFragment.java | 7 + .../views/viewmodel/CreatorViewModel.java | 30 +- .../main/res/layout/fragment_create_place.xml | 68 ++-- .../layout/fragment_create_place_location.xml | 30 ++ .../main/res/navigation/main_navigation.xml | 8 + app/src/main/res/values-en/strings.xml | 3 + app/src/main/res/values-es/strings.xml | 2 + app/src/main/res/values/strings.xml | 24 +- 11 files changed, 436 insertions(+), 201 deletions(-) create mode 100644 app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatePlaceLocationFragment.java create mode 100644 app/src/main/res/layout/fragment_create_place_location.xml diff --git a/app/src/main/java/com/martinlaizg/geofind/data/access/database/entities/Place.java b/app/src/main/java/com/martinlaizg/geofind/data/access/database/entities/Place.java index 2bbc80b..51d5039 100644 --- a/app/src/main/java/com/martinlaizg/geofind/data/access/database/entities/Place.java +++ b/app/src/main/java/com/martinlaizg/geofind/data/access/database/entities/Place.java @@ -1,5 +1,7 @@ package com.martinlaizg.geofind.data.access.database.entities; +import android.location.Location; + import androidx.room.Entity; import androidx.room.ForeignKey; import androidx.room.Ignore; @@ -197,4 +199,26 @@ public String getImage() { public void setImage(String image) { this.image = image; } + + public Location getLocation() { + if(lat == null || lon == null) return null; + Location l = new Location(""); + l.setLatitude(this.lat); + l.setLongitude(this.lon); + return l; + } + + public void setLocation(Location location) { + if(location == null) return; + lat = location.getLatitude(); + lon = location.getLongitude(); + } + + public void setCompleteQuestion(String question, String correctAnswer, String secondAnswer, + String thirdAnswer) { + this.question = question; + this.answer = correctAnswer; + this.answer2 = secondAnswer; + this.answer3 = thirdAnswer; + } } diff --git a/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatePlaceFragment.java b/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatePlaceFragment.java index 48d523a..d9680c3 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatePlaceFragment.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatePlaceFragment.java @@ -1,19 +1,14 @@ package com.martinlaizg.geofind.views.fragment.creator; -import android.Manifest; -import android.annotation.SuppressLint; import android.app.AlertDialog; import android.content.Context; -import android.content.pm.PackageManager; -import android.location.Location; -import android.location.LocationManager; +import android.location.Address; +import android.location.Geocoder; import android.os.Bundle; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; -import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.Switch; @@ -42,40 +37,41 @@ import com.martinlaizg.geofind.views.viewmodel.CreatorViewModel; import com.squareup.picasso.Picasso; +import java.io.IOException; import java.util.List; import java.util.Objects; import butterknife.BindView; import butterknife.ButterKnife; -import static android.content.Context.LOCATION_SERVICE; - public class CreatePlaceFragment extends Fragment - implements View.OnClickListener, OnMapReadyCallback, GoogleMap.OnMapLongClickListener { + implements View.OnClickListener, OnMapReadyCallback { public static final String PLACE_POSITION = "PLACE_POSITION"; private static final String TAG = CreatePlaceFragment.class.getSimpleName(); private static final int CAMERA_UPDATE_ZOOM = 15; - private static final int PERMISSION_ACCESS_COARSE_AND_FINE_LOCATION = 1; @BindView(R.id.new_place_name_layout) TextInputLayout new_place_name; @BindView(R.id.new_place_description_layout) TextInputLayout new_place_description; - @BindView(R.id.alert_no_place_text) - TextView alert_no_place_text; - @BindView(R.id.create_place) - Button create_button; + @BindView(R.id.new_place_create_button) + MaterialButton create_button; @BindView(R.id.new_place_map_view) MapView new_place_map_view; + @BindView(R.id.new_place_address) + TextView new_place_address; + @BindView(R.id.new_place_location_button) + MaterialButton new_place_location_button; @BindView(R.id.new_place_image_button) MaterialButton new_place_image_button; @BindView(R.id.place_image_view) ImageView place_image_view; + @BindView(R.id.question_switch) Switch question_switch; @BindView(R.id.question_layout) @@ -88,12 +84,10 @@ public class CreatePlaceFragment TextInputLayout new_place_answer_2; @BindView(R.id.new_place_answer_3) TextInputLayout new_place_answer_3; - private String image_url; private CreatorViewModel viewModel; - private MarkerOptions marker; - private GoogleMap gMap; - private Place place; + private GoogleMap googleMap; + private String image_url; @Override public void onClick(View v) { @@ -105,30 +99,28 @@ public void onClick(View v) { editTextInput.hideSoftInputFromWindow(currentFocus.getWindowToken(), 0); } - alert_no_place_text.setVisibility(View.INVISIBLE); - Place place = getPlace(); - if(place == null) return; + if(!storePlace()) return; - viewModel.setPlace(place); + viewModel.savePlace(); Navigation.findNavController(requireActivity(), R.id.main_fragment_holder).popBackStack(); } /** - * Get the place data from de inputs + * Sotre the place data (name, description, image, question) into the viewModel {@link Place} * - * @return the place + * @return true if no has errors else false */ - private Place getPlace() { + private boolean storePlace() { // Get the name String placeName = Objects.requireNonNull(new_place_name.getEditText()).getText().toString() .trim(); if(placeName.isEmpty()) { new_place_name.setError(getString(R.string.required_name)); - return null; + return false; } if(placeName.length() > getResources().getInteger(R.integer.max_name_length)) { new_place_name.setError(getString(R.string.text_too_long)); - return null; + return false; } new_place_name.setError(""); @@ -137,38 +129,36 @@ private Place getPlace() { .getText().toString().trim(); if(placeDescription.isEmpty()) { new_place_description.setError(getString(R.string.required_description)); - return null; + return false; } if(placeDescription.length() > getResources().getInteger(R.integer.max_description_length)) { new_place_description.setError(getString(R.string.text_too_long)); - return null; + return false; } new_place_description.setError(""); - // Get the marker - if(marker == null) { - alert_no_place_text.setVisibility(View.VISIBLE); - return null; - } - // Get the question - boolean question = getQuestion(); - if(!question) return null; + boolean question = storeQuestion(); + if(!question) return false; - place.setName(placeName); - place.setDescription(placeDescription); - place.setPosition(marker.getPosition()); + viewModel.getPlace().setName(placeName); + viewModel.getPlace().setDescription(placeDescription); - return place; + return true; } - private boolean getQuestion() { + /** + * Store the question data into the viewModel {@link Place} + * + * @return true if no has errors else false + */ + private boolean storeQuestion() { if(!question_switch.isChecked()) { - place.setQuestion(null); - place.setAnswer(null); - place.setAnswer2(null); - place.setAnswer3(null); + viewModel.getPlace().setQuestion(null); + viewModel.getPlace().setAnswer(null); + viewModel.getPlace().setAnswer2(null); + viewModel.getPlace().setAnswer3(null); return true; } @@ -214,83 +204,48 @@ private boolean getQuestion() { } // Set the values - place.setQuestion(question); - place.setAnswer(correctAnswer); - place.setAnswer2(secondAnswer); - place.setAnswer3(thirdAnswer); + viewModel.getPlace() + .setCompleteQuestion(question, correctAnswer, secondAnswer, thirdAnswer); return true; } @Override public void onMapReady(GoogleMap googleMap) { - gMap = googleMap; - if(requireActivity().checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != - PackageManager.PERMISSION_GRANTED && - requireActivity().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != - PackageManager.PERMISSION_GRANTED) { - requestPermissions(new String[]{android.Manifest.permission.ACCESS_COARSE_LOCATION, - android.Manifest.permission.ACCESS_FINE_LOCATION}, - PERMISSION_ACCESS_COARSE_AND_FINE_LOCATION); - Toast.makeText(requireActivity(), getString(R.string.rejected_location_access), - Toast.LENGTH_SHORT).show(); - return; - } - setMarker(); - } - - @SuppressLint("MissingPermission") - private void setMarker() { - Location usrLocation = getLastKnownLocation(); - if(gMap != null) { - gMap.setMyLocationEnabled(true); - gMap.setOnMapLongClickListener(this); - gMap.getUiSettings().setMyLocationButtonEnabled(true); - gMap.getUiSettings().setMapToolbarEnabled(false); - gMap.getUiSettings().setTiltGesturesEnabled(false); - gMap.getUiSettings().setZoomControlsEnabled(true); - - LatLng usrLatLng = new LatLng(usrLocation.getLatitude(), usrLocation.getLongitude()); - gMap.clear(); - if(marker != null) { - gMap.moveCamera(CameraUpdateFactory - .newLatLngZoom(marker.getPosition(), CAMERA_UPDATE_ZOOM)); - gMap.addMarker(marker); - } else { - gMap.animateCamera( - CameraUpdateFactory.newLatLngZoom(usrLatLng, CAMERA_UPDATE_ZOOM)); - } - } + this.googleMap = googleMap; + this.googleMap.getUiSettings().setAllGesturesEnabled(false); + this.googleMap.clear(); + setPosition(viewModel.getPlace()); } - @SuppressLint("MissingPermission") - private Location getLastKnownLocation() { - LocationManager locationManager = (LocationManager) requireActivity() - .getSystemService(LOCATION_SERVICE); - List providers = locationManager.getProviders(true); - Location bestLocation = null; - for(String provider : providers) { - Location l = locationManager.getLastKnownLocation(provider); - if(l == null) { - continue; - } - if(bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) { - bestLocation = l; + private void setPosition(Place place) { + if(place == null) return; + LatLng position = place.getPosition(); + if(position == null) return; + + // Change button text + new_place_location_button.setText(getString(R.string.update)); + new_place_address.setVisibility(View.VISIBLE); + + // Get address + Geocoder gc = new Geocoder(requireContext()); + List
locations; + new_place_address + .setText(getString(R.string.two_csv, position.latitude, position.longitude)); + try { + locations = gc.getFromLocation(position.latitude, position.longitude, 1); + if(locations != null && locations.size() > 1) { + new_place_address.setText(locations.get(0).getAddressLine(0)); } + } catch(IOException e) { + e.printStackTrace(); } - return bestLocation; - } - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, - @NonNull int[] grantResults) { - if(requestCode == PERMISSION_ACCESS_COARSE_AND_FINE_LOCATION) { - if(permissions[0].equals(Manifest.permission.ACCESS_COARSE_LOCATION) && - grantResults[0] == PackageManager.PERMISSION_GRANTED && - permissions[1].equals(Manifest.permission.ACCESS_FINE_LOCATION) && - grantResults[1] == PackageManager.PERMISSION_GRANTED) { - setMarker(); - } + if(googleMap != null) { + // Set static map + MarkerOptions marker = new MarkerOptions().position(position); + googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(position, CAMERA_UPDATE_ZOOM)); + googleMap.addMarker(marker); } } @@ -299,11 +254,6 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_create_place, container, false); ButterKnife.bind(this, view); - - new_place_map_view.onCreate(savedInstanceState); - new_place_map_view.onResume(); - new_place_map_view.getMapAsync(this); - // Back button listener requireActivity().getOnBackPressedDispatcher() .addCallback(this, new OnBackPressedCallback(true) { @@ -317,64 +267,80 @@ public void handleOnBackPressed() { @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + // Show/hide question layout question_switch.setOnCheckedChangeListener((buttonView, isChecked) -> question_layout .setVisibility(isChecked ? View.VISIBLE : View.GONE)); + viewModel = ViewModelProviders.of(requireActivity()).get(CreatorViewModel.class); Bundle b = getArguments(); if(b != null) { int position = b.getInt(PLACE_POSITION, viewModel.getPlaces().size()); - setPlace(viewModel.getPlace(position)); - Log.i(TAG, "onViewCreated: Get place and set"); + viewModel.retrievePlace(position); + setPlace(); } create_button.setOnClickListener(this); new_place_image_button.setOnClickListener(v -> { AlertDialog alertDialog = buildDialog(); alertDialog.show(); }); - if(marker != null) create_button.setText(R.string.update_place); - } - private void setPlace(Place place) { - this.place = place; - if(place != null) { - // Set name - if(place.getName() != null) { - Objects.requireNonNull(new_place_name.getEditText()).setText(place.getName()); - } - // Set description - if(place.getDescription() != null) { - Objects.requireNonNull(new_place_description.getEditText()) - .setText(place.getDescription()); - } - // Set position (marker) - if(place.getPosition() != null) { - onMapLongClick(place.getPosition()); - } - // Set question - question_switch.setChecked(false); - if(place.getQuestion() != null) { - question_switch.setChecked(true); - Objects.requireNonNull(new_place_question.getEditText()) - .setText(place.getQuestion()); - Objects.requireNonNull(new_place_correct_answer.getEditText()) - .setText(place.getAnswer()); - Objects.requireNonNull(new_place_answer_2.getEditText()) - .setText(place.getAnswer2()); - Objects.requireNonNull(new_place_answer_3.getEditText()) - .setText(place.getAnswer3()); + new_place_location_button.setOnClickListener(v -> { + if(!storePlace()) return; + + // Hide the keyboard + InputMethodManager editTextInput = (InputMethodManager) requireActivity() + .getSystemService(Context.INPUT_METHOD_SERVICE); + View currentFocus = requireActivity().getCurrentFocus(); + if(currentFocus != null) { + editTextInput.hideSoftInputFromWindow(currentFocus.getWindowToken(), 0); } - place_image_view.setVisibility(View.GONE); + Navigation.findNavController(requireActivity(), R.id.main_fragment_holder) + .navigate(R.id.toCreatePlaceLocation); + }); + } - if(place.getImage() != null && !place.getImage().isEmpty()) { - Picasso.with(requireContext()).load(image_url).into(place_image_view); - place_image_view.setVisibility(View.VISIBLE); - } - } else { - Toast.makeText(requireContext(), getResources().getString(R.string.invalid_place), + private void setPlace() { + Place place = viewModel.getPlace(); + if(place == null) { + Toast.makeText(requireContext(), getString(R.string.something_went_wrong), Toast.LENGTH_SHORT).show(); + Navigation.findNavController(requireActivity(), R.id.main_fragment_holder) + .popBackStack(); + return; + } + + // Set name + if(place.getName() != null) { + Objects.requireNonNull(new_place_name.getEditText()).setText(place.getName()); + } + + // Set description + if(place.getDescription() != null) { + Objects.requireNonNull(new_place_description.getEditText()) + .setText(place.getDescription()); + } + // Set location marker + setPosition(place); + + // Set question + question_switch.setChecked(false); + if(place.getQuestion() != null) { + question_switch.setChecked(true); + Objects.requireNonNull(new_place_question.getEditText()).setText(place.getQuestion()); + Objects.requireNonNull(new_place_correct_answer.getEditText()) + .setText(place.getAnswer()); + Objects.requireNonNull(new_place_answer_2.getEditText()).setText(place.getAnswer2()); + Objects.requireNonNull(new_place_answer_3.getEditText()).setText(place.getAnswer3()); + } + + // Set image + place_image_view.setVisibility(View.GONE); + if(place.getImage() != null && !place.getImage().isEmpty()) { + Picasso.with(requireContext()).load(image_url).into(place_image_view); + place_image_view.setVisibility(View.VISIBLE); } } @@ -404,18 +370,6 @@ private AlertDialog buildDialog() { }).create(); } - @Override - public void onMapLongClick(LatLng latLng) { - alert_no_place_text.setVisibility(View.INVISIBLE); - MarkerOptions m = new MarkerOptions().position(latLng); - if(gMap != null) { - gMap.clear(); - gMap.addMarker(m); - } - marker = m; - - } - private void showExitDialog() { new MaterialAlertDialogBuilder(requireContext()).setTitle(R.string.are_you_sure) .setMessage(getString(R.string.exit_lose_data_alert)) diff --git a/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatePlaceLocationFragment.java b/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatePlaceLocationFragment.java new file mode 100644 index 0000000..4f95dbd --- /dev/null +++ b/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatePlaceLocationFragment.java @@ -0,0 +1,149 @@ +package com.martinlaizg.geofind.views.fragment.creator; + +import android.annotation.SuppressLint; +import android.location.Location; +import android.location.LocationManager; +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProviders; +import androidx.navigation.Navigation; + +import com.google.android.gms.maps.CameraUpdateFactory; +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.MapView; +import com.google.android.gms.maps.OnMapReadyCallback; +import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.MarkerOptions; +import com.google.android.material.button.MaterialButton; +import com.martinlaizg.geofind.R; +import com.martinlaizg.geofind.views.viewmodel.CreatorViewModel; + +import butterknife.BindView; +import butterknife.ButterKnife; + +import static android.Manifest.permission.ACCESS_COARSE_LOCATION; +import static android.Manifest.permission.ACCESS_FINE_LOCATION; +import static android.content.Context.LOCATION_SERVICE; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; + +public class CreatePlaceLocationFragment + extends Fragment + implements OnMapReadyCallback, GoogleMap.OnMapLongClickListener { + + private static final String TAG = CreatePlaceLocationFragment.class.getSimpleName(); + + private static final float ZOOM = 15; + private static final int RC_LOCATION = 123; + + @BindView(R.id.map_view) + MapView map_view; + @BindView(R.id.create_place_location_button) + MaterialButton create_place_location_button; + + private CreatorViewModel viewModel; + private GoogleMap googleMap; + private LocationManager locationManager; + + private Location usrLocation; + private Location placeLocation; + + @SuppressLint("MissingPermission") + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, + @NonNull int[] grantResults) { + if(requestCode == RC_LOCATION) { + if(grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) { + if(googleMap != null) { + usrLocation = locationManager + .getLastKnownLocation(LocationManager.GPS_PROVIDER); + setMarker(); + } + } + } + } + + private void setMarker() { + if(googleMap == null) return; + + LatLng latLng; + this.googleMap.clear(); + + if(placeLocation != null) { + // Use the place location + latLng = new LatLng(placeLocation.getLatitude(), placeLocation.getLongitude()); + this.googleMap.addMarker(new MarkerOptions().position(latLng)); + } else { + // Use the user location + if(usrLocation == null) { + // Check location permissions + if(requireActivity().checkSelfPermission(ACCESS_FINE_LOCATION) != + PERMISSION_GRANTED && + requireActivity().checkSelfPermission(ACCESS_COARSE_LOCATION) != + PERMISSION_GRANTED) { + // Request location permissions + requireActivity().requestPermissions( + new String[]{ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION}, + RC_LOCATION); + return; + } + locationManager = (LocationManager) requireActivity() + .getSystemService(LOCATION_SERVICE); + usrLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + if(usrLocation == null) { + Log.e(TAG, "setMarker: fail to get last known location (GPS)"); + return; + } + } + latLng = new LatLng(usrLocation.getLatitude(), usrLocation.getLongitude()); + } + + this.googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, ZOOM)); + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_create_place_location, container, false); + ButterKnife.bind(this, view); + map_view.onCreate(savedInstanceState); + map_view.onResume(); + map_view.getMapAsync(this); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + viewModel = ViewModelProviders.of(requireActivity()).get(CreatorViewModel.class); + placeLocation = viewModel.getPlace().getLocation(); + setMarker(); + create_place_location_button.setOnClickListener( + v -> Navigation.findNavController(requireActivity(), R.id.main_fragment_holder) + .popBackStack()); + } + + @SuppressLint("MissingPermission") + @Override + public void onMapReady(GoogleMap googleMap) { + this.googleMap = googleMap; + this.googleMap.setPadding(0, 0, 0, create_place_location_button.getHeight()); + this.googleMap.setOnMapLongClickListener(this); + this.googleMap.setMyLocationEnabled(true); + this.googleMap.getUiSettings().setMyLocationButtonEnabled(true); + this.googleMap.getUiSettings().setAllGesturesEnabled(true); + setMarker(); + } + + @Override + public void onMapLongClick(LatLng latLng) { + googleMap.clear(); + googleMap.addMarker(new MarkerOptions().position(latLng)); + viewModel.getPlace().setPosition(latLng); + } +} diff --git a/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatorFragment.java b/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatorFragment.java index 9722f28..a325016 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatorFragment.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/fragment/creator/CreatorFragment.java @@ -132,6 +132,12 @@ public void onDestroy() { @Override public void onClick(View v) { + if(viewModel.getStoredTour().getPlaces().size() == 0) { + Toast.makeText(requireContext(), getString(R.string.at_least_one_place), + Toast.LENGTH_SHORT).show(); + + return; + } create_tour_button.setEnabled(false); viewModel.createTour().observe(this, tour -> { create_tour_button.setEnabled(true); @@ -149,4 +155,5 @@ public void onClick(View v) { .navigate(R.id.toNewTour, b); }); } + } diff --git a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/CreatorViewModel.java b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/CreatorViewModel.java index fdf4011..e91c973 100644 --- a/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/CreatorViewModel.java +++ b/app/src/main/java/com/martinlaizg/geofind/views/viewmodel/CreatorViewModel.java @@ -22,6 +22,7 @@ public class CreatorViewModel private final TourRepository tourRepo; private Tour tour; private ErrorType error; + private Place place; public CreatorViewModel(@NonNull Application application) { super(application); @@ -104,23 +105,42 @@ public List getPlaces() { places; } - public Place getPlace(int position) { - if(position > tour.getPlaces().size()) return null; - if(position < tour.getPlaces().size()) return tour.getPlaces().get(position); - return new Place(); + public void retrievePlace(int position) { + if(place != null) return; + if(position > tour.getPlaces().size()) { + place = null; + } else if(position < tour.getPlaces().size()) { + place = tour.getPlaces().get(position); + } else { + place = new Place(); + place.setOrder(position); + } } - public void setPlace(Place place) { + public void savePlace() { if(place.getOrder() == null) { place.setOrder(tour.getPlaces().size()); tour.getPlaces().add(place); } else { tour.getPlaces().set(place.getOrder(), place); } + this.place = null; } public void reset() { this.tour = null; this.error = null; } + + public Place getPlace() { + return place; + } + + public void setPlace(Place place) { + this.place = place; + } + + public Tour getStoredTour() { + return tour; + } } diff --git a/app/src/main/res/layout/fragment_create_place.xml b/app/src/main/res/layout/fragment_create_place.xml index 9773fde..d7019cd 100644 --- a/app/src/main/res/layout/fragment_create_place.xml +++ b/app/src/main/res/layout/fragment_create_place.xml @@ -28,7 +28,7 @@ + android:inputType="textNoSuggestions|textCapSentences" /> + android:lines="3" + android:maxLines="8" /> + app:layout_constraintTop_toBottomOf="@id/new_place_description_layout" + tools:visibility="visible" /> + +