Algo de limpieza de codigo, carga de nuevos logos, javadocs en el main

This commit is contained in:
Andrés Moran 2025-05-30 14:46:15 +02:00
parent 98ebf897fc
commit eccec1f943
146 changed files with 2407 additions and 607 deletions

View File

@ -4,10 +4,10 @@
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-05-23T14:38:41.985444400Z">
<DropdownSelection timestamp="2025-05-28T15:02:09.865617600Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\moran\.android\avd\Pixel_9_Pro.avd" />
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\moran\.android\avd\Pixel_8_Pro_API_35.avd" />
</handle>
</Target>
</DropdownSelection>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 KiB

After

Width:  |  Height:  |  Size: 307 KiB

View File

@ -7,5 +7,5 @@ import java.util.List;
public interface IOClickOnActivityListener {
void onClickOnActivity(Activity activity , List<ActivityResident> participants);
void onDeleteActivitie(Activity activity);
void onDeleteActivitie(Activity activity, Runnable runnable);
}

View File

@ -7,5 +7,5 @@ import com.andresgmoran.apptrabajadores.models.Resident;
import java.util.List;
public interface IOClickOnAddParticipantListener {
void onClickOnAddParticipant(Activity activity, List<ActivityResident> participants );
void onClickOnAddParticipant(Activity activity, List<ActivityResident> participants);
}

View File

@ -6,5 +6,5 @@ import com.andresgmoran.apptrabajadores.models.gameStats.GameStat;
public interface IOClickOnGameStatsListener {
void onClickOnLatestGame(GameStat gameStat, Resident gameStatResident, Game gameStatGame);
void onDeleteGameStat(GameStat gameStat, Game gameStatGame);
void onDeleteGameStat(GameStat gameStat, Game gameStatGame, Runnable runnable);
}

View File

@ -4,9 +4,10 @@ import com.andresgmoran.apptrabajadores.models.ActivityResident;
public interface IOClickOnParticipantListener {
void onClickOnParticipant(ActivityResident participant);
void onClickOnAssistance(ActivityResident participant, boolean isTrue);
void onClickOnAssistance(ActivityResident participant, boolean isTrue, Runnable refresh);
void onClickOnOpinion(ActivityResident participant, boolean isPreOpinion);
void onClickOnMaterialHelp(ActivityResident participant, boolean isTrue);
void onClickOnHumanHelp(ActivityResident participant, boolean isTrue);
void onClickOnMaterialHelp(ActivityResident participant, boolean isTrue, Runnable refresh);
void onClickOnHumanHelp(ActivityResident participant, boolean isTrue, Runnable refresh);
void onDeleteParticipant(ActivityResident participant, Runnable refresh);
}

View File

@ -4,5 +4,5 @@ import com.andresgmoran.apptrabajadores.models.Resident;
public interface IOClickOnResidentListener {
void onClickOnResident(Resident resident);
void onTakeOutResident(Resident resident);
void onTakeOutResident(Resident resident, Runnable refresh);
}

View File

@ -4,5 +4,5 @@ import com.andresgmoran.apptrabajadores.models.Activity;
import com.andresgmoran.apptrabajadores.models.ActivityState;
public interface IOnChageStateActivityListener {
void onChangeStateActivity(Activity activity, ActivityState state);
void onChangeStateActivity(Activity activity, ActivityState state, Runnable refresh);
}

View File

@ -21,7 +21,6 @@ import com.andresgmoran.apptrabajadores.interfaces.IOnChageStateActivityListener
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 java.time.format.DateTimeFormatter;
import java.util.ArrayList;
@ -35,14 +34,16 @@ public class ActivitiesAdapter extends RecyclerView.Adapter<ActivitiesAdapter.Ac
private List<ActivityResident> participants;
private IOClickOnActivityListener listener;
private IOnChageStateActivityListener changeStateListener;
private Runnable refresh;
public ActivitiesAdapter(Context context, List<Activity> activities, List<ActivityResident> participants, IOClickOnActivityListener listener, IOnChageStateActivityListener changeStateListener) {
public ActivitiesAdapter(Context context, List<Activity> activities, List<ActivityResident> participants, IOClickOnActivityListener listener, IOnChageStateActivityListener changeStateListener, Runnable refresh) {
this.context = context;
this.activities = activities;
this.participants = participants;
this.listener = listener;
this.changeStateListener = changeStateListener;
this.refresh = refresh;
}
@NonNull
@Override
@ -74,7 +75,7 @@ public class ActivitiesAdapter extends RecyclerView.Adapter<ActivitiesAdapter.Ac
.setTitle(context.getString(R.string.close_activity_title))
.setMessage(context.getString(R.string.close_activity_message))
.setPositiveButton(context.getString(R.string.accept_text), (dialog, which) -> {
changeStateListener.onChangeStateActivity(activity, ActivityState.CERRADO);
changeStateListener.onChangeStateActivity(activity, ActivityState.CERRADO, refresh);
})
.setNegativeButton(context.getString(R.string.cancel_text), (dialog, which) -> {
dialog.dismiss();
@ -90,7 +91,7 @@ public class ActivitiesAdapter extends RecyclerView.Adapter<ActivitiesAdapter.Ac
popupMenu.setOnMenuItemClickListener(item -> {
if (item.getItemId() == R.id.action_delete) {
if (activities != null)
listener.onDeleteActivitie(activity);
listener.onDeleteActivitie(activity, refresh);
return true;
}
return false;

View File

@ -3,6 +3,7 @@ package com.andresgmoran.apptrabajadores.models.adapters;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
@ -55,15 +56,18 @@ public class GamesAdapter extends RecyclerView.Adapter<GamesAdapter.GamesViewHol
private final TextView gameName;
private final ImageView gameImage;
private final TextView percentageView;
private final ImageButton optionsButton;
public GamesViewHolder(View view) {
super(view);
gameName = view.findViewById(R.id.name_list_item);
gameImage = view.findViewById(R.id.item_list_image);
percentageView = view.findViewById(R.id.resident_info_item); // asegúrate que existe en el layout
percentageView = view.findViewById(R.id.resident_info_item);
optionsButton = view.findViewById(R.id.more_options_item_list);
}
public void bindGame(Game game) {
optionsButton.setVisibility(View.GONE);
String name = game.getName();
String formattedName = name.substring(0, 1).toUpperCase() + name.substring(1);
gameName.setText(formattedName);
@ -74,7 +78,7 @@ public class GamesAdapter extends RecyclerView.Adapter<GamesAdapter.GamesViewHol
gameImage.setImageResource(imageResId);
double percentage = weeklyPercentages.getOrDefault(game.getId(), 0.0);
percentageView.setText(percentage + "%");
percentageView.setText(Math.round(percentage) + "%");
}
}
}

View File

@ -24,34 +24,49 @@ import java.util.Locale;
public class LastGamesAdapter extends RecyclerView.Adapter<LastGamesAdapter.LastGamesViewHolder> {
private final List<GameStat> gameStats;
private final List<Game> games;
private final List<Resident> residents;
private List<GameStat> gameStats;
private List<Game> games;
private List<Resident> residents;
private final IOClickOnGameStatsListener listener;
private Runnable runnable;
// Constructor para varios residentes
public LastGamesAdapter(List<GameStat> gameStats, List<Game> games, List<Resident> residents, IOClickOnGameStatsListener listener) {
public LastGamesAdapter(List<GameStat> gameStats, List<Game> games, List<Resident> residents, IOClickOnGameStatsListener listener, Runnable refresh) {
this.gameStats = gameStats;
this.games = games;
this.residents = residents;
this.listener = listener;
this.runnable = refresh;
this.gameStats.sort(Comparator.comparing(GameStat::getDateTime).reversed());
}
// Constructor para un solo un residente
public LastGamesAdapter(List<GameStat> gameStats, List<Game> games, Resident resident, IOClickOnGameStatsListener listener) {
this(gameStats, games, List.of(resident), listener);
public LastGamesAdapter(List<GameStat> gameStats, List<Game> games, Resident resident, IOClickOnGameStatsListener listener, Runnable refresh) {
this(gameStats, games, List.of(resident), listener, refresh);
}
// Constructor para un solo juego
public LastGamesAdapter(List<GameStat> gameStats, Game game, List<Resident> residents, IOClickOnGameStatsListener listener) {
this(gameStats, List.of(game), residents, listener);
public LastGamesAdapter(List<GameStat> gameStats, Game game, List<Resident> residents, IOClickOnGameStatsListener listener, Runnable refresh) {
this(gameStats, List.of(game), residents, listener, refresh);
}
public void updateData(List<GameStat> newGameStats) {
this.gameStats.clear();
this.gameStats.addAll(newGameStats);
public void updateData(List<GameStat> newGameStats, List<Game> newGames, List<Resident> newResidents) {
this.gameStats = newGameStats;
this.games = newGames;
this.residents = newResidents;
notifyDataSetChanged();
}
public void updateData(List<GameStat> newGameStats, List<Game> newGames, Resident newResident) {
this.gameStats = newGameStats;
this.games = newGames;
this.residents = List.of(newResident);
notifyDataSetChanged();
}
public void updateData(List<GameStat> newGameStats, Game newGame, List<Resident> newResidents) {
this.gameStats = newGameStats;
this.games = List.of(newGame);
this.residents = newResidents;
notifyDataSetChanged();
}
@ -95,7 +110,9 @@ public class LastGamesAdapter extends RecyclerView.Adapter<LastGamesAdapter.Last
popupMenu.setOnMenuItemClickListener(item -> {
if (item.getItemId() == R.id.action_delete) {
if (finalGameStatResident != null && finalGameStatGame != null)
listener.onDeleteGameStat(gameStat, finalGameStatGame);
listener.onDeleteGameStat(gameStat, finalGameStatGame, () -> {
runnable.run();
});
return true;
}
return false;
@ -133,6 +150,7 @@ public class LastGamesAdapter extends RecyclerView.Adapter<LastGamesAdapter.Last
}
public void bindObservation(GameStat gameStat, Resident gameStatResident, Game gameStatGame) {
if (gameStat == null) {
residentName.setText("Residente no encontrado");
gameName.setText("Juego desconocido");
@ -150,15 +168,9 @@ public class LastGamesAdapter extends RecyclerView.Adapter<LastGamesAdapter.Last
if (gameStatGame == null) {
gameName.setText("Juego desconocido");
} else {
if (gameStatGame.getName().equalsIgnoreCase("flecha y reacciona") || gameStatGame.getName().equalsIgnoreCase("bingo auditivo")){
if (gameStat.getNum() == 0){
gameName.setText(gameStatGame.getName() + " - PERDIDA");
} else if ( gameStat.getNum() == 1){
gameName.setText(gameStatGame.getName() + " - GANADA");
}
} else {
gameName.setText(gameStatGame.getName());
}
String name = gameStatGame.getName();
String formattedName = name.substring(0, 1).toUpperCase() + name.substring(1);
gameName.setText(formattedName);
}
Locale currentLocale = itemView.getContext().getResources().getConfiguration().getLocales().get(0);

View File

@ -6,6 +6,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.PopupMenu;
import android.widget.TextView;
import androidx.annotation.NonNull;
@ -23,18 +24,20 @@ import java.util.List;
public class ParticipantsAdapter extends RecyclerView.Adapter<ParticipantsAdapter.ParticipantsViewHolder> {
private final Context context;
private final Activity activity;
private Activity activity;
private List<Resident> residents;
private List<ActivityResident> activityResidents;
private IOClickOnParticipantListener listener;
private Runnable refresh;
public ParticipantsAdapter(Context context, Activity activity, List<ActivityResident> activityResidents, List<Resident> residents , IOClickOnParticipantListener listener) {
public ParticipantsAdapter(Context context, Activity activity, List<ActivityResident> activityResidents, List<Resident> residents , IOClickOnParticipantListener listener, Runnable refresh) {
this.context = context;
this.activity = activity;
this.residents = residents;
this.activityResidents = activityResidents;
this.listener = listener;
this.refresh = refresh;
}
@NonNull
@Override
@ -43,10 +46,35 @@ public class ParticipantsAdapter extends RecyclerView.Adapter<ParticipantsAdapte
return new ParticipantsAdapter.ParticipantsViewHolder(view);
}
public void updateData(Activity activity, List<ActivityResident> activityResidents, List<Resident> residents) {
this.activityResidents = activityResidents;
this.residents = residents;
this.activity = activity;
notifyDataSetChanged();
}
@Override
public void onBindViewHolder(@NonNull ParticipantsViewHolder holder, int position) {
ActivityResident activityResident = activityResidents.get(position);
holder.bindActivity(activityResident);
holder.optionsButton.setOnClickListener(v -> {
PopupMenu popupMenu = new PopupMenu(v.getContext(), v);
popupMenu.getMenuInflater().inflate(R.menu.menu_options, popupMenu.getMenu());
popupMenu.setOnMenuItemClickListener(item -> {
if (item.getItemId() == R.id.action_delete) {
listener.onDeleteParticipant(activityResident, () -> {
refresh.run();
});
return true;
}
return false;
});
popupMenu.show();
});
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
@ -59,9 +87,9 @@ public class ParticipantsAdapter extends RecyclerView.Adapter<ParticipantsAdapte
public void onClick(View view) {
if (activity.getState() == ActivityState.ABIERTO){
if (activityResident.isAssistance()){
listener.onClickOnAssistance(activityResident, false);
listener.onClickOnAssistance(activityResident, false, refresh);
} else {
listener.onClickOnAssistance(activityResident, true);
listener.onClickOnAssistance(activityResident, true, refresh);
}
}
}
@ -85,10 +113,10 @@ public class ParticipantsAdapter extends RecyclerView.Adapter<ParticipantsAdapte
public void onClick(View view) {
if (activity.getState() == ActivityState.ABIERTO){
if (activityResident.isMaterialHelp()){
listener.onClickOnMaterialHelp(activityResident, false);
listener.onClickOnMaterialHelp(activityResident, false, refresh);
}
if (!activityResident.isMaterialHelp()) {
listener.onClickOnMaterialHelp(activityResident, true);
listener.onClickOnMaterialHelp(activityResident, true, refresh);
}
}
}
@ -99,15 +127,20 @@ public class ParticipantsAdapter extends RecyclerView.Adapter<ParticipantsAdapte
public void onClick(View view) {
if (activity.getState() == ActivityState.ABIERTO){
if (activityResident.isHumanHelp()){
listener.onClickOnHumanHelp(activityResident, false);
listener.onClickOnHumanHelp(activityResident, false, refresh);
}
if (!activityResident.isHumanHelp()) {
listener.onClickOnHumanHelp(activityResident, true);
listener.onClickOnHumanHelp(activityResident, true, refresh);
}
}
}
});
holder.assitanceButton.setBackgroundResource(R.drawable.activity_button_unpressed_background);
holder.materialHelp.setBackgroundResource(R.drawable.activity_button_unpressed_background);
holder.humanHelp.setBackgroundResource(R.drawable.activity_button_unpressed_background);
holder.opinionButton.setBackgroundResource(R.drawable.activity_button_unpressed_background);
if (activityResident.isAssistance()){
holder.assitanceButton.setBackgroundResource(R.drawable.activity_button_pressed_background);
}
@ -144,6 +177,7 @@ public class ParticipantsAdapter extends RecyclerView.Adapter<ParticipantsAdapte
private final ImageButton opinionButton;
private final ImageButton materialHelp;
private final ImageButton humanHelp;
private final ImageButton optionsButton;
public ParticipantsViewHolder(View view) {
@ -153,6 +187,7 @@ public class ParticipantsAdapter extends RecyclerView.Adapter<ParticipantsAdapte
opinionButton = itemView.findViewById(R.id.participant_opinion_button);
materialHelp = itemView.findViewById(R.id.participant_material_help_button);
humanHelp = itemView.findViewById(R.id.participant_human_help_button);
optionsButton = itemView.findViewById(R.id.more_options_item_resident_activity);
}
public void bindActivity(ActivityResident activityResident) {

View File

@ -20,10 +20,12 @@ import java.util.List;
public class ResidentsAdapter extends RecyclerView.Adapter<ResidentsAdapter.ResidentsViewHolder> {
private List<Resident> residents;
private final IOClickOnResidentListener listener;
private Runnable refresh;
public ResidentsAdapter(List<Resident> residents, IOClickOnResidentListener listener) {
public ResidentsAdapter(List<Resident> residents, IOClickOnResidentListener listener, Runnable refresh) {
this.residents = residents;
this.listener = listener;
this.refresh = refresh;
}
public void updateData(List<Resident> newResidents) {
@ -49,7 +51,9 @@ public class ResidentsAdapter extends RecyclerView.Adapter<ResidentsAdapter.Resi
popupMenu.setOnMenuItemClickListener(item -> {
if (item.getItemId() == R.id.action_delete) {
listener.onTakeOutResident(resident);
listener.onTakeOutResident(resident, () -> {
refresh.run();
});
return true;
}
return false;

View File

@ -42,4 +42,43 @@ public class ResidenceParser {
throw new ParserException("Error al parsear residencia: " + e.getMessage(), e);
}
}
public static List<Residence> parseResidences(String jsonText) throws ParserException {
try {
JSONArray array = new JSONArray(jsonText);
List<Residence> residenceList = new ArrayList<>();
for (int i = 0; i < array.length(); i++) {
JSONObject obj = array.getJSONObject(i);
Long id = obj.getLong("id");
String nombre = obj.getString("nombre");
String email = obj.getString("email");
List<Long> usuarios = new ArrayList<>();
if (obj.has("usuarios") && !obj.isNull("usuarios")) {
JSONArray usuariosArray = obj.getJSONArray("usuarios");
for (int j = 0; j < usuariosArray.length(); j++) {
usuarios.add(usuariosArray.getLong(j));
}
}
List<Long> residentes = new ArrayList<>();
if (obj.has("residentes") && !obj.isNull("residentes")) {
JSONArray residentesArray = obj.getJSONArray("residentes");
for (int j = 0; j < residentesArray.length(); j++) {
residentes.add(residentesArray.getLong(j));
}
}
residenceList.add(new Residence(id, nombre, email, usuarios, residentes));
}
return residenceList;
} catch (JSONException e) {
throw new ParserException("Error al parsear lista de residencias: " + e.getMessage(), e);
}
}
}

View File

@ -26,7 +26,7 @@ public class UserParser {
String surnames = obj.getString("apellido");
String email = obj.getString("email");
boolean enabled = obj.getBoolean("enabled");
Long residentId = obj.has("idResidencia") && !obj.isNull("residentId") ? obj.getLong("residentId") : null;
Long residentId = obj.has("idResidencia") && !obj.isNull("idResidencia") ? obj.getLong("idResidencia") : null;
String accountImage = obj.getString("fotoPerfil");
boolean takenOut = obj.getBoolean("baja");

View File

@ -25,7 +25,22 @@ public class ApiClient {
private static final String BASE_URL = "http://10.0.2.2:8080";
// Endpoints
// Endpoints admin
private static final String ENDPOINT_GET_RESIDENCES = "/admin/resi/getAll";
private static final String ENDPOINT_ADD_RESIDENCE = "/admin/resi/add";
private static final String ENDPOINT_DELETE_RESIDENCE = "/admin/resi/%d/delete";
private static final String ENPOINT_GET_USERS_ADMIN = "/admin/resi/user/getAll";
private static final String ENDPOINT_ADD_USER = "/auth/signup";
private static final String ENDPOINT_VERIFY_USER = "/auth/verify";
private static final String ENDPOINT_DELETE_USER = "/admin/resi/%d/user/%d/delete";
private static final String ENDPOINT_GET_RESIDENTS_ADMIN = "/admin/resi/resident/getAll";
private static final String ENDPOINT_ADD_RESIDENT_ADMIN = "/admin/resi/%d/resident/add";
private static final String ENDPOINT_DELETE_RESIDENT = "/admin/resi/%d/resident/%d/delete";
private static final String ENDPOINT_ADD_GAME = "/admin/resi/juego/add";
private static final String ENDPOINT_DELETE_GAME = "/admin/resi/juego/%d/delete";
private static final String ENDPOINT_GET_GAMES_ADMIN = "/admin/resi/juego/getAll";
// Endpoints no admin
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_RESIDENCE = "/resi/get";
@ -37,12 +52,14 @@ public class ApiClient {
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_CHANGE_PASSWORD = "/resi/user/update/changePassword";
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_DELETE_PARTICIPANT = "/resi/evento/%d/participante/%d/delete";
private static final String ENDPOINT_UPDATE_PARTICIPANT = "/resi/evento/%d/participante/%d/update";
private static final String ENDPOINT_ALLOW_PARTICIPANT = "/resi/evento/%d/participante/%d/allow";
private static final String ENDPOINT_DENY_PARTICIPANT = "/resi/evento/%d/participante/%d/deny";
@ -57,6 +74,49 @@ public class ApiClient {
void onSuccess(Bitmap bitmap);
void onError(String error);
}
// ------------------------------------------------------------------ Admin Endpoints -------------------------------------------------
public static void getResidences(Context context, RawCallback callback) {
makeGetRequest(context, ENDPOINT_GET_RESIDENCES, callback);
}
public static void postResidence(Context context, String jsonBody, RawCallback callback) {
makePostRequest(context, ENDPOINT_ADD_RESIDENCE, jsonBody, callback);
}
public static void deleteResidence(Context context, long idResidence, RawCallback callback) {
makeDeleteRequest(context, String.format(ENDPOINT_DELETE_RESIDENCE, idResidence), callback);
}
public static void getUsersAdmin(Context context, RawCallback callback) {
makeGetRequest(context, ENPOINT_GET_USERS_ADMIN, callback);
}
public static void postUser(Context context, String jsonBody, RawCallback callback) {
makePostRequest(context, ENDPOINT_ADD_USER, jsonBody, callback);
}
public static void patchVerifyUser(Context context, String jsonBody, RawCallback callback) {
makePostRequest(context, ENDPOINT_VERIFY_USER, jsonBody, callback);
}
public static void deleteUser(Context context,long idResi, long idUser, RawCallback callback) {
makeDeleteRequest(context, String.format(ENDPOINT_DELETE_USER,idResi, idUser), callback);
}
public static void getResidentsAdmin(Context context, RawCallback callback) {
makeGetRequest(context, ENDPOINT_GET_RESIDENTS_ADMIN, callback);
}
public static void postResidentAdmin(Context context, long idResi, String jsonBody, RawCallback callback) {
makePostRequest(context,String.format(ENDPOINT_ADD_RESIDENT_ADMIN, idResi), jsonBody, callback);
}
public static void deleteResident(Context context, long idResi, long idResident, RawCallback callback) {
makeDeleteRequest(context, String.format(ENDPOINT_DELETE_RESIDENT, idResi, idResident), callback);
}
public static void postGame(Context context, String jsonBody, RawCallback callback) {
makePostRequest(context, ENDPOINT_ADD_GAME, jsonBody, callback);
}
public static void deleteGame(Context context, long idGame, RawCallback callback) {
makeDeleteRequest(context, String.format(ENDPOINT_DELETE_GAME, idGame), callback);
}
public static void getGamesAdmin(Context context, RawCallback callback) {
makeGetRequest(context, ENDPOINT_GET_GAMES_ADMIN, callback);
}
// ------------------------------------------------------------------ No Admin Endpoints -------------------------------------------------
public static void getUsers(Context context, RawCallback callback) {
makeGetRequest(context, ENDPOINT_GET_USERS, callback);
@ -73,6 +133,7 @@ public class ApiClient {
public static void getResidents(Context context, RawCallback callback) {
makeGetRequest(context, ENDPOINT_GET_RESIDENTS, callback);
}
public static void getResidentsTakenOut(Context context, RawCallback callback) {
makeGetRequest(context, ENDPOINT_GET_RESIDENTS_TAKEN_OUT , callback);
}
@ -97,6 +158,10 @@ public class ApiClient {
String jsonBody = String.format("{\"email\":\"%s\", \"password\":\"%s\"}", email, password);
makePostRequest(null, ENDPOINT_LOGIN, jsonBody, callback);
}
public static void patchChangePassword(Context context, String oldPassword, String newPassword, RawCallback callback) {
String jsonBody = String.format("{\"oldPassword\":\"%s\", \"newPassword\":\"%s\"}", oldPassword, newPassword);
makePatchRequest(context, ENDPOINT_CHANGE_PASSWORD, jsonBody, callback);
}
public static void postResident(Context context, String nombre, String apellido, LocalDate fechaNacimiento,
String documentoIdentidad, String familiar1, String familiar2, int year, int month,
@ -155,6 +220,10 @@ public class ApiClient {
makeDeleteRequest(context, String.format(ENDPOINT_DELETE_ACTIVITY, idActivity), callback);
}
public static void deleteParticipant(Context context, long idActivity, long idParticipant, RawCallback callback) {
makeDeleteRequest(context, String.format(ENDPOINT_DELETE_PARTICIPANT, idActivity, idParticipant), callback);
}
public static void makeGetRequest(Context context, String endpoint, RawCallback callback) {
new Thread(() -> {
HttpURLConnection connection = null;

View File

@ -4,9 +4,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.util.Log;
import android.widget.Toast;
import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.exceptions.ParserException;
import com.andresgmoran.apptrabajadores.models.Activity;
import com.andresgmoran.apptrabajadores.models.ActivityResident;
@ -24,7 +22,6 @@ import com.andresgmoran.apptrabajadores.models.parsers.ResidenceParser;
import com.andresgmoran.apptrabajadores.models.parsers.ResidentParser;
import com.andresgmoran.apptrabajadores.models.parsers.UserParser;
import com.andresgmoran.apptrabajadores.network.ApiClient;
import com.andresgmoran.apptrabajadores.ui.MainActivity;
import com.andresgmoran.apptrabajadores.utils.SecurePreferencesUtil;
import org.json.JSONObject;
@ -42,6 +39,8 @@ public class AppDataRepository {
private Bitmap actualUserImage;
private List<User> users = new ArrayList<>();
private Residence residence = null;
private List<Residence> residences = new ArrayList<>();
private Bitmap residentImage;
private List<Resident> residents = new ArrayList<>();
private List<Resident> residentsTakenOut = new ArrayList<>();
private List<Game> games = new ArrayList<>();
@ -68,6 +67,9 @@ public class AppDataRepository {
public Residence getResidence() { return residence; }
public void setResidence(Residence residence) { this.residence = residence; }
public List<Residence> getResidences() { return residences; }
public void setResidences(List<Residence> list) { this.residences = new ArrayList<>(list); }
public List<Resident> getResidents() { return residents; }
public void setResidents(List<Resident> list) { this.residents = new ArrayList<>(list); }
@ -86,7 +88,92 @@ public class AppDataRepository {
public List<ActivityResident> getActivityResidents() { return activityResidents; }
public void setActivityResidents(List<ActivityResident> list) { this.activityResidents = new ArrayList<>(list); }
// -------------------- API Calls --------------------
// -------------------- API Calls con ADMIN --------------------
public void fetchAllResidencesAdmin(Context context, Runnable onSuccess, Runnable onError) {
ApiClient.getResidences(context, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
try {
residences = ResidenceParser.parseResidences(jsonText);
fetchAllUsersAdmin(context, onSuccess, onError);
} catch (Exception e) {
Log.e("ResidenceParser", "Error al parsear residencias: " + e.getMessage());
onError.run();
}
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener residencias: " + error);
onError.run();
}
});
}
public void fetchAllUsersAdmin(Context context, Runnable onSuccess, Runnable onError) {
ApiClient.getUsersAdmin(context, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
try {
users = UserParser.parseUsers(jsonText);
fetchAllResidentsAdmin(context, onSuccess, onError);
} catch (Exception e) {
Log.e("UserParser", "Error al parsear usuarios: " + e.getMessage());
onError.run();
}
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener usuarios: " + error);
onError.run();
}
});
}
public void fetchAllResidentsAdmin(Context context, Runnable onSuccess, Runnable onError) {
ApiClient.getResidentsAdmin(context, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
try {
residents = ResidentParser.parseResidents(jsonText);
fetchAllGamesAdmin(context, onSuccess, onError);
} catch (Exception e) {
Log.e("ResidentParser", "Error al parsear residentes: " + e.getMessage());
onError.run();
}
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener residentes: " + error);
onError.run();
}
});
}
public void fetchAllGamesAdmin(Context context, Runnable onSuccess, Runnable onError) {
ApiClient.getGamesAdmin(context, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
try {
games = GameParser.parseGames(jsonText);
onSuccess.run();
} catch (Exception e) {
Log.e("GameParser", "Error al parsear juegos: " + e.getMessage());
onError.run();
}
}
@Override
public void onError(String error) {
Log.e("API", "Error al obtener juegos: " + error);
onError.run();
}
});
}
// -------------------- API Calls no ADMIN--------------------
public void fetchActualUser(Context context, Runnable onSuccess, Runnable onError) {
ApiClient.getActualUser(context, new ApiClient.RawCallback() {
@ -458,10 +545,148 @@ public void fetchResidentsTakenOutOnly(Context context, Runnable onFinish) {
}
}
// -------------------- Acciones API ADMIN --------------------
public void deleteResidence(Context context, long id, Runnable onSuccess, Runnable onError) {
ApiClient.deleteResidence(context, id, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
fetchAllResidencesAdmin(context, onSuccess, onError);
}
// -------------------- Otras acciones API --------------------
@Override
public void onError(String error) {
Log.e("API", "Error al eliminar residencia: " + error);
onError.run();
}
});
}
public void deleteResident(Context context,long idResi, long idResident, Runnable onSuccess, Runnable onError) {
ApiClient.deleteResident(context, idResi, idResident, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
fetchAllResidentsAdmin(context, onSuccess, onError);
}
public void login(Context context, String email, String password, boolean rememberPassword, Runnable onSuccess, Runnable onError) {
@Override
public void onError(String error) {
Log.e("API", "Error al eliminar residente: " + error);
onError.run();
}
});
}
public void deleteGame(Context context, long id, Runnable onSuccess, Runnable onError) {
ApiClient.deleteGame(context, id, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
fetchAllGamesAdmin(context, onSuccess, onError);
}
@Override
public void onError(String error) {
Log.e("API", "Error al eliminar juego: " + error);
onError.run();
}
});
}
public void deleteUser(Context context, long idResi, long idUser, Runnable onSuccess, Runnable onError) {
ApiClient.deleteUser(context, idResi, idUser, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
fetchAllUsersAdmin(context, onSuccess, onError);
}
@Override
public void onError(String error) {
Log.e("API", "Error al eliminar usuario: " + error);
onError.run();
}
});
}
public void addUser(Context context, long idResi, String name, String surnames, String email, String password, Runnable onSuccess, Runnable onError) {
String jsonBody = "{\"nombre\": \"" + name + "\", \"apellido\": \"" + surnames + "\", \"email\": \"" + email + "\", \"password\": \"" + password + "\", \"idResidencia\": " + idResi + "}";
ApiClient.postUser(context,jsonBody, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
fetchAllUsersAdmin(context, onSuccess, onError);
}
@Override
public void onError(String error) {
Log.e("API", "Error al añadir usuario: " + error);
onError.run();
}
});
}
public void verifyUser(Context context, String email, String code, Runnable onSuccess, Runnable onError) {
String jsonBody = "{\"email\": \"" + email + "\", \"verificationCode\": \"" + code + "\"}";
ApiClient.patchVerifyUser(context, jsonBody, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
fetchAllUsersAdmin(context, onSuccess, onError);
}
@Override
public void onError(String error) {
Log.e("API", "Error al verificar usuario: " + error);
onError.run();
}
});
}
public void addResidence(Context context, String name, String email, Runnable onSuccess, Runnable onError) {
String jsonBody = "{\"nombre\": \"" + name + "\", \"email\": \"" + email + "\"}";
ApiClient.postResidence(context,jsonBody, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
fetchAllResidencesAdmin(context, onSuccess, onError);
}
@Override
public void onError(String error) {
Log.e("API", "Error al añadir residencia: " + error);
onError.run();
}
});
}
public void addResidenteAdmin(Context context, long idResi, String nombre, String apellido, LocalDate fechaNacimiento, String documentoIdentidad, String familiar1, String familiar2, int year, int month, Runnable onSuccess, Runnable onError) {
String jsonBody = "{\"nombre\": \"" + nombre + "\", \"apellido\": \"" + apellido + "\", \"fechaNacimiento\": \"" + fechaNacimiento + "\", \"documentoIdentidad\": \"" + documentoIdentidad + "\", \"familiar1\": \"" + familiar1 + "\", \"familiar2\": \"" + familiar2 + "\", \"year\": " + year + ", \"month\": " + month + "}";
ApiClient.postResidentAdmin(context,idResi,jsonBody, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
fetchAllResidentsAdmin(context, onSuccess, onError);
}
@Override
public void onError(String error) {
Log.e("API", "Error al añadir residente: " + error);
onError.run();
}
});
}
public void addGame( Context context, String name, Runnable onSuccess, Runnable onError) {
String jsonBody = "{\"nombre\": \"" + name + "\"}";
ApiClient.postGame(context,jsonBody, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
fetchAllGamesAdmin(context, onSuccess, onError);
}
@Override
public void onError(String error) {
Log.e("API", "Error al añadir juego: " + error);
onError.run();
}
});
}
// -------------------- Otras acciones API no ADMIN --------------------
public void login(Context context, String email, String password, boolean rememberPassword, Runnable onSuccess, Runnable onSuccesAdmin, Runnable onError) {
ApiClient.postLogin(email, password, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
@ -488,11 +713,15 @@ public void fetchResidentsTakenOutOnly(Context context, Runnable onFinish) {
SecurePreferencesUtil.edit(context, editor);
if(idUser == 1)
fetchAllResidencesAdmin(context, onSuccesAdmin, onError);
else
fetchActualUser(context, onSuccess, onError);
} catch (Exception e) {
throw new ParserException("Error al parsear respuesta de login: " + e.getMessage(), e);
}
Log.d("API", "Inicio de sesión exitoso");
fetchActualUser(context, onSuccess, onError);
}
@Override
@ -503,6 +732,22 @@ public void fetchResidentsTakenOutOnly(Context context, Runnable onFinish) {
});
}
public void changePassword( Context context, String currentPassword, String newPassword, Runnable onSuccess, Runnable onError) {
ApiClient.patchChangePassword(context, currentPassword, newPassword, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
Log.d("API", "Contraseña cambiada correctamente");
onSuccess.run();
}
@Override
public void onError(String error) {
Log.e("API", "Error al cambiar contraseña: " + error);
onError.run();
}
});
}
public void addResident(Context context, String nombre, String apellido, LocalDate fechaNacimiento, String documentoIdentidad, String familiar1, String familiar2, int year, int month, Runnable onSuccess, Runnable onError) {
ApiClient.postResident(context, nombre, apellido, fechaNacimiento, documentoIdentidad, familiar1, familiar2, year, month, new ApiClient.RawCallback() {
@Override
@ -694,5 +939,21 @@ public void fetchResidentsTakenOutOnly(Context context, Runnable onFinish) {
}
});
}
public void deleteParticipant(Context context, long activityId, long participantId, Runnable onSuccess, Runnable onError) {
ApiClient.deleteParticipant(context, activityId, participantId, new ApiClient.RawCallback() {
@Override
public void onSuccess(String jsonText) {
fetchParticipantsOnly(context, onSuccess);
Log.d("API", "Participante eliminado correctamente");
}
@Override
public void onError(String error) {
onError.run();
Log.e("API", "Error al eliminar participante: " + error);
}
});
}
}

View File

@ -39,6 +39,7 @@ import com.andresgmoran.apptrabajadores.ui.fragments.activities.AddActivityFragm
import com.andresgmoran.apptrabajadores.ui.fragments.activities.OpinionFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.activities.ParticipantDetailFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.activities.ParticipantSelectionDialogFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.admin.AdminPanelFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.authentication.LoginFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.game.GameFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.gameDetail.GameDetailFragment;
@ -57,6 +58,7 @@ import java.util.List;
import java.util.Locale;
public class MainActivity extends AppCompatActivity implements
AdminPanelFragment.IOnAdminPanel,
NavigationBarView.OnItemSelectedListener,
IOnClickOnBackButtonListener,
HomeFragment.IOnRefreshHomeListener, HomeFragment.IOnClickOnAddParticipantListener,
@ -91,11 +93,13 @@ public class MainActivity extends AppCompatActivity implements
// Adaptar diseño a la pantalla pudiendo cambiar el color del padding top desde los fragments que sean necesarios
View rootView = findViewById(R.id.fcvMain);
//View statusBarView = findViewById(R.id.status_bar_background);
View statusBarView = findViewById(R.id.status_bar_background);
if (rootView != null && statusBarView != null) {
ViewCompat.setOnApplyWindowInsetsListener(rootView, (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(0, systemBars.top, 0, 0);
ViewGroup.LayoutParams params = statusBarView.getLayoutParams();
@ -104,6 +108,7 @@ public class MainActivity extends AppCompatActivity implements
return insets;
});
}
// -------- INICIO AUTOMÁTICO SI RECUERDA CONTRASEÑA Y TOKEN VÁLIDO --------
try {
@ -171,10 +176,10 @@ public class MainActivity extends AppCompatActivity implements
// --------------------------------------------------------------------- Login ---------------------------------------------------------------------
/**
*
* @param email
* @param password
* @param rememberPassword
* Llama al método de login con los datos introducidos en el fragmento de LoginFragment
* @param email correo electrónico del usuario
* @param password contraseña del usuario
* @param rememberPassword indica si se debe recordar la contraseña
*/
@Override
public void onLogin(String email, String password, boolean rememberPassword) {
@ -182,10 +187,10 @@ public class MainActivity extends AppCompatActivity implements
}
/**
*
* @param email
* @param password
* @param rememberPassword
* Realiza el login con los datos introducidos
* @param email correo electrónico del usuario
* @param password contraseña del usuario
* @param rememberPassword indica si se debe recordar la contraseña
*/
public void postLogin(String email, String password, boolean rememberPassword) {
AppDataRepository.getInstance().login(MainActivity.this, email, password, rememberPassword, () -> runOnUiThread(() -> {
@ -193,6 +198,8 @@ public class MainActivity extends AppCompatActivity implements
findViewById(R.id.nav_view).setVisibility(View.VISIBLE);
findViewById(R.id.progress_loader).setVisibility(View.GONE);
((BottomNavigationView) findViewById(R.id.nav_view)).setSelectedItemId(R.id.navigation_home);
}), () -> runOnUiThread(() -> {
loadFragment(new AdminPanelFragment());
}),
() -> runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Error al iniciar sesión", Toast.LENGTH_SHORT).show();
@ -212,6 +219,8 @@ public class MainActivity extends AppCompatActivity implements
* @return true si se ha cargado correctamente, false si no
*/
private boolean loadFragment(Fragment fragment) {
if (isFinishing() || isDestroyed()) return false;
if (fragment != null) {
Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fcvMain);
if (currentFragment != null) {
@ -237,26 +246,12 @@ public class MainActivity extends AppCompatActivity implements
return false;
}
private boolean loadFragmentWithoutTracking(Fragment fragment) {
if (fragment != null) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fcvMain, fragment)
.commit();
return true;
}
return false;
}
/**
* Crea el fragmento de HOME
* @return fragmento creado
*/
public Fragment createHomeFragment(){
HomeFragment homeFragment = new HomeFragment();
Bundle bundle = new Bundle();
homeFragment.setArguments(bundle);
return homeFragment;
}
@ -287,11 +282,11 @@ public class MainActivity extends AppCompatActivity implements
}
/**
*
* @param gameStat
* @param gameStatResident
* @param gameStatGame
* @return
* Crea el fragmento de GAME DETAIL
* @param gameStat partida a mostrar en el fragmento
* @param gameStatResident residente que ha jugado la partida
* @param gameStatGame juego que se ha jugado
* @return fragmento creado
*/
public Fragment createGameDetailFragment(GameStat gameStat, Resident gameStatResident, Game gameStatGame){
GameDetailFragment gameDetailFragment = new GameDetailFragment();
@ -304,10 +299,10 @@ public class MainActivity extends AppCompatActivity implements
}
/**
*
* @param activity
* @param participants
* @return
* Crea el fragmento de ActivityDetail
* @param activity actividad a mostrar en el fragmento
* @param participants lista de participantes de la actividad
* @return fragmento creado
*/
public Fragment createActivityDetailFragment(Activity activity, List<ActivityResident> participants){
ActivityDetailFragment activityDetailFragment = new ActivityDetailFragment();
@ -319,7 +314,7 @@ public class MainActivity extends AppCompatActivity implements
}
/**
*
* Para el botón de ir hacia atrás, depende del fragmento que se esté mostrando, recargará el fragmento correspondiente
*/
private void reloadFragment(Fragment fragment) {
if (fragment == null) return;
@ -391,10 +386,6 @@ public class MainActivity extends AppCompatActivity implements
}
// --------------------------------------------------------------------- OnClickListeners ---------------------------------------------------------------------
// --------------------------------------------------------------------- Resident listeners ---------------------------------------------------------------------
/**
@ -408,17 +399,17 @@ public class MainActivity extends AppCompatActivity implements
}
/**
*
* @param resident
* Listener para el click en el botón de dar de baja a un residente
* @param resident residente que se quiere dar de baja
*/
@Override
public void onTakeOutResident(Resident resident) {
public void onTakeOutResident(Resident resident, Runnable refresh) {
AppDataRepository.getInstance().takeDownResident(MainActivity.this, resident.getId(), () -> {
runOnUiThread(() -> {
AppDataRepository.getInstance().fetchResidentsTakenOutOnly( MainActivity.this, () -> {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Residente dado de baja correctamente", Toast.LENGTH_SHORT).show();
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain));
refresh.run();
});
});
});
@ -429,6 +420,34 @@ public class MainActivity extends AppCompatActivity implements
});
}
/**
* Listener para el envío del formulario de añadir residente
* @param nombre nombre del residente
* @param apellido apellido del residente
* @param fechaNacimiento fecha de nacimiento del residente
* @param documentoIdentidad documento de identidad del residente
* @param familiar1 correo electrónico del primer familiar
* @param familiar2 correo electrónico del segundo familiar
* @param year año de validez de documento de identidad
* @param month mes de validez de documento de identidad
*/
@Override
public void onAddResidentFormSubmitted(String nombre, String apellido, LocalDate fechaNacimiento, String documentoIdentidad, String familiar1, String familiar2, int year, int month) {
AppDataRepository.getInstance().addResident( MainActivity.this, nombre, apellido, fechaNacimiento, documentoIdentidad, familiar1, familiar2, year, month, () -> {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Residente añadido correctamente", Toast.LENGTH_SHORT).show();
if (lastFragment instanceof HomeFragment) {
((HomeFragment) lastFragment).refreshData();
}
loadFragment(lastFragment);
});
}, () -> {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Error al añadir residente", Toast.LENGTH_SHORT).show();
});
});
}
// --------------------------------------------------------------------- Game listeners ---------------------------------------------------------------------
/**
@ -455,16 +474,16 @@ public class MainActivity extends AppCompatActivity implements
}
/**
*
* @param gameStat
* @param gamestatGame
* Listener para el click en el botón de eliminar partida
* @param gameStat partida que se quiere eliminar
* @param gamestatGame juego de la partida
*/
@Override
public void onDeleteGameStat(GameStat gameStat, Game gamestatGame) {
public void onDeleteGameStat(GameStat gameStat, Game gamestatGame, Runnable refresh) {
AppDataRepository.getInstance().deleteGameStat(MainActivity.this, gameStat.getId(), () -> {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Partida eliminada correctamente", Toast.LENGTH_SHORT).show();
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain));
refresh.run();
});
}, () -> {
runOnUiThread(() -> {
@ -474,17 +493,17 @@ public class MainActivity extends AppCompatActivity implements
}
/**
*
* @param observation
* @param gameId
* @param gameStatId
* Listener para el click en el botón de añadir observación a una partida
* @param observation observación a añadir
* @param gameId id del juego al que pertenece la partida
* @param gameStatId id de la partida a la que se quiere añadir la observación
*/
@Override
public void onAddObservation(String observation, long gameId, long gameStatId) {
public void onAddObservation(String observation, long gameId, long gameStatId, Runnable refresh) {
AppDataRepository.getInstance().updateObservation(MainActivity.this, observation, gameStatId, () -> {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Observación actualizada correctamente", Toast.LENGTH_SHORT).show();
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain));
refresh.run();
});
}, () -> {
runOnUiThread(() -> {
@ -493,12 +512,25 @@ public class MainActivity extends AppCompatActivity implements
});
}
/**
* Listener para la actualización de las estadísticas de los juegos
* @param refresh Runnable para refrescar la vista después de actualizar las estadísticas
*/
@Override
public void onRefreshGameStats(Runnable refresh) {
AppDataRepository.getInstance().fetchGameStatsOnly( MainActivity.this, () -> {
runOnUiThread(() -> {
refresh.run();
});
});
}
// --------------------------------------------------------------------- Activity Listeners ---------------------------------------------------------------------
/**
*
* @param activity
* @param participants
* Listener para el click en una actividad
* @param activity actividad sobre la que se ha hecho click
* @param participants lista de participantes de la actividad
*/
@Override
public void onClickOnActivity(Activity activity, List<ActivityResident> participants) {
@ -506,17 +538,27 @@ public class MainActivity extends AppCompatActivity implements
}
/**
*
* @param activityName
* @param activityDescription
* @param date
* Listener para el click en el botón de añadir actividad
*/
@Override
public void onClickOnAddActivity() {
loadFragment(new AddActivityFragment());
}
/**
* Listener para el envío del formulario de añadir actividad
* @param activityName nombre de la actividad
* @param activityDescription descripción de la actividad
* @param date fecha de la actividad
*/
@Override
public void onAddActivity(String activityName, String activityDescription, LocalDateTime date) {
AppDataRepository.getInstance().addActivity(MainActivity.this, activityName, activityDescription, date, () -> {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Actividad añadida correctamente", Toast.LENGTH_SHORT).show();
loadFragment(new ActivitiesFragment());
if (lastFragment instanceof ActivitiesFragment)
((ActivitiesFragment) lastFragment).reloadData();
loadFragment(lastFragment);
});
}, () -> {
runOnUiThread(() -> {
@ -526,18 +568,19 @@ public class MainActivity extends AppCompatActivity implements
}
/**
*
* @param activity
* Listener para el click en el botón de eliminar actividad
* @param activity actividad que se quiere eliminar
* @param refresh Runnable para refrescar la vista después de eliminar la actividad
*/
@Override
public void onDeleteActivitie(Activity activity) {
public void onDeleteActivitie(Activity activity, Runnable refresh) {
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();
AppDataRepository.getInstance().fetchActivitiesOnly(MainActivity.this, () -> {
runOnUiThread(() -> {
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain));
Toast.makeText(MainActivity.this, "Actividad eliminada correctamente", Toast.LENGTH_SHORT).show();
refresh.run();
});
});
}
@ -550,13 +593,23 @@ public class MainActivity extends AppCompatActivity implements
});
}
/**
* Listener para el cambio de estado de una actividad
* @param activity actividad sobre la que se ha cambiado el estado
* @param state nuevo estado de la actividad (Abierto -> Cerrado -> En curso -> Finalizado)
* @param refresh Runnable para refrescar la vista después de cambiar el estado
*/
@Override
public void onChangeStateActivity(Activity activity, ActivityState state) {
public void onChangeStateActivity(Activity activity, ActivityState state, Runnable refresh) {
Log.e( "API", "Cambiando estado de la actividad: " + activity.getId());
AppDataRepository.getInstance().changeActivityState(MainActivity.this, activity.getId(), state, () -> {
runOnUiThread(() -> {
AppDataRepository.getInstance().fetchActivitiesOnly( MainActivity.this, () -> {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Estado de la actividad actualizado correctamente", Toast.LENGTH_SHORT).show();
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain));
refresh.run();
});
});
});
}, () -> {
runOnUiThread(() -> {
@ -565,14 +618,44 @@ public class MainActivity extends AppCompatActivity implements
});
}
/**
* Listener para la actualización de los detalles de una actividad
* @param refresh Runnable para refrescar la vista después de actualizar los detalles
*/
@Override
public void onRefreshActivityDetail(Runnable refresh) {
AppDataRepository.getInstance().fetchActivitiesOnly( MainActivity.this, () -> {
runOnUiThread(() -> {
AppDataRepository.getInstance().fetchParticipantsOnly( MainActivity.this, () -> {
runOnUiThread(() -> {
refresh.run();
});
});
});
});
}
/**
* Listener para la actualización de las actividades
* @param refresh Runnable para refrescar la vista después de actualizar las actividades
*/
@Override
public void onRefreshActivities(Runnable refresh) {
AppDataRepository.getInstance().fetchActivitiesOnly( MainActivity.this, () -> {
runOnUiThread(() -> {
refresh.run();
});
});
}
// --------------------------------------------------------------------- Participant Listeners ---------------------------------------------------------------------
/**
*
* @param activity
* @param participants
* @param residents
* Listener para el click en el botón de añadir participante a una actividad
* @param activity actividad a la que se quiere añadir un participante
* @param participants lista de participantes de la actividad
*/
@Override
public void onClickOnAddParticipant(Activity activity, List<ActivityResident> participants) {
@ -581,8 +664,16 @@ public class MainActivity extends AppCompatActivity implements
}
/**
*
* @param participant
* Listener para el click en el botón de añadir participante desde el fragmento de actividades
*/
@Override
public void onClickOnAddParticipant() {
loadFragment(new AddResidentFragment());
}
/**
* Listener para el click en un participante
* @param participant participante sobre el que se ha hecho click
*/
@Override
public void onClickOnParticipant(ActivityResident participant) {
@ -594,16 +685,17 @@ public class MainActivity extends AppCompatActivity implements
}
/**
*
* @param participant
* @param assistance
* Listener para el click en el botón de asistencia de un participante
* @param participant participante sobre el que se ha hecho click
* @param assistance indica si el participante ha asiste o no a la actividad
* @param refresh Runnable para refrescar la vista después de actualizar la asistencia
*/
@Override
public void onClickOnAssistance(ActivityResident participant, boolean assistance ) {
public void onClickOnAssistance(ActivityResident participant, boolean assistance, Runnable refresh ) {
AppDataRepository.getInstance().updateAssistance(MainActivity.this, participant.getActivityId(), participant.getId(), assistance, () -> {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Asistencia actualizada correctamente", Toast.LENGTH_SHORT).show();
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain));
refresh.run();
});
}, () -> {
runOnUiThread(() -> {
@ -613,9 +705,9 @@ public class MainActivity extends AppCompatActivity implements
}
/**
*
* @param participant
* @param isPreOpinion
* Listener para el click en el botón de opinión de un participante
* @param participant participante sobre el que se ha hecho click
* @param isPreOpinion indica si es una opinión previa o posterior a la actividad
*/
@Override
public void onClickOnOpinion(ActivityResident participant, boolean isPreOpinion) {
@ -628,17 +720,19 @@ public class MainActivity extends AppCompatActivity implements
}
/**
*
* @param participant
* @param isPreOpinion
* @param opinion
* Listener para el envío de la opinión de un participante
* @param participant participante al que se le añade la opinión
* @param isPreOpinion indica si es una opinión previa o posterior a la actividad
* @param opinion opinión a añadir
*/
@Override
public void onAddOpinion(ActivityResident participant ,boolean isPreOpinion, String opinion) {
AppDataRepository.getInstance().updateOpinion( MainActivity.this, participant.getActivityId(), participant.getId(), isPreOpinion, opinion, () -> {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Opinión actualizada correctamente", Toast.LENGTH_SHORT).show();
reloadFragment(lastFragment);
if (lastFragment instanceof ActivityDetailFragment)
((ActivityDetailFragment) lastFragment).updateData();
loadFragment(lastFragment);
});
}, () -> {
runOnUiThread(() -> {
@ -648,16 +742,17 @@ public class MainActivity extends AppCompatActivity implements
}
/**
*
* @param participant
* @param materialHelp
* Listener para el click en el botón de ayuda material de un participante
* @param participant participante sobre el que se ha hecho click
* @param materialHelp indica si el participante necesita ayuda material
* @param refresh Runnable para refrescar la vista después de actualizar la ayuda material
*/
@Override
public void onClickOnMaterialHelp(ActivityResident participant, boolean materialHelp) {
public void onClickOnMaterialHelp(ActivityResident participant, boolean materialHelp, Runnable refresh) {
AppDataRepository.getInstance().updateMaterialHelp( MainActivity.this, participant.getActivityId(), participant.getId(), materialHelp, () -> {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Ayuda material actualizada correctamente", Toast.LENGTH_SHORT).show();
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain));
refresh.run();
});
}, () -> {
runOnUiThread(() -> {
@ -667,16 +762,17 @@ public class MainActivity extends AppCompatActivity implements
}
/**
*
* @param participant
* @param humanHelp
* Listener para el click en el botón de ayuda humana de un participante
* @param participant participante sobre el que se ha hecho click
* @param humanHelp indica si el participante necesita ayuda humana
* @param refresh Runnable para refrescar la vista después de actualizar la ayuda humana
*/
@Override
public void onClickOnHumanHelp(ActivityResident participant, boolean humanHelp) {
public void onClickOnHumanHelp(ActivityResident participant, boolean humanHelp, Runnable refresh) {
AppDataRepository.getInstance().updateHumanHelp(MainActivity.this, participant.getActivityId(), participant.getId(), humanHelp, () -> {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Ayuda humana actualizada correctamente", Toast.LENGTH_SHORT).show();
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain));
refresh.run();
});
}, () -> {
runOnUiThread(() -> {
@ -686,10 +782,29 @@ public class MainActivity extends AppCompatActivity implements
}
/**
*
* @param activity
* @param participants
* @param selectedResident
* Listener para el click en el botón de eliminar participante
* @param participant participante que se quiere eliminar
* @param refresh Runnable para refrescar la vista después de eliminar el participante
*/
@Override
public void onDeleteParticipant(ActivityResident participant, Runnable refresh) {
AppDataRepository.getInstance().deleteParticipant(MainActivity.this, participant.getActivityId(), participant.getId(), () -> {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Participante eliminado correctamente", Toast.LENGTH_SHORT).show();
refresh.run();
});
}, () -> {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Error al eliminar participante", Toast.LENGTH_SHORT).show();
});
});
}
/**
* Listener para la selección de un participante en el diálogo de selección de participantes
* @param activity actividad a la que se quiere añadir el participante
* @param participants lista de participantes de la actividad
* @param selectedResident residente seleccionado para añadir como participante
*/
@Override
public void onParticipantSelected(Activity activity, List<ActivityResident> participants ,Resident selectedResident) {
@ -697,7 +812,11 @@ public class MainActivity extends AppCompatActivity implements
AppDataRepository.getInstance().addParticipant( MainActivity.this, activity.getId(), selectedResident.getId(), () -> {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Participante añadido correctamente", Toast.LENGTH_SHORT).show();
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain));
Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fcvMain);
if (currentFragment instanceof ActivityDetailFragment) {
((ActivityDetailFragment) currentFragment).updateData();
}
loadFragment(currentFragment);
});
}, () -> {
runOnUiThread(() -> {
@ -706,7 +825,20 @@ public class MainActivity extends AppCompatActivity implements
});
}
// --------------------------------------------------------------------- LogOut listener ---------------------------------------------------------------------
/**
* Listener para la actualización de los detalles de un participante
* @param refresh Runnable para refrescar la vista después de actualizar los detalles del participante
*/
@Override
public void onRefreshParticipantDetail(Runnable refresh) {
AppDataRepository.getInstance().fetchParticipantsOnly( MainActivity.this, () -> {
runOnUiThread(() -> {
refresh.run();
});
});
}
// --------------------------------------------------------------------- Account listeners ---------------------------------------------------------------------
@Override
public void OnResidenceButtonClicked() {
@ -731,71 +863,27 @@ public class MainActivity extends AppCompatActivity implements
}
@Override
public void onClickOnBackButton() {
Log.e( "API", "Back button clicked, reloading last fragment: " + (lastFragment != null ? lastFragment.getClass().getSimpleName() : "null"));
reloadFragment(lastFragment);
}
@Override
public void onRefreshActivityDetail() {
AppDataRepository.getInstance().fetchActivitiesOnly( MainActivity.this, () -> {
public void onChangePassword(String currentPassword, String newPassword) {
AppDataRepository.getInstance().changePassword( MainActivity.this, currentPassword, newPassword, () -> {
runOnUiThread(() -> {
AppDataRepository.getInstance().fetchParticipantsOnly( MainActivity.this, () -> {
runOnUiThread(() -> {
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain));
});
});
});
});
}
@Override
public void onRefreshActivities() {
AppDataRepository.getInstance().fetchActivitiesOnly( MainActivity.this, () -> {
runOnUiThread(() -> {
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain));
});
});
}
@Override
public void onClickOnAddActivity() {
loadFragment(new AddActivityFragment());
}
@Override
public void onRefreshGameStats() {
AppDataRepository.getInstance().fetchGameStatsOnly( MainActivity.this, () -> {
runOnUiThread(() -> {
loadFragmentWithoutTracking(getSupportFragmentManager().findFragmentById(R.id.fcvMain));
});
});
}
@Override
public void onRefreshHome() {
AppDataRepository.getInstance().fetchActualUser( MainActivity.this, () -> {
runOnUiThread(() -> {
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain));
SharedPreferences.Editor editor = SecurePreferencesUtil.getEncryptedPrefs(MainActivity.this).edit();
editor.putString("password", newPassword);
Toast.makeText(MainActivity.this, "Contraseña cambiada correctamente", Toast.LENGTH_SHORT).show();
loadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain));
});
}, () -> {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Error al cargar datos", Toast.LENGTH_SHORT).show();
Toast.makeText(MainActivity.this, "Error al cambiar la contraseña", Toast.LENGTH_SHORT).show();
});
});
}
/**
* Listener para la actualización de los detalles de la residencia
* @param refresh Runnable para refrescar la vista después de actualizar los detalles de la residencia
*/
@Override
public void onRefreshParticipantDetail() {
AppDataRepository.getInstance().fetchParticipantsOnly( MainActivity.this, () -> {
runOnUiThread(() -> {
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain));
});
});
}
@Override
public void onRefreshResidenceDetail() {
public void onRefreshResidenceDetail(Runnable refresh) {
AppDataRepository.getInstance().fetchResidenceOnly( MainActivity.this, () -> {
runOnUiThread(() -> {
AppDataRepository.getInstance().fetchResidentsOnly(MainActivity.this, () -> {
@ -806,7 +894,7 @@ public class MainActivity extends AppCompatActivity implements
runOnUiThread(() -> {
AppDataRepository.getInstance().fetchGameStatsOnly( MainActivity.this, () -> {
runOnUiThread(() -> {
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain));
refresh.run();
});
});
});
@ -819,24 +907,33 @@ public class MainActivity extends AppCompatActivity implements
});
}
// --------------------------------------------------------------------- General listeners ---------------------------------------------------------------------
/**
* Listener para el click en el botón de volver atrás
*/
@Override
public void onAddResidentFormSubmitted(String nombre, String apellido, LocalDate fechaNacimiento, String documentoIdentidad, String familiar1, String familiar2, int year, int month) {
AppDataRepository.getInstance().addResident( MainActivity.this, nombre, apellido, fechaNacimiento, documentoIdentidad, familiar1, familiar2, year, month, () -> {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Residente añadido correctamente", Toast.LENGTH_SHORT).show();
public void onClickOnBackButton() {
Log.e( "API", "Back button clicked, reloading last fragment: " + (lastFragment != null ? lastFragment.getClass().getSimpleName() : "null"));
reloadFragment(lastFragment);
}
/**
* Listener para la actualización de la pantalla de inicio
* @param refresh Runnable para refrescar la vista después de actualizar la pantalla de inicio
*/
@Override
public void onRefreshHome(Runnable refresh) {
AppDataRepository.getInstance().fetchActualUser( MainActivity.this, () -> {
runOnUiThread(() -> {
refresh.run();
});
}, () -> {
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Error al añadir residente", Toast.LENGTH_SHORT).show();
Toast.makeText(MainActivity.this, "Error al cargar datos", Toast.LENGTH_SHORT).show();
});
});
}
@Override
public void onClickOnAddParticipant() {
loadFragment(new AddResidentFragment());
}
}

View File

@ -9,7 +9,9 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
@ -30,18 +32,24 @@ public class AccountFragment extends Fragment {
private Button residenceButton;
private Button languageButton;
private Button logOutButton;
private Button toggleChangePasswordButton;
private Button confirmChangePasswordButton;
private LinearLayout passwordChangeLayout;
private EditText etCurrentPassword, etNewPassword;
private IOAccountFragmentListener accountFragmentListener;
public interface IOAccountFragmentListener {
void OnResidenceButtonClicked();
void onLanguageSelected(String selectedLanguageCode);
void onLogOutButtonClicked();
void onChangePassword(String currentPassword, String newPassword);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_account, container,false);
return inflater.inflate(R.layout.fragment_account, container, false);
}
@Override
@ -52,7 +60,6 @@ public class AccountFragment extends Fragment {
statusBar.setBackgroundColor(Color.parseColor("#0062FF"));
userCardView = view.findViewById(R.id.account_card_view);
userCardView.findViewById(R.id.back_button).setVisibility(View.GONE);
userNameTextView = userCardView.findViewById(R.id.banner_name_game);
@ -62,12 +69,7 @@ public class AccountFragment extends Fragment {
userImageView.setImageBitmap(userImage);
residenceButton = view.findViewById(R.id.residence_button_account);
residenceButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
accountFragmentListener.OnResidenceButtonClicked();
}
});
residenceButton.setOnClickListener(v -> accountFragmentListener.OnResidenceButtonClicked());
languageButton = view.findViewById(R.id.btn_idioma);
languageButton.setOnClickListener(v -> {
@ -87,30 +89,52 @@ public class AccountFragment extends Fragment {
.show();
});
// Botón cerrar sesión
logOutButton = view.findViewById(R.id.btn_cerrar_sesion);
logOutButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
logOutButton.setOnClickListener(v -> {
new AlertDialog.Builder(getContext())
.setTitle(getString(R.string.logout_title))
.setMessage(getString(R.string.confirm_logout_message))
.setPositiveButton( getString(R.string.accept_text), (dialog, which) -> {
.setPositiveButton(getString(R.string.accept_text), (dialog, which) -> {
accountFragmentListener.onLogOutButtonClicked();
})
.setNegativeButton(getString(R.string.cancel_text), (dialog, which) -> {
dialog.dismiss();
})
.setNegativeButton(getString(R.string.cancel_text), (dialog, which) -> dialog.dismiss())
.show();
});
toggleChangePasswordButton = view.findViewById(R.id.btn_toggle_password_change);
confirmChangePasswordButton = view.findViewById(R.id.btn_change_password);
passwordChangeLayout = view.findViewById(R.id.password_change_container);
etCurrentPassword = view.findViewById(R.id.et_current_password);
etNewPassword = view.findViewById(R.id.et_new_password);
toggleChangePasswordButton.setOnClickListener(v -> {
if (passwordChangeLayout.getVisibility() == View.VISIBLE) {
passwordChangeLayout.setVisibility(View.GONE);
} else {
passwordChangeLayout.setVisibility(View.VISIBLE);
}
});
confirmChangePasswordButton.setOnClickListener(v -> {
String currentPass = etCurrentPassword.getText().toString().trim();
String newPass = etNewPassword.getText().toString().trim();
if (currentPass.isEmpty()) {
etCurrentPassword.setError("Campo obligatorio");
} else if (newPass.isEmpty()) {
etNewPassword.setError("Campo obligatorio");
} else {
etCurrentPassword.setError(null);
etNewPassword.setError(null);
accountFragmentListener.onChangePassword(currentPass, newPass);
}
});
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
accountFragmentListener = (IOAccountFragmentListener) context;
}
}

View File

@ -36,7 +36,7 @@ public class ActivitiesFragment extends Fragment {
private RecyclerView activitiesRecyclerView;
public interface IOnActivities {
void onRefreshActivities();
void onRefreshActivities(Runnable refresh);
void onClickOnAddActivity();
}
private IOnActivities listener;
@ -59,11 +59,13 @@ public class ActivitiesFragment extends Fragment {
SwipeRefreshLayout swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_layout_activities_list);
swipeRefreshLayout.setOnRefreshListener(() -> {
listener.onRefreshActivities();
listener.onRefreshActivities( () -> {
reloadData();
});
swipeRefreshLayout.setRefreshing(false);
});
activitiesAdapter = new ActivitiesAdapter(requireContext(), activities, participants, (IOClickOnActivityListener) requireActivity(), (IOnChageStateActivityListener) requireActivity());
activitiesAdapter = new ActivitiesAdapter(requireContext(), activities, participants, (IOClickOnActivityListener) requireActivity(), (IOnChageStateActivityListener) requireActivity(), this::reloadData);
activitiesRecyclerView = view.findViewById(R.id.activities_recycleView);
activitiesRecyclerView.setAdapter(activitiesAdapter);
activitiesRecyclerView.setHasFixedSize(true);
@ -72,6 +74,11 @@ public class ActivitiesFragment extends Fragment {
setupFab(view);
filterButton(view);
}
public void reloadData() {
activities = AppDataRepository.getInstance().getActivities();
participants = AppDataRepository.getInstance().getActivityResidents();
activitiesAdapter.updateData(activities, participants);
}
private void setupFab(View view) {
MaterialButton fab = view.findViewById(R.id.add_activity_button);
@ -104,7 +111,7 @@ public class ActivitiesFragment extends Fragment {
}
private void filterButton(View view){
ImageButton filterButton = view.findViewById(R.id.filter_activities_list_button);
ImageButton filterButton = view.findViewById(R.id.filter_activities_list_image_button);
filterButton.setOnClickListener( v -> {
String[] options = {getString(R.string.status_open_filter_text),
getString(R.string.status_closed_filter_text),

View File

@ -39,16 +39,20 @@ import java.util.List;
public class ActivityDetailFragment extends Fragment {
private View rootView;
private Activity activity;
private List<ActivityResident> participants;
private List<Resident> residents = AppDataRepository.getInstance().getResidents();
private ParticipantsAdapter adapter;
private RecyclerView recyclerView;
private IOClickOnAddParticipantListener addParticipantListener;
private IOnChageStateActivityListener changeStateActivityListener;
private IOnClickOnBackButtonListener backButtonListener;
public interface OnRefreshActivityDetailListener {
void onRefreshActivityDetail();
void onRefreshActivityDetail(Runnable refresh);
}
private OnRefreshActivityDetailListener refreshActivityDetailListener;
@ -61,6 +65,7 @@ public class ActivityDetailFragment extends Fragment {
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
this.rootView = view;
View statusBar = requireActivity().findViewById(R.id.status_bar_background);
statusBar.setBackgroundColor(Color.parseColor("#0062FF"));
@ -74,10 +79,34 @@ public class ActivityDetailFragment extends Fragment {
setupFab(view);
}
public void updateData() {
List<Activity> activities = AppDataRepository.getInstance().getActivities();
for (Activity a : activities) {
if (a.getId() == activity.getId()) {
this.activity = a;
break;
}
}
this.participants.clear();
List<ActivityResident> allParticipants = AppDataRepository.getInstance().getActivityResidents();
for (ActivityResident p : allParticipants) {
if (p.getActivityId() == activity.getId()) {
this.participants.add(p);
}
}
residents = AppDataRepository.getInstance().getResidents();
setupSwipeRefresh(rootView);
setupActivityInfo(rootView);
setupParticipantsStats(rootView);
setupAssistanceStats(rootView);
adapter.updateData(activity, participants, residents);
}
private void setupSwipeRefresh(View view) {
SwipeRefreshLayout swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_activity_detail);
swipeRefreshLayout.setOnRefreshListener(() -> {
refreshActivityDetailListener.onRefreshActivityDetail();
refreshActivityDetailListener.onRefreshActivityDetail(this::updateData);
swipeRefreshLayout.setRefreshing(false);
});
}
@ -107,11 +136,11 @@ public class ActivityDetailFragment extends Fragment {
switch (state) {
case CERRADO:
configureButton(startEndButton, getContext().getString(R.string.start_activity_text), "#59FF00", () ->
changeStateActivityListener.onChangeStateActivity(activity, ActivityState.EN_CURSO));
changeStateActivityListener.onChangeStateActivity(activity, ActivityState.EN_CURSO, this::updateData));
break;
case EN_CURSO:
configureButton(startEndButton, getContext().getString(R.string.finish_activity_text), "#FF0000" , () ->
changeStateActivityListener.onChangeStateActivity(activity, ActivityState.FINALIZADA));
changeStateActivityListener.onChangeStateActivity(activity, ActivityState.FINALIZADA, this::updateData));
break;
case FINALIZADA:
startEndButton.setText(getContext().getString(R.string.activity_finished_text));
@ -170,8 +199,8 @@ public class ActivityDetailFragment extends Fragment {
}
private void setupRecyclerView(View view) {
RecyclerView recyclerView = view.findViewById(R.id.rv_participants);
ParticipantsAdapter adapter = new ParticipantsAdapter(requireContext(), activity, participants, residents, (IOClickOnParticipantListener) requireActivity());
recyclerView = view.findViewById(R.id.rv_participants);
adapter = new ParticipantsAdapter(requireContext(), activity, participants, residents, (IOClickOnParticipantListener) requireActivity(), this::updateData);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
recyclerView.setHasFixedSize(true);

View File

@ -41,7 +41,7 @@ public class ParticipantDetailFragment extends Fragment {
private List<Activity> activities;
public interface IOnRefreshParticipantDetailListener {
void onRefreshParticipantDetail();
void onRefreshParticipantDetail(Runnable refresh);
}
private IOnRefreshParticipantDetailListener refreshParticipantDetailListener;
@ -65,7 +65,7 @@ public class ParticipantDetailFragment extends Fragment {
SwipeRefreshLayout swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_participant_detail);
swipeRefreshLayout.setOnRefreshListener(() -> {
refreshParticipantDetailListener.onRefreshParticipantDetail();
refreshParticipantDetailListener.onRefreshParticipantDetail(this::updateData);
swipeRefreshLayout.setRefreshing(false);
});
@ -118,6 +118,11 @@ public class ParticipantDetailFragment extends Fragment {
}
private void updateData(){
residents = AppDataRepository.getInstance().getResidents();
activities = AppDataRepository.getInstance().getActivities();
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);

View File

@ -0,0 +1,502 @@
package com.andresgmoran.apptrabajadores.ui.fragments.admin;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.models.Game;
import com.andresgmoran.apptrabajadores.models.Residence;
import com.andresgmoran.apptrabajadores.models.Resident;
import com.andresgmoran.apptrabajadores.models.User;
import com.andresgmoran.apptrabajadores.repository.AppDataRepository;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class AdminPanelFragment extends Fragment {
private Map<String, View> actionViews = new HashMap<>();
private List<Residence> residences = new ArrayList<>();
private List<Resident> residents = new ArrayList<>();
private List<User> users = new ArrayList<>();
private List<Game> games = new ArrayList<>();
private static final String[] ACTIONS = {
"action_add_residencia", "action_delete_residencia",
"action_add_user", "action_delete_user",
"action_add_resident", "action_delete_resident",
"action_add_game", "action_delete_game"
};
public interface IOnAdminPanel{
void onLogOutButtonClicked();
}
private IOnAdminPanel listener;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_admin, container, false);
}
@Override
public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceState) {
super.onViewCreated(root, savedInstanceState);
for (String idName : ACTIONS) {
View actionLayout = root.findViewById(getResources().getIdentifier(idName, "id", requireContext().getPackageName()));
if (actionLayout != null) {
setupActionLayout(idName, actionLayout);
actionViews.put(idName, actionLayout);
}
}
Button logoutButton = root.findViewById(R.id.btn_logout_admin);
logoutButton.setOnClickListener( v -> {
if (listener != null) {
listener.onLogOutButtonClicked();
}
});
}
private void setupActionLayout(String idName, View layout) {
TextView title = layout.findViewById(R.id.title);
LinearLayout container = layout.findViewById(R.id.container);
Button executeBtn = layout.findViewById(R.id.btn_execute);
Spinner spinnerResidencias = layout.findViewById(R.id.spinner_residencias);
Spinner spinnerExtra = layout.findViewById(R.id.spinner_extra);
EditText residenceName = layout.findViewById(R.id.residence_name_input);
EditText residenceEmail = layout.findViewById(R.id.residence_email_input);
title.setText(formatActionTitle(idName));
title.setOnClickListener(v -> container.setVisibility(container.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE));
spinnerResidencias.setVisibility(View.GONE);
spinnerExtra.setVisibility(View.GONE);
layout.findViewById(R.id.layout_residence_inputs).setVisibility(View.GONE);
layout.findViewById(R.id.layout_resident_inputs).setVisibility(View.GONE);
layout.findViewById(R.id.layout_user_inputs).setVisibility(View.GONE);
layout.findViewById(R.id.layout_game_inputs).setVisibility(View.GONE);
switch (idName) {
case "action_add_residencia":
layout.findViewById(R.id.layout_residence_inputs).setVisibility(View.VISIBLE);
executeBtn.setOnClickListener(v -> {
String name = residenceName.getText().toString().trim();
String email = residenceEmail.getText().toString().trim();
boolean valid = true;
if (name.isEmpty()) {
residenceName.setError("Nombre obligatorio");
valid = false;
} else {
residenceName.setError(null);
}
if (email.isEmpty()) {
residenceEmail.setError("Email obligatorio");
valid = false;
} else {
residenceEmail.setError(null);
}
if (valid) {
addResidencia(name, email);
}
});
break;
case "action_delete_residencia":
setupResidenciaSpinner(spinnerResidencias);
executeBtn.setOnClickListener(v -> {
int pos = spinnerResidencias.getSelectedItemPosition();
if (pos >= 0) deleteResidencia(residences.get(pos).getId());
});
break;
case "action_add_user":
layout.findViewById(R.id.layout_user_inputs).setVisibility(View.VISIBLE);
layout.findViewById(R.id.layout_user_inputs).findViewById(R.id.et_add_user_verfication_code).setVisibility(View.GONE);
setupResidenciaSpinner(spinnerResidencias);
EditText userName = layout.findViewById(R.id.et_add_user_nombre);
EditText userSurname = layout.findViewById(R.id.et_add_user_apellido);
EditText userEmail = layout.findViewById(R.id.et_add_user_email);
EditText userPassword = layout.findViewById(R.id.et_add_user_password);
executeBtn.setOnClickListener( v -> {
String name = userName.getText().toString().trim();
String surname = userSurname.getText().toString().trim();
String email = userEmail.getText().toString().trim();
String password = userPassword.getText().toString().trim();
boolean valid = true;
if (userName.getText().toString().trim().isEmpty()) {
userName.setError("Nombre obligatorio");
valid = false;
} else {
userName.setError(null);
}
if (userSurname.getText().toString().trim().isEmpty()) {
userSurname.setError("Apellidos obligatorios");
valid = false;
} else {
userSurname.setError(null);
}
if (email.isEmpty()) {
userEmail.setError("Email obligatorio");
valid = false;
} else {
userEmail.setError(null);
}
if (password.isEmpty()) {
userPassword.setError("Contraseña obligatoria");
valid = false;
} else {
userPassword.setError(null);
}
if (valid) {
int pos = spinnerResidencias.getSelectedItemPosition();
if (pos >= 0) {
AppDataRepository.getInstance().addUser(requireContext(), residences.get(pos).getId(),name, surname, email, password,
() -> {
Toast.makeText(requireContext(), "Usuario añadido", Toast.LENGTH_SHORT).show();
refreshData();
layout.findViewById(R.id.layout_user_inputs).findViewById(R.id.et_add_user_verfication_code).setVisibility(View.VISIBLE);
EditText verificationCode = layout.findViewById(R.id.et_add_user_verfication_code);
executeBtn.setOnClickListener( v2 -> {
String code = verificationCode.getText().toString().trim();
if (code.isEmpty()) {
verificationCode.setError("Código de verificación obligatorio");
} else {
AppDataRepository.getInstance().verifyUser(requireContext(), email, code,
() -> Toast.makeText(requireContext(), "Usuario verificado", Toast.LENGTH_SHORT).show(),
() -> Toast.makeText(requireContext(), "Error al verificar usuario", Toast.LENGTH_SHORT).show());
}
});
},
() -> Toast.makeText(requireContext(), "Error al añadir usuario", Toast.LENGTH_SHORT).show());
}
}
});
break;
case "action_delete_user":
setupResidenciaSpinner(spinnerResidencias);
spinnerResidencias.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
setupUserSpinner(spinnerExtra, residences.get(position).getId());
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
});
executeBtn.setOnClickListener(v -> {
int posResi = spinnerResidencias.getSelectedItemPosition();
int pos = spinnerExtra.getSelectedItemPosition();
if (pos >= 0 && pos < users.size() && posResi >= 0) {
List<User> filteredUsers = (List<User>) spinnerExtra.getTag();
deleteUser( residences.get(posResi).getId(), filteredUsers.get(pos).getId());
}
});
break;
case "action_add_resident":
setupResidenciaSpinner(spinnerResidencias);
layout.findViewById(R.id.layout_resident_inputs).setVisibility(View.VISIBLE);
EditText residentName = layout.findViewById(R.id.et_add_resident_nombre);
EditText residentSurnames = layout.findViewById(R.id.et_add_resident_apellido);
EditText residentFechaNac = layout.findViewById(R.id.et_add_resident_fecha_nacimiento);
EditText residentIDDocument = layout.findViewById(R.id.et_add_resident_documento_identidad);
EditText residentDocumentYear = layout.findViewById(R.id.et_add_resident_year);
EditText residentDocumentMonth = layout.findViewById(R.id.et_add_resident_month);
EditText residentFamily1 = layout.findViewById(R.id.et_add_resident_familiar_1);
EditText residentFamily2 = layout.findViewById(R.id.et_add_resident_familiar_2);
executeBtn.setOnClickListener(v -> {
String name = residentName.getText().toString().trim();
String surnames = residentSurnames.getText().toString().trim();
String fechaNac = residentFechaNac.getText().toString().trim();
String idDocument = residentIDDocument.getText().toString().trim();
String documentYear = residentDocumentYear.getText().toString().trim();
String documentMonth = residentDocumentMonth.getText().toString().trim();
String family1 = residentFamily1.getText().toString().trim();
String family2 = residentFamily2.getText().toString().trim();
boolean valid = true;
// Validación campos texto
if (name.isEmpty()) {
residentName.setError("Nombre obligatorio");
valid = false;
} else {
residentName.setError(null);
}
if (surnames.isEmpty()) {
residentSurnames.setError("Apellidos obligatorios");
valid = false;
} else {
residentSurnames.setError(null);
}
if (idDocument.isEmpty()) {
residentIDDocument.setError("Documento obligatorio");
valid = false;
} else {
residentIDDocument.setError(null);
}
if (family1.isEmpty()) {
residentFamily1.setError("Familiar 1 obligatorio");
valid = false;
} else {
residentFamily1.setError(null);
}
if (family2.isEmpty()) {
residentFamily2.setError("Familiar 2 obligatorio");
valid = false;
} else {
residentFamily2.setError(null);
}
// Validación fecha nacimiento
LocalDate fechaNacimiento = null;
try {
fechaNacimiento = LocalDate.parse(fechaNac); // formato: yyyy-MM-dd
residentFechaNac.setError(null);
} catch (Exception e) {
residentFechaNac.setError("Formato válido: yyyy-MM-dd");
valid = false;
}
// Validación año y mes
int year = -1, month = -1;
try {
year = Integer.parseInt(documentYear);
residentDocumentYear.setError(null);
} catch (NumberFormatException e) {
residentDocumentYear.setError("Debe ser un número");
valid = false;
}
try {
month = Integer.parseInt(documentMonth);
residentDocumentMonth.setError(null);
} catch (NumberFormatException e) {
residentDocumentMonth.setError("Debe ser un número");
valid = false;
}
int pos = spinnerResidencias.getSelectedItemPosition();
if (valid && pos >= 0) {
addResident(residences.get(pos).getId(), name, surnames, fechaNacimiento, idDocument, family1, family2, year, month);
}
});
break;
case "action_delete_resident":
setupResidenciaSpinner(spinnerResidencias);
spinnerResidencias.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
setupResidenteSpinner(spinnerExtra, residences.get(position).getId());
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
});
executeBtn.setOnClickListener(v -> {
List<Long> residentIds = (List<Long>) spinnerExtra.getTag();
int pos = spinnerExtra.getSelectedItemPosition();
if (residentIds != null && pos >= 0 && pos < residentIds.size()) {
deleteResidente(residences.get(spinnerResidencias.getSelectedItemPosition()).getId(), residentIds.get(pos));
}
});
break;
case "action_add_game":
layout.findViewById(R.id.layout_game_inputs).setVisibility(View.VISIBLE);
EditText gameName = layout.findViewById(R.id.et_add_game_nombre);
executeBtn.setOnClickListener( v -> {
String name = gameName.getText().toString().trim();
if (name.isEmpty()) {
gameName.setError("Nombre obligatorio");
} else {
AppDataRepository.getInstance().addGame(requireContext(), name,
() -> {
Toast.makeText(requireContext(), "Juego añadido", Toast.LENGTH_SHORT).show();
refreshData();
},
() -> Toast.makeText(requireContext(), "Error al añadir juego", Toast.LENGTH_SHORT).show());
}
});
break;
case "action_delete_game":
spinnerResidencias.setVisibility(View.GONE);
setupGameSpinner(spinnerExtra);
executeBtn.setOnClickListener(v -> {
int pos = spinnerExtra.getSelectedItemPosition();
if (pos >= 0 && pos < games.size()) deleteJuego(games.get(pos).getId());
});
break;
}
}
private void refreshData() {
residences = AppDataRepository.getInstance().getResidences();
residents = AppDataRepository.getInstance().getResidents();
users = AppDataRepository.getInstance().getUsers();
games = AppDataRepository.getInstance().getGames();
for (Map.Entry<String, View> entry : actionViews.entrySet()) {
setupActionLayout(entry.getKey(), entry.getValue());
}
}
private void setupResidenciaSpinner(Spinner spinner) {
spinner.setVisibility(View.VISIBLE);
List<String> nombres = new ArrayList<>();
for (Residence r : residences) nombres.add(r.getName());
spinner.setAdapter(new ArrayAdapter<>(requireContext(), android.R.layout.simple_spinner_item, nombres));
}
private void setupResidenteSpinner(Spinner spinner, long idResidencia) {
spinner.setVisibility(View.VISIBLE);
List<String> nombres = new ArrayList<>();
List<Long> ids = new ArrayList<>();
for (Resident r : residents) {
if (r.getResidenceId() == idResidencia) {
nombres.add(r.getName() + " " + r.getSurnames());
ids.add(r.getId());
}
}
spinner.setAdapter(new ArrayAdapter<>(requireContext(), android.R.layout.simple_spinner_item, nombres));
spinner.setTag(ids);
}
private void setupGameSpinner(Spinner spinner) {
spinner.setVisibility(View.VISIBLE);
List<String> nombres = new ArrayList<>();
for (Game g : games) nombres.add(g.getName());
spinner.setAdapter(new ArrayAdapter<>(requireContext(), android.R.layout.simple_spinner_item, nombres));
}
private void setupUserSpinner(Spinner spinner, long idResidencia) {
spinner.setVisibility(View.VISIBLE);
List<User> filteredUsers = new ArrayList<>();
for (User u : users) {
if (u.getResidenceId() != null && u.getResidenceId() == idResidencia) {
filteredUsers.add(u);
}
}
if (filteredUsers.isEmpty()) {
spinner.setAdapter(new ArrayAdapter<>(requireContext(), android.R.layout.simple_spinner_item, new String[]{"No hay usuarios"}));
} else {
List<String> nombres = new ArrayList<>();
for (User u : filteredUsers) {
nombres.add(u.getName() + " " + u.getSurnames());
}
spinner.setAdapter(new ArrayAdapter<>(requireContext(), android.R.layout.simple_spinner_item, nombres));
spinner.setTag(filteredUsers);
}
}
private void addResidencia(String name, String email) {
AppDataRepository.getInstance().addResidence(requireContext(), name, email,
() -> {
Toast.makeText(requireContext(), "Residencia añadida", Toast.LENGTH_SHORT).show();
refreshData();
},
() -> Toast.makeText(requireContext(), "Error al añadir residencia", Toast.LENGTH_SHORT).show());
}
private void deleteResidencia(long id) {
AppDataRepository.getInstance().deleteResidence(requireContext(), id,
() -> {
Toast.makeText(requireContext(), "Residencia eliminada", Toast.LENGTH_SHORT).show();
refreshData();
},
() -> Toast.makeText(requireContext(), "Error al eliminar residencia", Toast.LENGTH_SHORT).show());
}
private void addResident(long idResi, String name, String surnames, LocalDate fechaNac, String idDocument, String family1, String family2, int documentYear, int documentMonth) {
AppDataRepository.getInstance().addResidenteAdmin(requireContext(), idResi, name, surnames, fechaNac, idDocument, family1, family2, documentYear, documentMonth,
() -> {
Toast.makeText(requireContext(), "Residente añadido", Toast.LENGTH_SHORT).show();
refreshData();
},
() -> Toast.makeText(requireContext(), "Error al añadir residente", Toast.LENGTH_SHORT).show());
}
private void deleteResidente(long idResi, long idResident) {
AppDataRepository.getInstance().deleteResident(requireContext(), idResi, idResident,
() -> {
Toast.makeText(requireContext(), "Residente eliminado", Toast.LENGTH_SHORT).show();
refreshData();
},
() -> Toast.makeText(requireContext(), "Error al eliminar residente", Toast.LENGTH_SHORT).show());
}
private void deleteJuego(long id) {
AppDataRepository.getInstance().deleteGame(requireContext(), id,
() -> {
Toast.makeText(requireContext(), "Juego eliminado", Toast.LENGTH_SHORT).show();
refreshData();
},
() -> Toast.makeText(requireContext(), "Error al eliminar juego", Toast.LENGTH_SHORT).show());
}
private void deleteUser(long idResi, long idUser) {
AppDataRepository.getInstance().deleteUser(requireContext(), idResi, idUser,
() -> {
Toast.makeText(requireContext(), "Usuario eliminado", Toast.LENGTH_SHORT).show();
refreshData();
},
() -> Toast.makeText(requireContext(), "Error al eliminar usuario", Toast.LENGTH_SHORT).show());
}
private String formatActionTitle(String idName) {
return idName.replace("action_", "").replace("_", " ").toUpperCase();
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
residences = AppDataRepository.getInstance().getResidences();
residents = AppDataRepository.getInstance().getResidents();
users = AppDataRepository.getInstance().getUsers();
games = AppDataRepository.getInstance().getGames();
listener = (IOnAdminPanel) context;
}
}

View File

@ -8,6 +8,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
@ -37,17 +38,21 @@ public class GameFragment extends Fragment {
private Game game;
public interface IOnRefreshGameListener {
void onRefreshGameStats();
void onRefreshGameStats(Runnable refresh);
}
private IOnRefreshGameListener refreshGameListener;
private IOnClickOnBackButtonListener backButtonListener;
private TextView gameNameTextView;
private ImageView gameImageView;
private TextView numberOfGamesLastWeekTextView;
private TextView totalGamesPlayedTextView;
private TextView topPlayerTextView;
private ImageButton backButton;
private LastGamesAdapter lastGamesAdapter;
private RecyclerView recyclerView;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
@ -62,6 +67,7 @@ public class GameFragment extends Fragment {
statusBar.setBackgroundColor(Color.parseColor("#0062FF"));
gameNameTextView = view.findViewById(R.id.banner_name_game);
gameImageView = view.findViewById(R.id.game_image);
numberOfGamesLastWeekTextView = view.findViewById(R.id.tv_number_of_games_last_week);
totalGamesPlayedTextView = view.findViewById(R.id.tv_total_games_played);
topPlayerTextView = view.findViewById(R.id.tv_top_jugador);
@ -69,7 +75,7 @@ public class GameFragment extends Fragment {
SwipeRefreshLayout swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_game);
swipeRefreshLayout.setOnRefreshListener(() -> {
refreshGameListener.onRefreshGameStats();
refreshGameListener.onRefreshGameStats(this::refreshData);
swipeRefreshLayout.setRefreshing(false);
});
@ -85,7 +91,14 @@ public class GameFragment extends Fragment {
}
}
gameNameTextView.setText(game.getName());
String name = game.getName();
String formattedName = name.substring(0, 1).toUpperCase() + name.substring(1);
gameNameTextView.setText(formattedName);
String resourceName = "logo_" + game.getName().toLowerCase().replace(" ", "_");
int imageResId = getContext().getResources().getIdentifier(resourceName, "drawable", getContext().getPackageName());
if (imageResId != 0)
gameImageView.setImageResource(imageResId);
if (allGameStats.isEmpty()) {
numberOfGamesLastWeekTextView.setText("-");
@ -100,15 +113,45 @@ public class GameFragment extends Fragment {
numberOfGamesLastWeekTextView.setText(String.valueOf(numberOfGamesLastWeek));
totalGamesPlayedTextView.setText(String.valueOf(allGameStats.size()));
Resident topResident = getTopResident(allGameStats, residents);
topPlayerTextView.setText(topResident.getName());
topPlayerTextView.setText(topResident.getName() + " " + topResident.getSurnames());
LastGamesAdapter lastGamesAdapter = new LastGamesAdapter(allGameStats, game, residents, (IOClickOnGameStatsListener) requireActivity());
RecyclerView recyclerView = view.findViewById(R.id.rv_game_stats);
lastGamesAdapter = new LastGamesAdapter(allGameStats, game, residents, (IOClickOnGameStatsListener) requireActivity(), () -> {
refreshData();
});
recyclerView = view.findViewById(R.id.rv_game_stats);
recyclerView.setAdapter( lastGamesAdapter );
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
}
private void refreshData() {
gameStats = AppDataRepository.getInstance().getGameStats();
residents = AppDataRepository.getInstance().getResidents();
List<GameStat> allGameStats = new ArrayList<>();
for (GameStat gs : gameStats) {
if (gs.getGameId() == game.getId()) {
allGameStats.add(gs);
}
}
if (allGameStats.isEmpty()) {
numberOfGamesLastWeekTextView.setText("-");
totalGamesPlayedTextView.setText("-");
topPlayerTextView.setText("-");
return;
}
lastGamesAdapter.updateData(allGameStats, game, residents);
int numberOfGamesLastWeek = getGamesLastWeek(allGameStats);
numberOfGamesLastWeekTextView.setText(String.valueOf(numberOfGamesLastWeek));
totalGamesPlayedTextView.setText(String.valueOf(allGameStats.size()));
Resident topResident = getTopResident(allGameStats, residents);
topPlayerTextView.setText(topResident.getName());
}
private int getGamesLastWeek(List<GameStat> allGameStats) {
int count = 0;
LocalDateTime now = LocalDateTime.now();

View File

@ -1,6 +1,7 @@
package com.andresgmoran.apptrabajadores.ui.fragments.gameDetail;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
@ -9,6 +10,7 @@ import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
@ -21,6 +23,7 @@ import com.andresgmoran.apptrabajadores.interfaces.IOnClickOnBackButtonListener;
import com.andresgmoran.apptrabajadores.models.Game;
import com.andresgmoran.apptrabajadores.models.Resident;
import com.andresgmoran.apptrabajadores.models.User;
import com.andresgmoran.apptrabajadores.models.gameStats.Difficulty;
import com.andresgmoran.apptrabajadores.models.gameStats.GameStat;
import com.andresgmoran.apptrabajadores.repository.AppDataRepository;
import com.andresgmoran.apptrabajadores.ui.MainActivity;
@ -30,10 +33,10 @@ import java.util.List;
public class GameDetailFragment extends Fragment {
public interface IOnAddObservationListener {
void onAddObservation(String observation, long gameId, long gameStatId);
void onAddObservation(String observation, long gameId, long gameStatId, Runnable refresh);
}
public interface IOnRefreshGameStatsListener {
void onRefreshGameStats();
void onRefreshGameStats(Runnable runnable);
}
private IOnRefreshGameStatsListener refreshGameStatsListener;
private IOnAddObservationListener addObservationListener;
@ -43,11 +46,13 @@ public class GameDetailFragment extends Fragment {
private Resident gameStatResident;
private Game gameStatGame;
private User actualUser = AppDataRepository.getInstance().getActualUser();
private Bitmap actualUserImage = AppDataRepository.getInstance().getActualUserImage();
private List<User> users = AppDataRepository.getInstance().getUsers();
private TextView residentNameTextView;
private TextView gameNameTextView;
private TextView durationTextView;
private TextView levelTextView;
private TextView failsTitle;
private TextView failsTextView;
private ImageButton backButton;
@ -68,7 +73,7 @@ public class GameDetailFragment extends Fragment {
SwipeRefreshLayout swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_game_detail);
swipeRefreshLayout.setOnRefreshListener(() -> {
refreshGameStatsListener.onRefreshGameStats();
refreshGameStatsListener.onRefreshGameStats(this::updateData);
swipeRefreshLayout.setRefreshing(false);
});
@ -80,11 +85,20 @@ public class GameDetailFragment extends Fragment {
residentNameTextView = view.findViewById(R.id.banner_name_resident);
gameNameTextView = view.findViewById(R.id.game_stats_detail_game_name);
durationTextView = view.findViewById(R.id.tv_duration);
levelTextView = view.findViewById(R.id.tv_level);
failsTitle = view.findViewById(R.id.label_fails);
failsTextView = view.findViewById(R.id.tv_fails);
residentNameTextView.setText(gameStatResident.getName() + " " + gameStatResident.getSurnames());
gameNameTextView.setText(gameStatGame.getName());
String name = gameStatGame.getName();
String formattedName = name.substring(0, 1).toUpperCase() + name.substring(1);
gameNameTextView.setText(formattedName);
if (gameStat.getDifficulty().equals(Difficulty.DIFICULTAD1))
levelTextView.setText(R.string.level1_text);
else if (gameStat.getDifficulty().equals(Difficulty.DIFICULTAD2))
levelTextView.setText(R.string.level2_text);
else if (gameStat.getDifficulty().equals(Difficulty.DIFICULTAD3))
levelTextView.setText(R.string.level3_text);
durationTextView.setText(Math.round(gameStat.getDuration()) + " seg");
if (gameStatGame.getName().equals("bingo auditivo") || gameStatGame.getName().equals("flecha y reacciona")) {
@ -92,16 +106,21 @@ public class GameDetailFragment extends Fragment {
if (gameStat.getNum() == 0) {
failsTextView.setText("PERDIDO");
} else {
failsTextView.setText("GANADO");
failsTextView.setText("GANADA");
}
} else if (gameStatGame.getName().equals("gimnasio")){
failsTitle.setVisibility( View.GONE);
failsTextView.setVisibility( View.GONE);
} else {
failsTextView.setText(gameStat.getNum() + " fallos");
failsTitle.setText("Fallos");
failsTextView.setText(String.valueOf(gameStat.getNum()));
}
View observation = view.findViewById(R.id.observation);
ImageView observationUserImage = observation.findViewById(R.id.user_image_observation);
observationUserImage.setImageBitmap(actualUserImage);
TextView observationUserName = observation.findViewById(R.id.observation_user_name);
TextView observationUserRole = observation.findViewById(R.id.observation_person_role);
TextView observationText = observation.findViewById(R.id.observation_text);
EditText observationEditText = observation.findViewById(R.id.observation_input);
@ -109,7 +128,7 @@ public class GameDetailFragment extends Fragment {
for (User user : users) {
if (user.getId() == gameStat.getUserId()) {
observationUserName.setText(actualUser.getName());
observationUserName.setText(actualUser.getName() + " " + actualUser.getSurnames());
break;
}
}
@ -121,20 +140,43 @@ public class GameDetailFragment extends Fragment {
addObservationButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
addObservationListener.onAddObservation(observationEditText.getText().toString(), gameStatGame.getId(), gameStat.getId());
addObservationListener.onAddObservation(observationEditText.getText().toString(), gameStatGame.getId(), gameStat.getId(),GameDetailFragment.this::updateData);
}
});
} else {
observationUserRole.setText("El usuario encargado no ha añadido ninguna observación");
observationText.setText("El usuario encargado no ha añadido ninguna observación");
}
} else {
observationText.setVisibility(View.VISIBLE);
//Añadir rol usuario
observationText.setText(gameStat.getObservation());
}
}
private void updateData() {
List<GameStat> gameStats = AppDataRepository.getInstance().getGameStats();
for (GameStat stat : gameStats) {
if (stat.getId() == gameStat.getId()) {
gameStat = stat;
break;
}
}
List<Resident> residents = AppDataRepository.getInstance().getResidents();
for (Resident resident : residents) {
if (resident.getId() == gameStat.getResidentId()) {
gameStatResident = resident;
break;
}
}
List<Game> games = AppDataRepository.getInstance().getGames();
for (Game game : games) {
if (game.getId() == gameStat.getGameId()) {
gameStatGame = game;
break;
}
}
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);

View File

@ -41,11 +41,11 @@ import java.util.Map;
public class HomeFragment extends Fragment {
private List<Resident> residents = AppDataRepository.getInstance().getResidents();
private List<GameStat> gameStats = AppDataRepository.getInstance().getGameStats();
private List<Game> games = AppDataRepository.getInstance().getGames();
private User user = AppDataRepository.getInstance().getActualUser();
private Bitmap userImageBitmap = AppDataRepository.getInstance().getActualUserImage();
private List<Resident> residents;
private List<GameStat> gameStats;
private List<Game> games;
private User user;
private Bitmap userImageBitmap;
private TextView userNameTextView;
private ImageView userImage;
@ -61,7 +61,7 @@ public class HomeFragment extends Fragment {
private LastGamesAdapter lastGamesAdapter;
public interface IOnRefreshHomeListener {
void onRefreshHome();
void onRefreshHome(Runnable refresh);
}
private IOnRefreshHomeListener refreshListener;
@ -92,10 +92,27 @@ public class HomeFragment extends Fragment {
setupFab(view);
}
public void refreshData() {
residents = AppDataRepository.getInstance().getResidents();
gameStats = AppDataRepository.getInstance().getGameStats();
games = AppDataRepository.getInstance().getGames();
user = AppDataRepository.getInstance().getActualUser();
userImageBitmap = AppDataRepository.getInstance().getActualUserImage();
userNameTextView.setText(user.getName() + " " + user.getSurnames());
userImage.setImageBitmap(userImageBitmap);
lastGamesAdapter.updateData(gameStats, games, residents);
gamesAdapter.updateData(games);
residentsAdapter.updateData(residents);
}
private void setupSwipeRefresh(View view) {
SwipeRefreshLayout swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_home);
swipeRefreshLayout.setOnRefreshListener(() -> {
refreshListener.onRefreshHome();
refreshListener.onRefreshHome( () -> {
refreshData();
});
swipeRefreshLayout.setRefreshing(false);
});
}
@ -111,7 +128,7 @@ public class HomeFragment extends Fragment {
emptyLatestGamesText = view.findViewById(R.id.tv_lastgames_empty_home);
recyclerViewLastGames = view.findViewById(R.id.latestGames_recycleView_home);
lastGamesAdapter = new LastGamesAdapter(gameStats, games, residents, (IOClickOnGameStatsListener) requireActivity());
lastGamesAdapter = new LastGamesAdapter(gameStats, games, residents, (IOClickOnGameStatsListener) requireActivity(), this::refreshData);
recyclerViewLastGames.setAdapter(lastGamesAdapter);
recyclerViewLastGames.setHasFixedSize(true);
recyclerViewLastGames.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false));
@ -172,7 +189,7 @@ public class HomeFragment extends Fragment {
emptyResidentsText = view.findViewById(R.id.tv_residents_empty_home);
recyclerViewResidents = view.findViewById(R.id.residents_recycleView_home);
residentsAdapter = new ResidentsAdapter(residents, (IOClickOnResidentListener) requireActivity());
residentsAdapter = new ResidentsAdapter(residents, (IOClickOnResidentListener) requireActivity(), this::refreshData );
recyclerViewResidents.setAdapter(residentsAdapter);
recyclerViewResidents.setHasFixedSize(true);
recyclerViewResidents.setLayoutManager(new LinearLayoutManager(getActivity()));
@ -231,6 +248,12 @@ public class HomeFragment extends Fragment {
public void onAttach(@NonNull Context context) {
super.onAttach(context);
residents = AppDataRepository.getInstance().getResidents();
gameStats = AppDataRepository.getInstance().getGameStats();
games = AppDataRepository.getInstance().getGames();
user = AppDataRepository.getInstance().getActualUser();
userImageBitmap = AppDataRepository.getInstance().getActualUserImage();
refreshListener = (IOnRefreshHomeListener) context;
addParticipantListener = (IOnClickOnAddParticipantListener) context;
}
@ -324,7 +347,7 @@ public class HomeFragment extends Fragment {
filteredList.sort((s1, s2) -> s2.getDateTime().compareTo(s1.getDateTime()));
}
lastGamesAdapter.updateData(filteredList);
lastGamesAdapter.updateData(filteredList, games, residents);
recyclerViewLastGames.scrollToPosition(0);
}

View File

@ -51,7 +51,7 @@ public class ResidenceDetailFragment extends Fragment {
private List<Game> games;
public interface IOnRefreshResidenceDetailListener {
void onRefreshResidenceDetail();
void onRefreshResidenceDetail(Runnable refresh);
}
private IOnRefreshResidenceDetailListener refreshListener;
@ -98,6 +98,18 @@ public class ResidenceDetailFragment extends Fragment {
}
}
private void updateData() {
residence = AppDataRepository.getInstance().getResidence();
residents = AppDataRepository.getInstance().getResidents();
residentsTakenOut = AppDataRepository.getInstance().getResidentsTakenOut();
gameStats = AppDataRepository.getInstance().getGameStats();
games = AppDataRepository.getInstance().getGames();
updateUI();
pieChart(getView());
generateBarCharts(getView());
}
private void updateUI() {
if (residence != null) {
residenceNameTextView.setText(residence.getName());
@ -119,7 +131,7 @@ public class ResidenceDetailFragment extends Fragment {
private void setupSwipeRefresh(View view) {
SwipeRefreshLayout swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_residence_detail);
swipeRefreshLayout.setOnRefreshListener(() -> {
refreshListener.onRefreshResidenceDetail();
refreshListener.onRefreshResidenceDetail(this::updateData);
swipeRefreshLayout.setRefreshing(false);
});
}
@ -172,7 +184,8 @@ public class ResidenceDetailFragment extends Fragment {
String nombreJuego = "";
for (Game g : games) {
if (g.getId().equals(entry.getKey())) {
nombreJuego = g.getName();
String name = g.getName();
nombreJuego = name.substring(0, 1).toUpperCase() + name.substring(1);
break;
}
}
@ -235,7 +248,8 @@ public class ResidenceDetailFragment extends Fragment {
String nombreJuego = "";
for (Game g : games) {
if (g.getId().equals(entry.getKey())) {
nombreJuego = g.getName();
String name = g.getName();
nombreJuego = name.substring(0, 1).toUpperCase() + name.substring(1);
break;
}
}

View File

@ -7,6 +7,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@ -57,7 +58,7 @@ public class ResidentFragment extends Fragment {
private List<GameStat> filteredStats;
public interface IOnRefreshResidentListener {
void onRefreshGameStats();
void onRefreshGameStats(Runnable runnable);
}
private IOnRefreshResidentListener refreshListener;
@ -78,7 +79,7 @@ public class ResidentFragment extends Fragment {
SwipeRefreshLayout swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_resident);
swipeRefreshLayout.setOnRefreshListener(() -> {
refreshListener.onRefreshGameStats();
refreshListener.onRefreshGameStats(this::updateData);
swipeRefreshLayout.setRefreshing(false);
});
@ -101,7 +102,9 @@ public class ResidentFragment extends Fragment {
}
}
lastGamesAdapter = new LastGamesAdapter(filteredStats, games, resident, (IOClickOnGameStatsListener) requireActivity());
lastGamesAdapter = new LastGamesAdapter(filteredStats, games, resident, (IOClickOnGameStatsListener) requireActivity(), () -> {
updateData();
});
recyclerViewLastGames.setAdapter(lastGamesAdapter);
recyclerViewLastGames.setHasFixedSize(true);
recyclerViewLastGames.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false));
@ -112,6 +115,18 @@ public class ResidentFragment extends Fragment {
updateVisibility(view);
}
private void updateData() {
gameStats = AppDataRepository.getInstance().getGameStats();
filteredStats.clear();
for (GameStat stat : gameStats) {
if (Objects.equals(stat.getResidentId(), resident.getId())) {
filteredStats.add(stat);
}
}
lastGamesAdapter.updateData(filteredStats, games, resident);
updateVisibility(getView());
}
private void updateVisibility(View view) {
if (filteredStats.isEmpty()) {
pieCard.setVisibility(View.GONE);
@ -130,37 +145,34 @@ public class ResidentFragment extends Fragment {
private void showLastGamesFilterDialog() {
String[] options = {
"Nombre juego [A-Z]",
"Nombre juego [Z-A]",
"De primera a última",
"default"
getString(R.string.game_name_a_z_filter_text),
getString(R.string.game_name_z_a_filter_text),
getString(R.string.first_to_last_filter_text),
getString(R.string.last_to_first_filter_text),
};
new AlertDialog.Builder(requireContext())
.setTitle("Filtrar últimas partidas")
new androidx.appcompat.app.AlertDialog.Builder(requireContext())
.setTitle(getString( R.string.filter_last_games_title))
.setItems(options, (dialog, which) -> filterLastGamesList(options[which]))
.show();
}
private void filterLastGamesList(String option) {
List<GameStat> sortedList = new ArrayList<>(filteredStats);
List<GameStat> filteredList = new ArrayList<>(gameStats);
switch (option) {
case "Nombre juego [A-Z]":
sortedList.sort(Comparator.comparing(stat -> getGameNameById(stat.getGameId())));
break;
case "Nombre juego [Z-A]":
sortedList.sort((s1, s2) -> getGameNameById(s2.getGameId()).compareTo(getGameNameById(s1.getGameId())));
break;
case "De primera a última":
sortedList.sort(Comparator.comparing(GameStat::getDateTime));
break;
default:
sortedList.sort((s1, s2) -> s2.getDateTime().compareTo(s1.getDateTime()));
break;
if (option.equals(getString(R.string.game_name_a_z_filter_text))) {
filteredList.sort(Comparator.comparing(stat -> getGameNameById(stat.getGameId())));
} else if (option.equals(getString(R.string.game_name_z_a_filter_text))) {
filteredList.sort((s1, s2) -> getGameNameById(s2.getGameId()).compareTo(getGameNameById(s1.getGameId())));
} else if (option.equals(getString(R.string.first_to_last_filter_text))) {
filteredList.sort(Comparator.comparing(GameStat::getDateTime));
} else if (option.equals(getString(R.string.last_to_first_filter_text))) {
filteredList.sort((s1, s2) -> s2.getDateTime().compareTo(s1.getDateTime()));
} else {
filteredList.sort((s1, s2) -> s2.getDateTime().compareTo(s1.getDateTime()));
}
lastGamesAdapter.updateData(sortedList);
lastGamesAdapter.updateData(filteredList, games, resident);
recyclerViewLastGames.scrollToPosition(0);
}
@ -217,7 +229,8 @@ public class ResidentFragment extends Fragment {
String nombreJuego = "";
for (Game g : games) {
if (g.getId().equals(entry.getKey())) {
nombreJuego = g.getName();
String name = g.getName();
nombreJuego = name.substring(0, 1).toUpperCase() + name.substring(1);
break;
}
}
@ -278,7 +291,8 @@ public class ResidentFragment extends Fragment {
String nombreJuego = "";
for (Game g : games) {
if (g.getId().equals(entry.getKey())) {
nombreJuego = g.getName();
String name = g.getName();
nombreJuego = name.substring(0, 1).toUpperCase() + name.substring(1);
break;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -5,6 +5,7 @@
android:layout_height="match_parent"
android:background="#CCCCCC">
<!-- Tarjeta de usuario -->
<include
android:id="@+id/account_card_view"
layout="@layout/item_person_banner"
@ -14,6 +15,7 @@
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<!-- Sección de destacados -->
<TextView
android:id="@+id/label_highlights"
android:layout_width="0dp"
@ -44,6 +46,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<!-- Preferencias -->
<TextView
android:id="@+id/label_preferences"
android:layout_width="0dp"
@ -58,6 +61,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<!-- Botón idioma -->
<Button
android:id="@+id/btn_idioma"
android:layout_width="0dp"
@ -73,6 +77,60 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<!-- Botón para desplegar cambio de contraseña -->
<Button
android:id="@+id/btn_toggle_password_change"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:fontFamily="@font/assistant_bold"
android:paddingStart="20dp"
android:text="Cambiar contraseña"
android:textAllCaps="false"
android:textColor="#324F5E"
app:layout_constraintTop_toBottomOf="@id/btn_idioma"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<!-- Layout oculto inicialmente para cambio de contraseña -->
<LinearLayout
android:id="@+id/password_change_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="12dp"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/btn_toggle_password_change"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<EditText
android:id="@+id/et_current_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Contraseña actual"
android:inputType="textPassword" />
<EditText
android:id="@+id/et_new_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Nueva contraseña"
android:inputType="textPassword"
android:layout_marginTop="8dp" />
<Button
android:id="@+id/btn_change_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:backgroundTint="#324F5E"
android:text="Cambiar contraseña"
android:textAllCaps="false"
android:textColor="@android:color/white" />
</LinearLayout>
<!-- Botón cerrar sesión -->
<Button
android:id="@+id/btn_cerrar_sesion"
android:layout_width="0dp"
@ -83,7 +141,7 @@
android:text="@string/logout_title"
android:textAllCaps="false"
android:textColor="#324F5E"
app:layout_constraintTop_toBottomOf="@id/btn_idioma"
app:layout_constraintTop_toBottomOf="@id/password_change_container"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />

View File

@ -39,7 +39,7 @@
android:textSize="20sp" />
<ImageButton
android:id="@+id/filter_activities_list_button"
android:id="@+id/filter_activities_list_image_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"

View File

@ -40,7 +40,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:backgroundTint="#00AF4848"
android:text="@string/select_date_text"
android:text="@string/select_datetime_text"
android:textAlignment="viewStart"
android:textColor="#324F5E"
android:textColorLink="#6CADFF"

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/adminScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<LinearLayout
android:id="@+id/adminContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Repetiremos esta estructura para cada acción -->
<include layout="@layout/item_admin_action" android:id="@+id/action_add_residencia" />
<include layout="@layout/item_admin_action" android:id="@+id/action_delete_residencia" />
<include layout="@layout/item_admin_action" android:id="@+id/action_add_user" />
<include layout="@layout/item_admin_action" android:id="@+id/action_delete_user" />
<include layout="@layout/item_admin_action" android:id="@+id/action_add_resident" />
<include layout="@layout/item_admin_action" android:id="@+id/action_delete_resident" />
<include layout="@layout/item_admin_action" android:id="@+id/action_add_game" />
<include layout="@layout/item_admin_action" android:id="@+id/action_delete_game" />
<!-- Botón de cerrar sesión -->
<Button
android:id="@+id/btn_logout_admin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Cerrar sesión"
android:backgroundTint="@android:color/holo_red_light"
android:textColor="@android:color/white"
android:textAllCaps="false"
android:textSize="16sp"
android:padding="12dp" />
</LinearLayout>
</ScrollView>

View File

@ -40,7 +40,7 @@
<!-- Avatar + texto -->
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/circularImageView"
android:id="@+id/game_image"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginStart="20dp"
@ -61,9 +61,9 @@
android:fontFamily="@font/assistant_bold"
android:textColor="@android:color/white"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="@+id/circularImageView"
app:layout_constraintStart_toEndOf="@+id/circularImageView"
app:layout_constraintTop_toTopOf="@+id/circularImageView" />
app:layout_constraintBottom_toBottomOf="@+id/game_image"
app:layout_constraintStart_toEndOf="@+id/game_image"
app:layout_constraintTop_toTopOf="@+id/game_image" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -38,13 +38,13 @@
<!-- Avatar + texto -->
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/circularImageView"
android:id="@+id/resident_image_gameDetail"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginStart="20dp"
android:layout_marginTop="16dp"
android:scaleType="centerCrop"
android:src="@drawable/woman_avatar"
android:src="@drawable/default_resident_image"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/back_button"
app:shapeAppearanceOverlay="@style/CircularShapeAppearance" />
@ -56,10 +56,10 @@
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="@id/circularImageView"
app:layout_constraintBottom_toBottomOf="@id/resident_image_gameDetail"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/circularImageView"
app:layout_constraintTop_toTopOf="@id/circularImageView">
app:layout_constraintStart_toEndOf="@id/resident_image_gameDetail"
app:layout_constraintTop_toTopOf="@id/resident_image_gameDetail">
<TextView
android:id="@+id/banner_name_resident"
@ -127,6 +127,30 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/label_duration" />
<TextView
android:id="@+id/label_level"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/assistant_semibold"
android:text="@string/level_text"
android:textColor="#2C3E50"
android:textSize="16sp"
app:layout_constraintEnd_toStartOf="@id/tv_level"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/label_duration" />
<TextView
android:id="@+id/tv_level"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/assistant_semibold"
android:textColor="#2C3E50"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/label_level" />
<!-- Fallos -->
<TextView
android:id="@+id/label_fails"
@ -139,7 +163,7 @@
android:textSize="16sp"
app:layout_constraintEnd_toStartOf="@id/tv_fails"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/label_duration" />
app:layout_constraintTop_toBottomOf="@id/label_level" />
<TextView
android:id="@+id/tv_fails"

View File

@ -138,7 +138,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:paddingStart="16dp">
android:paddingStart="5dp">
<TextView
android:id="@+id/pie_game_1_name"
@ -146,8 +146,10 @@
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:background="#FFFF00"
android:padding="5dp"
android:text="Sombras - 45%"
android:textColor="#000000" />
android:textColor="#324F5E"
android:textSize="16sp" />
<TextView
android:id="@+id/pie_game_2_name"
@ -155,8 +157,10 @@
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:background="#FF6666"
android:padding="5dp"
android:text="Reacción auditiva - 30%"
android:textColor="#000000" />
android:textColor="#324F5E"
android:textSize="16sp" />
<TextView
android:id="@+id/pie_game_3_name"
@ -164,8 +168,10 @@
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:background="#FF00FF"
android:padding="5dp"
android:text="Memoria - 15%"
android:textColor="#000000" />
android:textColor="#324F5E"
android:textSize="16sp" />
<TextView
android:id="@+id/pie_game_4_name"
@ -173,16 +179,20 @@
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:background="#00FF00"
android:padding="5dp"
android:text="Laberinto - 10%"
android:textColor="#000000" />
android:textColor="#324F5E"
android:textSize="16sp" />
<TextView
android:id="@+id/pie_game_5_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00FF00"
android:padding="5dp"
android:text="Laberinto - 10%"
android:textColor="#000000"/>
android:textColor="#324F5E"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>

View File

@ -33,6 +33,7 @@
android:fontFamily="@font/assistant_bold"
android:text="Iglesia de Benissa"
android:textColor="#F4F4F4"
android:textSize="20sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textview_salida" />

View File

@ -0,0 +1,194 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Acción"
android:textStyle="bold"
android:textSize="18sp"
android:padding="12dp"
android:background="#E0E0E0"
android:clickable="true"
android:focusable="true" />
<LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone"
android:padding="8dp"
android:background="#F5F5F5">
<Spinner
android:id="@+id/spinner_residencias"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Spinner
android:id="@+id/spinner_extra"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- Contenedor datos residencia -->
<LinearLayout
android:id="@+id/layout_residence_inputs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/residence_name_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Nombre" />
<EditText
android:id="@+id/residence_email_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Correo electrónico" />
</LinearLayout>
<LinearLayout
android:id="@+id/layout_user_inputs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/et_add_user_nombre"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Nombre" />
<EditText
android:id="@+id/et_add_user_apellido"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Apellidos"
android:layout_marginTop="12dp" />
<EditText
android:id="@+id/et_add_user_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Correo electronico" />
<EditText
android:id="@+id/et_add_user_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Contraseña"
android:layout_marginTop="12dp" />
<EditText
android:id="@+id/et_add_user_verfication_code"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Codigo verificacion"
android:layout_marginTop="12dp" />
</LinearLayout>
<!-- Contenedor datos residente -->
<LinearLayout
android:id="@+id/layout_resident_inputs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/et_add_resident_nombre"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/name_text"
android:inputType="textPersonName" />
<EditText
android:id="@+id/et_add_resident_apellido"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/surnames_text"
android:inputType="textPersonName"
android:layout_marginTop="12dp" />
<EditText
android:id="@+id/et_add_resident_fecha_nacimiento"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/date_of_birth_text"
android:inputType="date"
android:layout_marginTop="12dp" />
<EditText
android:id="@+id/et_add_resident_documento_identidad"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/identification_document_text"
android:inputType="text"
android:layout_marginTop="12dp" />
<EditText
android:id="@+id/et_add_resident_year"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/year_of_document_validity_text"
android:inputType="number"
android:layout_marginTop="12dp" />
<EditText
android:id="@+id/et_add_resident_month"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/month_of_document_validity_text"
android:inputType="number"
android:layout_marginTop="12dp" />
<EditText
android:id="@+id/et_add_resident_familiar_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/email_family_member_text"
android:inputType="textPersonName"
android:layout_marginTop="12dp" />
<EditText
android:id="@+id/et_add_resident_familiar_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/email_family_member_text"
android:inputType="textPersonName"
android:layout_marginTop="12dp" />
</LinearLayout>
<!-- Contenedor datos juego -->
<LinearLayout
android:id="@+id/layout_game_inputs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/et_add_game_nombre"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/name_text" />
</LinearLayout>
<Button
android:id="@+id/btn_execute"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Ejecutar" />
</LinearLayout>
</LinearLayout>

View File

@ -22,7 +22,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:shapeAppearanceOverlay="@style/CircularShapeAppearance"
app:srcCompat="@drawable/woman_avatar" />
app:srcCompat="@drawable/default_resident_image" />
<TextView
android:id="@+id/name_text_latestGameItem"

View File

@ -20,7 +20,7 @@
android:layout_height="41dp"
android:scaleType="centerCrop"
app:shapeAppearanceOverlay="@style/CircularShapeAppearance"
app:srcCompat="@drawable/woman_avatar" />
app:srcCompat="@drawable/default_resident_image" />
<LinearLayout
android:layout_width="0dp"

View File

@ -3,6 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:orientation="vertical"
android:padding="10dp">
@ -12,34 +13,22 @@
android:orientation="horizontal">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/circularImageView3"
android:id="@+id/user_image_observation"
android:layout_width="52dp"
android:layout_height="51dp"
android:scaleType="centerCrop"
app:shapeAppearanceOverlay="@style/CircularShapeAppearance"
app:srcCompat="@drawable/woman_avatar" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical"
android:layout_marginStart="10dp">
<TextView
android:id="@+id/observation_user_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:gravity="center_vertical"
android:text="Person Name"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/observation_person_role"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Person Role" />
</LinearLayout>
</LinearLayout>
<!-- Texto de la observación existente -->

View File

@ -62,7 +62,7 @@
android:layout_centerInParent="true"
android:layout_marginTop="-55dp"
android:scaleType="centerCrop"
android:src="@drawable/woman_avatar"
android:src="@drawable/default_resident_image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"

View File

@ -2,6 +2,7 @@
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="12dp"
@ -39,6 +40,15 @@
app:layout_constraintStart_toEndOf="@id/profile_image"
app:layout_constraintTop_toTopOf="@id/profile_image" />
<ImageButton
android:id="@+id/more_options_item_resident_activity"
android:layout_width="24dp"
android:layout_height="24dp"
android:background="@null"
app:srcCompat="@drawable/elipsis"
card_view:layout_constraintEnd_toEndOf="parent"
card_view:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/participant_asistencia_button"
android:layout_width="48dp"
@ -99,7 +109,6 @@
android:layout_marginStart="8dp"
android:layout_marginTop="12dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -87,5 +87,10 @@
<string name="filter_activities_title">Filtrar actividades</string>
<string name="activity_title">Actividad</string>
<string name="account_detail">Cuenta</string>
<string name="level_text">Nivel</string>
<string name="level1_text">FACIL</string>
<string name="level2_text">MEDIO</string>
<string name="level3_text">DIFICIL</string>
<string name="select_datetime_text">Seleccionar fecha y hora</string>
</resources>

BIN
juegos.zip Normal file

Binary file not shown.

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -192,4 +192,4 @@ Game={
"hide_selection": false,
"select_mode": 0
}
selected_nodes=Array[NodePath]([NodePath("/root/@EditorNode@21272/@Panel@14/@VBoxContainer@15/DockHSplitLeftL/DockHSplitLeftR/DockHSplitMain/@VBoxContainer@26/DockVSplitCenter/@VSplitContainer@54/@VBoxContainer@55/@EditorMainScreen@102/MainScreen/@CanvasItemEditor@11482/@VSplitContainer@11134/@HSplitContainer@11136/@HSplitContainer@11138/@Control@11139/@SubViewportContainer@11140/@SubViewport@11141/Node2D/VBoxContainer/MenuButton")])
selected_nodes=Array[NodePath]([])

View File

@ -1,5 +1,5 @@
[folding]
node_unfolds=[NodePath("."), PackedStringArray("Layout"), NodePath("VBoxContainer"), PackedStringArray("Layout"), NodePath("VBoxContainer/MenuButton"), PackedStringArray("Layout", "Theme"), NodePath("VBoxContainer/MarginContainer"), PackedStringArray("Layout", "Theme Overrides"), NodePath("VBoxContainer/MarginContainer/HBoxContainer"), PackedStringArray("Layout", "Theme Overrides"), NodePath("VBoxContainer/MarginContainer/HBoxContainer/VBoxContainer"), PackedStringArray("Layout"), NodePath("VBoxContainer/MarginContainer/HBoxContainer/VBoxContainer/TilesLabel"), PackedStringArray("Layout", "Theme Overrides"), NodePath("VBoxContainer/MarginContainer/HBoxContainer/VBoxContainer/TilesContainer"), PackedStringArray("Layout"), NodePath("VBoxContainer/MarginContainer/HBoxContainer/VBoxContainer2"), PackedStringArray("Layout"), NodePath("VBoxContainer/MarginContainer/HBoxContainer/VBoxContainer2/BoardLabel"), PackedStringArray("Layout", "Theme Overrides"), NodePath("VBoxContainer/MarginContainer/HBoxContainer/VBoxContainer2/GameBoardContainer"), PackedStringArray("Layout"), NodePath("VBoxContainer/MarginContainer/HBoxContainer/VBoxContainer2/GameBoardContainer/GameBoard"), PackedStringArray("Layout", "Theme Overrides"), NodePath("WinPopup"), PackedStringArray("Flags"), NodePath("WinPopup/VBoxContainer"), PackedStringArray("Layout"), NodePath("WinPopup/VBoxContainer/victory_label"), PackedStringArray("Layout", "Theme Overrides", "Theme Overrides/colors"), NodePath("WinPopup/VBoxContainer/duration_label"), PackedStringArray("Layout", "Theme Overrides", "Theme Overrides/colors"), NodePath("WinPopup/VBoxContainer/fail_count_label"), PackedStringArray("Layout", "Theme Overrides", "Theme Overrides/colors"), NodePath("WinPopup/VBoxContainer/exit_endgame_button"), PackedStringArray("Layout", "Theme Overrides"), NodePath("ExitButtonWindow"), PackedStringArray("Flags"), NodePath("ExitButtonWindow/VBoxContainer"), PackedStringArray("Layout", "Theme Overrides", "Theme Overrides/constants"), NodePath("ExitButtonWindow/VBoxContainer/Label"), PackedStringArray("Layout", "Theme Overrides", "Theme Overrides/font_sizes", "Theme Overrides/colors"), NodePath("ExitButtonWindow/VBoxContainer/HBoxContainer"), PackedStringArray("Layout"), NodePath("ExitButtonWindow/VBoxContainer/HBoxContainer/ConfirmExitButton"), PackedStringArray("Layout", "Theme Overrides"), NodePath("ExitButtonWindow/VBoxContainer/HBoxContainer/CancelExitButton"), PackedStringArray("Layout", "Theme Overrides"), NodePath("Blocker"), PackedStringArray("Visibility", "Layout", "Mouse"), NodePath("TextBallon/Label"), PackedStringArray("Theme Overrides")]
node_unfolds=[NodePath("."), PackedStringArray("Layout"), NodePath("VBoxContainer"), PackedStringArray("Layout"), NodePath("VBoxContainer/MenuButton"), PackedStringArray("Layout", "Theme"), NodePath("VBoxContainer/MarginContainer"), PackedStringArray("Layout", "Theme Overrides"), NodePath("VBoxContainer/MarginContainer/HBoxContainer"), PackedStringArray("Layout", "Theme Overrides"), NodePath("VBoxContainer/MarginContainer/HBoxContainer/VBoxContainer"), PackedStringArray("Layout"), NodePath("VBoxContainer/MarginContainer/HBoxContainer/VBoxContainer/TilesLabel"), PackedStringArray("Layout", "Theme Overrides"), NodePath("VBoxContainer/MarginContainer/HBoxContainer/VBoxContainer/TilesContainer"), PackedStringArray("Layout"), NodePath("VBoxContainer/MarginContainer/HBoxContainer/VBoxContainer2"), PackedStringArray("Layout"), NodePath("VBoxContainer/MarginContainer/HBoxContainer/VBoxContainer2/BoardLabel"), PackedStringArray("Layout", "Theme Overrides"), NodePath("VBoxContainer/MarginContainer/HBoxContainer/VBoxContainer2/GameBoardContainer"), PackedStringArray("Layout"), NodePath("VBoxContainer/MarginContainer/HBoxContainer/VBoxContainer2/GameBoardContainer/GameBoard"), PackedStringArray("Layout", "Theme Overrides"), NodePath("WinPopup"), PackedStringArray("Flags"), NodePath("WinPopup/VBoxContainer"), PackedStringArray("Layout"), NodePath("WinPopup/VBoxContainer/victory_label"), PackedStringArray("Layout", "Theme Overrides", "Theme Overrides/colors"), NodePath("WinPopup/VBoxContainer/fail_count_label"), PackedStringArray("Layout", "Theme Overrides", "Theme Overrides/colors"), NodePath("WinPopup/VBoxContainer/exit_endgame_button"), PackedStringArray("Layout", "Theme Overrides"), NodePath("ExitButtonWindow"), PackedStringArray("Flags"), NodePath("ExitButtonWindow/VBoxContainer"), PackedStringArray("Layout", "Theme Overrides", "Theme Overrides/constants"), NodePath("ExitButtonWindow/VBoxContainer/Label"), PackedStringArray("Layout", "Theme Overrides", "Theme Overrides/font_sizes", "Theme Overrides/colors"), NodePath("ExitButtonWindow/VBoxContainer/HBoxContainer"), PackedStringArray("Layout"), NodePath("ExitButtonWindow/VBoxContainer/HBoxContainer/ConfirmExitButton"), PackedStringArray("Layout", "Theme Overrides"), NodePath("ExitButtonWindow/VBoxContainer/HBoxContainer/CancelExitButton"), PackedStringArray("Layout", "Theme Overrides"), NodePath("Blocker"), PackedStringArray("Visibility", "Layout", "Mouse"), NodePath("TextBallon/Label"), PackedStringArray("Theme Overrides")]
resource_unfolds=["res://scenes/emparejar_las_sombras/GameEmparejarLasSombras.tscn::StyleBoxEmpty_cpr0p", PackedStringArray("Resource"), "res://scenes/emparejar_las_sombras/GameEmparejarLasSombras.tscn::StyleBoxFlat_cpr0p", PackedStringArray("Resource"), "res://scenes/emparejar_las_sombras/GameEmparejarLasSombras.tscn::StyleBoxFlat_78awf", PackedStringArray("Resource"), "res://scenes/emparejar_las_sombras/GameEmparejarLasSombras.tscn::StyleBoxFlat_s0nni", PackedStringArray("Resource")]
nodes_folded=[NodePath("WinPopup"), NodePath("ExitButtonWindow"), NodePath("TextBallon")]

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -8,7 +8,7 @@ Anim={
"grid_snap_active": false,
"grid_step": Vector2(8, 8),
"grid_visibility": 1,
"ofs": Vector2(-834.841, -190.963),
"ofs": Vector2(-770.151, -78.3636),
"primary_grid_step": Vector2i(8, 8),
"show_group_gizmos": true,
"show_guides": true,
@ -192,4 +192,4 @@ Game={
"hide_selection": false,
"select_mode": 0
}
selected_nodes=Array[NodePath]([])
selected_nodes=Array[NodePath]([NodePath("/root/@EditorNode@21272/@Panel@14/@VBoxContainer@15/DockHSplitLeftL/DockHSplitLeftR/DockHSplitMain/@VBoxContainer@26/DockVSplitCenter/@VSplitContainer@54/@VBoxContainer@55/@EditorMainScreen@102/MainScreen/@CanvasItemEditor@11482/@VSplitContainer@11134/@HSplitContainer@11136/@HSplitContainer@11138/@Control@11139/@SubViewportContainer@11140/@SubViewport@11141/Home/MarginContainer/VBoxContainer")])

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -1,7 +1,8 @@
Panel
MarginContainer
TextureRect
AudioStreamPlayer2D
Label
MarginContainer
CenterContainer
Button
VBoxContainer

View File

@ -5,18 +5,18 @@ dock_4_selected_tab_idx=0
dock_5_selected_tab_idx=0
dock_floating={}
dock_filesystem_h_split_offset=240
dock_filesystem_v_split_offset=0
dock_filesystem_v_split_offset=220
dock_filesystem_display_mode=0
dock_filesystem_file_sort=0
dock_filesystem_file_list_display_mode=1
dock_filesystem_selected_paths=PackedStringArray()
dock_filesystem_uncollapsed_paths=PackedStringArray("Favorites", "res://", "res://scenes/seguir_la_linea/", "res://scenes/gimnasio/", "res://scenes/flecha_y_reacciona/", "res://scenes/emparejar_las_sombras/", "res://scenes/bingo_auditivo/", "res://images/")
dock_filesystem_selected_paths=PackedStringArray("res://scripts/scene_manager.gd")
dock_filesystem_uncollapsed_paths=PackedStringArray("Favorites", "res://", "res://scripts/", "res://scenes/")
dock_node_current_tab=0
dock_history_include_scene=true
dock_history_include_global=true
dock_bottom=[]
dock_closed=[]
dock_split_2=-92
dock_split_2=-142
dock_split_3=0
dock_hsplit_1=0
dock_hsplit_2=270
@ -43,12 +43,12 @@ position=Vector2i(0, 23)
[ScriptEditor]
open_scripts=["res://scripts/emparejar_las_sombras/animal_tile.gd", "res://scripts/app_constants.gd", "res://scripts/bingo_auditivo/configuration_bingo.gd", "res://scripts/emparejar_las_sombras/configuration_emparejar_las_sombras.gd", "res://scripts/flecha_y_reacciona/configuration_f_y_r.gd", "res://scripts/gimnasio/configuration_gym.gd", "res://scripts/seguir_la_linea/configuration_seguir_la_linea.gd", "res://scripts/game_data.gd", "res://scripts/flecha_y_reacciona/game_flecha_y_reacciona.gd", "res://scripts/gimnasio/game_gym.gd", "res://scripts/home.gd"]
selected_script="res://scripts/app_constants.gd"
open_scripts=["res://scripts/emparejar_las_sombras/animal_tile.gd", "res://scripts/app_constants.gd", "res://scripts/bingo_auditivo/configuration_bingo.gd", "res://scripts/emparejar_las_sombras/configuration_emparejar_las_sombras.gd", "res://scripts/flecha_y_reacciona/configuration_f_y_r.gd", "res://scripts/gimnasio/configuration_gym.gd", "res://scripts/seguir_la_linea/configuration_seguir_la_linea.gd", "res://scripts/game_data.gd", "res://scripts/emparejar_las_sombras/game_emparejar_las_sombras.gd", "res://scripts/flecha_y_reacciona/game_flecha_y_reacciona.gd", "res://scripts/gimnasio/game_gym.gd", "res://scripts/home.gd", "res://scripts/scene_manager.gd"]
selected_script="res://scripts/game_data.gd"
open_help=[]
script_split_offset=250
list_split_offset=0
zoom_factor=1.14286
zoom_factor=1.0
[GameView]

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -1,8 +1,7 @@
fc8a56933c4b1c8d796fdb8f7a9f9475
::res://::1748128390
export_presets.cfg::TextFile/TextFile::-1::1748128390::0::1::::<><><>0<>0<><>::
::res://::1748545681
export_presets.cfg::TextFile::-1::1748528113::0::1::::<><><>0<>0<><>::
icon.svg::CompressedTexture2D/CompressedTexture2D::7703363691602546975::1747402263::1747402278::1::::<><><>0<>0<>dc50f06f4ec4156b8404fc76e68035b2<>res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex::
menu.tres::Theme/Theme::8317934371248321320::1747852682::0::1::::<><><>0<>0<><>::
::res://assets/::1747852892
back_button.png::CompressedTexture2D/CompressedTexture2D::2132119402147635853::1747694589::1747694590::1::::<><><>0<>0<>306f7421656b646a3d66454298c8e40f<>res://.godot/imported/back_button.png-ba49f75b53a9c1f509214b23d27cc2b4.ctex::
window3.png::CompressedTexture2D/CompressedTexture2D::6631485050052427251::1747675596::1747675598::1::::<><><>0<>0<>19d84c5119cf1d34038a6db3f27eaa30<>res://.godot/imported/window3.png-b1234ac1e7263dd18bb1843f6abab1e4.ctex::
@ -26,10 +25,10 @@ oveja.mp3::AudioStreamMP3/AudioStreamMP3::6892221899961415453::1745431841::17475
perro.mp3::AudioStreamMP3/AudioStreamMP3::2363096142831056952::1745431668::1747575855::1::::<><><>0<>0<>56043aba6662a9ec6db96cfe27541cf4<>res://.godot/imported/perro.mp3-245f05c17c1670247e9d65e55d81ddd0.mp3str::
vaca.mp3::AudioStreamMP3/AudioStreamMP3::2596745121890943594::1745431616::1747575855::1::::<><><>0<>0<>0135307959b6352ae4f4c702bed8362c<>res://.godot/imported/vaca.mp3-d751249d5f15334a95ae6c005701fcb3.mp3str::
wolf.mp3::AudioStreamMP3/AudioStreamMP3::4476753813126878356::1745431572::1747575855::1::::<><><>0<>0<>659cb7dd6fb08b576a36cf838b80ed79<>res://.godot/imported/wolf.mp3-3c99ed1860a7a0005da49c65f92ca4c5.mp3str::
::res://images/::1748128650
::res://images/::1748528041
charecter.png::CompressedTexture2D/CompressedTexture2D::1398867791648070462::1747746845::1747746846::1::::<><><>0<>0<>68d609f4cf72b7cee974b0d118c90955<>res://.godot/imported/charecter.png-58be5b09fc337b559f9bb40d47841b54.ctex::
cuadro de texto.png::CompressedTexture2D/CompressedTexture2D::7929815230707051517::1747752203::1747752203::1::::<><><>0<>0<>209748225dd912f7cf3dd54c7ea35877<>res://.godot/imported/cuadro de texto.png-069ecfbae193344546bd74f085248bd4.ctex::
game_logo.png::CompressedTexture2D::4914694277155003891::1748128650::1748128651::1::::<><><>0<>0<>3c4dfc4b74143bebfc2150de503c2955<>res://.godot/imported/game_logo.png-51208890158e5ed3dd849f86a05616d7.ctex::
logo_resi_games.png::CompressedTexture2D/CompressedTexture2D::2507302559016447935::1748528039::1748528041::1::::<><><>0<>0<>8c71df20357cfd04592eac3c77cbd36e<>res://.godot/imported/logo_resi_games.png-9a5c3031bd75f14b4db9b6a43951faed.ctex::
menu_logo.png::CompressedTexture2D/CompressedTexture2D::5689433748730304837::1745260946::1747403586::1::::<><><>0<>0<>aa8e65da18c85d772f423418a1d50520<>res://.godot/imported/menu_logo.png-326be22817043ae765a9aaa1fb96c9c5.ctex::
play-button.png::CompressedTexture2D/CompressedTexture2D::6478104816802874001::1744907721::1747419449::1::::<><><>0<>0<>1fc1f7403ff3525f1bfeec642567e90c<>res://.godot/imported/play-button.png-feb8b3a20dceb7f0a6bd641376526d2d.ctex::
::res://images/bingo_auditivo/::1747575856
@ -89,46 +88,50 @@ vaca_color.png::CompressedTexture2D/CompressedTexture2D::1639453517109408540::17
vaca_sombra.png::CompressedTexture2D/CompressedTexture2D::4137840386567035395::1744226338::1747403007::1::::<><><>0<>0<>7913a329232bef854d87a6ddec8c81e3<>res://.godot/imported/vaca_sombra.png-769fea26da6c81f0eea64130655d8a07.ctex::
zorro_color.png::CompressedTexture2D/CompressedTexture2D::1666546973926131984::1745322164::1747403007::1::::<><><>0<>0<>8856013afa6584f215b35bcfba373916<>res://.godot/imported/zorro_color.png-5a852bc51419751d7d287253d6ea7c3b.ctex::
zorro_sombra.png::CompressedTexture2D/CompressedTexture2D::6252548807644359177::1744226356::1747403007::1::::<><><>0<>0<>9c2cf80619a760076607a150050b8ce8<>res://.godot/imported/zorro_sombra.png-f45f9573d10a222e8a5fc95e53c57fa0.ctex::
::res://images/logos/::1748128298
logo_bingo_auditivo.jpg::CompressedTexture2D/CompressedTexture2D::2684211223156084402::1747700426::1747700426::1::::<><><>0<>0<>539a5dff78bee0e4cf4a4103cf9afa8b<>res://.godot/imported/logo_bingo_auditivo.jpg-03bdf8ad732b66a85cf2c9b04f150e8f.ctex::
logo_emparejar_las_sombras.jpg::CompressedTexture2D/CompressedTexture2D::1304789213788847404::1747700426::1747700426::1::::<><><>0<>0<>af932ef37111d1fb1189b2e9efdfcf9c<>res://.godot/imported/logo_emparejar_las_sombras.jpg-76d99c8ef0c28ec4cd7c7c5c902c6c62.ctex::
logo_flecha_y_reacciona.jpg::CompressedTexture2D/CompressedTexture2D::1741424296729248422::1747700426::1747700426::1::::<><><>0<>0<>e5132acc60bb8942ddb5d53f390494bd<>res://.godot/imported/logo_flecha_y_reacciona.jpg-3b637c92f0fd164adec036d673be209a.ctex::
logo_gimnasio.jpg::CompressedTexture2D/CompressedTexture2D::7269953945927652778::1747700426::1747700426::1::::<><><>0<>0<>b865210b4a91a83995039388a12db30b<>res://.godot/imported/logo_gimnasio.jpg-32d1be7a1c501ae50b3f9b8e51f9b26f.ctex::
logo_seguir_la_linea.jpg::CompressedTexture2D/CompressedTexture2D::3712652532896905776::1747700426::1747700426::1::::<><><>0<>0<>e37728575d6c225b9ce3598d1e909817<>res://.godot/imported/logo_seguir_la_linea.jpg-b143778eeffde4affe6ad2bc4b8d2213.ctex::
::res://scenes/::1748128312
Home.tscn::PackedScene::436761610444962465::1748128312::0::1::::<><><>0<>0<><>::uid://cmbsedaebmtix::::res://scripts/home.gd<>uid://c1qlub6rv4e3t::::res://assets/window3.png<>uid://354a75edxicg::::res://assets/sign in window/window.png<>uid://dpxdt6wxr63gn::::res://scripts/flecha_y_reacciona/configuration_f_y_r.gd<>uid://e41ws6j00o5::::res://scripts/bingo_auditivo/configuration_bingo.gd<>uid://dqrjftnev4ftw::::res://menu.tres<>uid://dim5arrthe0t4::::res://scripts/gimnasio/configuration_gym.gd<>uid://rcrqfnlhe4bb::::res://scripts/seguir_la_linea/configuration_seguir_la_linea.gd<>uid://ctge47k34s7yi::::res://scripts/emparejar_las_sombras/configuration_emparejar_las_sombras.gd
::res://scenes/bingo_auditivo/::1747852435
GameBingo.tscn::PackedScene/PackedScene::8967965762231623292::1747852435::0::1::::<><><>0<>0<><>::uid://dhqnf0xm2mwwm::::res://scripts/bingo_auditivo/game_bingo.gd<>uid://c4g0gbifdm5fe::::res://images/bingo_auditivo/background_bingo.png<>uid://cncae337c0ws8::::res://images/menu_logo.png<>uid://354a75edxicg::::res://assets/sign in window/window.png<>uid://dqrjftnev4ftw::::res://menu.tres<>uid://t6vfbi66g6fy::::res://images/charecter.png<>uid://dk8i5somirvt2::::res://images/cuadro de texto.png<>uid://cpeiuq7umndvk::::res://audios/instrucciones_bingo_auditivo.mp3
::res://scenes/emparejar_las_sombras/::1747852370
GameEmparejarLasSombras.tscn::PackedScene/PackedScene::7300647384769136354::1747852370::0::1::::<><><>0<>0<><>::uid://vsc3anuvlso6::::res://scripts/emparejar_las_sombras/game_emparejar_las_sombras.gd<>uid://c8kq84p5btav8::::res://audios/instrucciones_emparejar_las_sombras.mp3<>uid://cncae337c0ws8::::res://images/menu_logo.png<>uid://dqrjftnev4ftw::::res://menu.tres<>uid://t6vfbi66g6fy::::res://images/charecter.png<>uid://354a75edxicg::::res://assets/sign in window/window.png<>uid://dk8i5somirvt2::::res://images/cuadro de texto.png
::res://scenes/flecha_y_reacciona/::1747852368
GameFlechaYReacciona.tscn::PackedScene/PackedScene::2239309432930539111::1747852368::0::1::::<><><>0<>0<><>::uid://dlc5nmf2nugla::::res://scripts/flecha_y_reacciona/game_flecha_y_reacciona.gd<>uid://msfckci5lndd::::res://audios/instrucctions_flecha_y_reacciona.mp3<>uid://dqrjftnev4ftw::::res://menu.tres<>uid://cncae337c0ws8::::res://images/menu_logo.png<>uid://354a75edxicg::::res://assets/sign in window/window.png<>uid://t6vfbi66g6fy::::res://images/charecter.png<>uid://dk8i5somirvt2::::res://images/cuadro de texto.png
::res://scenes/gimnasio/::1747852367
GameGym.tscn::PackedScene/PackedScene::8761792870795266585::1747852366::0::1::::<><><>0<>0<><>::uid://c03j7kms107t6::::res://scripts/gimnasio/game_gym.gd<>uid://dqrjftnev4ftw::::res://menu.tres<>uid://cncae337c0ws8::::res://images/menu_logo.png<>uid://cykbo7qv3fy6l::::res://images/play-button.png<>uid://bf16kwp1ccwh4::::res://audios/instrucciones_gym.mp3<>uid://354a75edxicg::::res://assets/sign in window/window.png<>uid://t6vfbi66g6fy::::res://images/charecter.png<>uid://dk8i5somirvt2::::res://images/cuadro de texto.png
::res://scenes/seguir_la_linea/::1747852365
GameSeguirLaLinea.tscn::PackedScene/PackedScene::2653001513631914606::1747852365::0::1::::<><><>0<>0<><>::uid://cf24sqa5714px::::res://scripts/seguir_la_linea/game_seguir_la_linea.gd<>uid://cncae337c0ws8::::res://images/menu_logo.png<>uid://dqrjftnev4ftw::::res://menu.tres<>uid://cykbo7qv3fy6l::::res://images/play-button.png<>uid://t6vfbi66g6fy::::res://images/charecter.png<>uid://cwudtop42vbi8::::res://audios/instrucciones_seguir_la_linea.mp3<>uid://354a75edxicg::::res://assets/sign in window/window.png<>uid://dk8i5somirvt2::::res://images/cuadro de texto.png
::res://scripts/::1748117033
app_constants.gd::GDScript/GDScript::3537533678312647870::1748117032::0::1::::<>Node<><>0<>0<><>::
::res://images/logos/::1748286697
logo_bingo_auditivo.png::CompressedTexture2D/CompressedTexture2D::7364224477725827147::1748286696::1748286697::1::::<><><>0<>0<>9a3d568b0674c460180be7701ccb40d4<>res://.godot/imported/logo_bingo_auditivo.png-5e30e1bea621c3352de6b4ff2fe4b1b4.ctex::
logo_emparejar_las_sombras.png::CompressedTexture2D/CompressedTexture2D::5189884707796834854::1748286696::1748286697::1::::<><><>0<>0<>ef208b5316b61926682bd5d79cc84adb<>res://.godot/imported/logo_emparejar_las_sombras.png-a39f58aa0840328d00da516923b1decc.ctex::
logo_flecha_y_reacciona.png::CompressedTexture2D/CompressedTexture2D::4632161588619433328::1748286696::1748286697::1::::<><><>0<>0<>21783d7967b78ffe1e5c06a3c6e6b33a<>res://.godot/imported/logo_flecha_y_reacciona.png-e2131129eec278796e5d6370f754af16.ctex::
logo_gimnasio.png::CompressedTexture2D/CompressedTexture2D::3876597494743846730::1748286696::1748286697::1::::<><><>0<>0<>41092951a1b46dcb360a7c4b53263e72<>res://.godot/imported/logo_gimnasio.png-6666c955157a95828a9eb450917ec21c.ctex::
logo_seguir_la_linea.png::CompressedTexture2D/CompressedTexture2D::4597926115479110607::1748286696::1748286697::1::::<><><>0<>0<>71cccd3b16dd5142ebae03123fec2e29<>res://.godot/imported/logo_seguir_la_linea.png-ddb8660943bac58c1e37c99d2606c784.ctex::
::res://scenes/::1748529123
Home.tscn::PackedScene::436761610444962465::1748529123::0::1::::<><><>0<>0<><>::uid://cmbsedaebmtix::::res://scripts/home.gd<>uid://b1uof5qtp3k85::::res://styles/HollowSpace.ttf<>uid://c1qlub6rv4e3t::::res://assets/window3.png<>uid://cf7av4f8nqhry::::res://images/logos/logo_emparejar_las_sombras.png<>uid://354a75edxicg::::res://assets/sign in window/window.png<>uid://b6rjf3c85rxdf::::res://images/logos/logo_seguir_la_linea.png<>uid://dpxdt6wxr63gn::::res://scripts/flecha_y_reacciona/configuration_f_y_r.gd<>uid://e41ws6j00o5::::res://scripts/bingo_auditivo/configuration_bingo.gd<>uid://dqrjftnev4ftw::::res://styles/menu.tres<>uid://bvh382qlwuvtq::::res://images/logos/logo_gimnasio.png<>uid://dc6jx3u2rnpqx::::res://images/logos/logo_bingo_auditivo.png<>uid://dim5arrthe0t4::::res://scripts/gimnasio/configuration_gym.gd<>uid://rcrqfnlhe4bb::::res://scripts/seguir_la_linea/configuration_seguir_la_linea.gd<>uid://b684a3o1ibj5i::::res://images/logos/logo_flecha_y_reacciona.png<>uid://ctge47k34s7yi::::res://scripts/emparejar_las_sombras/configuration_emparejar_las_sombras.gd
::res://scenes/bingo_auditivo/::1748287448
GameBingo.tscn::PackedScene/PackedScene::8967965762231623292::1748287448::0::1::::<><><>0<>0<><>::uid://dhqnf0xm2mwwm::::res://scripts/bingo_auditivo/game_bingo.gd<>uid://c4g0gbifdm5fe::::res://images/bingo_auditivo/background_bingo.png<>uid://cncae337c0ws8::::res://images/menu_logo.png<>uid://354a75edxicg::::res://assets/sign in window/window.png<>uid://dqrjftnev4ftw::::res://styles/menu.tres<>uid://t6vfbi66g6fy::::res://images/charecter.png<>uid://dk8i5somirvt2::::res://images/cuadro de texto.png<>uid://cpeiuq7umndvk::::res://audios/instrucciones_bingo_auditivo.mp3
::res://scenes/emparejar_las_sombras/::1748364213
GameEmparejarLasSombras.tscn::PackedScene/PackedScene::7300647384769136354::1748364213::0::1::::<><><>0<>0<><>::uid://vsc3anuvlso6::::res://scripts/emparejar_las_sombras/game_emparejar_las_sombras.gd<>uid://c8kq84p5btav8::::res://audios/instrucciones_emparejar_las_sombras.mp3<>uid://cncae337c0ws8::::res://images/menu_logo.png<>uid://dqrjftnev4ftw::::res://styles/menu.tres<>uid://t6vfbi66g6fy::::res://images/charecter.png<>uid://354a75edxicg::::res://assets/sign in window/window.png<>uid://dk8i5somirvt2::::res://images/cuadro de texto.png
::res://scenes/flecha_y_reacciona/::1748287448
GameFlechaYReacciona.tscn::PackedScene/PackedScene::2239309432930539111::1748287448::0::1::::<><><>0<>0<><>::uid://dlc5nmf2nugla::::res://scripts/flecha_y_reacciona/game_flecha_y_reacciona.gd<>uid://msfckci5lndd::::res://audios/instrucctions_flecha_y_reacciona.mp3<>uid://dqrjftnev4ftw::::res://styles/menu.tres<>uid://cncae337c0ws8::::res://images/menu_logo.png<>uid://354a75edxicg::::res://assets/sign in window/window.png<>uid://t6vfbi66g6fy::::res://images/charecter.png<>uid://dk8i5somirvt2::::res://images/cuadro de texto.png
::res://scenes/gimnasio/::1748287448
GameGym.tscn::PackedScene/PackedScene::8761792870795266585::1748287448::0::1::::<><><>0<>0<><>::uid://c03j7kms107t6::::res://scripts/gimnasio/game_gym.gd<>uid://dqrjftnev4ftw::::res://styles/menu.tres<>uid://cncae337c0ws8::::res://images/menu_logo.png<>uid://cykbo7qv3fy6l::::res://images/play-button.png<>uid://bf16kwp1ccwh4::::res://audios/instrucciones_gym.mp3<>uid://354a75edxicg::::res://assets/sign in window/window.png<>uid://t6vfbi66g6fy::::res://images/charecter.png<>uid://dk8i5somirvt2::::res://images/cuadro de texto.png
::res://scenes/seguir_la_linea/::1748287448
GameSeguirLaLinea.tscn::PackedScene/PackedScene::2653001513631914606::1748287448::0::1::::<><><>0<>0<><>::uid://cf24sqa5714px::::res://scripts/seguir_la_linea/game_seguir_la_linea.gd<>uid://cncae337c0ws8::::res://images/menu_logo.png<>uid://dqrjftnev4ftw::::res://styles/menu.tres<>uid://cykbo7qv3fy6l::::res://images/play-button.png<>uid://t6vfbi66g6fy::::res://images/charecter.png<>uid://cwudtop42vbi8::::res://audios/instrucciones_seguir_la_linea.mp3<>uid://354a75edxicg::::res://assets/sign in window/window.png<>uid://dk8i5somirvt2::::res://images/cuadro de texto.png
::res://scripts/::1748529123
app_constants.gd::GDScript::3537533678312647870::1748529123::0::1::::<>Node<><>0<>0<><>::
game_data.gd::GDScript/GDScript::4985019478966635616::1748117032::0::1::::<>Node<><>0<>0<><>::
home.gd::GDScript/GDScript::5618272075595688803::1747849655::0::1::::<>Control<><>0<>0<><>::
image_loader.gd::GDScript/GDScript::611758767551863186::1747403452::0::1::::<>Node<><>0<>0<><>::
scene_manager.gd::GDScript/GDScript::2049891027188034232::1747403452::0::1::::<>Node<><>0<>0<><>::
::res://scripts/bingo_auditivo/::1747837163
configuration_bingo.gd::GDScript/GDScript::10065919189713686::1747837163::0::1::::<>Window<><>0<>0<><>::
::res://scripts/bingo_auditivo/::1748357418
configuration_bingo.gd::GDScript/GDScript::10065919189713686::1748357418::0::1::::<>Window<><>0<>0<><>::
game_bingo.gd::GDScript/GDScript::7684413599682033952::1747835483::0::1::::<>Control<><>0<>0<><>::
::res://scripts/emparejar_las_sombras/::1747841901
::res://scripts/emparejar_las_sombras/::1748360951
animal_tile.gd::GDScript/GDScript::798197404215561372::1747841901::0::1::::AnimalTile<>Node2D<><>0<>0<><>::
configuration_emparejar_las_sombras.gd::GDScript/GDScript::6119112016534423576::1747787817::0::1::::<>Window<><>0<>0<><>::
game_emparejar_las_sombras.gd::GDScript/GDScript::1511295973206308651::1747777885::0::1::::<>Control<><>0<>0<><>::
configuration_emparejar_las_sombras.gd::GDScript/GDScript::6119112016534423576::1748357152::0::1::::<>Window<><>0<>0<><>::
game_emparejar_las_sombras.gd::GDScript/GDScript::1511295973206308651::1748360951::0::1::::<>Control<><>0<>0<><>::
::res://scripts/flecha_y_reacciona/::1747851840
configuration_f_y_r.gd::GDScript/GDScript::8259793138334191281::1747851840::0::1::::<>Window<><>0<>0<><>::
game_flecha_y_reacciona.gd::GDScript/GDScript::7937313450958682526::1747849655::0::1::::<>Control<><>0<>0<><>::
::res://scripts/gimnasio/::1747840227
configuration_gym.gd::GDScript/GDScript::7747367763046715191::1747838928::0::1::::<>Window<><>0<>0<><>::
::res://scripts/gimnasio/::1748357460
configuration_gym.gd::GDScript/GDScript::7747367763046715191::1748357460::0::1::::<>Window<><>0<>0<><>::
game_gym.gd::GDScript/GDScript::6585969178415297357::1747840227::0::1::::<>Control<><>0<>0<><>::
::res://scripts/seguir_la_linea/::1747842068
configuration_seguir_la_linea.gd::GDScript/GDScript::1198400142142721223::1747842068::0::1::::<>Window<><>0<>0<><>::
::res://scripts/seguir_la_linea/::1748357204
configuration_seguir_la_linea.gd::GDScript/GDScript::1198400142142721223::1748357204::0::1::::<>Window<><>0<>0<><>::
game_seguir_la_linea.gd::GDScript/GDScript::5181317563796977305::1747787421::0::1::::<>Control<><>0<>0<><>::
::res://styles/::1748359156
HollowSpace.ttf::FontFile/FontFile::4253478741533199832::1748359136::1748359156::1::::<><><>0<>0<>819d222e50ae5defd727e3ec6c059945<>res://.godot/imported/HollowSpace.ttf-4abe360c6bbba8bbcf0c299a20d25e4c.fontdata::
Jackpot.ttf::FontFile/FontFile::7421148737085637010::1748287546::1748287547::1::::<><><>0<>0<>e9dd6a9b196bf0a5ac6e1f02023684b2<>res://.godot/imported/Jackpot.ttf-a94416b24d1da2bf60b641084cd3aacb.fontdata::
menu.tres::Theme/Theme::8317934371248321320::1747852682::0::1::::<><><>0<>0<><>::
::res://videos/::1747571283
::res://videos/gimnasio/::1747571294
1_marcha.ogv::VideoStreamTheora/VideoStreamTheora::8170332476493401942::1745338782::0::1::::<><><>0<>0<><>::

View File

@ -1 +1,2 @@
res://scenes/Home.tscn
res://scripts/app_constants.gd

View File

@ -9,8 +9,8 @@ last_selected_language="GDScript"
[recent_files]
scripts=["res://scripts/flecha_y_reacciona/configuration_f_y_r.gd", "res://scripts/app_constants.gd", "res://scripts/seguir_la_linea/configuration_seguir_la_linea.gd", "res://scripts/emparejar_las_sombras/configuration_emparejar_las_sombras.gd", "res://scripts/emparejar_las_sombras/animal_tile.gd", "res://scripts/game_data.gd", "res://scripts/gimnasio/game_gym.gd", "res://scripts/gimnasio/configuration_gym.gd", "res://scripts/flecha_y_reacciona/game_flecha_y_reacciona.gd", "res://scripts/bingo_auditivo/game_bingo.gd"]
scenes=["res://scenes/seguir_la_linea/GameSeguirLaLinea.tscn", "res://scenes/gimnasio/GameGym.tscn", "res://scenes/flecha_y_reacciona/GameFlechaYReacciona.tscn", "res://scenes/emparejar_las_sombras/GameEmparejarLasSombras.tscn", "res://scenes/bingo_auditivo/GameBingo.tscn", "res://scenes/Home.tscn", "res://scenes/emparejar_las_sombras/ConfigurationEmparejarLasSombras.tscn", "res://scenes/seguir_la_linea/ConfigurationSeguirLaLinea.tscn", "res://scenes/flecha_y_reacciona/ConfigurationFlechaYReacciona.tscn", "res://scenes/gimnasio/ConfigurationGym.tscn"]
scripts=["res://scripts/scene_manager.gd", "res://scripts/emparejar_las_sombras/game_emparejar_las_sombras.gd", "res://scripts/flecha_y_reacciona/configuration_f_y_r.gd", "res://scripts/app_constants.gd", "res://scripts/seguir_la_linea/configuration_seguir_la_linea.gd", "res://scripts/emparejar_las_sombras/configuration_emparejar_las_sombras.gd", "res://scripts/emparejar_las_sombras/animal_tile.gd", "res://scripts/game_data.gd", "res://scripts/gimnasio/game_gym.gd", "res://scripts/gimnasio/configuration_gym.gd"]
scenes=["res://scenes/Home.tscn", "res://scenes/emparejar_las_sombras/GameEmparejarLasSombras.tscn", "res://scenes/seguir_la_linea/GameSeguirLaLinea.tscn", "res://scenes/gimnasio/GameGym.tscn", "res://scenes/flecha_y_reacciona/GameFlechaYReacciona.tscn", "res://scenes/bingo_auditivo/GameBingo.tscn", "res://scenes/emparejar_las_sombras/ConfigurationEmparejarLasSombras.tscn", "res://scenes/seguir_la_linea/ConfigurationSeguirLaLinea.tscn", "res://scenes/flecha_y_reacciona/ConfigurationFlechaYReacciona.tscn", "res://scenes/gimnasio/ConfigurationGym.tscn"]
[dialog_bounds]
@ -21,10 +21,14 @@ export=Rect2(510, 127, 921, 799)
[color_picker]
picker_shape=3
recent_presets=PackedColorArray(0.634932, 0.16328, 0.211924, 1, 0.795252, 0.234038, 0.285736, 1, 1, 0.235294, 0.286275, 1, 0.74195, 0, 0.145017, 1, 0.741176, 0, 0, 1, 0.926244, 0.000504314, 0.000275693, 1, 0, 0, 0, 1, 0.588235, 0.654902, 0.686275, 1, 1, 1, 1, 1)
recent_presets=PackedColorArray(0.588235, 0.654902, 0.686275, 1, 1, 0.921569, 0.231373, 1, 0.290196, 0.0784314, 0.54902, 1, 0, 0, 0.701961, 1, 0, 0, 0.917647, 1, 0, 0, 0.901961, 1, 0.987008, 0.992212, 0.995128, 1, 0, 0, 0, 1, 1, 1, 1, 1)
color_mode=0
[export_options]
default_filename="ResiGames"
export_debug=true
[quick_open_dialog]
last_mode=0

View File

@ -0,0 +1,3 @@
[selected_history]
Font=PackedStringArray("uid://b1uof5qtp3k85", "uid://ddy4iagm4nqtu")

View File

@ -3,11 +3,11 @@
state={
"bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(),
"column": 5,
"column": 43,
"folded_lines": Array[int]([]),
"h_scroll_position": 0,
"row": 160,
"scroll_position": 285.0,
"row": 73,
"scroll_position": 54.0,
"selection": false,
"syntax_highlighter": "GDScript"
}
@ -17,16 +17,12 @@ state={
state={
"bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(),
"column": 18,
"column": 12,
"folded_lines": Array[int]([]),
"h_scroll_position": 0,
"row": 1,
"row": 0,
"scroll_position": 0.0,
"selection": true,
"selection_from_column": 4,
"selection_from_line": 1,
"selection_to_column": 18,
"selection_to_line": 1,
"selection": false,
"syntax_highlighter": "GDScript"
}
@ -63,11 +59,11 @@ state={
state={
"bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(),
"column": 0,
"column": 1,
"folded_lines": Array[int]([]),
"h_scroll_position": 0,
"row": 0,
"scroll_position": 0.0,
"row": 258,
"scroll_position": 258.0,
"selection": false,
"syntax_highlighter": "GDScript"
}
@ -77,11 +73,11 @@ state={
state={
"bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(),
"column": 87,
"column": 27,
"folded_lines": Array[int]([]),
"h_scroll_position": 4,
"row": 43,
"scroll_position": 39.0,
"h_scroll_position": 0,
"row": 37,
"scroll_position": 73.0,
"selection": false,
"syntax_highlighter": "GDScript"
}
@ -94,8 +90,8 @@ state={
"column": 1,
"folded_lines": Array[int]([]),
"h_scroll_position": 0,
"row": 84,
"scroll_position": 90.0,
"row": 92,
"scroll_position": 84.0,
"selection": false,
"syntax_highlighter": "GDScript"
}
@ -105,11 +101,11 @@ state={
state={
"bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(),
"column": 20,
"column": 1,
"folded_lines": Array[int]([]),
"h_scroll_position": 0,
"row": 89,
"scroll_position": 74.0,
"row": 193,
"scroll_position": 173.0,
"selection": false,
"syntax_highlighter": "GDScript"
}
@ -137,11 +133,11 @@ state={
state={
"bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(),
"column": 47,
"column": 33,
"folded_lines": Array[int]([]),
"h_scroll_position": 0,
"row": 209,
"scroll_position": 207.0,
"row": 244,
"scroll_position": 209.0,
"selection": false,
"syntax_highlighter": "GDScript"
}
@ -165,11 +161,11 @@ state={
state={
"bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(),
"column": 18,
"column": 1,
"folded_lines": Array[int]([]),
"h_scroll_position": 0,
"row": 18,
"scroll_position": 107.0,
"row": 114,
"scroll_position": 108.0,
"selection": false,
"syntax_highlighter": "GDScript"
}
@ -207,11 +203,11 @@ state={
state={
"bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(),
"column": 43,
"column": 0,
"folded_lines": Array[int]([]),
"h_scroll_position": 327,
"row": 12,
"scroll_position": 12.0,
"h_scroll_position": 0,
"row": 208,
"scroll_position": 208.0,
"selection": false,
"syntax_highlighter": "GDScript"
}
@ -221,10 +217,10 @@ state={
state={
"bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(),
"column": 71,
"column": 50,
"folded_lines": Array[int]([]),
"h_scroll_position": 0,
"row": 12,
"row": 5,
"scroll_position": 0.0,
"selection": false,
"syntax_highlighter": "GDScript"

View File

@ -1,7 +1,7 @@
res://scenes/bingo_auditivo/GameBingo.tscn::47a78f7f0cc30d8e9b903902060451a9::1747852435::res://.godot/exported/133200997/export-ff3c434b021ca044f15c00764a8472f2-GameBingo.scn
res://scenes/emparejar_las_sombras/GameEmparejarLasSombras.tscn::b6b60e3ce57c6692a35982cbd4af32bf::1747852370::res://.godot/exported/133200997/export-651394af674b52f4013ea20a840feef4-GameEmparejarLasSombras.scn
res://scenes/flecha_y_reacciona/GameFlechaYReacciona.tscn::e8a7e7668ed24aa49832f6d9e82ecbd7::1747852368::res://.godot/exported/133200997/export-ea279ed6ebbc6a034308a5ae742fa619-GameFlechaYReacciona.scn
res://scenes/gimnasio/GameGym.tscn::9b79ebd919907872e7e45e72de9304b7::1747852366::res://.godot/exported/133200997/export-902b29b7617aeec13be5947fbf71742d-GameGym.scn
res://scenes/seguir_la_linea/GameSeguirLaLinea.tscn::2f20dd7d4b633999f20049a743c22928::1747852365::res://.godot/exported/133200997/export-d5b736042ffd164b0954669ca2ec5614-GameSeguirLaLinea.scn
res://scenes/Home.tscn::42973a9671810b845f24b4c134ecf16e::1748128312::res://.godot/exported/133200997/export-20ec3a207690e015b9c115c7601d772c-Home.scn
res://menu.tres::11872ed4c8d121a05178d0a945aa2a55::1747852682::res://.godot/exported/133200997/export-6190c6dd272fa5536bd37dcd1686cacd-menu.res
res://scenes/bingo_auditivo/GameBingo.tscn::92f27a7f4ebc1d74d5bc4ea01261bd30::1748287448::res://.godot/exported/133200997/export-ff3c434b021ca044f15c00764a8472f2-GameBingo.scn
res://scenes/emparejar_las_sombras/GameEmparejarLasSombras.tscn::db43741d34eebf94a307feea05fbd224::1748364213::res://.godot/exported/133200997/export-651394af674b52f4013ea20a840feef4-GameEmparejarLasSombras.scn
res://scenes/flecha_y_reacciona/GameFlechaYReacciona.tscn::8ba63cb414babb71ec1b95cc5cfff7d2::1748287448::res://.godot/exported/133200997/export-ea279ed6ebbc6a034308a5ae742fa619-GameFlechaYReacciona.scn
res://scenes/gimnasio/GameGym.tscn::c986ec4d506cd61c97c6a01d59c05805::1748287448::res://.godot/exported/133200997/export-902b29b7617aeec13be5947fbf71742d-GameGym.scn
res://scenes/seguir_la_linea/GameSeguirLaLinea.tscn::39255dc26468f91c1354b51470436846::1748287448::res://.godot/exported/133200997/export-d5b736042ffd164b0954669ca2ec5614-GameSeguirLaLinea.scn
res://scenes/Home.tscn::cc3e7d9172f9a4b52af646493cf37489::1748360785::res://.godot/exported/133200997/export-20ec3a207690e015b9c115c7601d772c-Home.scn
res://styles/menu.tres::11872ed4c8d121a05178d0a945aa2a55::1747852682::res://.godot/exported/133200997/export-1744ff4701d9792877542237f193ac43-menu.res

View File

@ -0,0 +1,3 @@
source_md5="13aa3253380aa9d4ad76b439a1b1a1ec"
dest_md5="3b20f1acfc375a99f9cc54f50fac5ba0"

View File

@ -0,0 +1,3 @@
source_md5="aa2bebef0d9e3179ba58c024f1e11300"
dest_md5="97b99ca8adf6b3b3d1a9f0e066637f40"

View File

@ -0,0 +1,3 @@
source_md5="aa2bebef0d9e3179ba58c024f1e11300"
dest_md5="b96d954caca6d1e79843f861f1249b4f"

View File

@ -0,0 +1,3 @@
source_md5="47b272cff27d60a6c22f3d91febb3516"
dest_md5="4ea11dc0d9bfe028447353fecc7cae7e"

View File

@ -0,0 +1,3 @@
source_md5="a33326e52f8a8fb69328e8ef3f33876f"
dest_md5="04cdd6a874768dd91eba197a9af9bf77"

View File

@ -0,0 +1,3 @@
source_md5="ac54e2e5ee44294b48fdb5188d6e8cfe"
dest_md5="abaa01f614b428ad32f5264c9a8aed09"

View File

@ -0,0 +1,3 @@
source_md5="b253d8f5d01bb63176f32871cb2b416c"
dest_md5="a0eb52820843e08a911efd6d5809ad07"

Some files were not shown because too many files have changed in this diff Show More