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> <selectionStates>
<SelectionState runConfigName="app"> <SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" /> <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"> <Target type="DEFAULT_BOOT">
<handle> <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> </handle>
</Target> </Target>
</DropdownSelection> </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 { public interface IOClickOnActivityListener {
void onClickOnActivity(Activity activity , List<ActivityResident> participants); 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; import java.util.List;
public interface IOClickOnAddParticipantListener { 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 { public interface IOClickOnGameStatsListener {
void onClickOnLatestGame(GameStat gameStat, Resident gameStatResident, Game gameStatGame); 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 { public interface IOClickOnParticipantListener {
void onClickOnParticipant(ActivityResident participant); 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 onClickOnOpinion(ActivityResident participant, boolean isPreOpinion);
void onClickOnMaterialHelp(ActivityResident participant, boolean isTrue); void onClickOnMaterialHelp(ActivityResident participant, boolean isTrue, Runnable refresh);
void onClickOnHumanHelp(ActivityResident participant, boolean isTrue); 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 { public interface IOClickOnResidentListener {
void onClickOnResident(Resident resident); 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; import com.andresgmoran.apptrabajadores.models.ActivityState;
public interface IOnChageStateActivityListener { 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.Activity;
import com.andresgmoran.apptrabajadores.models.ActivityResident; import com.andresgmoran.apptrabajadores.models.ActivityResident;
import com.andresgmoran.apptrabajadores.models.ActivityState; import com.andresgmoran.apptrabajadores.models.ActivityState;
import com.andresgmoran.apptrabajadores.models.Game;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
@ -35,14 +34,16 @@ public class ActivitiesAdapter extends RecyclerView.Adapter<ActivitiesAdapter.Ac
private List<ActivityResident> participants; private List<ActivityResident> participants;
private IOClickOnActivityListener listener; private IOClickOnActivityListener listener;
private IOnChageStateActivityListener changeStateListener; 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.context = context;
this.activities = activities; this.activities = activities;
this.participants = participants; this.participants = participants;
this.listener = listener; this.listener = listener;
this.changeStateListener = changeStateListener; this.changeStateListener = changeStateListener;
this.refresh = refresh;
} }
@NonNull @NonNull
@Override @Override
@ -74,7 +75,7 @@ public class ActivitiesAdapter extends RecyclerView.Adapter<ActivitiesAdapter.Ac
.setTitle(context.getString(R.string.close_activity_title)) .setTitle(context.getString(R.string.close_activity_title))
.setMessage(context.getString(R.string.close_activity_message)) .setMessage(context.getString(R.string.close_activity_message))
.setPositiveButton(context.getString(R.string.accept_text), (dialog, which) -> { .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) -> { .setNegativeButton(context.getString(R.string.cancel_text), (dialog, which) -> {
dialog.dismiss(); dialog.dismiss();
@ -90,7 +91,7 @@ public class ActivitiesAdapter extends RecyclerView.Adapter<ActivitiesAdapter.Ac
popupMenu.setOnMenuItemClickListener(item -> { popupMenu.setOnMenuItemClickListener(item -> {
if (item.getItemId() == R.id.action_delete) { if (item.getItemId() == R.id.action_delete) {
if (activities != null) if (activities != null)
listener.onDeleteActivitie(activity); listener.onDeleteActivitie(activity, refresh);
return true; return true;
} }
return false; return false;

View File

@ -3,6 +3,7 @@ package com.andresgmoran.apptrabajadores.models.adapters;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
@ -55,15 +56,18 @@ public class GamesAdapter extends RecyclerView.Adapter<GamesAdapter.GamesViewHol
private final TextView gameName; private final TextView gameName;
private final ImageView gameImage; private final ImageView gameImage;
private final TextView percentageView; private final TextView percentageView;
private final ImageButton optionsButton;
public GamesViewHolder(View view) { public GamesViewHolder(View view) {
super(view); super(view);
gameName = view.findViewById(R.id.name_list_item); gameName = view.findViewById(R.id.name_list_item);
gameImage = view.findViewById(R.id.item_list_image); 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) { public void bindGame(Game game) {
optionsButton.setVisibility(View.GONE);
String name = game.getName(); String name = game.getName();
String formattedName = name.substring(0, 1).toUpperCase() + name.substring(1); String formattedName = name.substring(0, 1).toUpperCase() + name.substring(1);
gameName.setText(formattedName); gameName.setText(formattedName);
@ -74,7 +78,7 @@ public class GamesAdapter extends RecyclerView.Adapter<GamesAdapter.GamesViewHol
gameImage.setImageResource(imageResId); gameImage.setImageResource(imageResId);
double percentage = weeklyPercentages.getOrDefault(game.getId(), 0.0); 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> { public class LastGamesAdapter extends RecyclerView.Adapter<LastGamesAdapter.LastGamesViewHolder> {
private final List<GameStat> gameStats; private List<GameStat> gameStats;
private final List<Game> games; private List<Game> games;
private final List<Resident> residents; private List<Resident> residents;
private final IOClickOnGameStatsListener listener; private final IOClickOnGameStatsListener listener;
private Runnable runnable;
// Constructor para varios residentes // 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.gameStats = gameStats;
this.games = games; this.games = games;
this.residents = residents; this.residents = residents;
this.listener = listener; this.listener = listener;
this.runnable = refresh;
this.gameStats.sort(Comparator.comparing(GameStat::getDateTime).reversed()); this.gameStats.sort(Comparator.comparing(GameStat::getDateTime).reversed());
} }
// Constructor para un solo un residente // Constructor para un solo un residente
public LastGamesAdapter(List<GameStat> gameStats, List<Game> games, Resident resident, IOClickOnGameStatsListener listener) { public LastGamesAdapter(List<GameStat> gameStats, List<Game> games, Resident resident, IOClickOnGameStatsListener listener, Runnable refresh) {
this(gameStats, games, List.of(resident), listener); this(gameStats, games, List.of(resident), listener, refresh);
} }
// Constructor para un solo juego // Constructor para un solo juego
public LastGamesAdapter(List<GameStat> gameStats, Game game, List<Resident> residents, IOClickOnGameStatsListener listener) { public LastGamesAdapter(List<GameStat> gameStats, Game game, List<Resident> residents, IOClickOnGameStatsListener listener, Runnable refresh) {
this(gameStats, List.of(game), residents, listener); this(gameStats, List.of(game), residents, listener, refresh);
} }
public void updateData(List<GameStat> newGameStats) { public void updateData(List<GameStat> newGameStats, List<Game> newGames, List<Resident> newResidents) {
this.gameStats.clear(); this.gameStats = newGameStats;
this.gameStats.addAll(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(); notifyDataSetChanged();
} }
@ -95,7 +110,9 @@ public class LastGamesAdapter extends RecyclerView.Adapter<LastGamesAdapter.Last
popupMenu.setOnMenuItemClickListener(item -> { popupMenu.setOnMenuItemClickListener(item -> {
if (item.getItemId() == R.id.action_delete) { if (item.getItemId() == R.id.action_delete) {
if (finalGameStatResident != null && finalGameStatGame != null) if (finalGameStatResident != null && finalGameStatGame != null)
listener.onDeleteGameStat(gameStat, finalGameStatGame); listener.onDeleteGameStat(gameStat, finalGameStatGame, () -> {
runnable.run();
});
return true; return true;
} }
return false; return false;
@ -133,6 +150,7 @@ public class LastGamesAdapter extends RecyclerView.Adapter<LastGamesAdapter.Last
} }
public void bindObservation(GameStat gameStat, Resident gameStatResident, Game gameStatGame) { public void bindObservation(GameStat gameStat, Resident gameStatResident, Game gameStatGame) {
if (gameStat == null) { if (gameStat == null) {
residentName.setText("Residente no encontrado"); residentName.setText("Residente no encontrado");
gameName.setText("Juego desconocido"); gameName.setText("Juego desconocido");
@ -150,15 +168,9 @@ public class LastGamesAdapter extends RecyclerView.Adapter<LastGamesAdapter.Last
if (gameStatGame == null) { if (gameStatGame == null) {
gameName.setText("Juego desconocido"); gameName.setText("Juego desconocido");
} else { } else {
if (gameStatGame.getName().equalsIgnoreCase("flecha y reacciona") || gameStatGame.getName().equalsIgnoreCase("bingo auditivo")){ String name = gameStatGame.getName();
if (gameStat.getNum() == 0){ String formattedName = name.substring(0, 1).toUpperCase() + name.substring(1);
gameName.setText(gameStatGame.getName() + " - PERDIDA"); gameName.setText(formattedName);
} else if ( gameStat.getNum() == 1){
gameName.setText(gameStatGame.getName() + " - GANADA");
}
} else {
gameName.setText(gameStatGame.getName());
}
} }
Locale currentLocale = itemView.getContext().getResources().getConfiguration().getLocales().get(0); 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.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.PopupMenu;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -23,18 +24,20 @@ import java.util.List;
public class ParticipantsAdapter extends RecyclerView.Adapter<ParticipantsAdapter.ParticipantsViewHolder> { public class ParticipantsAdapter extends RecyclerView.Adapter<ParticipantsAdapter.ParticipantsViewHolder> {
private final Context context; private final Context context;
private final Activity activity; private Activity activity;
private List<Resident> residents; private List<Resident> residents;
private List<ActivityResident> activityResidents; private List<ActivityResident> activityResidents;
private IOClickOnParticipantListener listener; 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.context = context;
this.activity = activity; this.activity = activity;
this.residents = residents; this.residents = residents;
this.activityResidents = activityResidents; this.activityResidents = activityResidents;
this.listener = listener; this.listener = listener;
this.refresh = refresh;
} }
@NonNull @NonNull
@Override @Override
@ -43,10 +46,35 @@ public class ParticipantsAdapter extends RecyclerView.Adapter<ParticipantsAdapte
return new ParticipantsAdapter.ParticipantsViewHolder(view); 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 @Override
public void onBindViewHolder(@NonNull ParticipantsViewHolder holder, int position) { public void onBindViewHolder(@NonNull ParticipantsViewHolder holder, int position) {
ActivityResident activityResident = activityResidents.get(position); ActivityResident activityResident = activityResidents.get(position);
holder.bindActivity(activityResident); 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() { holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
@ -59,9 +87,9 @@ public class ParticipantsAdapter extends RecyclerView.Adapter<ParticipantsAdapte
public void onClick(View view) { public void onClick(View view) {
if (activity.getState() == ActivityState.ABIERTO){ if (activity.getState() == ActivityState.ABIERTO){
if (activityResident.isAssistance()){ if (activityResident.isAssistance()){
listener.onClickOnAssistance(activityResident, false); listener.onClickOnAssistance(activityResident, false, refresh);
} else { } 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) { public void onClick(View view) {
if (activity.getState() == ActivityState.ABIERTO){ if (activity.getState() == ActivityState.ABIERTO){
if (activityResident.isMaterialHelp()){ if (activityResident.isMaterialHelp()){
listener.onClickOnMaterialHelp(activityResident, false); listener.onClickOnMaterialHelp(activityResident, false, refresh);
} }
if (!activityResident.isMaterialHelp()) { 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) { public void onClick(View view) {
if (activity.getState() == ActivityState.ABIERTO){ if (activity.getState() == ActivityState.ABIERTO){
if (activityResident.isHumanHelp()){ if (activityResident.isHumanHelp()){
listener.onClickOnHumanHelp(activityResident, false); listener.onClickOnHumanHelp(activityResident, false, refresh);
} }
if (!activityResident.isHumanHelp()) { 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()){ if (activityResident.isAssistance()){
holder.assitanceButton.setBackgroundResource(R.drawable.activity_button_pressed_background); 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 opinionButton;
private final ImageButton materialHelp; private final ImageButton materialHelp;
private final ImageButton humanHelp; private final ImageButton humanHelp;
private final ImageButton optionsButton;
public ParticipantsViewHolder(View view) { public ParticipantsViewHolder(View view) {
@ -153,6 +187,7 @@ public class ParticipantsAdapter extends RecyclerView.Adapter<ParticipantsAdapte
opinionButton = itemView.findViewById(R.id.participant_opinion_button); opinionButton = itemView.findViewById(R.id.participant_opinion_button);
materialHelp = itemView.findViewById(R.id.participant_material_help_button); materialHelp = itemView.findViewById(R.id.participant_material_help_button);
humanHelp = itemView.findViewById(R.id.participant_human_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) { public void bindActivity(ActivityResident activityResident) {

View File

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

View File

@ -42,4 +42,43 @@ public class ResidenceParser {
throw new ParserException("Error al parsear residencia: " + e.getMessage(), e); 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 surnames = obj.getString("apellido");
String email = obj.getString("email"); String email = obj.getString("email");
boolean enabled = obj.getBoolean("enabled"); 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"); String accountImage = obj.getString("fotoPerfil");
boolean takenOut = obj.getBoolean("baja"); 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"; 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_USERS = "/resi/user/getAll";
private static final String ENDPOINT_GET_ME = "/resi/user/me"; private static final String ENDPOINT_GET_ME = "/resi/user/me";
private static final String ENDPOINT_RESIDENCE = "/resi/get"; 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_GET_ACTIVITIES = "/resi/evento/getAll";
private static final String ENDPOINT_ADD_EVENT = "/resi/evento/add"; private static final String ENDPOINT_ADD_EVENT = "/resi/evento/add";
private static final String ENDPOINT_LOGIN = "/auth/login"; 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_COMMENT_GAMESTAT = "/resi/registro/%d/addComment";
private static final String ENDPOINT_UPDATE_ACTIVITY_STATE = "/resi/evento/%d/update"; 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_GAMESTAT = "/resi/registro/%d/delete";
private static final String ENDPOINT_DELETE_ACTIVITY = "/resi/evento/%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_ACTIVITY_PARTICIPANTS = "/resi/evento/%d/participante/getAll";
private static final String ENDPOINT_ADD_PARTICIPANT = "/resi/evento/%d/participante/add"; 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_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_ALLOW_PARTICIPANT = "/resi/evento/%d/participante/%d/allow";
private static final String ENDPOINT_DENY_PARTICIPANT = "/resi/evento/%d/participante/%d/deny"; 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 onSuccess(Bitmap bitmap);
void onError(String error); 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) { public static void getUsers(Context context, RawCallback callback) {
makeGetRequest(context, ENDPOINT_GET_USERS, callback); makeGetRequest(context, ENDPOINT_GET_USERS, callback);
@ -73,6 +133,7 @@ public class ApiClient {
public static void getResidents(Context context, RawCallback callback) { public static void getResidents(Context context, RawCallback callback) {
makeGetRequest(context, ENDPOINT_GET_RESIDENTS, callback); makeGetRequest(context, ENDPOINT_GET_RESIDENTS, callback);
} }
public static void getResidentsTakenOut(Context context, RawCallback callback) { public static void getResidentsTakenOut(Context context, RawCallback callback) {
makeGetRequest(context, ENDPOINT_GET_RESIDENTS_TAKEN_OUT , 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); String jsonBody = String.format("{\"email\":\"%s\", \"password\":\"%s\"}", email, password);
makePostRequest(null, ENDPOINT_LOGIN, jsonBody, callback); 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, public static void postResident(Context context, String nombre, String apellido, LocalDate fechaNacimiento,
String documentoIdentidad, String familiar1, String familiar2, int year, int month, 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); 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) { public static void makeGetRequest(Context context, String endpoint, RawCallback callback) {
new Thread(() -> { new Thread(() -> {
HttpURLConnection connection = null; HttpURLConnection connection = null;

View File

@ -4,9 +4,7 @@ import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.util.Log; import android.util.Log;
import android.widget.Toast;
import com.andresgmoran.apptrabajadores.R;
import com.andresgmoran.apptrabajadores.exceptions.ParserException; import com.andresgmoran.apptrabajadores.exceptions.ParserException;
import com.andresgmoran.apptrabajadores.models.Activity; import com.andresgmoran.apptrabajadores.models.Activity;
import com.andresgmoran.apptrabajadores.models.ActivityResident; 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.ResidentParser;
import com.andresgmoran.apptrabajadores.models.parsers.UserParser; import com.andresgmoran.apptrabajadores.models.parsers.UserParser;
import com.andresgmoran.apptrabajadores.network.ApiClient; import com.andresgmoran.apptrabajadores.network.ApiClient;
import com.andresgmoran.apptrabajadores.ui.MainActivity;
import com.andresgmoran.apptrabajadores.utils.SecurePreferencesUtil; import com.andresgmoran.apptrabajadores.utils.SecurePreferencesUtil;
import org.json.JSONObject; import org.json.JSONObject;
@ -42,6 +39,8 @@ public class AppDataRepository {
private Bitmap actualUserImage; private Bitmap actualUserImage;
private List<User> users = new ArrayList<>(); private List<User> users = new ArrayList<>();
private Residence residence = null; private Residence residence = null;
private List<Residence> residences = new ArrayList<>();
private Bitmap residentImage;
private List<Resident> residents = new ArrayList<>(); private List<Resident> residents = new ArrayList<>();
private List<Resident> residentsTakenOut = new ArrayList<>(); private List<Resident> residentsTakenOut = new ArrayList<>();
private List<Game> games = new ArrayList<>(); private List<Game> games = new ArrayList<>();
@ -68,6 +67,9 @@ public class AppDataRepository {
public Residence getResidence() { return residence; } public Residence getResidence() { return residence; }
public void setResidence(Residence residence) { this.residence = 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 List<Resident> getResidents() { return residents; }
public void setResidents(List<Resident> list) { this.residents = new ArrayList<>(list); } 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 List<ActivityResident> getActivityResidents() { return activityResidents; }
public void setActivityResidents(List<ActivityResident> list) { this.activityResidents = new ArrayList<>(list); } 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) { public void fetchActualUser(Context context, Runnable onSuccess, Runnable onError) {
ApiClient.getActualUser(context, new ApiClient.RawCallback() { 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() { ApiClient.postLogin(email, password, new ApiClient.RawCallback() {
@Override @Override
public void onSuccess(String jsonText) { public void onSuccess(String jsonText) {
@ -488,11 +713,15 @@ public void fetchResidentsTakenOutOnly(Context context, Runnable onFinish) {
SecurePreferencesUtil.edit(context, editor); SecurePreferencesUtil.edit(context, editor);
if(idUser == 1)
fetchAllResidencesAdmin(context, onSuccesAdmin, onError);
else
fetchActualUser(context, onSuccess, onError);
} catch (Exception e) { } catch (Exception e) {
throw new ParserException("Error al parsear respuesta de login: " + e.getMessage(), e); throw new ParserException("Error al parsear respuesta de login: " + e.getMessage(), e);
} }
Log.d("API", "Inicio de sesión exitoso"); Log.d("API", "Inicio de sesión exitoso");
fetchActualUser(context, onSuccess, onError);
} }
@Override @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) { 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() { ApiClient.postResident(context, nombre, apellido, fechaNacimiento, documentoIdentidad, familiar1, familiar2, year, month, new ApiClient.RawCallback() {
@Override @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.OpinionFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.activities.ParticipantDetailFragment; import com.andresgmoran.apptrabajadores.ui.fragments.activities.ParticipantDetailFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.activities.ParticipantSelectionDialogFragment; 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.authentication.LoginFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.game.GameFragment; import com.andresgmoran.apptrabajadores.ui.fragments.game.GameFragment;
import com.andresgmoran.apptrabajadores.ui.fragments.gameDetail.GameDetailFragment; import com.andresgmoran.apptrabajadores.ui.fragments.gameDetail.GameDetailFragment;
@ -57,6 +58,7 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
public class MainActivity extends AppCompatActivity implements public class MainActivity extends AppCompatActivity implements
AdminPanelFragment.IOnAdminPanel,
NavigationBarView.OnItemSelectedListener, NavigationBarView.OnItemSelectedListener,
IOnClickOnBackButtonListener, IOnClickOnBackButtonListener,
HomeFragment.IOnRefreshHomeListener, HomeFragment.IOnClickOnAddParticipantListener, HomeFragment.IOnRefreshHomeListener, HomeFragment.IOnClickOnAddParticipantListener,
@ -91,19 +93,22 @@ 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 // 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 rootView = findViewById(R.id.fcvMain);
//View statusBarView = findViewById(R.id.status_bar_background);
View statusBarView = findViewById(R.id.status_bar_background); View statusBarView = findViewById(R.id.status_bar_background);
ViewCompat.setOnApplyWindowInsetsListener(rootView, (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(0, systemBars.top, 0, 0); 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(); ViewGroup.LayoutParams params = statusBarView.getLayoutParams();
params.height = systemBars.top; params.height = systemBars.top;
statusBarView.setLayoutParams(params); statusBarView.setLayoutParams(params);
return insets; return insets;
}); });
}
// -------- INICIO AUTOMÁTICO SI RECUERDA CONTRASEÑA Y TOKEN VÁLIDO -------- // -------- INICIO AUTOMÁTICO SI RECUERDA CONTRASEÑA Y TOKEN VÁLIDO --------
try { try {
@ -171,10 +176,10 @@ public class MainActivity extends AppCompatActivity implements
// --------------------------------------------------------------------- Login --------------------------------------------------------------------- // --------------------------------------------------------------------- Login ---------------------------------------------------------------------
/** /**
* * Llama al método de login con los datos introducidos en el fragmento de LoginFragment
* @param email * @param email correo electrónico del usuario
* @param password * @param password contraseña del usuario
* @param rememberPassword * @param rememberPassword indica si se debe recordar la contraseña
*/ */
@Override @Override
public void onLogin(String email, String password, boolean rememberPassword) { public void onLogin(String email, String password, boolean rememberPassword) {
@ -182,10 +187,10 @@ public class MainActivity extends AppCompatActivity implements
} }
/** /**
* * Realiza el login con los datos introducidos
* @param email * @param email correo electrónico del usuario
* @param password * @param password contraseña del usuario
* @param rememberPassword * @param rememberPassword indica si se debe recordar la contraseña
*/ */
public void postLogin(String email, String password, boolean rememberPassword) { public void postLogin(String email, String password, boolean rememberPassword) {
AppDataRepository.getInstance().login(MainActivity.this, email, password, rememberPassword, () -> runOnUiThread(() -> { 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.nav_view).setVisibility(View.VISIBLE);
findViewById(R.id.progress_loader).setVisibility(View.GONE); findViewById(R.id.progress_loader).setVisibility(View.GONE);
((BottomNavigationView) findViewById(R.id.nav_view)).setSelectedItemId(R.id.navigation_home); ((BottomNavigationView) findViewById(R.id.nav_view)).setSelectedItemId(R.id.navigation_home);
}), () -> runOnUiThread(() -> {
loadFragment(new AdminPanelFragment());
}), }),
() -> runOnUiThread(() -> { () -> runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Error al iniciar sesión", Toast.LENGTH_SHORT).show(); 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 * @return true si se ha cargado correctamente, false si no
*/ */
private boolean loadFragment(Fragment fragment) { private boolean loadFragment(Fragment fragment) {
if (isFinishing() || isDestroyed()) return false;
if (fragment != null) { if (fragment != null) {
Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fcvMain); Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fcvMain);
if (currentFragment != null) { if (currentFragment != null) {
@ -237,26 +246,12 @@ public class MainActivity extends AppCompatActivity implements
return false; 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 * Crea el fragmento de HOME
* @return fragmento creado * @return fragmento creado
*/ */
public Fragment createHomeFragment(){ public Fragment createHomeFragment(){
HomeFragment homeFragment = new HomeFragment(); HomeFragment homeFragment = new HomeFragment();
Bundle bundle = new Bundle();
homeFragment.setArguments(bundle);
return homeFragment; return homeFragment;
} }
@ -287,11 +282,11 @@ public class MainActivity extends AppCompatActivity implements
} }
/** /**
* * Crea el fragmento de GAME DETAIL
* @param gameStat * @param gameStat partida a mostrar en el fragmento
* @param gameStatResident * @param gameStatResident residente que ha jugado la partida
* @param gameStatGame * @param gameStatGame juego que se ha jugado
* @return * @return fragmento creado
*/ */
public Fragment createGameDetailFragment(GameStat gameStat, Resident gameStatResident, Game gameStatGame){ public Fragment createGameDetailFragment(GameStat gameStat, Resident gameStatResident, Game gameStatGame){
GameDetailFragment gameDetailFragment = new GameDetailFragment(); GameDetailFragment gameDetailFragment = new GameDetailFragment();
@ -304,10 +299,10 @@ public class MainActivity extends AppCompatActivity implements
} }
/** /**
* * Crea el fragmento de ActivityDetail
* @param activity * @param activity actividad a mostrar en el fragmento
* @param participants * @param participants lista de participantes de la actividad
* @return * @return fragmento creado
*/ */
public Fragment createActivityDetailFragment(Activity activity, List<ActivityResident> participants){ public Fragment createActivityDetailFragment(Activity activity, List<ActivityResident> participants){
ActivityDetailFragment activityDetailFragment = new ActivityDetailFragment(); 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) { private void reloadFragment(Fragment fragment) {
if (fragment == null) return; if (fragment == null) return;
@ -391,10 +386,6 @@ public class MainActivity extends AppCompatActivity implements
} }
// --------------------------------------------------------------------- OnClickListeners ---------------------------------------------------------------------
// --------------------------------------------------------------------- Resident listeners --------------------------------------------------------------------- // --------------------------------------------------------------------- Resident listeners ---------------------------------------------------------------------
/** /**
@ -408,17 +399,17 @@ public class MainActivity extends AppCompatActivity implements
} }
/** /**
* * Listener para el click en el botón de dar de baja a un residente
* @param resident * @param resident residente que se quiere dar de baja
*/ */
@Override @Override
public void onTakeOutResident(Resident resident) { public void onTakeOutResident(Resident resident, Runnable refresh) {
AppDataRepository.getInstance().takeDownResident(MainActivity.this, resident.getId(), () -> { AppDataRepository.getInstance().takeDownResident(MainActivity.this, resident.getId(), () -> {
runOnUiThread(() -> { runOnUiThread(() -> {
AppDataRepository.getInstance().fetchResidentsTakenOutOnly( MainActivity.this, () -> { AppDataRepository.getInstance().fetchResidentsTakenOutOnly( MainActivity.this, () -> {
runOnUiThread(() -> { runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Residente dado de baja correctamente", Toast.LENGTH_SHORT).show(); 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 --------------------------------------------------------------------- // --------------------------------------------------------------------- Game listeners ---------------------------------------------------------------------
/** /**
@ -455,16 +474,16 @@ public class MainActivity extends AppCompatActivity implements
} }
/** /**
* * Listener para el click en el botón de eliminar partida
* @param gameStat * @param gameStat partida que se quiere eliminar
* @param gamestatGame * @param gamestatGame juego de la partida
*/ */
@Override @Override
public void onDeleteGameStat(GameStat gameStat, Game gamestatGame) { public void onDeleteGameStat(GameStat gameStat, Game gamestatGame, Runnable refresh) {
AppDataRepository.getInstance().deleteGameStat(MainActivity.this, gameStat.getId(), () -> { AppDataRepository.getInstance().deleteGameStat(MainActivity.this, gameStat.getId(), () -> {
runOnUiThread(() -> { runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Partida eliminada correctamente", Toast.LENGTH_SHORT).show(); Toast.makeText(MainActivity.this, "Partida eliminada correctamente", Toast.LENGTH_SHORT).show();
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain)); refresh.run();
}); });
}, () -> { }, () -> {
runOnUiThread(() -> { runOnUiThread(() -> {
@ -474,17 +493,17 @@ public class MainActivity extends AppCompatActivity implements
} }
/** /**
* * Listener para el click en el botón de añadir observación a una partida
* @param observation * @param observation observación a añadir
* @param gameId * @param gameId id del juego al que pertenece la partida
* @param gameStatId * @param gameStatId id de la partida a la que se quiere añadir la observación
*/ */
@Override @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, () -> { AppDataRepository.getInstance().updateObservation(MainActivity.this, observation, gameStatId, () -> {
runOnUiThread(() -> { runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Observación actualizada correctamente", Toast.LENGTH_SHORT).show(); Toast.makeText(MainActivity.this, "Observación actualizada correctamente", Toast.LENGTH_SHORT).show();
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain)); refresh.run();
}); });
}, () -> { }, () -> {
runOnUiThread(() -> { 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 --------------------------------------------------------------------- // --------------------------------------------------------------------- Activity Listeners ---------------------------------------------------------------------
/** /**
* * Listener para el click en una actividad
* @param activity * @param activity actividad sobre la que se ha hecho click
* @param participants * @param participants lista de participantes de la actividad
*/ */
@Override @Override
public void onClickOnActivity(Activity activity, List<ActivityResident> participants) { public void onClickOnActivity(Activity activity, List<ActivityResident> participants) {
@ -506,17 +538,27 @@ public class MainActivity extends AppCompatActivity implements
} }
/** /**
* * Listener para el click en el botón de añadir actividad
* @param activityName */
* @param activityDescription @Override
* @param date 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 @Override
public void onAddActivity(String activityName, String activityDescription, LocalDateTime date) { public void onAddActivity(String activityName, String activityDescription, LocalDateTime date) {
AppDataRepository.getInstance().addActivity(MainActivity.this, activityName, activityDescription, date, () -> { AppDataRepository.getInstance().addActivity(MainActivity.this, activityName, activityDescription, date, () -> {
runOnUiThread(() -> { runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Actividad añadida correctamente", Toast.LENGTH_SHORT).show(); 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(() -> { runOnUiThread(() -> {
@ -526,18 +568,19 @@ public class MainActivity extends AppCompatActivity implements
} }
/** /**
* * Listener para el click en el botón de eliminar actividad
* @param activity * @param activity actividad que se quiere eliminar
* @param refresh Runnable para refrescar la vista después de eliminar la actividad
*/ */
@Override @Override
public void onDeleteActivitie(Activity activity) { public void onDeleteActivitie(Activity activity, Runnable refresh) {
ApiClient.deleteActivity(MainActivity.this, activity.getId(), new ApiClient.RawCallback() { ApiClient.deleteActivity(MainActivity.this, activity.getId(), new ApiClient.RawCallback() {
@Override @Override
public void onSuccess(String jsonText) { public void onSuccess(String jsonText) {
Toast.makeText(MainActivity.this, "Actividad eliminada correctamente", Toast.LENGTH_SHORT).show();
AppDataRepository.getInstance().fetchActivitiesOnly(MainActivity.this, () -> { AppDataRepository.getInstance().fetchActivitiesOnly(MainActivity.this, () -> {
runOnUiThread(() -> { 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 @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()); Log.e( "API", "Cambiando estado de la actividad: " + activity.getId());
AppDataRepository.getInstance().changeActivityState(MainActivity.this, activity.getId(), state, () -> { AppDataRepository.getInstance().changeActivityState(MainActivity.this, activity.getId(), state, () -> {
runOnUiThread(() -> { runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Estado de la actividad actualizado correctamente", Toast.LENGTH_SHORT).show(); AppDataRepository.getInstance().fetchActivitiesOnly( MainActivity.this, () -> {
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain)); runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Estado de la actividad actualizado correctamente", Toast.LENGTH_SHORT).show();
refresh.run();
});
});
}); });
}, () -> { }, () -> {
runOnUiThread(() -> { 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 --------------------------------------------------------------------- // --------------------------------------------------------------------- Participant Listeners ---------------------------------------------------------------------
/** /**
* * Listener para el click en el botón de añadir participante a una actividad
* @param activity * @param activity actividad a la que se quiere añadir un participante
* @param participants * @param participants lista de participantes de la actividad
* @param residents
*/ */
@Override @Override
public void onClickOnAddParticipant(Activity activity, List<ActivityResident> participants) { public void onClickOnAddParticipant(Activity activity, List<ActivityResident> participants) {
@ -581,8 +664,16 @@ public class MainActivity extends AppCompatActivity implements
} }
/** /**
* * Listener para el click en el botón de añadir participante desde el fragmento de actividades
* @param participant */
@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 @Override
public void onClickOnParticipant(ActivityResident participant) { public void onClickOnParticipant(ActivityResident participant) {
@ -594,16 +685,17 @@ public class MainActivity extends AppCompatActivity implements
} }
/** /**
* * Listener para el click en el botón de asistencia de un participante
* @param participant * @param participant participante sobre el que se ha hecho click
* @param assistance * @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 @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, () -> { AppDataRepository.getInstance().updateAssistance(MainActivity.this, participant.getActivityId(), participant.getId(), assistance, () -> {
runOnUiThread(() -> { runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Asistencia actualizada correctamente", Toast.LENGTH_SHORT).show(); Toast.makeText(MainActivity.this, "Asistencia actualizada correctamente", Toast.LENGTH_SHORT).show();
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain)); refresh.run();
}); });
}, () -> { }, () -> {
runOnUiThread(() -> { runOnUiThread(() -> {
@ -613,9 +705,9 @@ public class MainActivity extends AppCompatActivity implements
} }
/** /**
* * Listener para el click en el botón de opinión de un participante
* @param participant * @param participant participante sobre el que se ha hecho click
* @param isPreOpinion * @param isPreOpinion indica si es una opinión previa o posterior a la actividad
*/ */
@Override @Override
public void onClickOnOpinion(ActivityResident participant, boolean isPreOpinion) { public void onClickOnOpinion(ActivityResident participant, boolean isPreOpinion) {
@ -628,17 +720,19 @@ public class MainActivity extends AppCompatActivity implements
} }
/** /**
* * Listener para el envío de la opinión de un participante
* @param participant * @param participant participante al que se le añade la opinión
* @param isPreOpinion * @param isPreOpinion indica si es una opinión previa o posterior a la actividad
* @param opinion * @param opinion opinión a añadir
*/ */
@Override @Override
public void onAddOpinion(ActivityResident participant ,boolean isPreOpinion, String opinion) { public void onAddOpinion(ActivityResident participant ,boolean isPreOpinion, String opinion) {
AppDataRepository.getInstance().updateOpinion( MainActivity.this, participant.getActivityId(), participant.getId(), isPreOpinion, opinion, () -> { AppDataRepository.getInstance().updateOpinion( MainActivity.this, participant.getActivityId(), participant.getId(), isPreOpinion, opinion, () -> {
runOnUiThread(() -> { runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Opinión actualizada correctamente", Toast.LENGTH_SHORT).show(); Toast.makeText(MainActivity.this, "Opinión actualizada correctamente", Toast.LENGTH_SHORT).show();
reloadFragment(lastFragment); if (lastFragment instanceof ActivityDetailFragment)
((ActivityDetailFragment) lastFragment).updateData();
loadFragment(lastFragment);
}); });
}, () -> { }, () -> {
runOnUiThread(() -> { runOnUiThread(() -> {
@ -648,16 +742,17 @@ public class MainActivity extends AppCompatActivity implements
} }
/** /**
* * Listener para el click en el botón de ayuda material de un participante
* @param participant * @param participant participante sobre el que se ha hecho click
* @param materialHelp * @param materialHelp indica si el participante necesita ayuda material
* @param refresh Runnable para refrescar la vista después de actualizar la ayuda material
*/ */
@Override @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, () -> { AppDataRepository.getInstance().updateMaterialHelp( MainActivity.this, participant.getActivityId(), participant.getId(), materialHelp, () -> {
runOnUiThread(() -> { runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Ayuda material actualizada correctamente", Toast.LENGTH_SHORT).show(); Toast.makeText(MainActivity.this, "Ayuda material actualizada correctamente", Toast.LENGTH_SHORT).show();
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain)); refresh.run();
}); });
}, () -> { }, () -> {
runOnUiThread(() -> { runOnUiThread(() -> {
@ -667,16 +762,17 @@ public class MainActivity extends AppCompatActivity implements
} }
/** /**
* * Listener para el click en el botón de ayuda humana de un participante
* @param participant * @param participant participante sobre el que se ha hecho click
* @param humanHelp * @param humanHelp indica si el participante necesita ayuda humana
* @param refresh Runnable para refrescar la vista después de actualizar la ayuda humana
*/ */
@Override @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, () -> { AppDataRepository.getInstance().updateHumanHelp(MainActivity.this, participant.getActivityId(), participant.getId(), humanHelp, () -> {
runOnUiThread(() -> { runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Ayuda humana actualizada correctamente", Toast.LENGTH_SHORT).show(); Toast.makeText(MainActivity.this, "Ayuda humana actualizada correctamente", Toast.LENGTH_SHORT).show();
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain)); refresh.run();
}); });
}, () -> { }, () -> {
runOnUiThread(() -> { runOnUiThread(() -> {
@ -686,10 +782,29 @@ public class MainActivity extends AppCompatActivity implements
} }
/** /**
* * Listener para el click en el botón de eliminar participante
* @param activity * @param participant participante que se quiere eliminar
* @param participants * @param refresh Runnable para refrescar la vista después de eliminar el participante
* @param selectedResident */
@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 @Override
public void onParticipantSelected(Activity activity, List<ActivityResident> participants ,Resident selectedResident) { 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(), () -> { AppDataRepository.getInstance().addParticipant( MainActivity.this, activity.getId(), selectedResident.getId(), () -> {
runOnUiThread(() -> { runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Participante añadido correctamente", Toast.LENGTH_SHORT).show(); 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(() -> { 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 @Override
public void OnResidenceButtonClicked() { public void OnResidenceButtonClicked() {
@ -731,71 +863,27 @@ public class MainActivity extends AppCompatActivity implements
} }
@Override @Override
public void onClickOnBackButton() { public void onChangePassword(String currentPassword, String newPassword) {
Log.e( "API", "Back button clicked, reloading last fragment: " + (lastFragment != null ? lastFragment.getClass().getSimpleName() : "null")); AppDataRepository.getInstance().changePassword( MainActivity.this, currentPassword, newPassword, () -> {
reloadFragment(lastFragment);
}
@Override
public void onRefreshActivityDetail() {
AppDataRepository.getInstance().fetchActivitiesOnly( MainActivity.this, () -> {
runOnUiThread(() -> { runOnUiThread(() -> {
AppDataRepository.getInstance().fetchParticipantsOnly( MainActivity.this, () -> { SharedPreferences.Editor editor = SecurePreferencesUtil.getEncryptedPrefs(MainActivity.this).edit();
runOnUiThread(() -> { editor.putString("password", newPassword);
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain)); Toast.makeText(MainActivity.this, "Contraseña cambiada correctamente", Toast.LENGTH_SHORT).show();
}); loadFragment(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));
}); });
}, () -> { }, () -> {
runOnUiThread(() -> { 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 @Override
public void onRefreshParticipantDetail() { public void onRefreshResidenceDetail(Runnable refresh) {
AppDataRepository.getInstance().fetchParticipantsOnly( MainActivity.this, () -> {
runOnUiThread(() -> {
reloadFragment(getSupportFragmentManager().findFragmentById(R.id.fcvMain));
});
});
}
@Override
public void onRefreshResidenceDetail() {
AppDataRepository.getInstance().fetchResidenceOnly( MainActivity.this, () -> { AppDataRepository.getInstance().fetchResidenceOnly( MainActivity.this, () -> {
runOnUiThread(() -> { runOnUiThread(() -> {
AppDataRepository.getInstance().fetchResidentsOnly(MainActivity.this, () -> { AppDataRepository.getInstance().fetchResidentsOnly(MainActivity.this, () -> {
@ -806,7 +894,7 @@ public class MainActivity extends AppCompatActivity implements
runOnUiThread(() -> { runOnUiThread(() -> {
AppDataRepository.getInstance().fetchGameStatsOnly( MainActivity.this, () -> { AppDataRepository.getInstance().fetchGameStatsOnly( MainActivity.this, () -> {
runOnUiThread(() -> { 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 @Override
public void onAddResidentFormSubmitted(String nombre, String apellido, LocalDate fechaNacimiento, String documentoIdentidad, String familiar1, String familiar2, int year, int month) { public void onClickOnBackButton() {
AppDataRepository.getInstance().addResident( MainActivity.this, nombre, apellido, fechaNacimiento, documentoIdentidad, familiar1, familiar2, year, month, () -> { 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(() -> { runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Residente añadido correctamente", Toast.LENGTH_SHORT).show(); refresh.run();
reloadFragment(lastFragment);
}); });
}, () -> { }, () -> {
runOnUiThread(() -> { 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.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -30,18 +32,24 @@ public class AccountFragment extends Fragment {
private Button residenceButton; private Button residenceButton;
private Button languageButton; private Button languageButton;
private Button logOutButton; private Button logOutButton;
private Button toggleChangePasswordButton;
private Button confirmChangePasswordButton;
private LinearLayout passwordChangeLayout;
private EditText etCurrentPassword, etNewPassword;
private IOAccountFragmentListener accountFragmentListener; private IOAccountFragmentListener accountFragmentListener;
public interface IOAccountFragmentListener { public interface IOAccountFragmentListener {
void OnResidenceButtonClicked(); void OnResidenceButtonClicked();
void onLanguageSelected(String selectedLanguageCode); void onLanguageSelected(String selectedLanguageCode);
void onLogOutButtonClicked(); void onLogOutButtonClicked();
void onChangePassword(String currentPassword, String newPassword);
} }
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_account, container,false); return inflater.inflate(R.layout.fragment_account, container, false);
} }
@Override @Override
@ -52,7 +60,6 @@ public class AccountFragment extends Fragment {
statusBar.setBackgroundColor(Color.parseColor("#0062FF")); statusBar.setBackgroundColor(Color.parseColor("#0062FF"));
userCardView = view.findViewById(R.id.account_card_view); userCardView = view.findViewById(R.id.account_card_view);
userCardView.findViewById(R.id.back_button).setVisibility(View.GONE); userCardView.findViewById(R.id.back_button).setVisibility(View.GONE);
userNameTextView = userCardView.findViewById(R.id.banner_name_game); userNameTextView = userCardView.findViewById(R.id.banner_name_game);
@ -62,12 +69,7 @@ public class AccountFragment extends Fragment {
userImageView.setImageBitmap(userImage); userImageView.setImageBitmap(userImage);
residenceButton = view.findViewById(R.id.residence_button_account); residenceButton = view.findViewById(R.id.residence_button_account);
residenceButton.setOnClickListener(new View.OnClickListener() { residenceButton.setOnClickListener(v -> accountFragmentListener.OnResidenceButtonClicked());
@Override
public void onClick(View v) {
accountFragmentListener.OnResidenceButtonClicked();
}
});
languageButton = view.findViewById(R.id.btn_idioma); languageButton = view.findViewById(R.id.btn_idioma);
languageButton.setOnClickListener(v -> { languageButton.setOnClickListener(v -> {
@ -87,30 +89,52 @@ public class AccountFragment extends Fragment {
.show(); .show();
}); });
// Botón cerrar sesión
logOutButton = view.findViewById(R.id.btn_cerrar_sesion); logOutButton = view.findViewById(R.id.btn_cerrar_sesion);
logOutButton.setOnClickListener(new View.OnClickListener() { logOutButton.setOnClickListener(v -> {
@Override new AlertDialog.Builder(getContext())
public void onClick(View v) { .setTitle(getString(R.string.logout_title))
new AlertDialog.Builder(getContext()) .setMessage(getString(R.string.confirm_logout_message))
.setTitle(getString(R.string.logout_title)) .setPositiveButton(getString(R.string.accept_text), (dialog, which) -> {
.setMessage(getString(R.string.confirm_logout_message)) accountFragmentListener.onLogOutButtonClicked();
.setPositiveButton( getString(R.string.accept_text), (dialog, which) -> { })
accountFragmentListener.onLogOutButtonClicked(); .setNegativeButton(getString(R.string.cancel_text), (dialog, which) -> dialog.dismiss())
}) .show();
.setNegativeButton(getString(R.string.cancel_text), (dialog, which) -> { });
dialog.dismiss();
}) toggleChangePasswordButton = view.findViewById(R.id.btn_toggle_password_change);
.show(); 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 @Override
public void onAttach(@NonNull Context context) { public void onAttach(@NonNull Context context) {
super.onAttach(context); super.onAttach(context);
accountFragmentListener = (IOAccountFragmentListener) context; accountFragmentListener = (IOAccountFragmentListener) context;
} }
} }

View File

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

View File

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

View File

@ -41,7 +41,7 @@ public class ParticipantDetailFragment extends Fragment {
private List<Activity> activities; private List<Activity> activities;
public interface IOnRefreshParticipantDetailListener { public interface IOnRefreshParticipantDetailListener {
void onRefreshParticipantDetail(); void onRefreshParticipantDetail(Runnable refresh);
} }
private IOnRefreshParticipantDetailListener refreshParticipantDetailListener; private IOnRefreshParticipantDetailListener refreshParticipantDetailListener;
@ -65,7 +65,7 @@ public class ParticipantDetailFragment extends Fragment {
SwipeRefreshLayout swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_participant_detail); SwipeRefreshLayout swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_participant_detail);
swipeRefreshLayout.setOnRefreshListener(() -> { swipeRefreshLayout.setOnRefreshListener(() -> {
refreshParticipantDetailListener.onRefreshParticipantDetail(); refreshParticipantDetailListener.onRefreshParticipantDetail(this::updateData);
swipeRefreshLayout.setRefreshing(false); swipeRefreshLayout.setRefreshing(false);
}); });
@ -118,6 +118,11 @@ public class ParticipantDetailFragment extends Fragment {
} }
private void updateData(){
residents = AppDataRepository.getInstance().getResidents();
activities = AppDataRepository.getInstance().getActivities();
}
@Override @Override
public void onAttach(@NonNull Context context) { public void onAttach(@NonNull Context context) {
super.onAttach(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.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -37,17 +38,21 @@ public class GameFragment extends Fragment {
private Game game; private Game game;
public interface IOnRefreshGameListener { public interface IOnRefreshGameListener {
void onRefreshGameStats(); void onRefreshGameStats(Runnable refresh);
} }
private IOnRefreshGameListener refreshGameListener; private IOnRefreshGameListener refreshGameListener;
private IOnClickOnBackButtonListener backButtonListener; private IOnClickOnBackButtonListener backButtonListener;
private TextView gameNameTextView; private TextView gameNameTextView;
private ImageView gameImageView;
private TextView numberOfGamesLastWeekTextView; private TextView numberOfGamesLastWeekTextView;
private TextView totalGamesPlayedTextView; private TextView totalGamesPlayedTextView;
private TextView topPlayerTextView; private TextView topPlayerTextView;
private ImageButton backButton; private ImageButton backButton;
private LastGamesAdapter lastGamesAdapter;
private RecyclerView recyclerView;
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
@ -62,6 +67,7 @@ public class GameFragment extends Fragment {
statusBar.setBackgroundColor(Color.parseColor("#0062FF")); statusBar.setBackgroundColor(Color.parseColor("#0062FF"));
gameNameTextView = view.findViewById(R.id.banner_name_game); 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); numberOfGamesLastWeekTextView = view.findViewById(R.id.tv_number_of_games_last_week);
totalGamesPlayedTextView = view.findViewById(R.id.tv_total_games_played); totalGamesPlayedTextView = view.findViewById(R.id.tv_total_games_played);
topPlayerTextView = view.findViewById(R.id.tv_top_jugador); 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 swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_game);
swipeRefreshLayout.setOnRefreshListener(() -> { swipeRefreshLayout.setOnRefreshListener(() -> {
refreshGameListener.onRefreshGameStats(); refreshGameListener.onRefreshGameStats(this::refreshData);
swipeRefreshLayout.setRefreshing(false); 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()) { if (allGameStats.isEmpty()) {
numberOfGamesLastWeekTextView.setText("-"); numberOfGamesLastWeekTextView.setText("-");
@ -100,15 +113,45 @@ public class GameFragment extends Fragment {
numberOfGamesLastWeekTextView.setText(String.valueOf(numberOfGamesLastWeek)); numberOfGamesLastWeekTextView.setText(String.valueOf(numberOfGamesLastWeek));
totalGamesPlayedTextView.setText(String.valueOf(allGameStats.size())); totalGamesPlayedTextView.setText(String.valueOf(allGameStats.size()));
Resident topResident = getTopResident(allGameStats, residents); Resident topResident = getTopResident(allGameStats, residents);
topPlayerTextView.setText(topResident.getName()); topPlayerTextView.setText(topResident.getName() + " " + topResident.getSurnames());
LastGamesAdapter lastGamesAdapter = new LastGamesAdapter(allGameStats, game, residents, (IOClickOnGameStatsListener) requireActivity()); lastGamesAdapter = new LastGamesAdapter(allGameStats, game, residents, (IOClickOnGameStatsListener) requireActivity(), () -> {
RecyclerView recyclerView = view.findViewById(R.id.rv_game_stats); refreshData();
});
recyclerView = view.findViewById(R.id.rv_game_stats);
recyclerView.setAdapter( lastGamesAdapter ); recyclerView.setAdapter( lastGamesAdapter );
recyclerView.setHasFixedSize(true); recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false)); 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) { private int getGamesLastWeek(List<GameStat> allGameStats) {
int count = 0; int count = 0;
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();

View File

@ -1,6 +1,7 @@
package com.andresgmoran.apptrabajadores.ui.fragments.gameDetail; package com.andresgmoran.apptrabajadores.ui.fragments.gameDetail;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color; import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -9,6 +10,7 @@ import android.view.ViewGroup;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; 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.Game;
import com.andresgmoran.apptrabajadores.models.Resident; import com.andresgmoran.apptrabajadores.models.Resident;
import com.andresgmoran.apptrabajadores.models.User; import com.andresgmoran.apptrabajadores.models.User;
import com.andresgmoran.apptrabajadores.models.gameStats.Difficulty;
import com.andresgmoran.apptrabajadores.models.gameStats.GameStat; import com.andresgmoran.apptrabajadores.models.gameStats.GameStat;
import com.andresgmoran.apptrabajadores.repository.AppDataRepository; import com.andresgmoran.apptrabajadores.repository.AppDataRepository;
import com.andresgmoran.apptrabajadores.ui.MainActivity; import com.andresgmoran.apptrabajadores.ui.MainActivity;
@ -30,10 +33,10 @@ import java.util.List;
public class GameDetailFragment extends Fragment { public class GameDetailFragment extends Fragment {
public interface IOnAddObservationListener { public interface IOnAddObservationListener {
void onAddObservation(String observation, long gameId, long gameStatId); void onAddObservation(String observation, long gameId, long gameStatId, Runnable refresh);
} }
public interface IOnRefreshGameStatsListener { public interface IOnRefreshGameStatsListener {
void onRefreshGameStats(); void onRefreshGameStats(Runnable runnable);
} }
private IOnRefreshGameStatsListener refreshGameStatsListener; private IOnRefreshGameStatsListener refreshGameStatsListener;
private IOnAddObservationListener addObservationListener; private IOnAddObservationListener addObservationListener;
@ -43,11 +46,13 @@ public class GameDetailFragment extends Fragment {
private Resident gameStatResident; private Resident gameStatResident;
private Game gameStatGame; private Game gameStatGame;
private User actualUser = AppDataRepository.getInstance().getActualUser(); private User actualUser = AppDataRepository.getInstance().getActualUser();
private Bitmap actualUserImage = AppDataRepository.getInstance().getActualUserImage();
private List<User> users = AppDataRepository.getInstance().getUsers(); private List<User> users = AppDataRepository.getInstance().getUsers();
private TextView residentNameTextView; private TextView residentNameTextView;
private TextView gameNameTextView; private TextView gameNameTextView;
private TextView durationTextView; private TextView durationTextView;
private TextView levelTextView;
private TextView failsTitle; private TextView failsTitle;
private TextView failsTextView; private TextView failsTextView;
private ImageButton backButton; private ImageButton backButton;
@ -68,7 +73,7 @@ public class GameDetailFragment extends Fragment {
SwipeRefreshLayout swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_game_detail); SwipeRefreshLayout swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_game_detail);
swipeRefreshLayout.setOnRefreshListener(() -> { swipeRefreshLayout.setOnRefreshListener(() -> {
refreshGameStatsListener.onRefreshGameStats(); refreshGameStatsListener.onRefreshGameStats(this::updateData);
swipeRefreshLayout.setRefreshing(false); swipeRefreshLayout.setRefreshing(false);
}); });
@ -80,11 +85,20 @@ public class GameDetailFragment extends Fragment {
residentNameTextView = view.findViewById(R.id.banner_name_resident); residentNameTextView = view.findViewById(R.id.banner_name_resident);
gameNameTextView = view.findViewById(R.id.game_stats_detail_game_name); gameNameTextView = view.findViewById(R.id.game_stats_detail_game_name);
durationTextView = view.findViewById(R.id.tv_duration); durationTextView = view.findViewById(R.id.tv_duration);
levelTextView = view.findViewById(R.id.tv_level);
failsTitle = view.findViewById(R.id.label_fails); failsTitle = view.findViewById(R.id.label_fails);
failsTextView = view.findViewById(R.id.tv_fails); failsTextView = view.findViewById(R.id.tv_fails);
residentNameTextView.setText(gameStatResident.getName() + " " + gameStatResident.getSurnames()); 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"); durationTextView.setText(Math.round(gameStat.getDuration()) + " seg");
if (gameStatGame.getName().equals("bingo auditivo") || gameStatGame.getName().equals("flecha y reacciona")) { 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) { if (gameStat.getNum() == 0) {
failsTextView.setText("PERDIDO"); failsTextView.setText("PERDIDO");
} else { } else {
failsTextView.setText("GANADO"); failsTextView.setText("GANADA");
} }
} else if (gameStatGame.getName().equals("gimnasio")){
failsTitle.setVisibility( View.GONE);
failsTextView.setVisibility( View.GONE);
} else { } else {
failsTextView.setText(gameStat.getNum() + " fallos"); failsTitle.setText("Fallos");
failsTextView.setText(String.valueOf(gameStat.getNum()));
} }
View observation = view.findViewById(R.id.observation); 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 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); TextView observationText = observation.findViewById(R.id.observation_text);
EditText observationEditText = observation.findViewById(R.id.observation_input); EditText observationEditText = observation.findViewById(R.id.observation_input);
@ -109,7 +128,7 @@ public class GameDetailFragment extends Fragment {
for (User user : users) { for (User user : users) {
if (user.getId() == gameStat.getUserId()) { if (user.getId() == gameStat.getUserId()) {
observationUserName.setText(actualUser.getName()); observationUserName.setText(actualUser.getName() + " " + actualUser.getSurnames());
break; break;
} }
} }
@ -121,20 +140,43 @@ public class GameDetailFragment extends Fragment {
addObservationButton.setOnClickListener(new View.OnClickListener() { addObservationButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { 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 { } 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 { } else {
observationText.setVisibility(View.VISIBLE); observationText.setVisibility(View.VISIBLE);
//Añadir rol usuario
observationText.setText(gameStat.getObservation()); 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 @Override
public void onAttach(@NonNull Context context) { public void onAttach(@NonNull Context context) {
super.onAttach(context); super.onAttach(context);

View File

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

View File

@ -51,7 +51,7 @@ public class ResidenceDetailFragment extends Fragment {
private List<Game> games; private List<Game> games;
public interface IOnRefreshResidenceDetailListener { public interface IOnRefreshResidenceDetailListener {
void onRefreshResidenceDetail(); void onRefreshResidenceDetail(Runnable refresh);
} }
private IOnRefreshResidenceDetailListener refreshListener; 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() { private void updateUI() {
if (residence != null) { if (residence != null) {
residenceNameTextView.setText(residence.getName()); residenceNameTextView.setText(residence.getName());
@ -119,7 +131,7 @@ public class ResidenceDetailFragment extends Fragment {
private void setupSwipeRefresh(View view) { private void setupSwipeRefresh(View view) {
SwipeRefreshLayout swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_residence_detail); SwipeRefreshLayout swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_residence_detail);
swipeRefreshLayout.setOnRefreshListener(() -> { swipeRefreshLayout.setOnRefreshListener(() -> {
refreshListener.onRefreshResidenceDetail(); refreshListener.onRefreshResidenceDetail(this::updateData);
swipeRefreshLayout.setRefreshing(false); swipeRefreshLayout.setRefreshing(false);
}); });
} }
@ -172,7 +184,8 @@ public class ResidenceDetailFragment extends Fragment {
String nombreJuego = ""; String nombreJuego = "";
for (Game g : games) { for (Game g : games) {
if (g.getId().equals(entry.getKey())) { if (g.getId().equals(entry.getKey())) {
nombreJuego = g.getName(); String name = g.getName();
nombreJuego = name.substring(0, 1).toUpperCase() + name.substring(1);
break; break;
} }
} }
@ -235,7 +248,8 @@ public class ResidenceDetailFragment extends Fragment {
String nombreJuego = ""; String nombreJuego = "";
for (Game g : games) { for (Game g : games) {
if (g.getId().equals(entry.getKey())) { if (g.getId().equals(entry.getKey())) {
nombreJuego = g.getName(); String name = g.getName();
nombreJuego = name.substring(0, 1).toUpperCase() + name.substring(1);
break; break;
} }
} }

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -5,6 +5,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="#CCCCCC"> android:background="#CCCCCC">
<!-- Tarjeta de usuario -->
<include <include
android:id="@+id/account_card_view" android:id="@+id/account_card_view"
layout="@layout/item_person_banner" layout="@layout/item_person_banner"
@ -14,6 +15,7 @@
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent" /> app:layout_constraintEnd_toEndOf="parent" />
<!-- Sección de destacados -->
<TextView <TextView
android:id="@+id/label_highlights" android:id="@+id/label_highlights"
android:layout_width="0dp" android:layout_width="0dp"
@ -44,6 +46,7 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" /> app:layout_constraintEnd_toEndOf="parent" />
<!-- Preferencias -->
<TextView <TextView
android:id="@+id/label_preferences" android:id="@+id/label_preferences"
android:layout_width="0dp" android:layout_width="0dp"
@ -58,6 +61,7 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" /> app:layout_constraintEnd_toEndOf="parent" />
<!-- Botón idioma -->
<Button <Button
android:id="@+id/btn_idioma" android:id="@+id/btn_idioma"
android:layout_width="0dp" android:layout_width="0dp"
@ -73,6 +77,60 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="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 <Button
android:id="@+id/btn_cerrar_sesion" android:id="@+id/btn_cerrar_sesion"
android:layout_width="0dp" android:layout_width="0dp"
@ -83,7 +141,7 @@
android:text="@string/logout_title" android:text="@string/logout_title"
android:textAllCaps="false" android:textAllCaps="false"
android:textColor="#324F5E" 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_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" /> app:layout_constraintEnd_toEndOf="parent" />

View File

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

View File

@ -40,7 +40,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:backgroundTint="#00AF4848" android:backgroundTint="#00AF4848"
android:text="@string/select_date_text" android:text="@string/select_datetime_text"
android:textAlignment="viewStart" android:textAlignment="viewStart"
android:textColor="#324F5E" android:textColor="#324F5E"
android:textColorLink="#6CADFF" 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 --> <!-- Avatar + texto -->
<com.google.android.material.imageview.ShapeableImageView <com.google.android.material.imageview.ShapeableImageView
android:id="@+id/circularImageView" android:id="@+id/game_image"
android:layout_width="80dp" android:layout_width="80dp"
android:layout_height="80dp" android:layout_height="80dp"
android:layout_marginStart="20dp" android:layout_marginStart="20dp"
@ -61,9 +61,9 @@
android:fontFamily="@font/assistant_bold" android:fontFamily="@font/assistant_bold"
android:textColor="@android:color/white" android:textColor="@android:color/white"
android:textSize="24sp" android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="@+id/circularImageView" app:layout_constraintBottom_toBottomOf="@+id/game_image"
app:layout_constraintStart_toEndOf="@+id/circularImageView" app:layout_constraintStart_toEndOf="@+id/game_image"
app:layout_constraintTop_toTopOf="@+id/circularImageView" /> app:layout_constraintTop_toTopOf="@+id/game_image" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

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

View File

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

View File

@ -33,6 +33,7 @@
android:fontFamily="@font/assistant_bold" android:fontFamily="@font/assistant_bold"
android:text="Iglesia de Benissa" android:text="Iglesia de Benissa"
android:textColor="#F4F4F4" android:textColor="#F4F4F4"
android:textSize="20sp"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textview_salida" /> 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_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:shapeAppearanceOverlay="@style/CircularShapeAppearance" app:shapeAppearanceOverlay="@style/CircularShapeAppearance"
app:srcCompat="@drawable/woman_avatar" /> app:srcCompat="@drawable/default_resident_image" />
<TextView <TextView
android:id="@+id/name_text_latestGameItem" android:id="@+id/name_text_latestGameItem"

View File

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

View File

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

View File

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

View File

@ -2,6 +2,7 @@
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:app="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_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
card_view:cardCornerRadius="12dp" card_view:cardCornerRadius="12dp"
@ -39,6 +40,15 @@
app:layout_constraintStart_toEndOf="@id/profile_image" app:layout_constraintStart_toEndOf="@id/profile_image"
app:layout_constraintTop_toTopOf="@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 <ImageButton
android:id="@+id/participant_asistencia_button" android:id="@+id/participant_asistencia_button"
android:layout_width="48dp" android:layout_width="48dp"
@ -99,7 +109,6 @@
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginTop="12dp"/> android:layout_marginTop="12dp"/>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView> </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="filter_activities_title">Filtrar actividades</string>
<string name="activity_title">Actividad</string> <string name="activity_title">Actividad</string>
<string name="account_detail">Cuenta</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> </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, "hide_selection": false,
"select_mode": 0 "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] [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")] 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")] 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_snap_active": false,
"grid_step": Vector2(8, 8), "grid_step": Vector2(8, 8),
"grid_visibility": 1, "grid_visibility": 1,
"ofs": Vector2(-834.841, -190.963), "ofs": Vector2(-770.151, -78.3636),
"primary_grid_step": Vector2i(8, 8), "primary_grid_step": Vector2i(8, 8),
"show_group_gizmos": true, "show_group_gizmos": true,
"show_guides": true, "show_guides": true,
@ -192,4 +192,4 @@ Game={
"hide_selection": false, "hide_selection": false,
"select_mode": 0 "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 TextureRect
AudioStreamPlayer2D AudioStreamPlayer2D
Label Label
MarginContainer
CenterContainer CenterContainer
Button Button
VBoxContainer VBoxContainer

View File

@ -5,18 +5,18 @@ dock_4_selected_tab_idx=0
dock_5_selected_tab_idx=0 dock_5_selected_tab_idx=0
dock_floating={} dock_floating={}
dock_filesystem_h_split_offset=240 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_display_mode=0
dock_filesystem_file_sort=0 dock_filesystem_file_sort=0
dock_filesystem_file_list_display_mode=1 dock_filesystem_file_list_display_mode=1
dock_filesystem_selected_paths=PackedStringArray() dock_filesystem_selected_paths=PackedStringArray("res://scripts/scene_manager.gd")
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_uncollapsed_paths=PackedStringArray("Favorites", "res://", "res://scripts/", "res://scenes/")
dock_node_current_tab=0 dock_node_current_tab=0
dock_history_include_scene=true dock_history_include_scene=true
dock_history_include_global=true dock_history_include_global=true
dock_bottom=[] dock_bottom=[]
dock_closed=[] dock_closed=[]
dock_split_2=-92 dock_split_2=-142
dock_split_3=0 dock_split_3=0
dock_hsplit_1=0 dock_hsplit_1=0
dock_hsplit_2=270 dock_hsplit_2=270
@ -43,12 +43,12 @@ position=Vector2i(0, 23)
[ScriptEditor] [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"] 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/app_constants.gd" selected_script="res://scripts/game_data.gd"
open_help=[] open_help=[]
script_split_offset=250 script_split_offset=250
list_split_offset=0 list_split_offset=0
zoom_factor=1.14286 zoom_factor=1.0
[GameView] [GameView]

View File

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

View File

@ -1,8 +1,7 @@
fc8a56933c4b1c8d796fdb8f7a9f9475 fc8a56933c4b1c8d796fdb8f7a9f9475
::res://::1748128390 ::res://::1748545681
export_presets.cfg::TextFile/TextFile::-1::1748128390::0::1::::<><><>0<>0<><>:: 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:: 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 ::res://assets/::1747852892
back_button.png::CompressedTexture2D/CompressedTexture2D::2132119402147635853::1747694589::1747694590::1::::<><><>0<>0<>306f7421656b646a3d66454298c8e40f<>res://.godot/imported/back_button.png-ba49f75b53a9c1f509214b23d27cc2b4.ctex:: 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:: 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:: 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:: 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:: 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:: 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:: 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:: 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:: 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 ::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:: 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_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:: zorro_sombra.png::CompressedTexture2D/CompressedTexture2D::6252548807644359177::1744226356::1747403007::1::::<><><>0<>0<>9c2cf80619a760076607a150050b8ce8<>res://.godot/imported/zorro_sombra.png-f45f9573d10a222e8a5fc95e53c57fa0.ctex::
::res://images/logos/::1748128298 ::res://images/logos/::1748286697
logo_bingo_auditivo.jpg::CompressedTexture2D/CompressedTexture2D::2684211223156084402::1747700426::1747700426::1::::<><><>0<>0<>539a5dff78bee0e4cf4a4103cf9afa8b<>res://.godot/imported/logo_bingo_auditivo.jpg-03bdf8ad732b66a85cf2c9b04f150e8f.ctex:: 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.jpg::CompressedTexture2D/CompressedTexture2D::1304789213788847404::1747700426::1747700426::1::::<><><>0<>0<>af932ef37111d1fb1189b2e9efdfcf9c<>res://.godot/imported/logo_emparejar_las_sombras.jpg-76d99c8ef0c28ec4cd7c7c5c902c6c62.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.jpg::CompressedTexture2D/CompressedTexture2D::1741424296729248422::1747700426::1747700426::1::::<><><>0<>0<>e5132acc60bb8942ddb5d53f390494bd<>res://.godot/imported/logo_flecha_y_reacciona.jpg-3b637c92f0fd164adec036d673be209a.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.jpg::CompressedTexture2D/CompressedTexture2D::7269953945927652778::1747700426::1747700426::1::::<><><>0<>0<>b865210b4a91a83995039388a12db30b<>res://.godot/imported/logo_gimnasio.jpg-32d1be7a1c501ae50b3f9b8e51f9b26f.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.jpg::CompressedTexture2D/CompressedTexture2D::3712652532896905776::1747700426::1747700426::1::::<><><>0<>0<>e37728575d6c225b9ce3598d1e909817<>res://.godot/imported/logo_seguir_la_linea.jpg-b143778eeffde4affe6ad2bc4b8d2213.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/::1748128312 ::res://scenes/::1748529123
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 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/::1747852435 ::res://scenes/bingo_auditivo/::1748287448
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 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/::1747852370 ::res://scenes/emparejar_las_sombras/::1748364213
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 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/::1747852368 ::res://scenes/flecha_y_reacciona/::1748287448
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 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/::1747852367 ::res://scenes/gimnasio/::1748287448
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 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/::1747852365 ::res://scenes/seguir_la_linea/::1748287448
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 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/::1748117033 ::res://scripts/::1748529123
app_constants.gd::GDScript/GDScript::3537533678312647870::1748117032::0::1::::<>Node<><>0<>0<><>:: app_constants.gd::GDScript::3537533678312647870::1748529123::0::1::::<>Node<><>0<>0<><>::
game_data.gd::GDScript/GDScript::4985019478966635616::1748117032::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<><>:: home.gd::GDScript/GDScript::5618272075595688803::1747849655::0::1::::<>Control<><>0<>0<><>::
image_loader.gd::GDScript/GDScript::611758767551863186::1747403452::0::1::::<>Node<><>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<><>:: scene_manager.gd::GDScript/GDScript::2049891027188034232::1747403452::0::1::::<>Node<><>0<>0<><>::
::res://scripts/bingo_auditivo/::1747837163 ::res://scripts/bingo_auditivo/::1748357418
configuration_bingo.gd::GDScript/GDScript::10065919189713686::1747837163::0::1::::<>Window<><>0<>0<><>:: configuration_bingo.gd::GDScript/GDScript::10065919189713686::1748357418::0::1::::<>Window<><>0<>0<><>::
game_bingo.gd::GDScript/GDScript::7684413599682033952::1747835483::0::1::::<>Control<><>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<><>:: 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<><>:: configuration_emparejar_las_sombras.gd::GDScript/GDScript::6119112016534423576::1748357152::0::1::::<>Window<><>0<>0<><>::
game_emparejar_las_sombras.gd::GDScript/GDScript::1511295973206308651::1747777885::0::1::::<>Control<><>0<>0<><>:: game_emparejar_las_sombras.gd::GDScript/GDScript::1511295973206308651::1748360951::0::1::::<>Control<><>0<>0<><>::
::res://scripts/flecha_y_reacciona/::1747851840 ::res://scripts/flecha_y_reacciona/::1747851840
configuration_f_y_r.gd::GDScript/GDScript::8259793138334191281::1747851840::0::1::::<>Window<><>0<>0<><>:: 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<><>:: game_flecha_y_reacciona.gd::GDScript/GDScript::7937313450958682526::1747849655::0::1::::<>Control<><>0<>0<><>::
::res://scripts/gimnasio/::1747840227 ::res://scripts/gimnasio/::1748357460
configuration_gym.gd::GDScript/GDScript::7747367763046715191::1747838928::0::1::::<>Window<><>0<>0<><>:: configuration_gym.gd::GDScript/GDScript::7747367763046715191::1748357460::0::1::::<>Window<><>0<>0<><>::
game_gym.gd::GDScript/GDScript::6585969178415297357::1747840227::0::1::::<>Control<><>0<>0<><>:: game_gym.gd::GDScript/GDScript::6585969178415297357::1747840227::0::1::::<>Control<><>0<>0<><>::
::res://scripts/seguir_la_linea/::1747842068 ::res://scripts/seguir_la_linea/::1748357204
configuration_seguir_la_linea.gd::GDScript/GDScript::1198400142142721223::1747842068::0::1::::<>Window<><>0<>0<><>:: 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<><>:: 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/::1747571283
::res://videos/gimnasio/::1747571294 ::res://videos/gimnasio/::1747571294
1_marcha.ogv::VideoStreamTheora/VideoStreamTheora::8170332476493401942::1745338782::0::1::::<><><>0<>0<><>:: 1_marcha.ogv::VideoStreamTheora/VideoStreamTheora::8170332476493401942::1745338782::0::1::::<><><>0<>0<><>::

View File

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

View File

@ -9,8 +9,8 @@ last_selected_language="GDScript"
[recent_files] [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"] 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/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"] 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] [dialog_bounds]
@ -21,10 +21,14 @@ export=Rect2(510, 127, 921, 799)
[color_picker] [color_picker]
picker_shape=3 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 color_mode=0
[export_options] [export_options]
default_filename="ResiGames" default_filename="ResiGames"
export_debug=true 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={ state={
"bookmarks": PackedInt32Array(), "bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(), "breakpoints": PackedInt32Array(),
"column": 5, "column": 43,
"folded_lines": Array[int]([]), "folded_lines": Array[int]([]),
"h_scroll_position": 0, "h_scroll_position": 0,
"row": 160, "row": 73,
"scroll_position": 285.0, "scroll_position": 54.0,
"selection": false, "selection": false,
"syntax_highlighter": "GDScript" "syntax_highlighter": "GDScript"
} }
@ -17,16 +17,12 @@ state={
state={ state={
"bookmarks": PackedInt32Array(), "bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(), "breakpoints": PackedInt32Array(),
"column": 18, "column": 12,
"folded_lines": Array[int]([]), "folded_lines": Array[int]([]),
"h_scroll_position": 0, "h_scroll_position": 0,
"row": 1, "row": 0,
"scroll_position": 0.0, "scroll_position": 0.0,
"selection": true, "selection": false,
"selection_from_column": 4,
"selection_from_line": 1,
"selection_to_column": 18,
"selection_to_line": 1,
"syntax_highlighter": "GDScript" "syntax_highlighter": "GDScript"
} }
@ -63,11 +59,11 @@ state={
state={ state={
"bookmarks": PackedInt32Array(), "bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(), "breakpoints": PackedInt32Array(),
"column": 0, "column": 1,
"folded_lines": Array[int]([]), "folded_lines": Array[int]([]),
"h_scroll_position": 0, "h_scroll_position": 0,
"row": 0, "row": 258,
"scroll_position": 0.0, "scroll_position": 258.0,
"selection": false, "selection": false,
"syntax_highlighter": "GDScript" "syntax_highlighter": "GDScript"
} }
@ -77,11 +73,11 @@ state={
state={ state={
"bookmarks": PackedInt32Array(), "bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(), "breakpoints": PackedInt32Array(),
"column": 87, "column": 27,
"folded_lines": Array[int]([]), "folded_lines": Array[int]([]),
"h_scroll_position": 4, "h_scroll_position": 0,
"row": 43, "row": 37,
"scroll_position": 39.0, "scroll_position": 73.0,
"selection": false, "selection": false,
"syntax_highlighter": "GDScript" "syntax_highlighter": "GDScript"
} }
@ -94,8 +90,8 @@ state={
"column": 1, "column": 1,
"folded_lines": Array[int]([]), "folded_lines": Array[int]([]),
"h_scroll_position": 0, "h_scroll_position": 0,
"row": 84, "row": 92,
"scroll_position": 90.0, "scroll_position": 84.0,
"selection": false, "selection": false,
"syntax_highlighter": "GDScript" "syntax_highlighter": "GDScript"
} }
@ -105,11 +101,11 @@ state={
state={ state={
"bookmarks": PackedInt32Array(), "bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(), "breakpoints": PackedInt32Array(),
"column": 20, "column": 1,
"folded_lines": Array[int]([]), "folded_lines": Array[int]([]),
"h_scroll_position": 0, "h_scroll_position": 0,
"row": 89, "row": 193,
"scroll_position": 74.0, "scroll_position": 173.0,
"selection": false, "selection": false,
"syntax_highlighter": "GDScript" "syntax_highlighter": "GDScript"
} }
@ -137,11 +133,11 @@ state={
state={ state={
"bookmarks": PackedInt32Array(), "bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(), "breakpoints": PackedInt32Array(),
"column": 47, "column": 33,
"folded_lines": Array[int]([]), "folded_lines": Array[int]([]),
"h_scroll_position": 0, "h_scroll_position": 0,
"row": 209, "row": 244,
"scroll_position": 207.0, "scroll_position": 209.0,
"selection": false, "selection": false,
"syntax_highlighter": "GDScript" "syntax_highlighter": "GDScript"
} }
@ -165,11 +161,11 @@ state={
state={ state={
"bookmarks": PackedInt32Array(), "bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(), "breakpoints": PackedInt32Array(),
"column": 18, "column": 1,
"folded_lines": Array[int]([]), "folded_lines": Array[int]([]),
"h_scroll_position": 0, "h_scroll_position": 0,
"row": 18, "row": 114,
"scroll_position": 107.0, "scroll_position": 108.0,
"selection": false, "selection": false,
"syntax_highlighter": "GDScript" "syntax_highlighter": "GDScript"
} }
@ -207,11 +203,11 @@ state={
state={ state={
"bookmarks": PackedInt32Array(), "bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(), "breakpoints": PackedInt32Array(),
"column": 43, "column": 0,
"folded_lines": Array[int]([]), "folded_lines": Array[int]([]),
"h_scroll_position": 327, "h_scroll_position": 0,
"row": 12, "row": 208,
"scroll_position": 12.0, "scroll_position": 208.0,
"selection": false, "selection": false,
"syntax_highlighter": "GDScript" "syntax_highlighter": "GDScript"
} }
@ -221,10 +217,10 @@ state={
state={ state={
"bookmarks": PackedInt32Array(), "bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(), "breakpoints": PackedInt32Array(),
"column": 71, "column": 50,
"folded_lines": Array[int]([]), "folded_lines": Array[int]([]),
"h_scroll_position": 0, "h_scroll_position": 0,
"row": 12, "row": 5,
"scroll_position": 0.0, "scroll_position": 0.0,
"selection": false, "selection": false,
"syntax_highlighter": "GDScript" "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/bingo_auditivo/GameBingo.tscn::92f27a7f4ebc1d74d5bc4ea01261bd30::1748287448::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/emparejar_las_sombras/GameEmparejarLasSombras.tscn::db43741d34eebf94a307feea05fbd224::1748364213::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/flecha_y_reacciona/GameFlechaYReacciona.tscn::8ba63cb414babb71ec1b95cc5cfff7d2::1748287448::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/gimnasio/GameGym.tscn::c986ec4d506cd61c97c6a01d59c05805::1748287448::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/seguir_la_linea/GameSeguirLaLinea.tscn::39255dc26468f91c1354b51470436846::1748287448::res://.godot/exported/133200997/export-d5b736042ffd164b0954669ca2ec5614-GameSeguirLaLinea.scn
res://scenes/Home.tscn::42973a9671810b845f24b4c134ecf16e::1748128312::res://.godot/exported/133200997/export-20ec3a207690e015b9c115c7601d772c-Home.scn res://scenes/Home.tscn::cc3e7d9172f9a4b52af646493cf37489::1748360785::res://.godot/exported/133200997/export-20ec3a207690e015b9c115c7601d772c-Home.scn
res://menu.tres::11872ed4c8d121a05178d0a945aa2a55::1747852682::res://.godot/exported/133200997/export-6190c6dd272fa5536bd37dcd1686cacd-menu.res 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