diff --git a/app/src/main/java.zip b/app/src/main/java.zip
index 5d99493..ba60348 100644
Binary files a/app/src/main/java.zip and b/app/src/main/java.zip differ
diff --git a/app/src/main/java/com/santiparra/yomitrack/api/ApiClient.java b/app/src/main/java/com/santiparra/yomitrack/api/ApiClient.java
index 5017e9d..f659ffb 100644
--- a/app/src/main/java/com/santiparra/yomitrack/api/ApiClient.java
+++ b/app/src/main/java/com/santiparra/yomitrack/api/ApiClient.java
@@ -7,18 +7,34 @@ import retrofit2.converter.gson.GsonConverterFactory;
public class ApiClient {
+ /**
+ * URL base del servidor donde está alojada la API del backend.
+ *
Nota: "10.0.2.2" es una dirección especial utilizada para acceder al localhost
+ * del host desde el emulador de Android.
+ */
private static final String BASE_URL = "http://10.0.2.2:3000/";
+
+ /** Instancia única de Retrofit. */
private static Retrofit retrofit = null;
+ /**
+ * Devuelve una instancia de Retrofit configurada con la URL base, un cliente HTTP
+ * con un interceptor para loguear las peticiones/respuestas, y un convertidor JSON.
+ *
+ * @return una instancia única de Retrofit lista para usar con las interfaces de servicio.
+ */
public static Retrofit getClient() {
if (retrofit == null) {
+ // Interceptor para mostrar logs del cuerpo de la petición y respuesta HTTP
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
+ // Cliente HTTP personalizado con el interceptor de logging
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(logging)
.build();
+ // Construcción de la instancia de Retrofit
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
diff --git a/app/src/main/java/com/santiparra/yomitrack/api/ApiService.java b/app/src/main/java/com/santiparra/yomitrack/api/ApiService.java
index d67d525..a1a76e4 100644
--- a/app/src/main/java/com/santiparra/yomitrack/api/ApiService.java
+++ b/app/src/main/java/com/santiparra/yomitrack/api/ApiService.java
@@ -14,36 +14,58 @@ import com.santiparra.yomitrack.model.RegisterResponse;
import com.santiparra.yomitrack.model.UserStatsResponse;
import com.santiparra.yomitrack.utils.ActivityLog;
-
-
import java.util.List;
import java.util.Map;
import retrofit2.Call;
-import retrofit2.http.Body;
-import retrofit2.http.DELETE;
-import retrofit2.http.Field;
-import retrofit2.http.FormUrlEncoded;
-import retrofit2.http.GET;
-import retrofit2.http.HTTP;
-import retrofit2.http.POST;
-import retrofit2.http.PUT;
-import retrofit2.http.Path;
-import retrofit2.http.Query;
+import retrofit2.http.*;
+/**
+ * Interfaz ApiService que define todos los endpoints disponibles
+ * para la comunicación entre la app YomiTrack y el backend.
+ *
+ *
Usa Retrofit para declarar métodos HTTP de forma declarativa.
+ */
public interface ApiService {
- // ---------------- Usuario ----------------
+ // -------------------- USUARIO --------------------
+
+ /**
+ * Registra un nuevo usuario en la aplicación.
+ *
+ * @param user Objeto con los datos del usuario.
+ * @return respuesta del backend con éxito o error.
+ */
@POST("users/register")
Call registerUser(@Body UserEntity user);
+ /**
+ * Inicia sesión con un usuario existente.
+ *
+ * @param user Objeto con email y contraseña.
+ * @return respuesta con los datos del usuario autenticado.
+ */
@POST("users/login")
Call loginUser(@Body UserEntity user);
+ /**
+ * Solicita un enlace de recuperación de contraseña al correo proporcionado.
+ *
+ * @param email correo electrónico del usuario.
+ * @return respuesta de estado de la operación.
+ */
@FormUrlEncoded
@POST("users/forgot-password")
Call forgotPassword(@Field("email") String email);
+ /**
+ * Restablece la contraseña del usuario con un token válido.
+ *
+ * @param email correo electrónico del usuario.
+ * @param token token enviado al correo.
+ * @param newPassword nueva contraseña.
+ * @return respuesta de la operación.
+ */
@FormUrlEncoded
@POST("users/reset-password")
Call resetPassword(
@@ -52,11 +74,25 @@ public interface ApiService {
@Field("newPassword") String newPassword
);
- // ---------------- Anime ----------------
+ // -------------------- ANIME --------------------
+
+ /**
+ * Inserta un nuevo anime en la lista del usuario.
+ *
+ * @param anime Objeto con los datos del anime.
+ * @return respuesta del backend.
+ */
@POST("anime/add")
Call insertAnime(@Body AnimeEntity anime);
- // Scroll infinito: obtener lista paginada
+ /**
+ * Obtiene la lista paginada de animes de un usuario.
+ *
+ * @param userId ID del usuario.
+ * @param page número de página.
+ * @param size cantidad de ítems por página.
+ * @return página con lista de animes.
+ */
@GET("/anime/list/{userId}")
Call getAnimes(
@Path("userId") int userId,
@@ -64,16 +100,57 @@ public interface ApiService {
@Query("size") int size
);
+ /**
+ * Actualiza un anime existente.
+ *
+ * @param animeId ID del anime.
+ * @param anime Objeto con datos actualizados.
+ * @return respuesta del backend.
+ */
@PUT("anime/{id}")
Call updateAnime(@Path("id") int animeId, @Body AnimeEntity anime);
+ /**
+ * Elimina un anime por su ID.
+ *
+ * @param id ID del anime.
+ * @return respuesta del backend.
+ */
@DELETE("anime/delete/{id}")
Call deleteAnime(@Path("id") int id);
- // ---------------- Manga ----------------
+ /**
+ * Obtiene animes por estado para un usuario específico.
+ *
+ * @param userId ID del usuario.
+ * @param status estado deseado (e.g., Watching, Completed).
+ * @return lista de animes con dicho estado.
+ */
+ @GET("anime/user/{userId}/status/{status}")
+ Call> getAnimeByUserAndStatus(
+ @Path("userId") int userId,
+ @Path("status") String status
+ );
+
+ // -------------------- MANGA --------------------
+
+ /**
+ * Inserta un nuevo manga en la lista del usuario.
+ *
+ * @param manga Objeto con los datos del manga.
+ * @return respuesta del backend.
+ */
@POST("manga/add")
Call insertManga(@Body MangaEntity manga);
+ /**
+ * Obtiene la lista paginada de mangas de un usuario.
+ *
+ * @param userId ID del usuario.
+ * @param page número de página.
+ * @param size cantidad de ítems por página.
+ * @return página con lista de mangas.
+ */
@GET("/manga/list/{userId}")
Call getMangas(
@Path("userId") int userId,
@@ -81,57 +158,125 @@ public interface ApiService {
@Query("size") int size
);
+ /**
+ * Obtiene mangas por estado para un usuario específico.
+ *
+ * @param userId ID del usuario.
+ * @param status estado deseado (e.g., Reading, Completed).
+ * @return lista de mangas con dicho estado.
+ */
@GET("manga/user/{userId}/status/{status}")
Call> getMangaByUserAndStatus(
@Path("userId") int userId,
@Path("status") String status
);
+ /**
+ * Actualiza un manga existente.
+ *
+ * @param mangaId ID del manga.
+ * @param manga Objeto con datos actualizados.
+ * @return respuesta del backend.
+ */
@PUT("manga/{id}")
Call updateManga(@Path("id") int mangaId, @Body MangaEntity manga);
+ /**
+ * Elimina un manga por su ID.
+ *
+ * @param id ID del manga.
+ * @return respuesta del backend.
+ */
@DELETE("manga/delete/{id}")
Call deleteManga(@Path("id") int id);
- // ---------------- Activity -------------------
+ // -------------------- ACTIVIDAD --------------------
+ /**
+ * Obtiene estadísticas de anime y manga del usuario.
+ *
+ * @param userId ID del usuario.
+ * @return objeto con estadísticas.
+ */
@GET("users/{id}/stats")
Call getUserStats(@Path("id") int userId);
+ /**
+ * Obtiene el historial de actividad de un usuario.
+ *
+ * @param userId ID del usuario.
+ * @return lista de actividades.
+ */
@GET("api/activity/list/{userId}")
Call> getActivityLog(@Path("userId") int userId);
+ /**
+ * Obtiene los comentarios de una actividad específica.
+ *
+ * @param activityId ID de la actividad.
+ * @return lista de comentarios.
+ */
@GET("api/activity/comments/{activityId}")
Call> getCommentsByActivity(@Path("activityId") int activityId);
+ /**
+ * Verifica si un usuario dio like a una actividad.
+ *
+ * @param userId ID del usuario.
+ * @param activityId ID de la actividad.
+ * @return objeto JSON con resultado (true/false).
+ */
@GET("/api/activity/like/{userId}/{activityId}")
Call checkLike(
@Path("userId") int userId,
@Path("activityId") int activityId
);
- @GET("anime/user/{userId}/status/{status}")
- Call> getAnimeByUserAndStatus(
- @Path("userId") int userId,
- @Path("status") String status
- );
-
+ /**
+ * Envía un like a una actividad.
+ *
+ * @param body JSON con userId y activityId.
+ * @return respuesta del backend.
+ */
@POST("api/activity/like")
Call postLike(@Body JsonObject body);
- @POST("api/activity/comment")
- Call postComment(@Body JsonObject body);
-
- @POST("api/activity/add")
- Call postActivity(@Body Map body);
-
+ /**
+ * Elimina un like de una actividad.
+ *
+ * @param body JSON con userId y activityId.
+ * @return respuesta del backend.
+ */
@HTTP(method = "DELETE", path = "api/activity/like/remove", hasBody = true)
Call deleteLike(@Body JsonObject body);
+ /**
+ * Publica un comentario en una actividad.
+ *
+ * @param body JSON con userId, activityId, texto y otros datos.
+ * @return respuesta del backend.
+ */
+ @POST("api/activity/comment")
+ Call postComment(@Body JsonObject body);
- // ---------------- AniList API ----------------
+ /**
+ * Publica una nueva actividad.
+ *
+ * @param body mapa con los datos de la actividad (userId, tipo, contenido...).
+ * @return respuesta del backend.
+ */
+ @POST("api/activity/add")
+ Call postActivity(@Body Map body);
+ // -------------------- ANIList API --------------------
+
+ /**
+ * Busca animes o mangas en AniList.
+ *
+ * @param query término de búsqueda.
+ * @param type tipo de media: "ANIME" o "MANGA".
+ * @return lista de resultados obtenidos desde AniList.
+ */
@GET("anilist/search")
Call> searchAniList(@Query("query") String query, @Query("type") String type);
-
}
diff --git a/app/src/main/java/com/santiparra/yomitrack/db/entities/AnimeEntity.java b/app/src/main/java/com/santiparra/yomitrack/db/entities/AnimeEntity.java
index e35a6cd..39ec8f4 100644
--- a/app/src/main/java/com/santiparra/yomitrack/db/entities/AnimeEntity.java
+++ b/app/src/main/java/com/santiparra/yomitrack/db/entities/AnimeEntity.java
@@ -4,22 +4,55 @@ import java.io.Serializable;
/**
* Entidad que representa un anime guardado por el usuario en la base de datos local.
+ * Implementa Serializable para facilitar el paso entre componentes.
*/
public class AnimeEntity implements Serializable {
+ /** ID único del anime en la base de datos. */
private int id;
+
+ /** ID del usuario al que pertenece este anime. */
private int userId;
+
+ /** Título del anime. */
private String title;
+
+ /** Puntuación asignada por el usuario (por ejemplo, del 1 al 10). */
private int score;
+
+ /** Progreso actual del usuario (número de episodios vistos). */
private int progress;
+
+ /** Estado del anime (Watching, Completed, Paused, etc.). */
private String status;
+
+ /** Tipo del anime (TV, Movie, OVA, etc.). */
private String type;
+
+ /** URL de la imagen de portada del anime. */
private String imageUrl;
+
+ /** Número total de episodios del anime. */
private int totalEpisodes;
+ /**
+ * Constructor vacío requerido por algunas librerías como Room o Retrofit.
+ */
public AnimeEntity() {
}
+ /**
+ * Constructor completo de la entidad Anime.
+ *
+ * @param id ID único del anime.
+ * @param title Título del anime.
+ * @param status Estado del anime.
+ * @param userId ID del usuario propietario.
+ * @param imageUrl URL de la imagen del anime.
+ * @param progress Episodios vistos.
+ * @param score Puntuación asignada.
+ * @param totalEpisodes Total de episodios del anime.
+ */
public AnimeEntity(int id, String title, String status, int userId, String imageUrl, int progress, int score, int totalEpisodes) {
this.id = id;
this.title = title;
@@ -31,75 +64,92 @@ public class AnimeEntity implements Serializable {
this.totalEpisodes = totalEpisodes;
}
- // Getters y Setters
+ /** @return ID del anime. */
public int getId() {
return id;
}
+ /** @param id ID del anime. */
public void setId(int id) {
this.id = id;
}
+ /** @return ID del usuario. */
public int getUserId() {
return userId;
}
+ /** @param userId ID del usuario. */
public void setUserId(int userId) {
this.userId = userId;
}
+ /** @return Título del anime. */
public String getTitle() {
return title;
}
+ /** @param title Título del anime. */
public void setTitle(String title) {
this.title = title;
}
+ /** @return Puntuación del anime. */
public int getScore() {
return score;
}
+ /** @param score Puntuación del anime. */
public void setScore(int score) {
this.score = score;
}
+ /** @return Progreso del usuario (episodios vistos). */
public int getProgress() {
return progress;
}
+ /** @param progress Episodios vistos por el usuario. */
public void setProgress(int progress) {
this.progress = progress;
}
+ /** @return Estado del anime. */
public String getStatus() {
return status;
}
+ /** @param status Estado del anime. */
public void setStatus(String status) {
this.status = status;
}
+ /** @return Tipo de anime (TV, Movie, etc.). */
public String getType() {
return type;
}
+ /** @param type Tipo de anime. */
public void setType(String type) {
this.type = type;
}
+ /** @return URL de la imagen del anime. */
public String getImageUrl() {
return imageUrl;
}
+ /** @param imageUrl URL de la imagen del anime. */
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
+ /** @return Total de episodios del anime. */
public int getTotalEpisodes() {
return totalEpisodes;
}
+ /** @param totalEpisodes Número total de episodios. */
public void setTotalEpisodes(int totalEpisodes) {
this.totalEpisodes = totalEpisodes;
}
diff --git a/app/src/main/java/com/santiparra/yomitrack/db/entities/MangaEntity.java b/app/src/main/java/com/santiparra/yomitrack/db/entities/MangaEntity.java
index 4af8fbf..91e5630 100644
--- a/app/src/main/java/com/santiparra/yomitrack/db/entities/MangaEntity.java
+++ b/app/src/main/java/com/santiparra/yomitrack/db/entities/MangaEntity.java
@@ -4,22 +4,55 @@ import java.io.Serializable;
/**
* Entidad que representa un manga guardado por el usuario en la base de datos local.
+ * Implementa Serializable para permitir su paso entre actividades y fragmentos.
*/
public class MangaEntity implements Serializable {
+ /** ID único del manga en la base de datos. */
private int id;
+
+ /** ID del usuario al que pertenece este manga. */
private int userId;
+
+ /** Título del manga. */
private String title;
+
+ /** Puntuación asignada por el usuario (por ejemplo, del 1 al 10). */
private int score;
+
+ /** Progreso actual del usuario (capítulos leídos). */
private int progress;
+
+ /** Estado del manga (Reading, Completed, On-Hold, etc.). */
private String status;
+
+ /** Tipo del manga (Manga, Manhwa, Doujinshi, etc.). */
private String type;
+
+ /** URL de la imagen de portada del manga. */
private String imageUrl;
+
+ /** Número total de capítulos del manga. */
private int totalChapters;
+ /**
+ * Constructor vacío necesario para serialización y frameworks como Room o Retrofit.
+ */
public MangaEntity() {
}
+ /**
+ * Constructor completo para inicializar una instancia de manga.
+ *
+ * @param id ID único del manga.
+ * @param title Título del manga.
+ * @param status Estado actual del manga.
+ * @param userId ID del usuario que lo añadió.
+ * @param imageUrl URL de la portada del manga.
+ * @param progress Capítulos leídos.
+ * @param score Puntuación dada por el usuario.
+ * @param totalChapters Total de capítulos disponibles.
+ */
public MangaEntity(int id, String title, String status, int userId, String imageUrl, int progress, int score, int totalChapters) {
this.id = id;
this.title = title;
@@ -31,76 +64,92 @@ public class MangaEntity implements Serializable {
this.totalChapters = totalChapters;
}
- // Getters y Setters
-
+ /** @return ID del manga. */
public int getId() {
return id;
}
+ /** @param id ID del manga. */
public void setId(int id) {
this.id = id;
}
+ /** @return ID del usuario propietario del manga. */
public int getUserId() {
return userId;
}
+ /** @param userId ID del usuario propietario. */
public void setUserId(int userId) {
this.userId = userId;
}
+ /** @return Título del manga. */
public String getTitle() {
return title;
}
+ /** @param title Título del manga. */
public void setTitle(String title) {
this.title = title;
}
+ /** @return Puntuación asignada al manga. */
public int getScore() {
return score;
}
+ /** @param score Puntuación del manga. */
public void setScore(int score) {
this.score = score;
}
+ /** @return Capítulos leídos por el usuario. */
public int getProgress() {
return progress;
}
+ /** @param progress Capítulos que el usuario ha leído. */
public void setProgress(int progress) {
this.progress = progress;
}
+ /** @return Estado del manga (Reading, Dropped, etc.). */
public String getStatus() {
return status;
}
+ /** @param status Estado actual del manga. */
public void setStatus(String status) {
this.status = status;
}
+ /** @return Tipo de manga (e.g., Manhwa, Doujinshi). */
public String getType() {
return type;
}
+ /** @param type Tipo de manga. */
public void setType(String type) {
this.type = type;
}
+ /** @return URL de la imagen del manga. */
public String getImageUrl() {
return imageUrl;
}
+ /** @param imageUrl URL de la imagen de portada. */
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
+ /** @return Total de capítulos del manga. */
public int getTotalChapters() {
return totalChapters;
}
+ /** @param totalChapters Cantidad total de capítulos. */
public void setTotalChapters(int totalChapters) {
this.totalChapters = totalChapters;
}
diff --git a/app/src/main/java/com/santiparra/yomitrack/db/entities/UserEntity.java b/app/src/main/java/com/santiparra/yomitrack/db/entities/UserEntity.java
index df6dbff..89726b3 100644
--- a/app/src/main/java/com/santiparra/yomitrack/db/entities/UserEntity.java
+++ b/app/src/main/java/com/santiparra/yomitrack/db/entities/UserEntity.java
@@ -3,60 +3,87 @@ package com.santiparra.yomitrack.db.entities;
import com.google.gson.annotations.SerializedName;
/**
- * Entidad que representa un usuario.
+ * Entidad que representa un usuario dentro del sistema.
+ * Utilizada tanto para autenticación como para registro y obtención de datos del backend.
*/
public class UserEntity {
+ /** Identificador único del usuario. */
@SerializedName("id")
private int id;
+ /** Nombre de usuario utilizado para iniciar sesión y mostrar en el perfil. */
@SerializedName("username")
private String username;
+ /** Contraseña del usuario (debe manejarse con cuidado y encriptación en producción). */
@SerializedName("password")
private String password;
+
+ /** Dirección de correo electrónico del usuario. */
@SerializedName("email")
private String email;
+ /**
+ * Constructor utilizado para iniciar sesión con username y contraseña.
+ *
+ * @param username nombre de usuario.
+ * @param password contraseña del usuario.
+ */
public UserEntity(String username, String password) {
this.username = username;
this.password = password;
}
+ /**
+ * Constructor utilizado para registrar un nuevo usuario.
+ *
+ * @param username nombre de usuario.
+ * @param email correo electrónico.
+ * @param password contraseña del usuario.
+ */
public UserEntity(String username, String email, String password) {
this.username = username;
this.email = email;
this.password = password;
}
+ /** @return ID del usuario. */
public int getId() {
return id;
}
+ /** @param id ID del usuario. */
public void setId(int id) {
this.id = id;
}
+ /** @return nombre de usuario. */
public String getUsername() {
return username;
}
+ /** @param username nombre de usuario. */
public void setUsername(String username) {
this.username = username;
}
+ /** @return contraseña del usuario. */
public String getPassword() {
return password;
}
+ /** @param password contraseña del usuario. */
public void setPassword(String password) {
this.password = password;
}
+ /** @return correo electrónico del usuario. */
public String getEmail() {
return email;
}
+ /** @param email correo electrónico del usuario. */
public void setEmail(String email) {
this.email = email;
}
diff --git a/app/src/main/java/com/santiparra/yomitrack/model/AniListMedia.java b/app/src/main/java/com/santiparra/yomitrack/model/AniListMedia.java
index e4ba69d..8789283 100644
--- a/app/src/main/java/com/santiparra/yomitrack/model/AniListMedia.java
+++ b/app/src/main/java/com/santiparra/yomitrack/model/AniListMedia.java
@@ -1,32 +1,75 @@
package com.santiparra.yomitrack.model;
+/**
+ * Modelo de datos que representa un resultado de búsqueda desde la API de AniList.
+ * Utilizado tanto para anime como manga.
+ */
public class AniListMedia {
+
+ /** ID único del media (anime o manga) proporcionado por AniList. */
private int id;
+
+ /** Título del anime o manga. */
private String title;
+
+ /** URL de la imagen de portada del anime o manga. */
private String imageUrl;
+ /**
+ * Constructor vacío necesario para serialización/deserialización automática.
+ */
public AniListMedia() {}
+ /**
+ * Devuelve el ID del media.
+ *
+ * @return ID del anime o manga.
+ */
public int getId() {
return id;
}
- public String getTitle() {
- return title;
- }
-
- public String getImageUrl() {
- return imageUrl;
- }
-
+ /**
+ * Establece el ID del media.
+ *
+ * @param id ID del anime o manga.
+ */
public void setId(int id) {
this.id = id;
}
+ /**
+ * Devuelve el título del media.
+ *
+ * @return título del anime o manga.
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ /**
+ * Establece el título del media.
+ *
+ * @param title título del anime o manga.
+ */
public void setTitle(String title) {
this.title = title;
}
+ /**
+ * Devuelve la URL de la imagen de portada.
+ *
+ * @return URL de la imagen.
+ */
+ public String getImageUrl() {
+ return imageUrl;
+ }
+
+ /**
+ * Establece la URL de la imagen de portada.
+ *
+ * @param imageUrl URL de la imagen.
+ */
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
diff --git a/app/src/main/java/com/santiparra/yomitrack/model/ApiResponse.java b/app/src/main/java/com/santiparra/yomitrack/model/ApiResponse.java
deleted file mode 100644
index a95b32e..0000000
--- a/app/src/main/java/com/santiparra/yomitrack/model/ApiResponse.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.santiparra.yomitrack.model;
-
-public class ApiResponse {
- private String message;
-
- public String getMessage() {
- return message;
- }
-}
diff --git a/app/src/main/java/com/santiparra/yomitrack/model/adapters/airing/AiringViewHolder.java b/app/src/main/java/com/santiparra/yomitrack/model/adapters/airing/AiringViewHolder.java
deleted file mode 100644
index 827e45e..0000000
--- a/app/src/main/java/com/santiparra/yomitrack/model/adapters/airing/AiringViewHolder.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.santiparra.yomitrack.model.adapters.airing;
-
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.bumptech.glide.Glide;
-import com.santiparra.yomitrack.R;
-import com.santiparra.yomitrack.model.ItemModel;
-
-public class AiringViewHolder extends RecyclerView.ViewHolder {
-
- public ImageView imageView;
- public TextView titleTextView;
- public TextView progressTextView;
-
- public AiringViewHolder(@NonNull View itemView) {
- super(itemView);
- imageView = itemView.findViewById(R.id.mediaImage);
- titleTextView = itemView.findViewById(R.id.titleTextView);
- progressTextView = itemView.findViewById(R.id.progressTextView);
- }
-
- public void bind(ItemModel item) {
- titleTextView.setText(item.getTitle());
- progressTextView.setText("Progress: " + item.getProgress());
-
- if (item.getImageUrl() != null && !item.getImageUrl().isEmpty()) {
- Glide.with(itemView.getContext())
- .load(item.getImageUrl())
- .placeholder(R.drawable.placeholder_image)
- .error(R.drawable.error_image)
- .into(imageView);
- } else {
- imageView.setImageResource(R.drawable.placeholder_image);
- }
- }
-}
diff --git a/app/src/main/java/com/santiparra/yomitrack/model/adapters/airing/AnimeViewHolder.java b/app/src/main/java/com/santiparra/yomitrack/model/adapters/airing/AnimeViewHolder.java
deleted file mode 100644
index e630cbc..0000000
--- a/app/src/main/java/com/santiparra/yomitrack/model/adapters/airing/AnimeViewHolder.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.santiparra.yomitrack.model.adapters.airing;
-
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.bumptech.glide.Glide;
-import com.santiparra.yomitrack.R;
-import com.santiparra.yomitrack.model.ItemModel;
-
-public class AnimeViewHolder extends RecyclerView.ViewHolder {
-
- public ImageView imageView;
- public TextView titleTextView;
- public TextView progressTextView;
-
- public AnimeViewHolder(@NonNull View itemView) {
- super(itemView);
- imageView = itemView.findViewById(R.id.mediaImage);
- titleTextView = itemView.findViewById(R.id.titleTextView);
- progressTextView = itemView.findViewById(R.id.progressTextView);
- }
-
- public void bind(ItemModel item) {
- titleTextView.setText(item.getTitle());
- progressTextView.setText("Progress: " + item.getProgress());
-
- if (item.getImageUrl() != null && !item.getImageUrl().isEmpty()) {
- Glide.with(itemView.getContext())
- .load(item.getImageUrl())
- .placeholder(R.drawable.placeholder_image)
- .error(R.drawable.error_image)
- .into(imageView);
- } else {
- imageView.setImageResource(R.drawable.placeholder_image);
- }
- }
-}
diff --git a/app/src/main/java/com/santiparra/yomitrack/model/adapters/anilist_adapter/AniListSearchAdapter.java b/app/src/main/java/com/santiparra/yomitrack/model/adapters/anilist_adapter/AniListSearchAdapter.java
index 6c28d19..e28055f 100644
--- a/app/src/main/java/com/santiparra/yomitrack/model/adapters/anilist_adapter/AniListSearchAdapter.java
+++ b/app/src/main/java/com/santiparra/yomitrack/model/adapters/anilist_adapter/AniListSearchAdapter.java
@@ -20,7 +20,6 @@ import com.santiparra.yomitrack.api.ApiService;
import com.santiparra.yomitrack.db.entities.AnimeEntity;
import com.santiparra.yomitrack.db.entities.MangaEntity;
import com.santiparra.yomitrack.model.AniListMedia;
-import com.santiparra.yomitrack.utils.ActivityLog;
import com.santiparra.yomitrack.utils.DateUtils;
import java.util.HashMap;
@@ -31,18 +30,36 @@ import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
+/**
+ * Adaptador para mostrar resultados de búsqueda provenientes de AniList
+ * y permitir al usuario añadir animes o mangas a su lista local mediante la API.
+ */
public class AniListSearchAdapter extends RecyclerView.Adapter {
private final List mediaList;
private final Context context;
private final String mediaType;
+ /**
+ * Constructor del adaptador.
+ *
+ * @param context contexto de la aplicación.
+ * @param mediaList lista de resultados de búsqueda de AniList.
+ * @param mediaType tipo de media ("ANIME" o "MANGA").
+ */
public AniListSearchAdapter(Context context, List mediaList, String mediaType) {
this.context = context;
this.mediaList = mediaList;
this.mediaType = mediaType;
}
+ /**
+ * Infla el layout de cada ítem de la lista.
+ *
+ * @param parent el ViewGroup padre.
+ * @param viewType el tipo de vista.
+ * @return ViewHolder que contiene la vista del ítem.
+ */
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
@@ -50,6 +67,12 @@ public class AniListSearchAdapter extends RecyclerView.Adapter() {
@Override
public void onResponse(Call call, Response response) {
Toast.makeText(context, "Anime añadido", Toast.LENGTH_SHORT).show();
- // 🔁 Registrar actividad usando Map
+ // Registrar actividad
Map body = new HashMap<>();
body.put("userId", userId);
body.put("action", "añadió");
@@ -96,7 +121,9 @@ public class AniListSearchAdapter extends RecyclerView.Adapter() {
@Override
- public void onResponse(Call call, Response response) {}
+ public void onResponse(Call call, Response response) {
+ // Actividad registrada (sin acción adicional)
+ }
@Override
public void onFailure(Call call, Throwable t) {
@@ -112,6 +139,7 @@ public class AniListSearchAdapter extends RecyclerView.Adapter() {
@Override
public void onResponse(Call call, Response response) {
@@ -156,16 +185,35 @@ public class AniListSearchAdapter extends RecyclerView.Adapter {
+ /** Vista normal por defecto. */
public static final int VIEW_NORMAL = 0;
+
+ /** Vista compacta. */
public static final int VIEW_COMPACT = 1;
+
+ /** Vista ampliada. */
public static final int VIEW_LARGE = 2;
+ /** Lista de animes a mostrar. */
private List animeList;
+
+ /** Tipo de vista actual. */
private int viewType;
+
+ /** Listener para clics normales (edición). */
private final OnAnimeClickListener onEditClick;
+
+ /** Listener para clics prolongados (acciones extendidas). */
private final OnAnimeClickListener onLongClick;
+ /**
+ * Constructor del adaptador.
+ *
+ * @param animeList lista de animes.
+ * @param viewType tipo de vista a usar (normal, compacta, grande).
+ * @param onEditClick callback para clics normales.
+ * @param onLongClick callback para clics prolongados.
+ */
public AnimeAdapter(List animeList, int viewType,
OnAnimeClickListener onEditClick,
OnAnimeClickListener onLongClick) {
@@ -38,13 +61,23 @@ public class AnimeAdapter extends RecyclerView.Adapter newList) {
- this.animeList = newList != null ? newList : new ArrayList<>();
+ this.animeList = new ArrayList<>(newList); // o .clear() + .addAll()
notifyDataSetChanged();
}
@@ -145,11 +178,37 @@ public class AnimeAdapter extends RecyclerView.Adapter {
-
- private final List items;
-
- public BrowseGridAdapter(List items) {
- this.items = items;
- }
-
- @NonNull
- @Override
- public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
- View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_browse_card, parent, false);
- return new ViewHolder(view);
- }
-
- @Override
- public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
- ItemModel item = items.get(position);
- holder.title.setText(item.getTitle());
- Glide.with(holder.itemView.getContext())
- .load(item.getImageUrl())
- .placeholder(R.drawable.placeholder_image)
- .into(holder.cover);
-
- // 👉 Animación
- Animation animation = AnimationUtils.loadAnimation(holder.itemView.getContext(), R.anim.item_animation_fade_scale);
- holder.itemView.startAnimation(animation);
- }
-
- @Override
- public int getItemCount() {
- return items.size();
- }
-
- static class ViewHolder extends RecyclerView.ViewHolder {
- ImageView cover;
- TextView title;
-
- ViewHolder(View itemView) {
- super(itemView);
- cover = itemView.findViewById(R.id.imageViewCover);
- title = itemView.findViewById(R.id.textViewTitle);
- }
- }
-}
-
diff --git a/app/src/main/java/com/santiparra/yomitrack/model/adapters/browser_section_adapter/BrowseSectionAdapter.java b/app/src/main/java/com/santiparra/yomitrack/model/adapters/browser_section_adapter/BrowseSectionAdapter.java
deleted file mode 100644
index 33d1c83..0000000
--- a/app/src/main/java/com/santiparra/yomitrack/model/adapters/browser_section_adapter/BrowseSectionAdapter.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.santiparra.yomitrack.model.adapters.browser_section_adapter;
-
-
-
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.santiparra.yomitrack.R;
-import com.santiparra.yomitrack.model.BrowseSection;
-import com.santiparra.yomitrack.model.adapters.homeadapter.HomeAdapter;
-
-import java.util.List;
-
-public class BrowseSectionAdapter extends RecyclerView.Adapter {
-
- private final List sectionList;
-
- public BrowseSectionAdapter(List sectionList) {
- this.sectionList = sectionList;
- }
-
- @NonNull
- @Override
- public BrowseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
- View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_section, parent, false);
- return new BrowseViewHolder(view);
- }
-
- @Override
- public void onBindViewHolder(@NonNull BrowseViewHolder holder, int position) {
- BrowseSection section = sectionList.get(position);
- holder.sectionTitle.setText(section.getTitle());
-
- HomeAdapter adapter = new HomeAdapter(section.getItems(), section.getTitle());
- holder.recyclerView.setLayoutManager(new LinearLayoutManager(holder.itemView.getContext(), LinearLayoutManager.HORIZONTAL, false));
- holder.recyclerView.setAdapter(adapter);
- }
-
- @Override
- public int getItemCount() {
- return sectionList.size();
- }
-
- static class BrowseViewHolder extends RecyclerView.ViewHolder {
- TextView sectionTitle;
- RecyclerView recyclerView;
-
- public BrowseViewHolder(@NonNull View itemView) {
- super(itemView);
- sectionTitle = itemView.findViewById(R.id.sectionTitle);
- recyclerView = itemView.findViewById(R.id.sectionRecyclerView);
- }
- }
-}
diff --git a/app/src/main/java/com/santiparra/yomitrack/model/adapters/homeadapter/HomeAdapter.java b/app/src/main/java/com/santiparra/yomitrack/model/adapters/homeadapter/HomeAdapter.java
deleted file mode 100644
index 86d32fa..0000000
--- a/app/src/main/java/com/santiparra/yomitrack/model/adapters/homeadapter/HomeAdapter.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package com.santiparra.yomitrack.model.adapters.homeadapter;
-
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.santiparra.yomitrack.R;
-import com.santiparra.yomitrack.model.ItemModel;
-import com.santiparra.yomitrack.model.adapters.airing.AiringViewHolder;
-import com.santiparra.yomitrack.model.adapters.airing.AnimeViewHolder;
-
-import java.util.List;
-
-public class HomeAdapter extends RecyclerView.Adapter {
-
- private List itemList;
- private String sectionTitle;
-
- private static final int TYPE_AIRING = 0;
- private static final int TYPE_ANIME_MANGA = 1;
-
- public HomeAdapter(List itemList, String sectionTitle) {
- this.itemList = itemList;
- this.sectionTitle = sectionTitle;
- }
-
- @Override
- public int getItemViewType(int position) {
- if (sectionTitle.equalsIgnoreCase("Airing")) {
- return TYPE_AIRING;
- } else {
- return TYPE_ANIME_MANGA;
- }
- }
-
- @NonNull
- @Override
- public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
- View view = LayoutInflater.from(parent.getContext())
- .inflate(R.layout.item_media_card, parent, false);
-
- // Ajustamos manualmente el ancho
- ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
- view.setLayoutParams(layoutParams);
-
- if (viewType == TYPE_AIRING) {
- return new AiringViewHolder(view);
- } else {
- return new AnimeViewHolder(view);
- }
- }
-
- @Override
- public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
- ItemModel item = itemList.get(position);
-
- if (holder instanceof AiringViewHolder) {
- ((AiringViewHolder) holder).bind(item);
- } else if (holder instanceof AnimeViewHolder) {
- ((AnimeViewHolder) holder).bind(item);
- }
- }
-
- @Override
- public int getItemCount() {
- return itemList.size();
- }
-}
diff --git a/app/src/main/java/com/santiparra/yomitrack/model/adapters/homeadapter/HomeCardAdapter.java b/app/src/main/java/com/santiparra/yomitrack/model/adapters/homeadapter/HomeCardAdapter.java
index 4f30552..2a079a5 100644
--- a/app/src/main/java/com/santiparra/yomitrack/model/adapters/homeadapter/HomeCardAdapter.java
+++ b/app/src/main/java/com/santiparra/yomitrack/model/adapters/homeadapter/HomeCardAdapter.java
@@ -17,20 +17,48 @@ import com.santiparra.yomitrack.model.ItemModel;
import java.util.List;
+/**
+ * Adaptador para el RecyclerView del fragmento de inicio (Home).
+ * Muestra tarjetas con imagen, título y progreso de animes o mangas recientes.
+ */
public class HomeCardAdapter extends RecyclerView.Adapter {
+ /**
+ * Interfaz para manejar clics en los ítems del RecyclerView.
+ */
public interface OnItemClickListener {
+ /**
+ * Se llama cuando el usuario hace clic sobre un ítem.
+ *
+ * @param item el ítem seleccionado.
+ */
void onItemClick(ItemModel item);
}
+ /** Lista de ítems a mostrar (animes o mangas). */
private final List itemList;
+
+ /** Listener que maneja clics en los ítems. */
private final OnItemClickListener listener;
+ /**
+ * Constructor del adaptador.
+ *
+ * @param itemList lista de ítems a mostrar.
+ * @param listener manejador de eventos de clic.
+ */
public HomeCardAdapter(List itemList, OnItemClickListener listener) {
this.itemList = itemList;
this.listener = listener;
}
+ /**
+ * Infla la vista para un ítem del RecyclerView.
+ *
+ * @param parent vista contenedora.
+ * @param viewType tipo de vista (no usado aquí).
+ * @return instancia de ViewHolder.
+ */
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
@@ -38,26 +66,58 @@ public class HomeCardAdapter extends RecyclerView.Adapter listener.onItemClick(item));
}
+ /**
+ * Devuelve la cantidad de ítems en la lista.
+ *
+ * @return número total de ítems.
+ */
@Override
public int getItemCount() {
return itemList.size();
}
+ /**
+ * ViewHolder que representa cada tarjeta (ítem) en el RecyclerView.
+ */
public static class ViewHolder extends RecyclerView.ViewHolder {
- TextView title, progress;
+
+ /** Texto que muestra el título del ítem. */
+ TextView title;
+
+ /** Texto que muestra el progreso del ítem. */
+ TextView progress;
+
+ /** Imagen de portada del ítem. */
ImageView cover;
+
+ /** Tarjeta contenedora del ítem. */
CardView card;
+ /**
+ * Constructor del ViewHolder.
+ *
+ * @param itemView vista del ítem inflada desde el layout.
+ */
public ViewHolder(@NonNull View itemView) {
super(itemView);
title = itemView.findViewById(R.id.itemTitle);
diff --git a/app/src/main/java/com/santiparra/yomitrack/model/adapters/manga_adapter/MangaAdapter.java b/app/src/main/java/com/santiparra/yomitrack/model/adapters/manga_adapter/MangaAdapter.java
index f91ea4b..6954268 100644
--- a/app/src/main/java/com/santiparra/yomitrack/model/adapters/manga_adapter/MangaAdapter.java
+++ b/app/src/main/java/com/santiparra/yomitrack/model/adapters/manga_adapter/MangaAdapter.java
@@ -1,6 +1,5 @@
package com.santiparra.yomitrack.model.adapters.manga_adapter;
-import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -17,17 +16,41 @@ import com.santiparra.yomitrack.db.entities.MangaEntity;
import java.util.List;
+/**
+ * Adaptador para mostrar una lista de mangas en un RecyclerView con distintos tipos de vista:
+ * normal, compacta y grande. Soporta clics normales y prolongados.
+ */
public class MangaAdapter extends RecyclerView.Adapter {
+ /** Vista estándar. */
public static final int VIEW_NORMAL = 0;
+
+ /** Vista compacta. */
public static final int VIEW_COMPACT = 1;
+
+ /** Vista grande. */
public static final int VIEW_LARGE = 2;
+ /** Lista de mangas a mostrar. */
private List mangaList;
+
+ /** Tipo de vista actual. */
private int viewType;
+
+ /** Listener para clic corto (edición). */
private final OnMangaClickListener onEditClick;
+
+ /** Listener para clic prolongado (acciones extendidas). */
private final OnMangaClickListener onLongClick;
+ /**
+ * Constructor del adaptador.
+ *
+ * @param mangaList lista de mangas a mostrar.
+ * @param viewType tipo de vista deseado.
+ * @param onEditClick callback para clics normales.
+ * @param onLongClick callback para clics prolongados.
+ */
public MangaAdapter(List mangaList, int viewType,
OnMangaClickListener onEditClick,
OnMangaClickListener onLongClick) {
@@ -124,21 +147,51 @@ public class MangaAdapter extends RecyclerView.Adapter newList) {
+ mangaList.clear();
+ mangaList.addAll(newList);
+ notifyDataSetChanged();
+ }
+
+ /**
+ * ViewHolder para representar un ítem de manga en el RecyclerView.
+ */
public static class MangaViewHolder extends RecyclerView.ViewHolder {
ImageView imageCover;
TextView textTitle, textStatus, textProgress, textScore, textType;
View statusDot;
+ /**
+ * Constructor del ViewHolder.
+ *
+ * @param itemView vista inflada del ítem.
+ */
public MangaViewHolder(@NonNull View itemView) {
super(itemView);
imageCover = itemView.findViewById(R.id.imageCover);
@@ -151,12 +204,15 @@ public class MangaAdapter extends RecyclerView.Adapter newList) {
- this.mangaList = newList;
- notifyDataSetChanged();
- }
-
+ /**
+ * Interfaz para manejar clics sobre ítems de manga.
+ */
public interface OnMangaClickListener {
+ /**
+ * Se ejecuta cuando se hace clic en un manga.
+ *
+ * @param manga el ítem clicado.
+ */
void onClick(MangaEntity manga);
}
}
diff --git a/app/src/main/java/com/santiparra/yomitrack/model/adapters/manga_adapter/MangaSearchAdapter.java b/app/src/main/java/com/santiparra/yomitrack/model/adapters/manga_adapter/MangaSearchAdapter.java
index 2d760fb..dcd74f4 100644
--- a/app/src/main/java/com/santiparra/yomitrack/model/adapters/manga_adapter/MangaSearchAdapter.java
+++ b/app/src/main/java/com/santiparra/yomitrack/model/adapters/manga_adapter/MangaSearchAdapter.java
@@ -15,25 +15,58 @@ import com.santiparra.yomitrack.model.AniListMedia;
import java.util.List;
+/**
+ * Adaptador para mostrar resultados de búsqueda de mangas desde AniList.
+ * Utilizado en el fragmento de búsqueda para permitir seleccionar un manga.
+ */
public class MangaSearchAdapter extends RecyclerView.Adapter {
+ /** Lista de mangas obtenidos desde la API de AniList. */
private List mangaList;
+
+ /** Listener para manejar clics en los ítems del RecyclerView. */
private final OnMangaClickListener clickListener;
+ /**
+ * Interfaz que define el callback cuando se hace clic en un manga.
+ */
public interface OnMangaClickListener {
+ /**
+ * Método invocado al hacer clic sobre un manga.
+ *
+ * @param manga objeto de AniList clicado.
+ */
void onClick(AniListMedia manga);
}
+ /**
+ * Constructor del adaptador.
+ *
+ * @param mangaList lista de resultados de búsqueda.
+ * @param clickListener listener para manejar el clic en cada ítem.
+ */
public MangaSearchAdapter(List mangaList, OnMangaClickListener clickListener) {
this.mangaList = mangaList;
this.clickListener = clickListener;
}
+ /**
+ * Reemplaza la lista de mangas actual por una nueva y actualiza el RecyclerView.
+ *
+ * @param mangaList nueva lista de mangas.
+ */
public void setMangaList(List mangaList) {
this.mangaList = mangaList;
notifyDataSetChanged();
}
+ /**
+ * Infla el layout para un ítem individual del RecyclerView.
+ *
+ * @param parent el ViewGroup padre.
+ * @param viewType tipo de vista (no utilizado aquí).
+ * @return instancia del ViewHolder.
+ */
@NonNull
@Override
public SearchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
@@ -41,6 +74,12 @@ public class MangaSearchAdapter extends RecyclerView.Adapter clickListener.onClick(manga));
}
+ /**
+ * Devuelve la cantidad total de mangas en la lista.
+ *
+ * @return tamaño de la lista.
+ */
@Override
public int getItemCount() {
return mangaList != null ? mangaList.size() : 0;
}
+ /**
+ * ViewHolder que representa cada ítem del RecyclerView.
+ */
static class SearchViewHolder extends RecyclerView.ViewHolder {
+ /** Imagen de portada del manga. */
ImageView imageCover;
+
+ /** Título del manga. */
TextView title;
+ /**
+ * Constructor del ViewHolder.
+ *
+ * @param itemView vista inflada del ítem.
+ */
public SearchViewHolder(@NonNull View itemView) {
super(itemView);
imageCover = itemView.findViewById(R.id.imageCover);
diff --git a/app/src/main/java/com/santiparra/yomitrack/model/adapters/recentactivity_adapter/RecentActivityAdapter.java b/app/src/main/java/com/santiparra/yomitrack/model/adapters/recentactivity_adapter/RecentActivityAdapter.java
index 06776e0..3e43e33 100644
--- a/app/src/main/java/com/santiparra/yomitrack/model/adapters/recentactivity_adapter/RecentActivityAdapter.java
+++ b/app/src/main/java/com/santiparra/yomitrack/model/adapters/recentactivity_adapter/RecentActivityAdapter.java
@@ -7,6 +7,7 @@ import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
+
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
@@ -18,11 +19,24 @@ import com.santiparra.yomitrack.model.RecentActivityModel;
import java.util.List;
+/**
+ * Adaptador para mostrar la actividad reciente del usuario en forma de tarjetas.
+ * Cada tarjeta puede incluir una acción, portada, comentarios, botón de like y comentar.
+ */
public class RecentActivityAdapter extends RecyclerView.Adapter {
+ /** Lista de actividades recientes. */
private List activityList;
+
+ /** ID del usuario actualmente logueado (para comentarios y likes). */
private final int currentUserId;
+ /**
+ * Constructor del adaptador.
+ *
+ * @param activityList lista de actividades a mostrar.
+ * @param currentUserId ID del usuario actual.
+ */
public RecentActivityAdapter(List activityList, int currentUserId) {
this.activityList = activityList;
this.currentUserId = currentUserId;
@@ -31,7 +45,8 @@ public class RecentActivityAdapter extends RecyclerView.Adapter {
+ boolean newLike = !comment.isLiked();
+ comment.setLiked(newLike);
+ likeButton.setImageResource(newLike ? R.drawable.ic_heart_filled : R.drawable.ic_heart_outline);
+ likeButton.setColorFilter(commentView.getContext().getColor(newLike ? R.color.pink : R.color.gray));
});
- replyButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- int adapterPos = holder.getAdapterPosition();
- if (adapterPos == RecyclerView.NO_POSITION) return;
- RecentActivityModel activityItem = activityList.get(adapterPos);
- CommentDialog dialog = new CommentDialog(
- holder.itemView.getContext(),
- currentUserId,
- activityItem.getId(),
- () -> notifyItemChanged(adapterPos),
- comment.getUsername()
- );
- dialog.show();
- }
- });
-
- holder.commentContainer.addView(commentView);
- }
-
- holder.commentButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
+ // Manejo de respuesta a un comentario
+ replyButton.setOnClickListener(v -> {
int adapterPos = holder.getAdapterPosition();
if (adapterPos == RecyclerView.NO_POSITION) return;
RecentActivityModel activityItem = activityList.get(adapterPos);
@@ -115,39 +109,72 @@ public class RecentActivityAdapter extends RecyclerView.Adapter notifyItemChanged(adapterPos)
+ () -> notifyItemChanged(adapterPos),
+ comment.getUsername()
);
dialog.show();
- }
+ });
+
+ holder.commentContainer.addView(commentView);
+ }
+
+ // Botón para añadir nuevo comentario a la actividad
+ holder.commentButton.setOnClickListener(v -> {
+ int adapterPos = holder.getAdapterPosition();
+ if (adapterPos == RecyclerView.NO_POSITION) return;
+ RecentActivityModel activityItem = activityList.get(adapterPos);
+ CommentDialog dialog = new CommentDialog(
+ holder.itemView.getContext(),
+ currentUserId,
+ activityItem.getId(),
+ () -> notifyItemChanged(adapterPos)
+ );
+ dialog.show();
});
- holder.likeButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- activity.liked = !activity.liked;
- holder.likeButton.setImageResource(activity.liked ? R.drawable.ic_heart_filled : R.drawable.ic_heart_outline);
- holder.likeButton.setColorFilter(holder.itemView.getContext().getColor(
- activity.liked ? R.color.pink : R.color.textPrimary));
- }
+ // Botón de like para la actividad
+ holder.likeButton.setOnClickListener(v -> {
+ activity.liked = !activity.liked;
+ holder.likeButton.setImageResource(activity.liked ? R.drawable.ic_heart_filled : R.drawable.ic_heart_outline);
+ holder.likeButton.setColorFilter(holder.itemView.getContext().getColor(
+ activity.liked ? R.color.pink : R.color.textPrimary));
});
}
+ /**
+ * Devuelve la cantidad de actividades en la lista.
+ *
+ * @return tamaño de la lista.
+ */
@Override
public int getItemCount() {
return activityList.size();
}
+ /**
+ * Reemplaza la lista actual por una nueva y actualiza la vista.
+ *
+ * @param newList nueva lista de actividades.
+ */
public void updateData(List newList) {
this.activityList = newList;
notifyDataSetChanged();
}
+ /**
+ * ViewHolder que representa una tarjeta de actividad reciente.
+ */
static class ActivityViewHolder extends RecyclerView.ViewHolder {
TextView user, action, title, time;
ImageView image;
ImageButton likeButton, commentButton;
LinearLayout commentContainer;
+ /**
+ * Constructor del ViewHolder.
+ *
+ * @param itemView vista inflada del ítem.
+ */
public ActivityViewHolder(@NonNull View itemView) {
super(itemView);
user = itemView.findViewById(R.id.activityUser);
diff --git a/app/src/main/java/com/santiparra/yomitrack/model/adapters/sectionadapter/SectionAdapter.java b/app/src/main/java/com/santiparra/yomitrack/model/adapters/sectionadapter/SectionAdapter.java
deleted file mode 100644
index a759b59..0000000
--- a/app/src/main/java/com/santiparra/yomitrack/model/adapters/sectionadapter/SectionAdapter.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package com.santiparra.yomitrack.model.adapters.sectionadapter;
-
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.santiparra.yomitrack.R;
-import com.santiparra.yomitrack.model.ItemModel;
-import com.santiparra.yomitrack.model.adapters.homeadapter.HomeAdapter;
-
-import java.util.List;
-import java.util.Map;
-
-public class SectionAdapter extends RecyclerView.Adapter {
-
- private final List sectionTitles;
- private final Map> sectionItems;
-
- public SectionAdapter(List sectionTitles, Map> sectionItems) {
- this.sectionTitles = sectionTitles;
- this.sectionItems = sectionItems;
- }
-
- @NonNull
- @Override
- public SectionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
- View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_section, parent, false);
- return new SectionViewHolder(view);
- }
-
- @Override
- public void onBindViewHolder(@NonNull SectionViewHolder holder, int position) {
- String sectionTitle = sectionTitles.get(position);
- holder.title.setText(sectionTitle);
-
- List fullList = sectionItems.get(sectionTitle);
-
- HomeAdapter adapter = new HomeAdapter(fullList, sectionTitle);
- holder.recyclerView.setLayoutManager(new LinearLayoutManager(holder.itemView.getContext(), LinearLayoutManager.HORIZONTAL, false));
- holder.recyclerView.setAdapter(adapter);
- }
-
- @Override
- public int getItemCount() {
- return sectionTitles.size();
- }
-
- static class SectionViewHolder extends RecyclerView.ViewHolder {
- TextView title;
- RecyclerView recyclerView;
-
- public SectionViewHolder(@NonNull View itemView) {
- super(itemView);
- title = itemView.findViewById(R.id.sectionTitle);
- recyclerView = itemView.findViewById(R.id.sectionRecyclerView);
- }
- }
-}
diff --git a/app/src/main/java/com/santiparra/yomitrack/ui/fragments/addanime/AddAnimeFragment.java b/app/src/main/java/com/santiparra/yomitrack/ui/fragments/addanime/AddAnimeFragment.java
index 3eb114e..188704f 100644
--- a/app/src/main/java/com/santiparra/yomitrack/ui/fragments/addanime/AddAnimeFragment.java
+++ b/app/src/main/java/com/santiparra/yomitrack/ui/fragments/addanime/AddAnimeFragment.java
@@ -75,18 +75,12 @@ public class AddAnimeFragment extends Fragment {
private void setupSpinners() {
ArrayAdapter statusAdapter = ArrayAdapter.createFromResource(
- requireContext(),
- R.array.anime_status_array,
- R.layout.item_spinner
- );
- statusAdapter.setDropDownViewResource(R.layout.item_spinner); // ✅ blanco también al desplegar
+ requireContext(), R.array.anime_status_array, R.layout.item_spinner);
+ statusAdapter.setDropDownViewResource(R.layout.item_spinner);
statusSpinner.setAdapter(statusAdapter);
ArrayAdapter typeAdapter = ArrayAdapter.createFromResource(
- requireContext(),
- R.array.anime_type_array,
- R.layout.item_spinner
- );
+ requireContext(), R.array.anime_type_array, R.layout.item_spinner);
typeAdapter.setDropDownViewResource(R.layout.item_spinner);
typeSpinner.setAdapter(typeAdapter);
}
@@ -128,23 +122,16 @@ public class AddAnimeFragment extends Fragment {
String status = statusSpinner.getSelectedItem().toString();
String type = typeSpinner.getSelectedItem().toString();
- int score = 0;
- int progress = 0;
- try {
- score = Integer.parseInt(scoreEditText.getText().toString());
- progress = Integer.parseInt(progressEditText.getText().toString());
- } catch (NumberFormatException ignored) {
- }
+ int score = parseIntOrZero(scoreEditText.getText().toString());
+ int progress = parseIntOrZero(progressEditText.getText().toString());
AnimeEntity anime = new AnimeEntity();
anime.setUserId(userId);
anime.setTitle(selected.getTitle());
- if (selected.getImageUrl() == null || selected.getImageUrl().isEmpty()) {
- selectedImageUrl = "android.resource://" + requireContext().getPackageName() + "/" + R.drawable.sample_cover;
- } else {
- selectedImageUrl = selected.getImageUrl();
- }
+ selectedImageUrl = (selected.getImageUrl() == null || selected.getImageUrl().isEmpty())
+ ? "android.resource://" + requireContext().getPackageName() + "/" + R.drawable.sample_cover
+ : selected.getImageUrl();
anime.setImageUrl(selectedImageUrl);
anime.setStatus(status);
@@ -158,6 +145,7 @@ public class AddAnimeFragment extends Fragment {
if (response.isSuccessful() && response.body() != null) {
Toast.makeText(getContext(), response.body().getMessage(), Toast.LENGTH_SHORT).show();
registrarActividad(anime.getTitle());
+ notificarAñadido();
requireActivity().getSupportFragmentManager().popBackStack();
} else {
Toast.makeText(getContext(), "Error al guardar anime", Toast.LENGTH_SHORT).show();
@@ -182,17 +170,29 @@ public class AddAnimeFragment extends Fragment {
@Override
public void onResponse(Call call, Response response) {
Log.d("ACTIVITY_POST", "Código de respuesta: " + response.code());
- if (!response.isSuccessful()) {
- Log.e("ACTIVITY_POST", "Error en response: " + response.errorBody());
- }
}
@Override
public void onFailure(Call call, Throwable t) {
Log.e("ACTIVITY_POST", "Error al registrar actividad: " + t.getMessage(), t);
- if (!isAdded()) return;
- Toast.makeText(getContext(), "Error al registrar actividad", Toast.LENGTH_SHORT).show();
+ if (isAdded()) {
+ Toast.makeText(getContext(), "Error al registrar actividad", Toast.LENGTH_SHORT).show();
+ }
}
});
}
+
+ private void notificarAñadido() {
+ Bundle result = new Bundle();
+ result.putBoolean("anime_added", true);
+ getParentFragmentManager().setFragmentResult("anime_add_request", result);
+ }
+
+ private int parseIntOrZero(String value) {
+ try {
+ return Integer.parseInt(value.trim());
+ } catch (NumberFormatException e) {
+ return 0;
+ }
+ }
}
diff --git a/app/src/main/java/com/santiparra/yomitrack/ui/fragments/addmanga/AddMangaFragment.java b/app/src/main/java/com/santiparra/yomitrack/ui/fragments/addmanga/AddMangaFragment.java
index 0ca99c4..17c7d38 100644
--- a/app/src/main/java/com/santiparra/yomitrack/ui/fragments/addmanga/AddMangaFragment.java
+++ b/app/src/main/java/com/santiparra/yomitrack/ui/fragments/addmanga/AddMangaFragment.java
@@ -90,7 +90,6 @@ public class AddMangaFragment extends Fragment {
typeSpinner.setAdapter(typeAdapter);
}
-
private void setupRecycler() {
searchAdapter = new MangaSearchAdapter(new ArrayList<>(), this::onMangaSelected);
searchResults.setAdapter(searchAdapter);
@@ -98,8 +97,7 @@ public class AddMangaFragment extends Fragment {
private void setupSearch() {
searchEditText.setOnEditorActionListener((TextView v, int actionId, KeyEvent event) -> {
- if (actionId == EditorInfo.IME_ACTION_SEARCH ||
- (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
+ if (actionId == EditorInfo.IME_ACTION_SEARCH || (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
String query = searchEditText.getText().toString().trim();
if (!query.isEmpty()) {
api.searchAniList(query, "MANGA").enqueue(new Callback>() {
@@ -133,8 +131,7 @@ public class AddMangaFragment extends Fragment {
try {
score = Integer.parseInt(scoreEditText.getText().toString());
progress = Integer.parseInt(progressEditText.getText().toString());
- } catch (NumberFormatException ignored) {
- }
+ } catch (NumberFormatException ignored) {}
MangaEntity manga = new MangaEntity();
manga.setUserId(userId);
@@ -158,6 +155,9 @@ public class AddMangaFragment extends Fragment {
if (response.isSuccessful() && response.body() != null) {
Toast.makeText(getContext(), response.body().getMessage(), Toast.LENGTH_SHORT).show();
registrarActividad(manga.getTitle());
+ Bundle result = new Bundle();
+ result.putBoolean("manga_added", true);
+ getParentFragmentManager().setFragmentResult("manga_add_request", result);
requireActivity().getSupportFragmentManager().popBackStack();
} else {
Toast.makeText(getContext(), "Error al guardar manga", Toast.LENGTH_SHORT).show();
@@ -180,11 +180,7 @@ public class AddMangaFragment extends Fragment {
api.postActivity(actividad).enqueue(new Callback() {
@Override
- public void onResponse(Call call, Response response) {
- if (!response.isSuccessful()) {
- // Puedes logear el error si lo deseas
- }
- }
+ public void onResponse(Call call, Response response) {}
@Override
public void onFailure(Call call, Throwable t) {
diff --git a/app/src/main/java/com/santiparra/yomitrack/ui/fragments/anime_list/FragmentAnime.java b/app/src/main/java/com/santiparra/yomitrack/ui/fragments/anime_list/FragmentAnime.java
index c51f223..48d9580 100644
--- a/app/src/main/java/com/santiparra/yomitrack/ui/fragments/anime_list/FragmentAnime.java
+++ b/app/src/main/java/com/santiparra/yomitrack/ui/fragments/anime_list/FragmentAnime.java
@@ -59,15 +59,12 @@ public class FragmentAnime extends Fragment {
@Nullable
@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_alist, container, false);
}
@Override
- public void onViewCreated(@NonNull View view,
- @Nullable Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initViews(view);
@@ -76,6 +73,7 @@ public class FragmentAnime extends Fragment {
setupSearchListener();
setupFab(view);
setupInsets(view);
+ setupResultListener();
SharedPreferences prefs = requireContext().getSharedPreferences("user_session", Context.MODE_PRIVATE);
userId = prefs.getInt("user_id", -1);
@@ -84,7 +82,7 @@ public class FragmentAnime extends Fragment {
Toast.makeText(getContext(), "Error: sesión no iniciada", Toast.LENGTH_SHORT).show();
return;
}
- // Mostrar el nombre del usuario
+
String username = prefs.getString("username", "Usuario");
TextView textViewUsername = view.findViewById(R.id.textViewUsername);
textViewUsername.setText(username);
@@ -124,6 +122,30 @@ public class FragmentAnime extends Fragment {
});
}
+ private void setupResultListener() {
+ getParentFragmentManager().setFragmentResultListener("anime_add_request", this, (requestKey, bundle) -> {
+ if (bundle.getBoolean("anime_added", false)) {
+ currentPage = 1;
+ animeList.clear();
+ adapter.updateList(new ArrayList<>());
+ loadMoreAnimes(currentPage);
+ }
+ });
+
+ getParentFragmentManager().setFragmentResultListener("anime_delete_request", this, (requestKey, bundle) -> {
+ int deletedId = bundle.getInt("anime_id", -1);
+ if (deletedId != -1) {
+ for (int i = 0; i < animeList.size(); i++) {
+ if (animeList.get(i).getId() == deletedId) {
+ animeList.remove(i);
+ adapter.updateList(animeList);
+ break;
+ }
+ }
+ }
+ });
+ }
+
private void setupViewButtons() {
btnViewCompact.setOnClickListener(v -> setViewType(AnimeAdapter.VIEW_COMPACT));
btnViewNormal.setOnClickListener(v -> setViewType(AnimeAdapter.VIEW_NORMAL));
@@ -197,9 +219,8 @@ public class FragmentAnime extends Fragment {
if (response.isSuccessful() && response.body() != null) {
Toast.makeText(requireContext(), response.body().getMessage(), Toast.LENGTH_SHORT).show();
- currentPage = 1;
- animeList.clear();
- loadMoreAnimes(currentPage);
+ animeList.remove(anime);
+ adapter.updateList(animeList);
} else {
Toast.makeText(requireContext(), "Error al eliminar", Toast.LENGTH_SHORT).show();
}
@@ -225,8 +246,15 @@ public class FragmentAnime extends Fragment {
if (response.isSuccessful() && response.body() != null) {
List nuevos = response.body().getData();
- animeList.addAll(nuevos);
- adapter.notifyItemRangeInserted(animeList.size() - nuevos.size(), nuevos.size());
+ if (page == 1) {
+ animeList.clear();
+ animeList.addAll(nuevos);
+ adapter.updateList(animeList);
+ } else {
+ int start = animeList.size();
+ animeList.addAll(nuevos);
+ adapter.notifyItemRangeInserted(start, nuevos.size());
+ }
isLoading = response.body().isHasNextPage();
} else {
isLoading = false;
diff --git a/app/src/main/java/com/santiparra/yomitrack/ui/fragments/editanime/EditAnimeFragment.java b/app/src/main/java/com/santiparra/yomitrack/ui/fragments/editanime/EditAnimeFragment.java
index b58feb2..192943b 100644
--- a/app/src/main/java/com/santiparra/yomitrack/ui/fragments/editanime/EditAnimeFragment.java
+++ b/app/src/main/java/com/santiparra/yomitrack/ui/fragments/editanime/EditAnimeFragment.java
@@ -67,7 +67,7 @@ public class EditAnimeFragment extends Fragment {
String[] typeArray = getResources().getStringArray(R.array.anime_type_array);
ArrayAdapter statusAdapter = new ArrayAdapter<>(requireContext(), R.layout.item_spinner, statusArray);
- statusAdapter.setDropDownViewResource(R.layout.item_spinner); // Aplica color blanco en lista desplegable también
+ statusAdapter.setDropDownViewResource(R.layout.item_spinner);
spinnerStatus.setAdapter(statusAdapter);
ArrayAdapter typeAdapter = new ArrayAdapter<>(requireContext(), R.layout.item_spinner, typeArray);
@@ -142,8 +142,6 @@ public class EditAnimeFragment extends Fragment {
api.updateAnime(anime.getId(), anime).enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
- Log.d("API_RESPONSE", "onResponse ejecutado: " + response.body());
-
if (!isAdded()) return;
if (response.isSuccessful()) {
@@ -160,7 +158,6 @@ public class EditAnimeFragment extends Fragment {
@Override
public void onFailure(Call call, Throwable t) {
- Log.e("API_RESPONSE", "onFailure ejecutado: " + t.getMessage(), t);
if (!isAdded()) return;
Toast.makeText(requireContext(), "Fallo en la conexión", Toast.LENGTH_SHORT).show();
}
@@ -179,6 +176,10 @@ public class EditAnimeFragment extends Fragment {
Toast.makeText(requireContext(), "Anime eliminado", Toast.LENGTH_SHORT).show();
requireContext().getSharedPreferences("user_session", Context.MODE_PRIVATE)
.edit().putBoolean("refresh_profile", true).apply();
+ Bundle result = new Bundle();
+ result.putBoolean("anime_deleted", true);
+ result.putInt("anime_id", anime.getId());
+ getParentFragmentManager().setFragmentResult("anime_delete_request", result);
requireActivity().getSupportFragmentManager().popBackStack();
} else {
Toast.makeText(requireContext(), "Error al eliminar", Toast.LENGTH_SHORT).show();
@@ -231,7 +232,6 @@ public class EditAnimeFragment extends Fragment {
public void onResponse(Call call, Response response) {
Log.d("ACTIVITY_DELETE", "Actividad de eliminación registrada");
-
if (getParentFragment() instanceof FragmentProfile) {
((FragmentProfile) getParentFragment()).loadActivity();
}
diff --git a/app/src/main/java/com/santiparra/yomitrack/ui/fragments/editmanga/EditMangaFragment.java b/app/src/main/java/com/santiparra/yomitrack/ui/fragments/editmanga/EditMangaFragment.java
index 9fb0c63..8b0b472 100644
--- a/app/src/main/java/com/santiparra/yomitrack/ui/fragments/editmanga/EditMangaFragment.java
+++ b/app/src/main/java/com/santiparra/yomitrack/ui/fragments/editmanga/EditMangaFragment.java
@@ -61,30 +61,18 @@ public class EditMangaFragment extends Fragment {
fillFields();
- String[] statusArray = getResources().getStringArray(R.array.manga_status_array);
- String[] typeArray = getResources().getStringArray(R.array.manga_type_array);
-
- ArrayAdapter statusAdapter = new ArrayAdapter<>(requireContext(), R.layout.item_spinner, statusArray);
+ ArrayAdapter statusAdapter = new ArrayAdapter<>(requireContext(), R.layout.item_spinner,
+ getResources().getStringArray(R.array.manga_status_array));
statusAdapter.setDropDownViewResource(R.layout.item_spinner);
spinnerStatus.setAdapter(statusAdapter);
- ArrayAdapter typeAdapter = new ArrayAdapter<>(requireContext(), R.layout.item_spinner, typeArray);
+ ArrayAdapter typeAdapter = new ArrayAdapter<>(requireContext(), R.layout.item_spinner,
+ getResources().getStringArray(R.array.manga_type_array));
typeAdapter.setDropDownViewResource(R.layout.item_spinner);
spinnerType.setAdapter(typeAdapter);
- for (int i = 0; i < statusArray.length; i++) {
- if (statusArray[i].equalsIgnoreCase(manga.getStatus())) {
- spinnerStatus.setSelection(i);
- break;
- }
- }
-
- for (int i = 0; i < typeArray.length; i++) {
- if (typeArray[i].equalsIgnoreCase(manga.getType())) {
- spinnerType.setSelection(i);
- break;
- }
- }
+ setSpinnerSelection(spinnerStatus, manga.getStatus());
+ setSpinnerSelection(spinnerType, manga.getType());
buttonSave.setOnClickListener(v -> saveChanges());
@@ -104,6 +92,15 @@ public class EditMangaFragment extends Fragment {
editTextProgress.setText(String.valueOf(manga.getProgress()));
}
+ private void setSpinnerSelection(Spinner spinner, String value) {
+ for (int i = 0; i < spinner.getCount(); i++) {
+ if (spinner.getItemAtPosition(i).toString().equalsIgnoreCase(value)) {
+ spinner.setSelection(i);
+ break;
+ }
+ }
+ }
+
private void saveChanges() {
if (manga == null) {
Toast.makeText(requireContext(), "Error: Manga no cargado", Toast.LENGTH_SHORT).show();
@@ -128,14 +125,11 @@ public class EditMangaFragment extends Fragment {
return;
}
- String status = spinnerStatus.getSelectedItem().toString();
- String type = spinnerType.getSelectedItem().toString();
-
manga.setTitle(title);
manga.setScore(score);
manga.setProgress(progress);
- manga.setStatus(status);
- manga.setType(type);
+ manga.setStatus(spinnerStatus.getSelectedItem().toString());
+ manga.setType(spinnerType.getSelectedItem().toString());
api.updateManga(manga.getId(), manga).enqueue(new Callback() {
@Override
@@ -144,7 +138,7 @@ public class EditMangaFragment extends Fragment {
if (response.isSuccessful() && response.body() != null) {
Toast.makeText(requireContext(), response.body().getMessage(), Toast.LENGTH_SHORT).show();
- registrarActividad(manga.getTitle(), manga.getImageUrl());
+ registrarActividad("update de un manga", manga.getTitle(), manga.getImageUrl());
requireContext().getSharedPreferences("user_session", Context.MODE_PRIVATE)
.edit().putBoolean("refresh_profile", true).apply();
requireActivity().getSupportFragmentManager().popBackStack();
@@ -162,7 +156,7 @@ public class EditMangaFragment extends Fragment {
}
private void deleteManga() {
- registrarActividadEliminacionManga(manga.getTitle(), manga.getImageUrl());
+ registrarActividad("eliminó un manga", manga.getTitle(), manga.getImageUrl());
api.deleteManga(manga.getId()).enqueue(new Callback() {
@Override
@@ -173,6 +167,12 @@ public class EditMangaFragment extends Fragment {
Toast.makeText(requireContext(), "Manga eliminado", Toast.LENGTH_SHORT).show();
requireContext().getSharedPreferences("user_session", Context.MODE_PRIVATE)
.edit().putBoolean("refresh_profile", true).apply();
+
+ Bundle result = new Bundle();
+ result.putBoolean("manga_deleted", true);
+ result.putInt("manga_id", manga.getId());
+ getParentFragmentManager().setFragmentResult("manga_delete_request", result);
+
requireActivity().getSupportFragmentManager().popBackStack();
} else {
Toast.makeText(requireContext(), "Error al eliminar", Toast.LENGTH_SHORT).show();
@@ -187,44 +187,20 @@ public class EditMangaFragment extends Fragment {
});
}
- private void registrarActividad(String titulo, String imagen) {
+ private void registrarActividad(String action, String titulo, String imagen) {
int userId = requireContext().getSharedPreferences("user_session", Context.MODE_PRIVATE).getInt("user_id", -1);
if (userId == -1) return;
Map actividad = new HashMap<>();
actividad.put("userId", userId);
- actividad.put("action", "update de un manga");
+ actividad.put("action", action);
actividad.put("mediaTitle", titulo);
actividad.put("imageUrl", imagen);
api.postActivity(actividad).enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
- Log.d("ACTIVITY_DELETE", "Actividad de edicion registrada");
- }
-
- @Override
- public void onFailure(Call call, Throwable t) {
- Log.e("ACTIVITY_DELETE", "Error al registrar actividad: " + t.getMessage(), t);
- }
- });
- }
-
- private void registrarActividadEliminacionManga(String titulo, String imagen) {
- int userId = requireContext().getSharedPreferences("user_session", Context.MODE_PRIVATE).getInt("user_id", -1);
- if (userId == -1) return;
-
- Map actividad = new HashMap<>();
- actividad.put("userId", userId);
- actividad.put("action", "eliminó un manga");
- actividad.put("mediaTitle", titulo);
- actividad.put("imageUrl", imagen);
-
- api.postActivity(actividad).enqueue(new Callback() {
- @Override
- public void onResponse(Call call, Response response) {
- Log.d("ACTIVITY_DELETE", "Actividad de eliminación registrada");
-
+ Log.d("ACTIVITY", "Actividad registrada: " + action);
if (getParentFragment() instanceof FragmentProfile) {
((FragmentProfile) getParentFragment()).loadActivity();
}
@@ -232,10 +208,8 @@ public class EditMangaFragment extends Fragment {
@Override
public void onFailure(Call call, Throwable t) {
- Log.e("ACTIVITY_DELETE", "Error al registrar actividad: " + t.getMessage(), t);
+ Log.e("ACTIVITY", "Error al registrar actividad: " + t.getMessage(), t);
}
});
}
-
-
}
diff --git a/app/src/main/java/com/santiparra/yomitrack/ui/fragments/home/FragmentHome.java b/app/src/main/java/com/santiparra/yomitrack/ui/fragments/home/FragmentHome.java
index 69edc41..9216b48 100644
--- a/app/src/main/java/com/santiparra/yomitrack/ui/fragments/home/FragmentHome.java
+++ b/app/src/main/java/com/santiparra/yomitrack/ui/fragments/home/FragmentHome.java
@@ -1,6 +1,4 @@
-// FragmentHome.java
package com.santiparra.yomitrack.ui.fragments.home;
-
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
@@ -15,13 +13,11 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
-
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
-
import com.bumptech.glide.Glide;
import com.google.gson.JsonObject;
import com.santiparra.yomitrack.R;
diff --git a/app/src/main/java/com/santiparra/yomitrack/ui/fragments/manga_list/FragmentManga.java b/app/src/main/java/com/santiparra/yomitrack/ui/fragments/manga_list/FragmentManga.java
index ec213df..73234f0 100644
--- a/app/src/main/java/com/santiparra/yomitrack/ui/fragments/manga_list/FragmentManga.java
+++ b/app/src/main/java/com/santiparra/yomitrack/ui/fragments/manga_list/FragmentManga.java
@@ -70,6 +70,7 @@ public class FragmentManga extends Fragment {
initViews(view);
setupListeners();
setupRecyclerView();
+ setupResultListeners();
api = ApiClient.getClient().create(ApiService.class);
SharedPreferences prefs = requireContext().getSharedPreferences("user_session", Context.MODE_PRIVATE);
@@ -79,10 +80,9 @@ public class FragmentManga extends Fragment {
Toast.makeText(getContext(), "Error: sesión no iniciada", Toast.LENGTH_SHORT).show();
return;
}
- // Mostrar el nombre del usuario
+
String username = prefs.getString("username", "Usuario");
- TextView textViewUsername = view.findViewById(R.id.textViewUsername);
- textViewUsername.setText(username);
+ ((TextView) view.findViewById(R.id.textViewUsername)).setText(username);
setViewType(currentViewType);
loadMoreMangas(currentPage);
@@ -151,15 +151,37 @@ public class FragmentManga extends Fragment {
});
}
+ private void setupResultListeners() {
+ getParentFragmentManager().setFragmentResultListener("manga_add_request", this, (key, bundle) -> {
+ if (bundle.getBoolean("manga_added", false)) {
+ currentPage = 1;
+ mangaList.clear();
+ adapter.updateList(new ArrayList<>());
+ loadMoreMangas(currentPage);
+ }
+ });
+
+ getParentFragmentManager().setFragmentResultListener("manga_delete_request", this, (key, bundle) -> {
+ int deletedId = bundle.getInt("manga_id", -1);
+ if (deletedId != -1) {
+ for (int i = 0; i < mangaList.size(); i++) {
+ if (mangaList.get(i).getId() == deletedId) {
+ mangaList.remove(i);
+ adapter.notifyItemRemoved(i);
+ break;
+ }
+ }
+ }
+ });
+ }
+
private void setViewType(int viewType) {
currentViewType = viewType;
-
if (viewType == MangaAdapter.VIEW_LARGE) {
recyclerView.setLayoutManager(new GridLayoutManager(requireContext(), 2));
} else {
recyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
}
-
adapter = new MangaAdapter(mangaList, viewType, this::showEditDialog, this::deleteManga);
recyclerView.setAdapter(adapter);
}
@@ -187,12 +209,15 @@ public class FragmentManga extends Fragment {
@Override
public void onResponse(Call call, Response response) {
if (!isAdded()) return;
-
if (response.isSuccessful()) {
+ for (int i = 0; i < mangaList.size(); i++) {
+ if (mangaList.get(i).getId() == manga.getId()) {
+ mangaList.remove(i);
+ adapter.notifyItemRemoved(i);
+ break;
+ }
+ }
Toast.makeText(requireContext(), response.body() != null ? response.body().getMessage() : "Manga eliminado", Toast.LENGTH_SHORT).show();
- currentPage = 1;
- mangaList.clear();
- loadMoreMangas(currentPage);
} else {
Toast.makeText(requireContext(), "Error al eliminar", Toast.LENGTH_SHORT).show();
}
@@ -214,7 +239,6 @@ public class FragmentManga extends Fragment {
@Override
public void onResponse(Call call, Response response) {
if (!isAdded()) return;
-
if (response.isSuccessful() && response.body() != null) {
List nuevos = response.body().getData();
mangaList.addAll(nuevos);
diff --git a/app/src/main/res.zip b/app/src/main/res.zip
index b332b7f..3106aff 100644
Binary files a/app/src/main/res.zip and b/app/src/main/res.zip differ
diff --git a/app/src/main/res/drawable/progress_bar.xml b/app/src/main/res/drawable/progress_bar.xml
index 3cc0b0b..9fdd773 100644
--- a/app/src/main/res/drawable/progress_bar.xml
+++ b/app/src/main/res/drawable/progress_bar.xml
@@ -7,11 +7,10 @@
-
-
+
diff --git a/app/src/main/res/layout/fragment_forgot_password.xml b/app/src/main/res/layout/fragment_forgot_password.xml
index b504833..9467c79 100644
--- a/app/src/main/res/layout/fragment_forgot_password.xml
+++ b/app/src/main/res/layout/fragment_forgot_password.xml
@@ -59,13 +59,6 @@
android:textColor="@android:color/white"
android:layout_marginBottom="12dp" />
-
diff --git a/app/src/main/res/layout/item_section.xml b/app/src/main/res/layout/item_section.xml
deleted file mode 100644
index 0f4dae3..0000000
--- a/app/src/main/res/layout/item_section.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-