Guardadno backUp de app, por cambio de gestion de los datos en toda la app

This commit is contained in:
Andrés Moran 2025-05-24 17:05:40 +02:00
parent da463260aa
commit b5853be7fb
36 changed files with 1116 additions and 761 deletions

View File

@ -9,9 +9,9 @@
android:allowBackup="true" android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules" android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules" android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/icon"
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/icon_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.AppTrabajadores" android:theme="@style/Theme.AppTrabajadores"
tools:targetApi="31"> tools:targetApi="31">

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

View File

@ -0,0 +1,7 @@
package com.andresgmoran.apptrabajadores.interfaces;
import androidx.fragment.app.Fragment;
public interface IOnClickOnBackButtonListener {
void onClickOnBackButton();
}

View File

@ -6,13 +6,11 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.util.Log;
import androidx.security.crypto.EncryptedSharedPreferences; import androidx.security.crypto.EncryptedSharedPreferences;
import androidx.security.crypto.MasterKey; import androidx.security.crypto.MasterKey;
import com.andresgmoran.apptrabajadores.models.ActivityState; import com.andresgmoran.apptrabajadores.models.ActivityState;
import com.andresgmoran.apptrabajadores.models.User;
import com.andresgmoran.apptrabajadores.utils.SecurePreferencesUtil; import com.andresgmoran.apptrabajadores.utils.SecurePreferencesUtil;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -20,13 +18,30 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
public class ApiClient { public class ApiClient {
private static final String BASE_URL = "http://10.0.2.2:8080"; private static final String BASE_URL = "http://10.0.2.2:8080";
// Endpoints
private static final String ENDPOINT_GET_USERS = "/resi/user/getAll";
private static final String ENDPOINT_GET_ME = "/resi/user/me";
private static final String ENDPOINT_GET_RESIDENTS = "/resi/resident/getAll";
private static final String ENDPOINT_GET_GAMES = "/resi/juego/getAll";
private static final String ENDPOINT_GET_STATS = "/resi/registro/getAll";
private static final String ENDPOINT_GET_ACTIVITIES = "/resi/evento/getAll";
private static final String ENDPOINT_ADD_EVENT = "/resi/evento/add";
private static final String ENDPOINT_LOGIN = "/auth/login";
private static final String ENDPOINT_COMMENT_GAMESTAT = "/resi/registro/%d/addComment";
private static final String ENDPOINT_UPDATE_ACTIVITY_STATE = "/resi/evento/%d/update";
private static final String ENDPOINT_DELETE_GAMESTAT = "/resi/registro/%d/delete";
private static final String ENDPOINT_DELETE_ACTIVITY = "/resi/evento/%d/delete";
private static final String ENDPOINT_ACTIVITY_PARTICIPANTS = "/resi/evento/%d/participante/getAll";
private static final String ENDPOINT_ADD_PARTICIPANT = "/resi/evento/%d/participante/add";
private static final String ENDPOINT_UPDATE_PARTICIPANT = "/resi/evento/%d/participante/%d/update";
private static final String ENDPOINT_TAKE_OUT_RESIDENT = "/resi/resident/%d/baja";
public interface RawCallback { public interface RawCallback {
void onSuccess(String jsonText); void onSuccess(String jsonText);
void onError(String error); void onError(String error);
@ -37,73 +52,81 @@ public class ApiClient {
void onError(String error); void onError(String error);
} }
/**
*
* @param context
* @param callback
*/
public static void getUsers(Context context, RawCallback callback) { public static void getUsers(Context context, RawCallback callback) {
long idResidence = SecurePreferencesUtil.getLong(context, "idResidence", -1); makeGetRequest(context, ENDPOINT_GET_USERS, callback);
makeGetRequest(context, "/resi/user/getAll", callback);
} }
public static void getActualUser(Context context, RawCallback callback) { public static void getActualUser(Context context, RawCallback callback) {
makeGetRequest(context, "/resi/user/me", callback); makeGetRequest(context, ENDPOINT_GET_ME, callback);
} }
/**
*
* @param context
* @param callback
*/
public static void getResidents(Context context, RawCallback callback) { public static void getResidents(Context context, RawCallback callback) {
long idResidence = SecurePreferencesUtil.getLong(context, "idResidence", -1); makeGetRequest(context, ENDPOINT_GET_RESIDENTS, callback);
makeGetRequest(context, "/resi/resident/getAll", callback);
} }
/**
*
* @param context
* @param callback
*/
public static void getGames(Context context, RawCallback callback) { public static void getGames(Context context, RawCallback callback) {
long idResidence = SecurePreferencesUtil.getLong(context, "idResidence", -1); makeGetRequest(context, ENDPOINT_GET_GAMES, callback);
makeGetRequest(context, "/resi/juego/getAll", callback);
} }
/**
*
* @param context
* @param callback
*/
public static void getGamesStats(Context context, RawCallback callback) { public static void getGamesStats(Context context, RawCallback callback) {
long idResidence = SecurePreferencesUtil.getLong(context, "idResidence", -1); makeGetRequest(context, ENDPOINT_GET_STATS, callback);
makeGetRequest(context, "/resi/registro/getAll", callback);
} }
/**
*
* @param context
* @param callback
*/
public static void getAllActivities(Context context, RawCallback callback) { public static void getAllActivities(Context context, RawCallback callback) {
long idResidence = SecurePreferencesUtil.getLong(context, "idResidence", -1); makeGetRequest(context, ENDPOINT_GET_ACTIVITIES, callback);
makeGetRequest(context, "/resi/evento/getAll", callback);
} }
public static void getAllParticipants(Context context, Long idActivity, RawCallback callback) { public static void getAllParticipants(Context context, Long idActivity, RawCallback callback) {
long idResidence = SecurePreferencesUtil.getLong(context, "idResidence", -1); makeGetRequest(context, String.format(ENDPOINT_ACTIVITY_PARTICIPANTS, idActivity), callback);
makeGetRequest(context, "/resi/evento/" + idActivity + "/participante/getAll", callback);
} }
/** public static void postLogin(String email, String password, RawCallback callback) {
* String jsonBody = String.format("{\"email\":\"%s\", \"password\":\"%s\"}", email, password);
* @param context makePostRequest(null, ENDPOINT_LOGIN, jsonBody, callback);
* @param endpoint }
* @param callback
*/ public static void postEvento(Context context, String nombre, String descripcion, LocalDateTime fecha, RawCallback callback) {
private static void makeGetRequest(Context context, String endpoint, RawCallback callback) { String jsonBody = String.format("{\"nombre\":\"%s\", \"descripcion\":\"%s\", \"fecha\":\"%s\", \"estado\":\"%s\"}",
nombre, descripcion, fecha.toString(), ActivityState.ABIERTO);
makePostRequest(context, ENDPOINT_ADD_EVENT, jsonBody, callback);
}
public static void postParticipant(Context context, Long residentId, boolean humanHelp, boolean materialHelp,
String opinionPre, String opinionPost, Long idActivity, RawCallback callback) {
String jsonBody = String.format(
"{\"idResidente\":%d, \"recursosHumanos\":%b, \"recursosMateriales\":%b, \"preOpinion\":\"%s\", \"postOpinion\":\"%s\"}",
residentId, humanHelp, materialHelp, opinionPre, opinionPost);
makePostRequest(context, String.format(ENDPOINT_ADD_PARTICIPANT, idActivity), jsonBody, callback);
}
public static void patchObservation(Context context, String observation, long idGameStat, RawCallback callback) {
String jsonBody = String.format("{\"observacion\":\"%s\"}", observation);
makePatchRequest(context, String.format(ENDPOINT_COMMENT_GAMESTAT, idGameStat), jsonBody, callback);
}
public static void patchActivityState(Context context, long idActivity, ActivityState state, RawCallback callback) {
String jsonBody = String.format("{\"estado\":\"%s\"}", state);
makePatchRequest(context, String.format(ENDPOINT_UPDATE_ACTIVITY_STATE, idActivity), jsonBody, callback);
}
public static void patchParticipant(Context context, long idActivity, long idParticipant,
String jsonBody, RawCallback callback) {
makePatchRequest(context, String.format(ENDPOINT_UPDATE_PARTICIPANT, idActivity, idParticipant), jsonBody, callback);
}
public static void patchTakeOutResident(Context context, long idResident, RawCallback callback) {
makePatchRequest(context, String.format(ENDPOINT_TAKE_OUT_RESIDENT, idResident), "", callback);
}
public static void deleteGameStat(Context context, long idGameStat, RawCallback callback) {
makeDeleteRequest(context, String.format(ENDPOINT_DELETE_GAMESTAT, idGameStat), callback);
}
public static void deleteActivity(Context context, long idActivity, RawCallback callback) {
makeDeleteRequest(context, String.format(ENDPOINT_DELETE_ACTIVITY, idActivity), callback);
}
public static void makeGetRequest(Context context, String endpoint, RawCallback callback) {
new Thread(() -> { new Thread(() -> {
HttpURLConnection connection = null; HttpURLConnection connection = null;
BufferedReader reader = null; BufferedReader reader = null;
@ -114,20 +137,7 @@ public class ApiClient {
connection.setRequestMethod("GET"); connection.setRequestMethod("GET");
connection.setRequestProperty("User-Agent", "Android"); connection.setRequestProperty("User-Agent", "Android");
// Obtener el token desde EncryptedSharedPreferences String token = SecurePreferencesUtil.getString(context, "token", null);
MasterKey masterKey = new MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build();
SharedPreferences encryptedPrefs = EncryptedSharedPreferences.create(
context,
"secure_auth",
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
);
String token = encryptedPrefs.getString("token", null);
if (token != null) { if (token != null) {
connection.setRequestProperty("Authorization", "Bearer " + token); connection.setRequestProperty("Authorization", "Bearer " + token);
} }
@ -136,109 +146,13 @@ public class ApiClient {
connection.setReadTimeout(5000); connection.setReadTimeout(5000);
int responseCode = connection.getResponseCode(); int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) { InputStream inputStream = (responseCode >= 200 && responseCode < 300)
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder json = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
json.append(line);
}
new Handler(Looper.getMainLooper()).post(() ->
callback.onSuccess(json.toString()));
} else {
new Handler(Looper.getMainLooper()).post(() ->
callback.onError("Código de error: " + responseCode));
}
} catch (Exception e) {
Log.e("API", "Error: " + e.getMessage(), e);
new Handler(Looper.getMainLooper()).post(() ->
callback.onError("Excepción: " + e.getMessage()));
} finally {
try {
if (reader != null) reader.close();
if (connection != null) connection.disconnect();
} catch (Exception ignored) {}
}
}).start();
}
/**
*
* @param email
* @param password
* @param callback
*/
public static void postLogin(String email, String password, RawCallback callback) {
String jsonBody = String.format("{\"email\":\"%s\", \"password\":\"%s\"}", email, password);
makePostRequest("/auth/login", jsonBody, callback);
}
/**
*
* @param context
* @param nombre
* @param descripcion
* @param fecha
* @param callback
*/
public static void postEvento(Context context, String nombre, String descripcion, LocalDateTime fecha, RawCallback callback) {
String jsonBody = String.format("{\"nombre\":\"%s\", \"descripcion\":\"%s\", \"fecha\":\"%s\", \"estado\":\"%s\"}", nombre, descripcion, fecha.toString(), ActivityState.ABIERTO);
makePostRequest(context,"/resi/evento/add", jsonBody, callback);
}
/**
*
* @param context
* @param residentId
* @param asistencia
* @param opinionPre
* @param opinionPost
* @param idActivity
* @param callback
*/
public static void postParticipant( Context context, Long residentId, boolean humanHelp, boolean materialHelp, String opinionPre, String opinionPost, Long idActivity, RawCallback callback) {
String jsonBody = String.format("{\"idResidente\":%d, \"recursosHumanos\":%b, \"recursosMateriales\":%b, \"preOpinion\":\"%s\", \"postOpinion\":\"%s\"}", residentId, humanHelp, materialHelp, opinionPre, opinionPost); long idResidence = SecurePreferencesUtil.getLong(context, "idResidence", -1);
makePostRequest(context,"/resi/evento/" + idActivity + "/participante/add", jsonBody, callback);
}
/**
*
* @param endpoint
* @param jsonBody
* @param callback
*/
public static void makePostRequest(String endpoint, String jsonBody, RawCallback callback) {
new Thread(() -> {
HttpURLConnection connection = null;
try {
URL url = new URL(BASE_URL + endpoint);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json; utf-8");
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("User-Agent", "Android");
connection.setDoOutput(true);
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
try (java.io.OutputStream os = connection.getOutputStream()) {
byte[] input = jsonBody.getBytes("utf-8");
os.write(input, 0, input.length);
}
int responseCode = connection.getResponseCode();
java.io.InputStream inputStream = (responseCode >= 200 && responseCode < 300)
? connection.getInputStream() ? connection.getInputStream()
: connection.getErrorStream(); : connection.getErrorStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "utf-8")); reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder response = new StringBuilder(); StringBuilder response = new StringBuilder();
String line; String line;
while ((line = reader.readLine()) != null) { while ((line = reader.readLine()) != null) {
response.append(line.trim()); response.append(line.trim());
} }
@ -256,18 +170,14 @@ public class ApiClient {
new Handler(Looper.getMainLooper()).post(() -> new Handler(Looper.getMainLooper()).post(() ->
callback.onError("Excepción: " + e.getMessage())); callback.onError("Excepción: " + e.getMessage()));
} finally { } finally {
if (connection != null) connection.disconnect(); try {
if (reader != null) reader.close();
if (connection != null) connection.disconnect();
} catch (Exception ignored) {}
} }
}).start(); }).start();
} }
/**
*
* @param context
* @param endpoint
* @param jsonBody
* @param callback
*/
public static void makePostRequest(Context context, String endpoint, String jsonBody, RawCallback callback) { public static void makePostRequest(Context context, String endpoint, String jsonBody, RawCallback callback) {
new Thread(() -> { new Thread(() -> {
HttpURLConnection connection = null; HttpURLConnection connection = null;
@ -283,9 +193,11 @@ public class ApiClient {
connection.setConnectTimeout(5000); connection.setConnectTimeout(5000);
connection.setReadTimeout(5000); connection.setReadTimeout(5000);
String token = SecurePreferencesUtil.getString(context, "token", null); if (context != null) {
if (token != null) { String token = SecurePreferencesUtil.getString(context, "token", null);
connection.setRequestProperty("Authorization", "Bearer " + token); if (token != null) {
connection.setRequestProperty("Authorization", "Bearer " + token);
}
} }
try (java.io.OutputStream os = connection.getOutputStream()) { try (java.io.OutputStream os = connection.getOutputStream()) {
@ -294,7 +206,7 @@ public class ApiClient {
} }
int responseCode = connection.getResponseCode(); int responseCode = connection.getResponseCode();
java.io.InputStream inputStream = (responseCode >= 200 && responseCode < 300) InputStream inputStream = (responseCode >= 200 && responseCode < 300)
? connection.getInputStream() ? connection.getInputStream()
: connection.getErrorStream(); : connection.getErrorStream();
@ -324,29 +236,11 @@ public class ApiClient {
}).start(); }).start();
} }
public static void patchObservation(Context context, String observation, long idGameStat, RawCallback callback) {
String jsonBody = String.format("{\"observacion\":\"%s\"}", observation);
long idResidence = SecurePreferencesUtil.getLong(context, "idResidence", -1);
makePatchRequest(context,"/resi/registro/" + idGameStat + "/addComment", jsonBody, callback);
}
public static void patchActivityState(Context context, long idActivity, ActivityState state, RawCallback callback) {
String jsonBody = String.format("{\"estado\":\"%s\"}", state);
makePatchRequest(context,"/resi/evento/" + idActivity + "/update", jsonBody, callback);
}
public static void patchParticipant( Context context, long idActivity, long idParticipant, String jsonBody, RawCallback callback) {
makePatchRequest(context,"/resi/evento/" + idActivity + "/participante/" + idParticipant + "/update", jsonBody, callback);
}
public static void patchTakeOutResident(Context context,long idResident, RawCallback callback) {
makePatchRequest(context,"/resi/resident/" + idResident + "/baja", "", callback);
}
public static void makePatchRequest(Context context, String endpoint, String jsonBody, RawCallback callback) { public static void makePatchRequest(Context context, String endpoint, String jsonBody, RawCallback callback) {
// Puedes usar makePostRequest cambiando el método a PATCH si lo prefieres
// Aquí dejamos separado por claridad
new Thread(() -> { new Thread(() -> {
HttpURLConnection connection = null; HttpURLConnection connection = null;
try { try {
URL url = new URL(BASE_URL + endpoint); URL url = new URL(BASE_URL + endpoint);
connection = (HttpURLConnection) url.openConnection(); connection = (HttpURLConnection) url.openConnection();
@ -369,7 +263,7 @@ public class ApiClient {
} }
int responseCode = connection.getResponseCode(); int responseCode = connection.getResponseCode();
java.io.InputStream inputStream = (responseCode >= 200 && responseCode < 300) InputStream inputStream = (responseCode >= 200 && responseCode < 300)
? connection.getInputStream() ? connection.getInputStream()
: connection.getErrorStream(); : connection.getErrorStream();
@ -399,24 +293,9 @@ public class ApiClient {
}).start(); }).start();
} }
public static void deleteGameStat(Context context, long idGameStat, RawCallback callback) {
makeDeleteRequest(context,"/resi/registro/" + idGameStat + "/delete", callback);
}
public static void deleteActivity(Context context, long idActivity, RawCallback callback) {
makeDeleteRequest(context,"/resi/evento/" + idActivity + "/delete", callback);
}
/**
*
* @param context
* @param endpoint
* @param callback
*/
public static void makeDeleteRequest(Context context, String endpoint, RawCallback callback) { public static void makeDeleteRequest(Context context, String endpoint, RawCallback callback) {
new Thread(() -> { new Thread(() -> {
HttpURLConnection connection = null; HttpURLConnection connection = null;
try { try {
URL url = new URL(BASE_URL + endpoint); URL url = new URL(BASE_URL + endpoint);
connection = (HttpURLConnection) url.openConnection(); connection = (HttpURLConnection) url.openConnection();
@ -426,14 +305,13 @@ public class ApiClient {
connection.setConnectTimeout(5000); connection.setConnectTimeout(5000);
connection.setReadTimeout(5000); connection.setReadTimeout(5000);
// Añadir el token si está disponible
String token = SecurePreferencesUtil.getString(context, "token", null); String token = SecurePreferencesUtil.getString(context, "token", null);
if (token != null) { if (token != null) {
connection.setRequestProperty("Authorization", "Bearer " + token); connection.setRequestProperty("Authorization", "Bearer " + token);
} }
int responseCode = connection.getResponseCode(); int responseCode = connection.getResponseCode();
java.io.InputStream inputStream = (responseCode >= 200 && responseCode < 300) InputStream inputStream = (responseCode >= 200 && responseCode < 300)
? connection.getInputStream() ? connection.getInputStream()
: connection.getErrorStream(); : connection.getErrorStream();
@ -465,12 +343,13 @@ public class ApiClient {
public static void downloadImage(Context context, String imageUrl, ImageCallback callback) { public static void downloadImage(Context context, String imageUrl, ImageCallback callback) {
new Thread(() -> { new Thread(() -> {
HttpURLConnection connection = null;
try { try {
URL url = new URL(BASE_URL + imageUrl); URL url = new URL(BASE_URL + imageUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET"); connection.setRequestMethod("GET");
// Headers // Autorización
MasterKey masterKey = new MasterKey.Builder(context) MasterKey masterKey = new MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM) .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build(); .build();
@ -494,14 +373,11 @@ public class ApiClient {
new Handler(Looper.getMainLooper()).post(() -> callback.onSuccess(bitmap)); new Handler(Looper.getMainLooper()).post(() -> callback.onSuccess(bitmap));
} catch (Exception e) { } catch (Exception e) {
new Handler(Looper.getMainLooper()).post(() -> callback.onError(e.getMessage())); new Handler(Looper.getMainLooper()).post(() -> callback.onError("Error al descargar imagen: " + e.getMessage()));
} finally {
if (connection != null) connection.disconnect();
} }
}).start(); }).start();
} }
} }

View File

@ -0,0 +1,436 @@
package com.andresgmoran.apptrabajadores.repository;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
import com.andresgmoran.apptrabajadores.models.Activity;
import com.andresgmoran.apptrabajadores.models.ActivityResident;
import com.andresgmoran.apptrabajadores.models.ActivityState;
import com.andresgmoran.apptrabajadores.models.Game;
import com.andresgmoran.apptrabajadores.models.Resident;
import com.andresgmoran.apptrabajadores.models.User;
import com.andresgmoran.apptrabajadores.models.gameStats.GameStat;
import com.andresgmoran.apptrabajadores.models.parsers.ActivityParser;
import com.andresgmoran.apptrabajadores.models.parsers.ActivityResidentParser;
import com.andresgmoran.apptrabajadores.models.parsers.GameParser;
import com.andresgmoran.apptrabajadores.models.parsers.GameStatParser;
import com.andresgmoran.apptrabajadores.models.parsers.ResidentParser;
import com.andresgmoran.apptrabajadores.models.parsers.UserParser;
import com.andresgmoran.apptrabajadores.network.ApiClient;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
public class AppDataRepository {
private static final AppDataRepository instance = new AppDataRepository();
private User actualUser;
private Bitmap actualUserImage;
private List<User> users = new ArrayList<>();
private List<Resident> residents = new ArrayList<>();
private List<Game> games = new ArrayList<>();
private List<GameStat> gameStats = new ArrayList<>();
private List<Activity> activities = new ArrayList<>();
private List<ActivityResident> activityResidents = new ArrayList<>();
private AppDataRepository() {}
public static AppDataRepository getInstance() {
return instance;
}
// -------------------- Getters/Setters Básicos --------------------
public User getActualUser() { return actualUser; }
public void setActualUser(User user) { this.actualUser = user; }
public Bitmap getActualUserImage() { return actualUserImage; }
public void setActualUserImage(Bitmap image) { this.actualUserImage = image; }
public List<User> getUsers() { return users; }
public void setUsers(List<User> list) { this.users = new ArrayList<>(list); }
public List<Resident> getResidents() { return residents; }
public void setResidents(List<Resident> list) { this.residents = new ArrayList<>(list); }
public List<Game> getGames() { return games; }
public void setGames(List<Game> list) { this.games = new ArrayList<>(list); }
public List<GameStat> getGameStats() { return gameStats; }
public void setGameStats(List<GameStat> list) { this.gameStats = new ArrayList<>(list); }
public List<Activity> getActivities() { return activities; }
public void setActivities(List<Activity> list) { this.activities = new ArrayList<>(list); }
public List<ActivityResident> getActivityResidents() { return activityResidents; }
public void setActivityResidents(List<ActivityResident> list) { this.activityResidents = new ArrayList<>(list); }
// -------------------- API Calls --------------------
public void fetchActualUser(Context context, Runnable onFinish) {
ApiClient.getActualUser(context, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
actualUser = UserParser.parseUser(jsonText);
fetchUserImage(context, actualUser.getAccountImage(), onFinish);
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener usuario: " + error);
onFinish.run();
}
});
}
private void fetchUserImage(Context context, String imageUrl, Runnable onFinish) {
ApiClient.downloadImage(context, imageUrl, new ApiClient.ImageCallback() {
@Override
public void onSuccess(Bitmap bitmap) {
actualUserImage = bitmap;
fetchUsers(context, onFinish);
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener imagen de usuario: " + error);
onFinish.run();
}
});
}
public void fetchUsers(Context context, Runnable onFinish) {
ApiClient.getUsers(context, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
users = UserParser.parseUsers(jsonText);
fetchResidents(context, onFinish);
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener usuarios: " + error);
onFinish.run();
}
});
}
public void fetchResidents(Context context, Runnable onFinish) {
ApiClient.getResidents(context, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
residents = ResidentParser.parseResidents(jsonText);
fetchGames(context, onFinish);
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener residentes: " + error);
onFinish.run();
}
});
}
public void fetchGames(Context context, Runnable onFinish) {
ApiClient.getGames(context, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
games = GameParser.parseGames(jsonText);
fetchGameStats(context, onFinish);
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener juegos: " + error);
onFinish.run();
}
});
}
public void fetchGameStats(Context context, Runnable onFinish) {
ApiClient.getGamesStats(context, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
gameStats = GameStatParser.parseStats(jsonText);
fetchActivities(context, onFinish);
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener partidas: " + error);
onFinish.run();
}
});
}
public void fetchActivities(Context context, Runnable onFinish) {
ApiClient.getAllActivities(context, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
activities = ActivityParser.parseActivities(jsonText);
if (activities.isEmpty()) {
onFinish.run();
} else {
fetchAllParticipants(context, onFinish);
}
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener actividades: " + error);
onFinish.run();
}
});
}
public void fetchAllParticipants(Context context, Runnable onFinish) {
activityResidents.clear();
final int total = activities.size();
final int[] completed = {0};
for (Activity activity : activities) {
ApiClient.getAllParticipants(context, activity.getId(), new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
List<ActivityResident> parsed = ActivityResidentParser.parseActivityResidents(jsonText);
synchronized (activityResidents) {
activityResidents.addAll(parsed);
}
checkDone();
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener participantes: " + error);
checkDone();
}
private void checkDone() {
synchronized (completed) {
completed[0]++;
if (completed[0] == total) {
onFinish.run();
}
}
}
});
}
}
public void fetchActualUserOnly(Context context, Runnable onFinish) {
ApiClient.getActualUser(context, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
actualUser = UserParser.parseUser(jsonText);
onFinish.run();
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener usuario: " + error);
onFinish.run();
}
});
}
public void fetchUserImageOnly(Context context, String imageUrl, Runnable onFinish) {
ApiClient.downloadImage(context, imageUrl, new ApiClient.ImageCallback() {
@Override
public void onSuccess(Bitmap bitmap) {
actualUserImage = bitmap;
onFinish.run();
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener imagen de usuario: " + error);
onFinish.run();
}
});
}
public void fetchUsersOnly(Context context, Runnable onFinish) {
ApiClient.getUsers(context, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
users = UserParser.parseUsers(jsonText);
onFinish.run();
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener usuarios: " + error);
onFinish.run();
}
});
}
public void fetchResidentsOnly(Context context, Runnable onFinish) {
ApiClient.getResidents(context, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
residents = ResidentParser.parseResidents(jsonText);
onFinish.run();
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener residentes: " + error);
onFinish.run();
}
});
}
public void fetchGamesOnly(Context context, Runnable onFinish) {
ApiClient.getGames(context, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
games = GameParser.parseGames(jsonText);
onFinish.run();
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener juegos: " + error);
onFinish.run();
}
});
}
public void fetchGameStatsOnly(Context context, Runnable onFinish) {
ApiClient.getGamesStats(context, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
gameStats = GameStatParser.parseStats(jsonText);
onFinish.run();
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener partidas: " + error);
onFinish.run();
}
});
}
public void fetchActivitiesOnly(Context context, Runnable onFinish) {
ApiClient.getAllActivities(context, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
activities = ActivityParser.parseActivities(jsonText);
onFinish.run();
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener actividades: " + error);
onFinish.run();
}
});
}
public void fetchParticipantsOnly(Context context, List<Activity> sourceActivities, Runnable onFinish) {
activityResidents.clear();
final int total = sourceActivities.size();
final int[] completed = {0};
if (total == 0) {
onFinish.run();
return;
}
for (Activity activity : sourceActivities) {
ApiClient.getAllParticipants(context, activity.getId(), new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
List<ActivityResident> parsed = ActivityResidentParser.parseActivityResidents(jsonText);
synchronized (activityResidents) {
activityResidents.addAll(parsed);
}
checkDone();
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener participantes: " + error);
checkDone();
}
private void checkDone() {
synchronized (completed) {
completed[0]++;
if (completed[0] == total) {
onFinish.run();
}
}
}
});
}
}
// -------------------- Otras acciones API --------------------
public void addActivity(Context context, String nombre, String descripcion, LocalDateTime fecha, Runnable onSuccess, Runnable onError) {
ApiClient.postEvento(context, nombre, descripcion, fecha, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
fetchActivities(context, onSuccess);
}
@Override
public void onError(String error) {
Log.e("API", "Error al añadir actividad: " + error);
onError.run();
}
});
}
public void deleteGameStat(Context context, long id, Runnable onSuccess) {
ApiClient.deleteGameStat(context, id, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
fetchGameStats(context, onSuccess);
}
@Override
public void onError(String error) {
Log.e("API", "Error al borrar partida: " + error);
onSuccess.run(); // puede seguir aunque falle
}
});
}
public void updateObservation(Context context, String comment, long id, Runnable onSuccess) {
ApiClient.patchObservation(context, comment, id, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
fetchGameStats(context, onSuccess);
}
@Override
public void onError(String error) {
Log.e("API", "Error al actualizar observación: " + error);
onSuccess.run();
}
});
}
public void changeActivityState(Context context, long id, ActivityState state, Runnable onSuccess) {
ApiClient.patchActivityState(context, id, state, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
fetchActivities(context, onSuccess);
}
@Override
public void onError(String error) {
Log.e("API", "Error al cambiar estado: " + error);
onSuccess.run();
}
});
}
}

View File

@ -1,7 +1,5 @@
package com.andresgmoran.apptrabajadores.ui; package com.andresgmoran.apptrabajadores.ui;
import static java.lang.Thread.sleep;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.os.Bundle; import android.os.Bundle;
@ -10,7 +8,12 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.Fragment;
import com.andresgmoran.apptrabajadores.R; import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.exceptions.ParserException; import com.andresgmoran.apptrabajadores.exceptions.ParserException;
import com.andresgmoran.apptrabajadores.interfaces.IOChangeFragmentListener; import com.andresgmoran.apptrabajadores.interfaces.IOChangeFragmentListener;
@ -21,6 +24,7 @@ import com.andresgmoran.apptrabajadores.interfaces.IOClickOnGameStatsListener;
import com.andresgmoran.apptrabajadores.interfaces.IOClickOnParticipantListener; import com.andresgmoran.apptrabajadores.interfaces.IOClickOnParticipantListener;
import com.andresgmoran.apptrabajadores.interfaces.IOClickOnResidentListener; import com.andresgmoran.apptrabajadores.interfaces.IOClickOnResidentListener;
import com.andresgmoran.apptrabajadores.interfaces.IOnChageStateActivityListener; import com.andresgmoran.apptrabajadores.interfaces.IOnChageStateActivityListener;
import com.andresgmoran.apptrabajadores.interfaces.IOnClickOnBackButtonListener;
import com.andresgmoran.apptrabajadores.models.Activity; import com.andresgmoran.apptrabajadores.models.Activity;
import com.andresgmoran.apptrabajadores.models.ActivityResident; import com.andresgmoran.apptrabajadores.models.ActivityResident;
import com.andresgmoran.apptrabajadores.models.ActivityState; import com.andresgmoran.apptrabajadores.models.ActivityState;
@ -35,44 +39,38 @@ import com.andresgmoran.apptrabajadores.models.parsers.GameStatParser;
import com.andresgmoran.apptrabajadores.models.parsers.ResidentParser; import com.andresgmoran.apptrabajadores.models.parsers.ResidentParser;
import com.andresgmoran.apptrabajadores.models.parsers.UserParser; import com.andresgmoran.apptrabajadores.models.parsers.UserParser;
import com.andresgmoran.apptrabajadores.network.ApiClient; import com.andresgmoran.apptrabajadores.network.ApiClient;
import com.andresgmoran.apptrabajadores.ui.fragments.account.AccountFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.account.EditAccountFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.activities.ActivitiesFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.activities.ActivityDetailFragment; import com.andresgmoran.apptrabajadores.ui.fragments.activities.ActivityDetailFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.activities.AddActivityFragment; import com.andresgmoran.apptrabajadores.ui.fragments.activities.AddActivityFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.activities.OpinionFragment; import com.andresgmoran.apptrabajadores.ui.fragments.activities.OpinionFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.activities.ParticipantSelectionDialogFragment; import com.andresgmoran.apptrabajadores.ui.fragments.activities.ParticipantSelectionDialogFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.authentication.LoginFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.game.GameFragment; import com.andresgmoran.apptrabajadores.ui.fragments.game.GameFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.gameDetail.GameDetailFragment; import com.andresgmoran.apptrabajadores.ui.fragments.gameDetail.GameDetailFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.authentication.LoginFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.account.AccountFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.account.EditAccountFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.activities.ActivitiesFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.home.HomeFragment; import com.andresgmoran.apptrabajadores.ui.fragments.home.HomeFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.resident.ResidentFragment; import com.andresgmoran.apptrabajadores.ui.fragments.resident.ResidentFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.residentList.ResidentsListFragment;
import com.andresgmoran.apptrabajadores.utils.SecurePreferencesUtil; import com.andresgmoran.apptrabajadores.utils.SecurePreferencesUtil;
import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.bottomnavigation.BottomNavigationView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.Fragment;
import com.google.android.material.navigation.NavigationBarView; import com.google.android.material.navigation.NavigationBarView;
import org.json.JSONObject;
import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import org.json.JSONObject;
public class MainActivity extends AppCompatActivity implements
NavigationBarView.OnItemSelectedListener, IOChangeFragmentListener, IOnClickOnBackButtonListener,
LoginFragment.OnLoginListener,
HomeFragment.IOnAttachListener,
IOClickOnResidentListener,
IOClickOnGameListener, IOClickOnGameStatsListener, GameDetailFragment.IOnAddObservationListener,
IOClickOnActivityListener, AddActivityFragment.IOnAddActivity, IOnChageStateActivityListener, ActivitiesFragment.IOOnAttachListener, ActivityDetailFragment.IOOnAttachListener,
IOClickOnParticipantListener, IOClickOnAddParticipantListener, ParticipantSelectionDialogFragment.OnParticipantSelectedListener,
OpinionFragment.OnAddOpinionListener,
AccountFragment.IOAccountFragmentListener {
public class MainActivity extends AppCompatActivity implements NavigationBarView.OnItemSelectedListener, LoginFragment.OnLoginListener, IOChangeFragmentListener, IOClickOnResidentListener, IOClickOnGameStatsListener, IOClickOnGameListener, IOClickOnActivityListener, private Fragment lastFragment = null;
ResidentsListFragment.IOOnAttachListener, HomeFragment.IOOnAttachListenerUser , HomeFragment.IOOnAttachListenerResidents, HomeFragment.IOOnAttachListenerGameStats, HomeFragment.IOOnAttachListenerGames, GameDetailFragment.IOnAddObservationListener,
AddActivityFragment.IOnAddActivity, IOnChageStateActivityListener, ActivitiesFragment.IOOnAttachListener, ActivityDetailFragment.IOOnAttachListener, IOClickOnParticipantListener, ParticipantSelectionDialogFragment.OnParticipantSelectedListener, IOClickOnAddParticipantListener,
OpinionFragment.OnAddOpinionListener, AccountFragment.IOAccountFragmentListener {
private User actualUser; private User actualUser;
private Bitmap actualUserImage; private Bitmap actualUserImage;
@ -104,9 +102,9 @@ public class MainActivity extends AppCompatActivity implements NavigationBarView
if (rememberPassword) { if (rememberPassword) {
if (token != null && System.currentTimeMillis() < expiration) { if (token != null && System.currentTimeMillis() < expiration) {
// Token válido
getActualUserFromAPI(); getActualUserFromAPI();
} else { } else {
Log.i( "AUTH", "Token no válido o expirado, intentando login automático");
// Token expirado: intentar login automático // Token expirado: intentar login automático
String email = SecurePreferencesUtil.getString(this, "email", null); String email = SecurePreferencesUtil.getString(this, "email", null);
String password = SecurePreferencesUtil.getString(this, "password", null); String password = SecurePreferencesUtil.getString(this, "password", null);
@ -131,13 +129,13 @@ public class MainActivity extends AppCompatActivity implements NavigationBarView
} }
@Override @Override
// --------------------------------------------------------------------- NAVIGATION ---------------------------------------------------------------------
public boolean onNavigationItemSelected(@NonNull MenuItem item) { public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Fragment f = null; Fragment f = null;
int id = item.getItemId(); int id = item.getItemId();
if (id == R.id.navigation_home) if (id == R.id.navigation_home)
f = createHomeFragment(); f = createHomeFragment();
else if (id == R.id.navigation_list)
f = new ResidentsListFragment();
else if (id == R.id.navigation_activities) else if (id == R.id.navigation_activities)
f = new ActivitiesFragment(); f = new ActivitiesFragment();
else if (id == R.id.navigation_account) else if (id == R.id.navigation_account)
@ -235,11 +233,16 @@ public class MainActivity extends AppCompatActivity implements NavigationBarView
* @return true si se ha cargado correctamente, false si no * @return true si se ha cargado correctamente, false si no
*/ */
private boolean loadFragment(Fragment fragment) { private boolean loadFragment(Fragment fragment) {
if (fragment != null) {
Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fcvMain);
if (currentFragment != null) {
lastFragment = currentFragment; // guarda el actual como "anterior"
}
}
if (fragment != null) { if (fragment != null) {
getSupportFragmentManager() getSupportFragmentManager()
.beginTransaction() .beginTransaction()
.replace(R.id.fcvMain, fragment) .replace(R.id.fcvMain, fragment)
.addToBackStack(null)
.commit(); .commit();
return true; return true;
} }
@ -325,31 +328,27 @@ public class MainActivity extends AppCompatActivity implements NavigationBarView
/** /**
* *
*/ */
private void reloadCurrentFragment() { private void reloadFragment(Fragment fragment) {
Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fcvMain); if (fragment == null) return;
if (currentFragment == null) return;
Bundle args = currentFragment.getArguments(); Bundle args = fragment.getArguments();
if (currentFragment instanceof HomeFragment) { if (fragment instanceof HomeFragment) {
loadFragment(createHomeFragment()); loadFragment(createHomeFragment());
} else if (currentFragment instanceof ResidentsListFragment) { } else if (fragment instanceof ResidentFragment && args != null) {
loadFragment(new ResidentsListFragment());
} else if (currentFragment instanceof ResidentFragment && args != null) {
Resident resident = (Resident) args.getSerializable("resident"); Resident resident = (Resident) args.getSerializable("resident");
if (resident != null) { if (resident != null) {
loadFragment(createResidentFragment(resident)); loadFragment(createResidentFragment(resident));
} }
} else if (currentFragment instanceof GameFragment && args != null) { } else if (fragment instanceof GameFragment && args != null) {
Game game = (Game) args.getSerializable("game"); Game game = (Game) args.getSerializable("game");
if (game != null) { if (game != null) {
loadFragment(createGameFragment(game)); loadFragment(createGameFragment(game));
} }
} else if (currentFragment instanceof GameDetailFragment && args != null) { } else if (fragment instanceof GameDetailFragment && args != null) {
GameStat originalStat = (GameStat) args.getSerializable("gameStat"); GameStat originalStat = (GameStat) args.getSerializable("gameStat");
Resident resident = (Resident) args.getSerializable("gameStatResident"); Resident resident = (Resident) args.getSerializable("gameStatResident");
Game game = (Game) args.getSerializable("gameStatGame"); Game game = (Game) args.getSerializable("gameStatGame");
@ -367,23 +366,34 @@ public class MainActivity extends AppCompatActivity implements NavigationBarView
} }
} }
} else if (currentFragment instanceof ActivitiesFragment) { } else if (fragment instanceof ActivitiesFragment) {
loadFragment(new ActivitiesFragment()); loadFragment(new ActivitiesFragment());
} else if (currentFragment instanceof ActivityDetailFragment && args != null) { } else if (fragment instanceof ActivityDetailFragment && args != null) {
Activity activity = (Activity) args.getSerializable("activity"); Activity originalActivity = (Activity) args.getSerializable("activity");
if (activity != null) { if (originalActivity != null) {
List<ActivityResident> participants = new ArrayList<>(); Activity updatedActivity = null;
for (ActivityResident ar : activityResidents) { for (Activity act : activities) {
if (ar.getActivityId() == activity.getId()) { if (act.getId() == originalActivity.getId()) {
participants.add(ar); updatedActivity = act;
break;
} }
} }
loadFragment(createActivityDetailFragment(activity, participants));
if (updatedActivity != null) {
List<ActivityResident> participants = new ArrayList<>();
for (ActivityResident ar : activityResidents) {
if (ar.getActivityId() == updatedActivity.getId()) {
participants.add(ar);
}
}
loadFragment(createActivityDetailFragment(updatedActivity, participants));
}
} }
} }
} }
// --------------------------------------------------------------------- GET DATOS FROM API --------------------------------------------------------------------- // --------------------------------------------------------------------- GET DATOS FROM API ---------------------------------------------------------------------
/** /**
@ -523,7 +533,8 @@ public class MainActivity extends AppCompatActivity implements NavigationBarView
Log.e("ResidentParser", e.getMessage()); Log.e("ResidentParser", e.getMessage());
} }
reloadCurrentFragment(); Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fcvMain);
reloadFragment(currentFragment);
} }
@Override @Override
@ -605,7 +616,8 @@ public class MainActivity extends AppCompatActivity implements NavigationBarView
Log.e("GameStatParser", e.getMessage()); Log.e("GameStatParser", e.getMessage());
} }
reloadCurrentFragment(); Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fcvMain);
reloadFragment(currentFragment);
} }
@Override @Override
@ -737,7 +749,8 @@ public class MainActivity extends AppCompatActivity implements NavigationBarView
final int[] completedRequests = {0}; final int[] completedRequests = {0};
if (totalActivities == 0) { if (totalActivities == 0) {
reloadCurrentFragment(); Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fcvMain);
reloadFragment(currentFragment);
return; return;
} }
@ -763,10 +776,12 @@ public class MainActivity extends AppCompatActivity implements NavigationBarView
} }
private void checkAndReload() { private void checkAndReload() {
Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fcvMain);
synchronized (completedRequests) { synchronized (completedRequests) {
completedRequests[0]++; completedRequests[0]++;
if (completedRequests[0] == totalActivities) { if (completedRequests[0] == totalActivities) {
runOnUiThread(() -> reloadCurrentFragment()); runOnUiThread(() ->
reloadFragment(currentFragment));
} }
} }
} }
@ -777,6 +792,9 @@ public class MainActivity extends AppCompatActivity implements NavigationBarView
// --------------------------------------------------------------------- OnClickListeners --------------------------------------------------------------------- // --------------------------------------------------------------------- OnClickListeners ---------------------------------------------------------------------
// --------------------------------------------------------------------- Resident listeners ---------------------------------------------------------------------
/** /**
* Listener para el click en un residente * Listener para el click en un residente
* @param resident residente sobre el que se ha hecho click * @param resident residente sobre el que se ha hecho click
@ -787,6 +805,42 @@ public class MainActivity extends AppCompatActivity implements NavigationBarView
loadFragment(f); loadFragment(f);
} }
/**
*
* @param resident
*/
@Override
public void onTakeOutResident(Resident resident) {
ApiClient.patchTakeOutResident( MainActivity.this, resident.getId(), new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
Toast.makeText(MainActivity.this, "Residente dado de baja correctamente", Toast.LENGTH_SHORT).show();
refreshResidentsAndReload();
refreshGameStatsAndReload();
}
@Override
public void onError(String error) {
Toast.makeText(MainActivity.this, "Error al dar de baja a residente", Toast.LENGTH_SHORT).show();
Log.e("API", "Error al eliminar residente: " + error);
}
});
}
// --------------------------------------------------------------------- Game listeners ---------------------------------------------------------------------
/**
* Listener para el click en un juego
* @param game juego sobre el que se ha hecho click
*/
@Override
public void onClickOnGame(Game game) {
Fragment f = createGameFragment(game);
loadFragment(f);
}
// --------------------------------------------------------------------- GameStats Listeners ---------------------------------------------------------------------
/** /**
* Listener para el click en una partida * Listener para el click en una partida
* @param gameStat partida sobre la que se ha hecho click * @param gameStat partida sobre la que se ha hecho click
@ -799,138 +853,62 @@ public class MainActivity extends AppCompatActivity implements NavigationBarView
} }
/** /**
* Listener para el click en un juego *
* @param game juego sobre el que se ha hecho click * @param gameStat
* @param gamestatGame
*/ */
@Override @Override
public void onClickOnGame(Game game) { public void onDeleteGameStat(GameStat gameStat, Game gamestatGame) {
Fragment f = createGameFragment(game); ApiClient.deleteGameStat(MainActivity.this, gameStat.getId(), new ApiClient.RawCallback() {
loadFragment(f); @Override
public void onSuccess(String jsonText) {
Toast.makeText(MainActivity.this, "Partida eliminada correctamente", Toast.LENGTH_SHORT).show();
refreshGameStatsAndReload();
}
@Override
public void onError(String error) {
Toast.makeText(MainActivity.this, "Error al eliminar partida", Toast.LENGTH_SHORT).show();
Log.e("API", "Error al eliminar partida: " + error);
}
});
} }
/**
*
* @param observation
* @param gameId
* @param gameStatId
*/
@Override
public void onAddObservation(String observation, long gameId, long gameStatId) {
ApiClient.patchObservation(MainActivity.this, observation, gameStatId, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
Toast.makeText(MainActivity.this, "Observación añadida correctamente", Toast.LENGTH_SHORT).show();
refreshGameStatsAndReload();
}
@Override
public void onError(String error) {
Toast.makeText(MainActivity.this, "Error al añadir observación", Toast.LENGTH_SHORT).show();
Log.e("API", "Error al añadir observación: " + error);
}
});
}
// --------------------------------------------------------------------- Activity Listeners ---------------------------------------------------------------------
/**
*
* @param activity
* @param participants
*/
@Override @Override
public void onClickOnActivity(Activity activity, List<ActivityResident> participants) { public void onClickOnActivity(Activity activity, List<ActivityResident> participants) {
loadFragment(createActivityDetailFragment(activity, participants)); loadFragment(createActivityDetailFragment(activity, participants));
} }
@Override
public void onChangeStateActivity(Activity activity, ActivityState state) {
ApiClient.patchActivityState(MainActivity.this, activity.getId(), state, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
Toast.makeText(MainActivity.this, "Actividad cerrada correctamente", Toast.LENGTH_SHORT).show();
refreshActivitiesAndReload();
}
@Override
public void onError(String error) {
Toast.makeText(MainActivity.this, "Error al cerrar actividad", Toast.LENGTH_SHORT).show();
Log.e("API", "Error al cerrar actividad: " + error);
}
});
}
@Override
public void onClickOnAddParticipant(Activity activity, List<ActivityResident> participants ,List<Resident> residents) {
ParticipantSelectionDialogFragment dialog = new ParticipantSelectionDialogFragment(activity, participants, residents);
dialog.show(getSupportFragmentManager(), "ParticipantDialog");
}
@Override
public void onClickOnParticipant(ActivityResident participant) {
Toast.makeText( this, "Clicked on participant: " + participant.getIdResident() , Toast.LENGTH_SHORT).show();
}
@Override
public void onClickOnAssistance(ActivityResident participant, boolean assistance ) {
String jsonBody = "{\"asistenciaPermitida\": " + assistance + "}";
ApiClient.patchParticipant( MainActivity.this, participant.getActivityId(), participant.getId() , jsonBody, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
Toast.makeText(MainActivity.this, "Asistencia actualizada correctamente", Toast.LENGTH_SHORT).show();
refreshActivitiesAndReload();
}
@Override
public void onError(String error) {
Toast.makeText(MainActivity.this, "Error al actualizar asistencia", Toast.LENGTH_SHORT).show();
Log.e("API", "Error al actualizar asistencia: " + error);
}
});
}
@Override
public void onClickOnOpinion(ActivityResident participant, boolean isPreOpinion) {
Fragment f = new OpinionFragment();
Bundle bundle = new Bundle();
bundle.putSerializable("participant", participant);
bundle.putBoolean("isPreOpinion", isPreOpinion);
f.setArguments(bundle);
loadFragment(f);
}
@Override
public void onAddOpinion(ActivityResident participant ,boolean isPreOpinion, String opinion) {
String jsonBody = "";
if (isPreOpinion) {
jsonBody = "{\"preOpinion\": \"" + opinion + "\"}";
} else {
jsonBody = "{\"postOpinion\": \"" + opinion + "\"}";
}
ApiClient.patchParticipant( MainActivity.this, participant.getActivityId(), participant.getId() , jsonBody, new ApiClient.RawCallback() {;
@Override
public void onSuccess(String jsonText) {
Toast.makeText(MainActivity.this, "Opinion actualizada correctamente", Toast.LENGTH_SHORT).show();
refreshActivitiesAndReload();
}
@Override
public void onError(String error) {
Toast.makeText(MainActivity.this, "Error al actualizar opinion", Toast.LENGTH_SHORT).show();
Log.e("API", "Error al actualizar opinion: " + error);
}
});
}
@Override
public void onClickOnMaterialHelp(ActivityResident participant, boolean materialHelp) {
String jsonBody = "{\"recursosMateriales\": " + materialHelp + "}";
ApiClient.patchParticipant( MainActivity.this, participant.getActivityId(), participant.getId() , jsonBody, new ApiClient.RawCallback() {;
@Override
public void onSuccess(String jsonText) {
Toast.makeText(MainActivity.this, "Ayuda material actualizada correctamente", Toast.LENGTH_SHORT).show();
refreshActivitiesAndReload();
}
@Override
public void onError(String error) {
Toast.makeText(MainActivity.this, "Error al actualizar ayuda material", Toast.LENGTH_SHORT).show();
Log.e("API", "Error al actualizar ayuda material: " + error);
}
});
}
@Override
public void onClickOnHumanHelp(ActivityResident participant, boolean humanHelp) {
String jsonBody = "{\"recursosHumanos\": " + humanHelp + "}";
ApiClient.patchParticipant( MainActivity.this, participant.getActivityId(), participant.getId() , jsonBody, new ApiClient.RawCallback() {;
@Override
public void onSuccess(String jsonText) {
Toast.makeText(MainActivity.this, "Ayuda humana actualizada correctamente", Toast.LENGTH_SHORT).show();
refreshActivitiesAndReload();
}
@Override
public void onError(String error) {
Toast.makeText(MainActivity.this, "Error al actualizar ayuda humana", Toast.LENGTH_SHORT).show();
Log.e("API", "Error al actualizar ayuda humana: " + error);
}
});
}
// --------------------------------------------------------------------- OnAddListeners ---------------------------------------------------------------------
/** /**
* *
* @param activityName * @param activityName
@ -958,23 +936,175 @@ public class MainActivity extends AppCompatActivity implements NavigationBarView
/** /**
* *
* @param observation * @param activity
* @param gameId
* @param gameStatId
*/ */
@Override @Override
public void onAddObservation(String observation, long gameId, long gameStatId) { public void onDeleteActivitie(Activity activity) {
ApiClient.patchObservation(MainActivity.this, observation, gameStatId, new ApiClient.RawCallback() { ApiClient.deleteActivity(MainActivity.this, activity.getId(), new ApiClient.RawCallback() {
@Override @Override
public void onSuccess(String jsonText) { public void onSuccess(String jsonText) {
Toast.makeText(MainActivity.this, "Observación añadida correctamente", Toast.LENGTH_SHORT).show(); Toast.makeText(MainActivity.this, "Actividad eliminada correctamente", Toast.LENGTH_SHORT).show();
refreshGameStatsAndReload(); refreshActivitiesAndReload();
} }
@Override @Override
public void onError(String error) { public void onError(String error) {
Toast.makeText(MainActivity.this, "Error al añadir observación", Toast.LENGTH_SHORT).show(); Toast.makeText(MainActivity.this, "Error al eliminar actividad", Toast.LENGTH_SHORT).show();
Log.e("API", "Error al añadir observación: " + error); Log.e("API", "Error al eliminar actividad: " + error);
}
});
}
@Override
public void onChangeStateActivity(Activity activity, ActivityState state) {
ApiClient.patchActivityState(MainActivity.this, activity.getId(), state, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
Toast.makeText(MainActivity.this, "Actividad cerrada correctamente", Toast.LENGTH_SHORT).show();
refreshActivitiesAndReload();
}
@Override
public void onError(String error) {
Toast.makeText(MainActivity.this, "Error al cerrar actividad", Toast.LENGTH_SHORT).show();
Log.e("API", "Error al cerrar actividad: " + error);
}
});
}
// --------------------------------------------------------------------- Participant Listeners ---------------------------------------------------------------------
/**
*
* @param activity
* @param participants
* @param residents
*/
@Override
public void onClickOnAddParticipant(Activity activity, List<ActivityResident> participants ,List<Resident> residents) {
ParticipantSelectionDialogFragment dialog = new ParticipantSelectionDialogFragment(activity, participants, residents);
dialog.show(getSupportFragmentManager(), "ParticipantDialog");
}
/**
*
* @param participant
*/
@Override
public void onClickOnParticipant(ActivityResident participant) {
Toast.makeText( this, "Clicked on participant: " + participant.getIdResident() , Toast.LENGTH_SHORT).show();
}
/**
*
* @param participant
* @param assistance
*/
@Override
public void onClickOnAssistance(ActivityResident participant, boolean assistance ) {
String jsonBody = "{\"asistenciaPermitida\": " + assistance + "}";
ApiClient.patchParticipant( MainActivity.this, participant.getActivityId(), participant.getId() , jsonBody, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
Toast.makeText(MainActivity.this, "Asistencia actualizada correctamente", Toast.LENGTH_SHORT).show();
refreshActivitiesAndReload();
}
@Override
public void onError(String error) {
Toast.makeText(MainActivity.this, "Error al actualizar asistencia", Toast.LENGTH_SHORT).show();
Log.e("API", "Error al actualizar asistencia: " + error);
}
});
}
/**
*
* @param participant
* @param isPreOpinion
*/
@Override
public void onClickOnOpinion(ActivityResident participant, boolean isPreOpinion) {
Fragment f = new OpinionFragment();
Bundle bundle = new Bundle();
bundle.putSerializable("participant", participant);
bundle.putBoolean("isPreOpinion", isPreOpinion);
f.setArguments(bundle);
loadFragment(f);
}
/**
*
* @param participant
* @param isPreOpinion
* @param opinion
*/
@Override
public void onAddOpinion(ActivityResident participant ,boolean isPreOpinion, String opinion) {
String jsonBody = "";
if (isPreOpinion) {
jsonBody = "{\"preOpinion\": \"" + opinion + "\"}";
} else {
jsonBody = "{\"postOpinion\": \"" + opinion + "\"}";
}
ApiClient.patchParticipant( MainActivity.this, participant.getActivityId(), participant.getId() , jsonBody, new ApiClient.RawCallback() {;
@Override
public void onSuccess(String jsonText) {
Toast.makeText(MainActivity.this, "Opinion actualizada correctamente", Toast.LENGTH_SHORT).show();
refreshActivitiesAndReload();
}
@Override
public void onError(String error) {
Toast.makeText(MainActivity.this, "Error al actualizar opinion", Toast.LENGTH_SHORT).show();
Log.e("API", "Error al actualizar opinion: " + error);
}
});
}
/**
*
* @param participant
* @param materialHelp
*/
@Override
public void onClickOnMaterialHelp(ActivityResident participant, boolean materialHelp) {
String jsonBody = "{\"recursosMateriales\": " + materialHelp + "}";
ApiClient.patchParticipant( MainActivity.this, participant.getActivityId(), participant.getId() , jsonBody, new ApiClient.RawCallback() {;
@Override
public void onSuccess(String jsonText) {
Toast.makeText(MainActivity.this, "Ayuda material actualizada correctamente", Toast.LENGTH_SHORT).show();
refreshActivitiesAndReload();
}
@Override
public void onError(String error) {
Toast.makeText(MainActivity.this, "Error al actualizar ayuda material", Toast.LENGTH_SHORT).show();
Log.e("API", "Error al actualizar ayuda material: " + error);
}
});
}
/**
*
* @param participant
* @param humanHelp
*/
@Override
public void onClickOnHumanHelp(ActivityResident participant, boolean humanHelp) {
String jsonBody = "{\"recursosHumanos\": " + humanHelp + "}";
ApiClient.patchParticipant( MainActivity.this, participant.getActivityId(), participant.getId() , jsonBody, new ApiClient.RawCallback() {;
@Override
public void onSuccess(String jsonText) {
Toast.makeText(MainActivity.this, "Ayuda humana actualizada correctamente", Toast.LENGTH_SHORT).show();
refreshActivitiesAndReload();
}
@Override
public void onError(String error) {
Toast.makeText(MainActivity.this, "Error al actualizar ayuda humana", Toast.LENGTH_SHORT).show();
Log.e("API", "Error al actualizar ayuda humana: " + error);
} }
}); });
} }
@ -1003,61 +1133,16 @@ public class MainActivity extends AppCompatActivity implements NavigationBarView
}); });
} }
@Override // --------------------------------------------------------------------- LogOut listener ---------------------------------------------------------------------
public void onDeleteGameStat(GameStat gameStat, Game gamestatGame) {
ApiClient.deleteGameStat(MainActivity.this, gameStat.getId(), new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
Toast.makeText(MainActivity.this, "Partida eliminada correctamente", Toast.LENGTH_SHORT).show();
refreshGameStatsAndReload();
}
@Override
public void onError(String error) {
Toast.makeText(MainActivity.this, "Error al eliminar partida", Toast.LENGTH_SHORT).show();
Log.e("API", "Error al eliminar partida: " + error);
}
});
}
@Override
public void onTakeOutResident(Resident resident) {
ApiClient.patchTakeOutResident( MainActivity.this, resident.getId(), new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
Toast.makeText(MainActivity.this, "Residente dado de baja correctamente", Toast.LENGTH_SHORT).show();
refreshResidentsAndReload();
refreshGameStatsAndReload();
}
@Override
public void onError(String error) {
Toast.makeText(MainActivity.this, "Error al dar de baja a residente", Toast.LENGTH_SHORT).show();
Log.e("API", "Error al eliminar residente: " + error);
}
});
}
@Override
public void onDeleteActivitie(Activity activity) {
ApiClient.deleteActivity(MainActivity.this, activity.getId(), new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
Toast.makeText(MainActivity.this, "Actividad eliminada correctamente", Toast.LENGTH_SHORT).show();
refreshActivitiesAndReload();
}
@Override
public void onError(String error) {
Toast.makeText(MainActivity.this, "Error al eliminar actividad", Toast.LENGTH_SHORT).show();
Log.e("API", "Error al eliminar actividad: " + error);
}
});
}
@Override @Override
public void onLogOutButtonClicked() { public void onLogOutButtonClicked() {
SecurePreferencesUtil.clear(MainActivity.this); SecurePreferencesUtil.clear(MainActivity.this);
loadFragment(new LoginFragment()); loadFragment(new LoginFragment());
} }
@Override
public void onClickOnBackButton() {
reloadFragment(lastFragment);
}
} }

View File

@ -22,7 +22,6 @@ import com.andresgmoran.apptrabajadores.models.ActivityResident;
import com.andresgmoran.apptrabajadores.models.Resident; import com.andresgmoran.apptrabajadores.models.Resident;
import com.andresgmoran.apptrabajadores.models.adapters.ActivitiesAdapter; import com.andresgmoran.apptrabajadores.models.adapters.ActivitiesAdapter;
import com.andresgmoran.apptrabajadores.ui.MainActivity; import com.andresgmoran.apptrabajadores.ui.MainActivity;
import com.andresgmoran.apptrabajadores.ui.fragments.residentList.ResidentsListFragment;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.List; import java.util.List;

View File

@ -1,7 +1,6 @@
package com.andresgmoran.apptrabajadores.ui.fragments.activities; package com.andresgmoran.apptrabajadores.ui.fragments.activities;
import android.content.Context; import android.content.Context;
import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -22,6 +21,7 @@ import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.interfaces.IOClickOnAddParticipantListener; import com.andresgmoran.apptrabajadores.interfaces.IOClickOnAddParticipantListener;
import com.andresgmoran.apptrabajadores.interfaces.IOClickOnParticipantListener; import com.andresgmoran.apptrabajadores.interfaces.IOClickOnParticipantListener;
import com.andresgmoran.apptrabajadores.interfaces.IOnChageStateActivityListener; import com.andresgmoran.apptrabajadores.interfaces.IOnChageStateActivityListener;
import com.andresgmoran.apptrabajadores.interfaces.IOnClickOnBackButtonListener;
import com.andresgmoran.apptrabajadores.models.Activity; import com.andresgmoran.apptrabajadores.models.Activity;
import com.andresgmoran.apptrabajadores.models.ActivityResident; import com.andresgmoran.apptrabajadores.models.ActivityResident;
import com.andresgmoran.apptrabajadores.models.ActivityState; import com.andresgmoran.apptrabajadores.models.ActivityState;
@ -39,15 +39,14 @@ public class ActivityDetailFragment extends Fragment {
private List<ActivityResident> participants; private List<ActivityResident> participants;
private List<Resident> residents; private List<Resident> residents;
private ImageButton backButton; private IOClickOnAddParticipantListener addParticipantListener;
private IOnChageStateActivityListener changeStateActivityListener;
private IOnClickOnBackButtonListener backButtonListener;
public interface IOOnAttachListener { public interface IOOnAttachListener {
List<Resident> getResidents(); List<Resident> getResidents();
} }
private IOClickOnAddParticipantListener addParticipantListener;
private IOnChageStateActivityListener changeStateActivityListener;
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
@ -57,62 +56,71 @@ public class ActivityDetailFragment extends Fragment {
@Override @Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
setupSwipeRefresh(view);
setupBackButton(view);
setupActivityInfo(view);
setupParticipantsStats(view);
setupAssistanceStats(view);
setupRecyclerView(view);
setupFab(view);
}
private void setupSwipeRefresh(View view) {
SwipeRefreshLayout swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_activity_detail); SwipeRefreshLayout swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_activity_detail);
swipeRefreshLayout.setOnRefreshListener(() -> { swipeRefreshLayout.setOnRefreshListener(() -> {
((MainActivity) requireActivity()).refreshActivitiesAndReload(); ((MainActivity) requireActivity()).refreshActivitiesAndReload();
swipeRefreshLayout.setRefreshing(false); swipeRefreshLayout.setRefreshing(false);
}); });
}
private void setupBackButton(View view) {
ImageButton backButton;
backButton = view.findViewById(R.id.back_button); backButton = view.findViewById(R.id.back_button);
backButton.setOnClickListener(v -> { backButton.setOnClickListener(v -> backButtonListener.onClickOnBackButton());
requireActivity().getSupportFragmentManager().popBackStack(); }
});
private void setupActivityInfo(View view) {
TextView activityName = view.findViewById(R.id.activitie_detail_name); TextView activityName = view.findViewById(R.id.activitie_detail_name);
MaterialButton startEndButton = view.findViewById(R.id.btn_start_end_activity);
if (activity.getState() == ActivityState.ABIERTO){
startEndButton.setVisibility(View.GONE);
} else {
startEndButton.setVisibility(View.VISIBLE);
ActivityState state = activity.getState();
if (state == ActivityState.CERRADO) {
startEndButton.setText("Iniciar actividad");
startEndButton.setBackgroundTintList(ContextCompat.getColorStateList(requireContext(), R.color.purple_200));
startEndButton.setOnClickListener(v -> {
changeStateActivityListener.onChangeStateActivity(activity, ActivityState.EN_CURSO);
});
} else if (state == ActivityState.EN_CURSO) {
startEndButton.setText("Finalizar actividad");
startEndButton.setBackgroundTintList(ContextCompat.getColorStateList(requireContext(), R.color.teal_200));
startEndButton.setOnClickListener(v -> {
changeStateActivityListener.onChangeStateActivity(activity, ActivityState.FINALIZADA);
});
} else if (state == ActivityState.FINALIZADA) {
startEndButton.setText("Actividad finalizada");
startEndButton.setBackgroundTintList(ContextCompat.getColorStateList(requireContext(), R.color.teal_200));
startEndButton.setEnabled(false);
}
}
TextView description = view.findViewById(R.id.tv_description_activity_detail); TextView description = view.findViewById(R.id.tv_description_activity_detail);
description.setText(activity.getDescription());
TextView activityDate = view.findViewById(R.id.tv_date_activity_detail); TextView activityDate = view.findViewById(R.id.tv_date_activity_detail);
TextView activityExitTime = view.findViewById(R.id.tv_exit_time_activity_detail); TextView activityExitTime = view.findViewById(R.id.tv_exit_time_activity_detail);
activityName.setText(activity.getName()); activityName.setText(activity.getName());
description.setText(activity.getDescription());
activityDate.setText(activity.getDate().toLocalDate().toString()); activityDate.setText(activity.getDate().toLocalDate().toString());
activityExitTime.setText(activity.getDate().toLocalTime().toString()); activityExitTime.setText(activity.getDate().toLocalTime().toString());
MaterialButton startEndButton = view.findViewById(R.id.btn_start_end_activity);
ActivityState state = activity.getState();
switch (state) {
case ABIERTO:
configureButton(startEndButton, "Cerrar actividad", R.color.purple_200, () ->
changeStateActivityListener.onChangeStateActivity(activity, ActivityState.CERRADO));
break;
case CERRADO:
configureButton(startEndButton, "Iniciar actividad", R.color.purple_200, () ->
changeStateActivityListener.onChangeStateActivity(activity, ActivityState.EN_CURSO));
break;
case EN_CURSO:
configureButton(startEndButton, "Finalizar actividad", R.color.teal_200, () ->
changeStateActivityListener.onChangeStateActivity(activity, ActivityState.FINALIZADA));
break;
case FINALIZADA:
startEndButton.setText("Actividad finalizada");
startEndButton.setBackgroundTintList(ContextCompat.getColorStateList(requireContext(), R.color.teal_200));
startEndButton.setEnabled(false);
break;
}
}
private void configureButton(MaterialButton button, String text, int colorRes, Runnable onClick) {
button.setText(text);
button.setBackgroundTintList(ContextCompat.getColorStateList(requireContext(), colorRes));
button.setOnClickListener(v -> onClick.run());
}
private void setupParticipantsStats(View view) {
List<ActivityResident> activityParticipants = new ArrayList<>(); List<ActivityResident> activityParticipants = new ArrayList<>();
for (ActivityResident p : participants) { for (ActivityResident p : participants) {
if (p.getActivityId() == activity.getId()) { if (p.getActivityId() == activity.getId()) {
@ -121,47 +129,45 @@ public class ActivityDetailFragment extends Fragment {
} }
TextView totalParticipants = view.findViewById(R.id.tv_total_participants_activity_detail); TextView totalParticipants = view.findViewById(R.id.tv_total_participants_activity_detail);
totalParticipants.setText(String.valueOf(activityParticipants.size()));
TextView confirmedParticipants = view.findViewById(R.id.tv_confirmed_residents); TextView confirmedParticipants = view.findViewById(R.id.tv_confirmed_residents);
TextView notGoingParticipants = view.findViewById(R.id.tv_unconfirmed_residents); TextView notGoingParticipants = view.findViewById(R.id.tv_unconfirmed_residents);
int goingCount = 0;
int notGoingCount = 0; int goingCount = 0, notGoingCount = 0;
for (ActivityResident p : activityParticipants) { for (ActivityResident p : activityParticipants) {
if (p.isAssistance()) { if (p.isAssistance()) goingCount++;
goingCount++; else notGoingCount++;
} else {
notGoingCount++;
}
} }
totalParticipants.setText(String.valueOf(activityParticipants.size()));
confirmedParticipants.setText(String.valueOf(goingCount)); confirmedParticipants.setText(String.valueOf(goingCount));
notGoingParticipants.setText(String.valueOf(notGoingCount)); notGoingParticipants.setText(String.valueOf(notGoingCount));
}
private void setupAssistanceStats(View view) {
TextView humanAssistance = view.findViewById(R.id.tv_required_human_attendance); TextView humanAssistance = view.findViewById(R.id.tv_required_human_attendance);
TextView materialAssistance = view.findViewById(R.id.tv_required_material_attendance); TextView materialAssistance = view.findViewById(R.id.tv_required_material_attendance);
int humanAssistanceCount = 0; int humanCount = 0, materialCount = 0;
int materialAssistanceCount = 0; for (ActivityResident p : participants) {
for (ActivityResident p : activityParticipants) { if (p.getActivityId() == activity.getId()) {
if (p.isHumanHelp()) { if (p.isHumanHelp()) humanCount++;
humanAssistanceCount++; else if (p.isMaterialHelp()) materialCount++;
} else if (p.isMaterialHelp()) {
materialAssistanceCount++;
} }
} }
humanAssistance.setText(String.valueOf(humanAssistanceCount));
materialAssistance.setText(String.valueOf(materialAssistanceCount));
humanAssistance.setText(String.valueOf(humanCount));
materialAssistance.setText(String.valueOf(materialCount));
}
private void setupRecyclerView(View view) {
RecyclerView recyclerView = view.findViewById(R.id.rv_participants); RecyclerView recyclerView = view.findViewById(R.id.rv_participants);
ParticipantsAdapter participantsAdapter = new ParticipantsAdapter(requireContext() , activity, participants, residents, (IOClickOnParticipantListener) requireActivity()); ParticipantsAdapter adapter = new ParticipantsAdapter(requireContext(), activity, participants, residents, (IOClickOnParticipantListener) requireActivity());
recyclerView.setAdapter(participantsAdapter); recyclerView.setAdapter(adapter);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false)); recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
recyclerView.setHasFixedSize(true);
}
private void setupFab(View view) {
MaterialButton fab = view.findViewById(R.id.add_participant_button); MaterialButton fab = view.findViewById(R.id.add_participant_button);
if (activity.getState() == ActivityState.CERRADO) { if (activity.getState() == ActivityState.CERRADO) {
fab.setVisibility(View.GONE); fab.setVisibility(View.GONE);
@ -171,7 +177,6 @@ public class ActivityDetailFragment extends Fragment {
); );
NestedScrollView scrollView = view.findViewById(R.id.nested_scroll_game_detail); NestedScrollView scrollView = view.findViewById(R.id.nested_scroll_game_detail);
scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() { scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
private int lastScrollY = 0; private int lastScrollY = 0;
private boolean isButtonVisible = true; private boolean isButtonVisible = true;
@ -179,11 +184,9 @@ public class ActivityDetailFragment extends Fragment {
@Override @Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
if (scrollY > lastScrollY + 10 && isButtonVisible) { if (scrollY > lastScrollY + 10 && isButtonVisible) {
// Scroll hacia abajo: ocultar con animación
fab.animate().translationY(fab.getHeight() + 50).alpha(0.0f).setDuration(200).withEndAction(() -> fab.setVisibility(View.GONE)); fab.animate().translationY(fab.getHeight() + 50).alpha(0.0f).setDuration(200).withEndAction(() -> fab.setVisibility(View.GONE));
isButtonVisible = false; isButtonVisible = false;
} else if (scrollY < lastScrollY - 10 && !isButtonVisible) { } else if (scrollY < lastScrollY - 10 && !isButtonVisible) {
// Scroll hacia arriba: mostrar con animación
fab.setVisibility(View.VISIBLE); fab.setVisibility(View.VISIBLE);
fab.setAlpha(0f); fab.setAlpha(0f);
fab.setTranslationY(fab.getHeight() + 50); fab.setTranslationY(fab.getHeight() + 50);
@ -198,19 +201,16 @@ public class ActivityDetailFragment extends Fragment {
@Override @Override
public void onAttach(@NonNull Context context) { public void onAttach(@NonNull Context context) {
super.onAttach(context);
if (getArguments() != null) { if (getArguments() != null) {
activity = (Activity) getArguments().getSerializable("activity"); activity = (Activity) getArguments().getSerializable("activity");
participants = (List<ActivityResident>) getArguments().getSerializable("participants"); participants = (List<ActivityResident>) getArguments().getSerializable("participants");
} }
if (context instanceof IOOnAttachListener) { residents = ((IOOnAttachListener) context).getResidents();
residents = ((IOOnAttachListener) context).getResidents();
} else {
throw new RuntimeException(context.toString() + " must implement IOOnAttachListener");
}
addParticipantListener = (IOClickOnAddParticipantListener) context; addParticipantListener = (IOClickOnAddParticipantListener) context;
changeStateActivityListener = (IOnChageStateActivityListener) context; changeStateActivityListener = (IOnChageStateActivityListener) context;
super.onAttach(context); backButtonListener = (IOnClickOnBackButtonListener) context;
} }
} }

View File

@ -18,6 +18,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.andresgmoran.apptrabajadores.R; import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.interfaces.IOClickOnGameStatsListener; import com.andresgmoran.apptrabajadores.interfaces.IOClickOnGameStatsListener;
import com.andresgmoran.apptrabajadores.interfaces.IOnClickOnBackButtonListener;
import com.andresgmoran.apptrabajadores.models.Game; import com.andresgmoran.apptrabajadores.models.Game;
import com.andresgmoran.apptrabajadores.models.Resident; import com.andresgmoran.apptrabajadores.models.Resident;
import com.andresgmoran.apptrabajadores.models.adapters.LastGamesAdapter; import com.andresgmoran.apptrabajadores.models.adapters.LastGamesAdapter;
@ -33,6 +34,8 @@ public class GameFragment extends Fragment {
private List<Resident> residents; private List<Resident> residents;
private Game game; private Game game;
private IOnClickOnBackButtonListener backButtonListener;
private TextView gameNameTextView; private TextView gameNameTextView;
private TextView numberOfGamesLastWeekTextView; private TextView numberOfGamesLastWeekTextView;
private TextView totalGamesPlayedTextView; private TextView totalGamesPlayedTextView;
@ -61,7 +64,7 @@ public class GameFragment extends Fragment {
backButton = view.findViewById(R.id.back_button); backButton = view.findViewById(R.id.back_button);
backButton.setOnClickListener(v -> { backButton.setOnClickListener(v -> {
requireActivity().getSupportFragmentManager().popBackStack(); backButtonListener.onClickOnBackButton();
}); });
List<GameStat> allGameStats = new ArrayList<>(); List<GameStat> allGameStats = new ArrayList<>();
@ -142,7 +145,9 @@ public class GameFragment extends Fragment {
gameStats = (List<GameStat>) getArguments().getSerializable("gameStats"); gameStats = (List<GameStat>) getArguments().getSerializable("gameStats");
residents = (List<Resident>) getArguments().getSerializable("residents"); residents = (List<Resident>) getArguments().getSerializable("residents");
game = (Game) getArguments().getSerializable("game"); game = (Game) getArguments().getSerializable("game");
} }
backButtonListener = (IOnClickOnBackButtonListener) context;
} }
} }

View File

@ -16,6 +16,7 @@ import androidx.fragment.app.Fragment;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.andresgmoran.apptrabajadores.R; import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.interfaces.IOnClickOnBackButtonListener;
import com.andresgmoran.apptrabajadores.models.Game; import com.andresgmoran.apptrabajadores.models.Game;
import com.andresgmoran.apptrabajadores.models.Resident; import com.andresgmoran.apptrabajadores.models.Resident;
import com.andresgmoran.apptrabajadores.models.User; import com.andresgmoran.apptrabajadores.models.User;
@ -31,6 +32,7 @@ public class GameDetailFragment extends Fragment {
List<User> getUsers(); List<User> getUsers();
} }
private IOnAddObservationListener addObservationListener; private IOnAddObservationListener addObservationListener;
private IOnClickOnBackButtonListener backButtonListener;
private GameStat gameStat; private GameStat gameStat;
private Resident gameStatResident; private Resident gameStatResident;
@ -64,7 +66,7 @@ public class GameDetailFragment extends Fragment {
backButton = view.findViewById(R.id.back_button); backButton = view.findViewById(R.id.back_button);
backButton.setOnClickListener(v -> { backButton.setOnClickListener(v -> {
requireActivity().getSupportFragmentManager().popBackStack(); backButtonListener.onClickOnBackButton();
}); });
residentNameTextView = view.findViewById(R.id.banner_name_resident); residentNameTextView = view.findViewById(R.id.banner_name_resident);
@ -129,11 +131,8 @@ public class GameDetailFragment extends Fragment {
public void onAttach(@NonNull Context context) { public void onAttach(@NonNull Context context) {
super.onAttach(context); super.onAttach(context);
if (context instanceof IOnAddObservationListener) { addObservationListener = (IOnAddObservationListener) context;
addObservationListener = (IOnAddObservationListener) context; backButtonListener = (IOnClickOnBackButtonListener) context;
} else {
throw new RuntimeException(context.toString() + " must implement IOnAddObservationListener");
}
users = addObservationListener.getUsers(); users = addObservationListener.getUsers();

View File

@ -3,17 +3,16 @@ package com.andresgmoran.apptrabajadores.ui.fragments.home;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@ -29,9 +28,8 @@ import com.andresgmoran.apptrabajadores.models.adapters.GamesAdapter;
import com.andresgmoran.apptrabajadores.models.adapters.LastGamesAdapter; import com.andresgmoran.apptrabajadores.models.adapters.LastGamesAdapter;
import com.andresgmoran.apptrabajadores.models.adapters.ResidentsAdapter; import com.andresgmoran.apptrabajadores.models.adapters.ResidentsAdapter;
import com.andresgmoran.apptrabajadores.models.gameStats.GameStat; import com.andresgmoran.apptrabajadores.models.gameStats.GameStat;
import com.andresgmoran.apptrabajadores.network.ApiClient;
import com.andresgmoran.apptrabajadores.ui.MainActivity; import com.andresgmoran.apptrabajadores.ui.MainActivity;
import com.bumptech.glide.Glide; import com.andresgmoran.apptrabajadores.viewmodel.HomeViewModel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -40,18 +38,10 @@ import java.util.List;
public class HomeFragment extends Fragment { public class HomeFragment extends Fragment {
public interface IOOnAttachListenerResidents { public interface IOnAttachListener {
List<Resident> getResidents(); List<Resident> getResidents();
}
public interface IOOnAttachListenerGameStats {
List<GameStat> getGameStats(); List<GameStat> getGameStats();
}
public interface IOOnAttachListenerGames {
List<Game> getGames(); List<Game> getGames();
}
public interface IOOnAttachListenerUser {
User getActualUser(); User getActualUser();
Bitmap getActualUserImage(); Bitmap getActualUserImage();
} }
@ -62,15 +52,14 @@ public class HomeFragment extends Fragment {
private User user; private User user;
private Bitmap userImageBitmap; private Bitmap userImageBitmap;
private TextView userNameTextView; private TextView userNameTextView;
private RecyclerView recyclerViewLastGames;
private TextView emptyLatestGamesText;
private RecyclerView recyclerViewGames;
private TextView emptyGamesText;
private RecyclerView recyclerViewResidents;
private TextView emptyResidentsText;
private ImageView userImage; private ImageView userImage;
private RecyclerView recyclerViewLastGames;
private RecyclerView recyclerViewGames;
private RecyclerView recyclerViewResidents;
private TextView emptyLatestGamesText;
private TextView emptyGamesText;
private TextView emptyResidentsText;
private GamesAdapter gamesAdapter; private GamesAdapter gamesAdapter;
private ResidentsAdapter residentsAdapter; private ResidentsAdapter residentsAdapter;
@ -84,24 +73,35 @@ public class HomeFragment extends Fragment {
@Override @Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
setupSwipeRefresh(view);
setupUserInfo(view);
setupLastGamesList(view);
setupGamesList(view);
setupResidentsList(view);
setupFilterButtons(view);
}
private void setupSwipeRefresh(View view) {
SwipeRefreshLayout swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_home); SwipeRefreshLayout swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_home);
swipeRefreshLayout.setOnRefreshListener(() -> { swipeRefreshLayout.setOnRefreshListener(() -> {
((MainActivity) requireActivity()).refreshGameStatsAndReload(); ((MainActivity) requireActivity()).refreshGameStatsAndReload();
swipeRefreshLayout.setRefreshing(false); swipeRefreshLayout.setRefreshing(false);
}); });
}
private void setupUserInfo(View view) {
userNameTextView = view.findViewById(R.id.home_user_name); userNameTextView = view.findViewById(R.id.home_user_name);
String fullName = user.getName() + " " + user.getSurnames();
userNameTextView.setText(fullName);
userImage = view.findViewById(R.id.user_image_home); userImage = view.findViewById(R.id.user_image_home);
userNameTextView.setText(user.getName() + " " + user.getSurnames());
userImage.setImageBitmap(userImageBitmap); userImage.setImageBitmap(userImageBitmap);
}
private void setupLastGamesList(View view) {
emptyLatestGamesText = view.findViewById(R.id.tv_lastgames_empty_home); emptyLatestGamesText = view.findViewById(R.id.tv_lastgames_empty_home);
LastGamesAdapter lastGamesAdapter = new LastGamesAdapter(gameStats, games, residents, (IOClickOnGameStatsListener) requireActivity());
recyclerViewLastGames = view.findViewById(R.id.latestGames_recycleView_home); recyclerViewLastGames = view.findViewById(R.id.latestGames_recycleView_home);
recyclerViewLastGames.setAdapter(lastGamesAdapter);
LastGamesAdapter adapter = new LastGamesAdapter(gameStats, games, residents, (IOClickOnGameStatsListener) requireActivity());
recyclerViewLastGames.setAdapter(adapter);
recyclerViewLastGames.setHasFixedSize(true); recyclerViewLastGames.setHasFixedSize(true);
recyclerViewLastGames.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false)); recyclerViewLastGames.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false));
@ -112,13 +112,16 @@ public class HomeFragment extends Fragment {
recyclerViewLastGames.setVisibility(View.VISIBLE); recyclerViewLastGames.setVisibility(View.VISIBLE);
emptyLatestGamesText.setVisibility(View.GONE); emptyLatestGamesText.setVisibility(View.GONE);
} }
}
private void setupGamesList(View view) {
emptyGamesText = view.findViewById(R.id.tv_games_empty_home); emptyGamesText = view.findViewById(R.id.tv_games_empty_home);
gamesAdapter = new GamesAdapter(games, (IOClickOnGameListener) requireActivity());
recyclerViewGames = view.findViewById(R.id.games_recycleView_home); recyclerViewGames = view.findViewById(R.id.games_recycleView_home);
gamesAdapter = new GamesAdapter(games, (IOClickOnGameListener) requireActivity());
recyclerViewGames.setAdapter(gamesAdapter); recyclerViewGames.setAdapter(gamesAdapter);
recyclerViewGames.setHasFixedSize(true); recyclerViewGames.setHasFixedSize(true);
recyclerViewGames.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false)); recyclerViewGames.setLayoutManager(new LinearLayoutManager(getActivity()));
if (games.isEmpty()) { if (games.isEmpty()) {
recyclerViewGames.setVisibility(View.GONE); recyclerViewGames.setVisibility(View.GONE);
@ -127,13 +130,16 @@ public class HomeFragment extends Fragment {
recyclerViewGames.setVisibility(View.VISIBLE); recyclerViewGames.setVisibility(View.VISIBLE);
emptyGamesText.setVisibility(View.GONE); emptyGamesText.setVisibility(View.GONE);
} }
}
private void setupResidentsList(View view) {
emptyResidentsText = view.findViewById(R.id.tv_residents_empty_home); emptyResidentsText = view.findViewById(R.id.tv_residents_empty_home);
residentsAdapter = new ResidentsAdapter(residents, (IOClickOnResidentListener) requireActivity());
recyclerViewResidents = view.findViewById(R.id.residents_recycleView_home); recyclerViewResidents = view.findViewById(R.id.residents_recycleView_home);
residentsAdapter = new ResidentsAdapter(residents, (IOClickOnResidentListener) requireActivity());
recyclerViewResidents.setAdapter(residentsAdapter); recyclerViewResidents.setAdapter(residentsAdapter);
recyclerViewResidents.setHasFixedSize(true); recyclerViewResidents.setHasFixedSize(true);
recyclerViewResidents.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false)); recyclerViewResidents.setLayoutManager(new LinearLayoutManager(getActivity()));
if (residents.isEmpty()) { if (residents.isEmpty()) {
recyclerViewResidents.setVisibility(View.GONE); recyclerViewResidents.setVisibility(View.GONE);
@ -142,7 +148,9 @@ public class HomeFragment extends Fragment {
recyclerViewResidents.setVisibility(View.VISIBLE); recyclerViewResidents.setVisibility(View.VISIBLE);
emptyResidentsText.setVisibility(View.GONE); emptyResidentsText.setVisibility(View.GONE);
} }
}
private void setupFilterButtons(View view) {
View filterGamesButton = view.findViewById(R.id.filter_games_list_button); View filterGamesButton = view.findViewById(R.id.filter_games_list_button);
View filterResidentsButton = view.findViewById(R.id.filter_residents_list_button); View filterResidentsButton = view.findViewById(R.id.filter_residents_list_button);
@ -153,19 +161,13 @@ public class HomeFragment extends Fragment {
@Override @Override
public void onAttach(@NonNull Context context) { public void onAttach(@NonNull Context context) {
super.onAttach(context); super.onAttach(context);
IOnAttachListener attachListener = (IOnAttachListener) context;
IOOnAttachListenerUser attachListenerActualUser = (IOOnAttachListenerUser) context; user = attachListener.getActualUser();
user = attachListenerActualUser.getActualUser(); userImageBitmap = attachListener.getActualUserImage();
userImageBitmap = attachListenerActualUser.getActualUserImage(); residents = attachListener.getResidents();
games = attachListener.getGames();
IOOnAttachListenerGameStats attachListenerLastGames = (IOOnAttachListenerGameStats) context; gameStats = attachListener.getGameStats();
gameStats = attachListenerLastGames.getGameStats();
IOOnAttachListenerResidents attachListenerResidents = (IOOnAttachListenerResidents) context;
residents = attachListenerResidents.getResidents();
IOOnAttachListenerGames attachListenerGames = (IOOnAttachListenerGames) context;
games = attachListenerGames.getGames();
} }
private void showGamesFilterDialog() { private void showGamesFilterDialog() {
@ -173,10 +175,7 @@ public class HomeFragment extends Fragment {
new androidx.appcompat.app.AlertDialog.Builder(requireContext()) new androidx.appcompat.app.AlertDialog.Builder(requireContext())
.setTitle("Filtrar juegos") .setTitle("Filtrar juegos")
.setItems(options, (dialog, which) -> { .setItems(options, (dialog, which) -> filterGamesList(options[which]))
String selectedOption = options[which];
filterGamesList(selectedOption);
})
.show(); .show();
} }
@ -185,10 +184,7 @@ public class HomeFragment extends Fragment {
new androidx.appcompat.app.AlertDialog.Builder(requireContext()) new androidx.appcompat.app.AlertDialog.Builder(requireContext())
.setTitle("Filtrar residentes") .setTitle("Filtrar residentes")
.setItems(options, (dialog, which) -> { .setItems(options, (dialog, which) -> filterResidentsList(options[which]))
String selectedOption = options[which];
filterResidentsList(selectedOption);
})
.show(); .show();
} }
@ -197,26 +193,16 @@ public class HomeFragment extends Fragment {
switch (option) { switch (option) {
case "A-Z": case "A-Z":
Collections.sort(filteredList, Comparator.comparing(Game::getName)); filteredList.sort(Comparator.comparing(Game::getName));
break; break;
case "Z-A": case "Z-A":
Collections.sort(filteredList, (g1, g2) -> g2.getName().compareTo(g1.getName())); filteredList.sort((g1, g2) -> g2.getName().compareTo(g1.getName()));
break; break;
case "Más jugados": case "Más jugados":
Collections.sort(filteredList, (g1, g2) -> { filteredList.sort((g1, g2) -> {
int count1 = 0; long count1 = gameStats.stream().filter(stat -> stat.getGameId() == g1.getId()).count();
int count2 = 0; long count2 = gameStats.stream().filter(stat -> stat.getGameId() == g2.getId()).count();
return Long.compare(count2, count1);
for (GameStat stat : gameStats) {
if (stat.getGameId() == g1.getId()) {
count1++;
}
if (stat.getGameId() == g2.getId()) {
count2++;
}
}
return Integer.compare(count2, count1); // Mayor a menor
}); });
break; break;
} }
@ -230,13 +216,13 @@ public class HomeFragment extends Fragment {
switch (option) { switch (option) {
case "A-Z": case "A-Z":
Collections.sort(filteredList, Comparator.comparing(Resident::getName)); filteredList.sort(Comparator.comparing(Resident::getName));
break; break;
case "Z-A": case "Z-A":
Collections.sort(filteredList, (r1, r2) -> r2.getName().compareTo(r1.getName())); filteredList.sort((r1, r2) -> r2.getName().compareTo(r1.getName()));
break; break;
case "Fecha de nacimiento": case "Fecha de nacimiento":
Collections.sort(filteredList, Comparator.comparing(Resident::getBirthDate)); filteredList.sort(Comparator.comparing(Resident::getBirthDate));
break; break;
} }

View File

@ -20,6 +20,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.andresgmoran.apptrabajadores.R; import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.interfaces.IOClickOnGameStatsListener; import com.andresgmoran.apptrabajadores.interfaces.IOClickOnGameStatsListener;
import com.andresgmoran.apptrabajadores.interfaces.IOnClickOnBackButtonListener;
import com.andresgmoran.apptrabajadores.models.Game; import com.andresgmoran.apptrabajadores.models.Game;
import com.andresgmoran.apptrabajadores.models.Resident; import com.andresgmoran.apptrabajadores.models.Resident;
import com.andresgmoran.apptrabajadores.models.adapters.LastGamesAdapter; import com.andresgmoran.apptrabajadores.models.adapters.LastGamesAdapter;
@ -45,6 +46,8 @@ public class ResidentFragment extends Fragment {
private TextView tvLastGamesEmpty; private TextView tvLastGamesEmpty;
private TextView tvStatsEmpty; private TextView tvStatsEmpty;
private IOnClickOnBackButtonListener backButtonListener;
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
@ -70,7 +73,7 @@ public class ResidentFragment extends Fragment {
backButton = banner.findViewById(R.id.back_button); backButton = banner.findViewById(R.id.back_button);
backButton.setOnClickListener(v -> { backButton.setOnClickListener(v -> {
requireActivity().getSupportFragmentManager().popBackStack(); backButtonListener.onClickOnBackButton();
}); });
residentName = banner.findViewById(R.id.banner_name_game); residentName = banner.findViewById(R.id.banner_name_game);
@ -268,6 +271,8 @@ public class ResidentFragment extends Fragment {
games = (ArrayList<Game>) args.getSerializable("games"); games = (ArrayList<Game>) args.getSerializable("games");
gameStats = (ArrayList<GameStat>) args.getSerializable("gameStats"); gameStats = (ArrayList<GameStat>) args.getSerializable("gameStats");
} }
backButtonListener = (IOnClickOnBackButtonListener) context;
} }
} }

View File

@ -1,92 +0,0 @@
package com.andresgmoran.apptrabajadores.ui.fragments.residentList;
import android.content.Context;
import android.os.Bundle;
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.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.interfaces.IOClickOnResidentListener;
import com.andresgmoran.apptrabajadores.models.Resident;
import com.andresgmoran.apptrabajadores.models.adapters.ResidentsAdapter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ResidentsListFragment extends Fragment {
private ResidentsAdapter residentsAdapter;
private RecyclerView recyclerViewResidents;
public interface IOOnAttachListener{
List<Resident> getResidents();
}
private List<Resident> residents;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate( R.layout.fragment_residents_list, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
residentsAdapter = new ResidentsAdapter(residents, (IOClickOnResidentListener) requireActivity());
recyclerViewResidents = view.findViewById(R.id.residents_recycleView);
recyclerViewResidents.setAdapter(residentsAdapter);
recyclerViewResidents.setHasFixedSize(true);
recyclerViewResidents.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
View filterResidentsButton = view.findViewById(R.id.filter_residents_list_button);
filterResidentsButton.setOnClickListener(v -> showResidentsFilterDialog());
}
private void showResidentsFilterDialog() {
String[] options = {"A-Z", "Z-A", "Fecha de nacimiento"};
new androidx.appcompat.app.AlertDialog.Builder(requireContext())
.setTitle("Filtrar residentes")
.setItems(options, (dialog, which) -> {
String selectedOption = options[which];
filterResidentsList(selectedOption);
})
.show();
}
private void filterResidentsList(String option) {
List<Resident> filteredList = new ArrayList<>(residents);
switch (option) {
case "A-Z":
Collections.sort(filteredList, Comparator.comparing(Resident::getName));
break;
case "Z-A":
Collections.sort(filteredList, (r1, r2) -> r2.getName().compareTo(r1.getName()));
break;
case "Fecha de nacimiento":
Collections.sort(filteredList, Comparator.comparing(Resident::getBirthDate));
break;
}
residentsAdapter.updateData(filteredList);
recyclerViewResidents.scrollToPosition(0);
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
ResidentsListFragment.IOOnAttachListener attachListener = (ResidentsListFragment.IOOnAttachListener) context;
residents = attachListener.getResidents();
}
}

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
android:height="108dp"
android:width="108dp"
android:viewportHeight="108"
android:viewportWidth="108"
xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z"/>
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
</vector>

View File

@ -45,7 +45,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:fontFamily="@font/assistant_bold" android:fontFamily="@font/assistant_bold"
android:text="Últimas partidas" android:text="@string/last_games_list_title"
android:textColor="#324F5E" android:textColor="#324F5E"
android:textSize="20sp" /> android:textSize="20sp" />
@ -77,7 +77,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:fontFamily="@font/assistant_semibold" android:fontFamily="@font/assistant_semibold"
android:text="No hay partidas disponibles" android:text="@string/no_last_games_available_text"
android:textColor="#96A7AF" android:textColor="#96A7AF"
android:visibility="gone" android:visibility="gone"
app:layout_constraintEnd_toEndOf="@+id/linearLayout2" app:layout_constraintEnd_toEndOf="@+id/linearLayout2"
@ -91,7 +91,7 @@
android:layout_marginHorizontal="20dp" android:layout_marginHorizontal="20dp"
android:layout_marginTop="20dp" android:layout_marginTop="20dp"
android:fontFamily="@font/assistant_bold" android:fontFamily="@font/assistant_bold"
android:text="Estadísticas" android:text="@string/stats_title"
android:textColor="#324F5E" android:textColor="#324F5E"
android:textSize="20sp" android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
@ -105,7 +105,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:fontFamily="@font/assistant_semibold" android:fontFamily="@font/assistant_semibold"
android:text="No hay estadisticas disponibles" android:text="@string/no_stats_available_text"
android:textColor="#96A7AF" android:textColor="#96A7AF"
android:visibility="gone" android:visibility="gone"
app:layout_constraintEnd_toEndOf="@+id/textView16" app:layout_constraintEnd_toEndOf="@+id/textView16"

View File

@ -1,48 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCCCCC">
<LinearLayout
android:id="@+id/linearLayout3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/textView18"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:fontFamily="@font/assistant_bold"
android:text="Residentes"
android:textColor="#324F5E"
android:textSize="20sp" />
<ImageButton
android:id="@+id/filter_residents_list_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@android:color/transparent"
android:contentDescription="Filtro"
app:srcCompat="@drawable/filter" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/residents_recycleView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
app:layout_constraintEnd_toEndOf="@+id/linearLayout3"
app:layout_constraintStart_toStartOf="@+id/linearLayout3"
app:layout_constraintTop_toBottomOf="@+id/linearLayout3" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -6,11 +6,6 @@
android:icon="@drawable/ic_home_black_24dp" android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_home" /> android:title="@string/title_home" />
<item
android:id="@+id/navigation_list"
android:icon="@drawable/ic_align_horizontal_left_24"
android:title="Lista residentes" />
<item <item
android:id="@+id/navigation_activities" android:id="@+id/navigation_activities"
android:icon="@drawable/ic_dashboard_black_24dp" android:icon="@drawable/ic_dashboard_black_24dp"

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/icon_background"/>
<foreground android:drawable="@mipmap/icon_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/icon_background"/>
<foreground android:drawable="@mipmap/icon_foreground"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">App Trabajadores</string>
<string name="title_home">Home</string>
<string name="title_dashboard">Dashboard</string>
<string name="title_notifications">Notifications</string>
<string name="residents_list_title">Residents</string>
<string name="last_games_list_title">Last games</string>
<string name="no_last_games_available_text">There are no games available</string>
<string name="stats_title">Stats</string>
<string name="no_stats_available_text">No stats available</string>
</resources>

View File

@ -3,4 +3,10 @@
<string name="title_home">Home</string> <string name="title_home">Home</string>
<string name="title_dashboard">Dashboard</string> <string name="title_dashboard">Dashboard</string>
<string name="title_notifications">Notifications</string> <string name="title_notifications">Notifications</string>
<string name="residents_list_title">Residentes</string>
<string name="last_games_list_title">Últimas partidas\n</string>
<string name="no_last_games_available_text">No hay partidas disponibles</string>
<string name="stats_title">Estadísticas</string>
<string name="no_stats_available_text">No hay estadisticas disponibles</string>
</resources> </resources>