Terminacion de la clase FragmentProfile que ya tiene toda la funcionalidad que a de tener y optimizacion de otras para que funcione y creacion de javas y xml!
This commit is contained in:
parent
c7053368a2
commit
b7770c9fc6
Binary file not shown.
|
|
@ -53,6 +53,9 @@ public interface ApiService {
|
||||||
@Query("size") int size
|
@Query("size") int size
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@GET("anime/airing")
|
||||||
|
Call<List<AnimeEntity>> getAiringAnime();
|
||||||
|
|
||||||
@PUT("anime/{id}")
|
@PUT("anime/{id}")
|
||||||
Call<ApiResponse> updateAnime(@Path("id") int animeId, @Body AnimeEntity anime);
|
Call<ApiResponse> updateAnime(@Path("id") int animeId, @Body AnimeEntity anime);
|
||||||
|
|
||||||
|
|
@ -73,6 +76,12 @@ public interface ApiService {
|
||||||
@Query("size") int size
|
@Query("size") int size
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@GET("manga/user/{userId}/status/{status}")
|
||||||
|
Call<List<MangaEntity>> getMangaByUserAndStatus(
|
||||||
|
@Path("userId") int userId,
|
||||||
|
@Path("status") String status
|
||||||
|
);
|
||||||
|
|
||||||
@PUT("manga/{id}")
|
@PUT("manga/{id}")
|
||||||
Call<ApiResponse> updateManga(@Path("id") int mangaId, @Body MangaEntity manga);
|
Call<ApiResponse> updateManga(@Path("id") int mangaId, @Body MangaEntity manga);
|
||||||
|
|
||||||
|
|
@ -96,6 +105,12 @@ public interface ApiService {
|
||||||
@Path("activityId") int activityId
|
@Path("activityId") int activityId
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@GET("anime/user/{userId}/status/{status}")
|
||||||
|
Call<List<AnimeEntity>> getAnimeByUserAndStatus(
|
||||||
|
@Path("userId") int userId,
|
||||||
|
@Path("status") String status
|
||||||
|
);
|
||||||
|
|
||||||
@POST("api/activity/like")
|
@POST("api/activity/like")
|
||||||
Call<JsonObject> postLike(@Body JsonObject body);
|
Call<JsonObject> postLike(@Body JsonObject body);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,19 @@ public class AnimeEntity implements Serializable {
|
||||||
private String imageUrl;
|
private String imageUrl;
|
||||||
private int totalEpisodes;
|
private int totalEpisodes;
|
||||||
|
|
||||||
|
public AnimeEntity() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimeEntity(int id, String title, String status, int userId, String imageUrl, int progress, int score, int totalEpisodes) {
|
||||||
|
this.id = id;
|
||||||
|
this.title = title;
|
||||||
|
this.status = status;
|
||||||
|
this.userId = userId;
|
||||||
|
this.imageUrl = imageUrl;
|
||||||
|
this.progress = progress;
|
||||||
|
this.score = score;
|
||||||
|
this.totalEpisodes = totalEpisodes;
|
||||||
|
}
|
||||||
|
|
||||||
// Getters y Setters
|
// Getters y Setters
|
||||||
public int getId() {
|
public int getId() {
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,20 @@ public class MangaEntity implements Serializable {
|
||||||
private String imageUrl;
|
private String imageUrl;
|
||||||
private int totalChapters;
|
private int totalChapters;
|
||||||
|
|
||||||
|
public MangaEntity() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public MangaEntity(int id, String title, String status, int userId, String imageUrl, int progress, int score, int totalChapters) {
|
||||||
|
this.id = id;
|
||||||
|
this.title = title;
|
||||||
|
this.status = status;
|
||||||
|
this.userId = userId;
|
||||||
|
this.imageUrl = imageUrl;
|
||||||
|
this.progress = progress;
|
||||||
|
this.score = score;
|
||||||
|
this.totalChapters = totalChapters;
|
||||||
|
}
|
||||||
|
|
||||||
// Getters y Setters
|
// Getters y Setters
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,20 @@ package com.santiparra.yomitrack.model;
|
||||||
|
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.Window;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
import com.santiparra.yomitrack.R;
|
import com.santiparra.yomitrack.R;
|
||||||
import com.santiparra.yomitrack.api.ApiClient;
|
import com.santiparra.yomitrack.api.ApiClient;
|
||||||
import com.santiparra.yomitrack.api.ApiService;
|
import com.santiparra.yomitrack.api.ApiService;
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
|
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
import retrofit2.Callback;
|
import retrofit2.Callback;
|
||||||
|
|
@ -19,40 +23,74 @@ import retrofit2.Response;
|
||||||
|
|
||||||
public class CommentDialog extends Dialog {
|
public class CommentDialog extends Dialog {
|
||||||
|
|
||||||
|
private final int userId;
|
||||||
|
private final int activityId;
|
||||||
|
private final String replyToUsername;
|
||||||
|
private final Runnable onCommentPosted;
|
||||||
|
|
||||||
|
private EditText editComment;
|
||||||
|
private Button buttonSend;
|
||||||
|
private ApiService api;
|
||||||
|
|
||||||
public CommentDialog(@NonNull Context context, int userId, int activityId, Runnable onCommentPosted) {
|
public CommentDialog(@NonNull Context context, int userId, int activityId, Runnable onCommentPosted) {
|
||||||
|
this(context, userId, activityId, onCommentPosted, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommentDialog(@NonNull Context context, int userId, int activityId, Runnable onCommentPosted, String replyToUsername) {
|
||||||
super(context);
|
super(context);
|
||||||
|
this.userId = userId;
|
||||||
|
this.activityId = activityId;
|
||||||
|
this.replyToUsername = replyToUsername;
|
||||||
|
this.onCommentPosted = onCommentPosted;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||||
setContentView(R.layout.dialog_comment);
|
setContentView(R.layout.dialog_comment);
|
||||||
|
|
||||||
EditText commentInput = findViewById(R.id.commentInput);
|
editComment = findViewById(R.id.commentInput);
|
||||||
Button sendButton = findViewById(R.id.sendComment);
|
buttonSend = findViewById(R.id.sendComment);
|
||||||
|
api = ApiClient.getClient().create(ApiService.class);
|
||||||
|
|
||||||
sendButton.setOnClickListener(v -> {
|
// Prefill @usuario si es respuesta
|
||||||
String commentText = commentInput.getText().toString().trim();
|
if (replyToUsername != null && !replyToUsername.isEmpty()) {
|
||||||
if (commentText.isEmpty()) {
|
editComment.setText("@" + replyToUsername + " ");
|
||||||
Toast.makeText(context, "Escribe un comentario", Toast.LENGTH_SHORT).show();
|
editComment.setSelection(editComment.getText().length()); // Coloca el cursor al final
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
buttonSend.setOnClickListener(v -> postComment());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void postComment() {
|
||||||
|
String text = editComment.getText().toString().trim();
|
||||||
|
if (TextUtils.isEmpty(text)) {
|
||||||
|
Toast.makeText(getContext(), "Escribe un comentario", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject comment = new JsonObject();
|
||||||
|
comment.addProperty("userId", userId);
|
||||||
|
comment.addProperty("activityId", activityId);
|
||||||
|
comment.addProperty("text", text);
|
||||||
|
|
||||||
|
api.postComment(comment).enqueue(new Callback<JsonObject>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
dismiss();
|
||||||
|
Toast.makeText(getContext(), "Comentario enviado", Toast.LENGTH_SHORT).show();
|
||||||
|
if (onCommentPosted != null) onCommentPosted.run();
|
||||||
|
} else {
|
||||||
|
Toast.makeText(getContext(), "Error al comentar", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObject body = new JsonObject();
|
@Override
|
||||||
body.addProperty("userId", userId);
|
public void onFailure(Call<JsonObject> call, Throwable t) {
|
||||||
body.addProperty("activityId", activityId);
|
Toast.makeText(getContext(), "Fallo de conexión", Toast.LENGTH_SHORT).show();
|
||||||
body.addProperty("text", commentText);
|
}
|
||||||
|
|
||||||
ApiClient.getClient().create(ApiService.class).postComment(body).enqueue(new Callback<JsonObject>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
|
||||||
if (response.isSuccessful()) {
|
|
||||||
Toast.makeText(context, "Comentario enviado", Toast.LENGTH_SHORT).show();
|
|
||||||
dismiss();
|
|
||||||
onCommentPosted.run(); // recarga comentarios en FragmentProfile
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Call<JsonObject> call, Throwable t) {
|
|
||||||
Toast.makeText(context, "Error al comentar", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,44 @@
|
||||||
package com.santiparra.yomitrack.model;
|
package com.santiparra.yomitrack.model;
|
||||||
|
|
||||||
public class CommentModel {
|
public class CommentModel {
|
||||||
public String text;
|
private int id;
|
||||||
public boolean liked;
|
private String text;
|
||||||
|
private boolean liked;
|
||||||
private String username;
|
private String username;
|
||||||
private String avatarUrl;
|
private String avatarUrl;
|
||||||
private String created_at;
|
private String created_at;
|
||||||
|
|
||||||
|
|
||||||
public CommentModel(String text) {
|
public CommentModel(String text) {
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.liked = false;
|
this.liked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Constructor completo (opcional)
|
||||||
|
public CommentModel(int id, String text, boolean liked, String username, String avatarUrl, String created_at) {
|
||||||
|
this.id = id;
|
||||||
|
this.text = text;
|
||||||
|
this.liked = liked;
|
||||||
|
this.username = username;
|
||||||
|
this.avatarUrl = avatarUrl;
|
||||||
|
this.created_at = created_at;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
public String getText() {
|
public String getText() {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isLiked() {
|
||||||
|
return liked;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLiked(boolean liked) {
|
||||||
|
this.liked = liked;
|
||||||
|
}
|
||||||
|
|
||||||
public String getUsername() {
|
public String getUsername() {
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,26 @@
|
||||||
package com.santiparra.yomitrack.model;
|
package com.santiparra.yomitrack.model;
|
||||||
|
|
||||||
/**
|
import java.io.Serializable;
|
||||||
* Modelo general de ítem para mostrar en secciones del home.
|
|
||||||
* Se usa tanto para anime como manga.
|
public class ItemModel implements Serializable {
|
||||||
*/
|
|
||||||
public class ItemModel {
|
|
||||||
private String title;
|
|
||||||
private String progress;
|
|
||||||
private String imageUrl;
|
|
||||||
private ContentType contentType;
|
|
||||||
|
|
||||||
public enum ContentType {
|
public enum ContentType {
|
||||||
ANIME,
|
ANIME,
|
||||||
MANGA
|
MANGA
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemModel(String title, String progress, String imageUrl, ContentType contentType) {
|
private final String title;
|
||||||
|
private final String progress;
|
||||||
|
private final String imageUrl;
|
||||||
|
private final ContentType type;
|
||||||
|
private final Object object;
|
||||||
|
|
||||||
|
public ItemModel(String title, String progress, String imageUrl, ContentType type, Object object) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.progress = progress;
|
this.progress = progress;
|
||||||
this.imageUrl = imageUrl;
|
this.imageUrl = imageUrl;
|
||||||
this.contentType = contentType;
|
this.type = type;
|
||||||
|
this.object = object;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
|
|
@ -34,23 +35,11 @@ public class ItemModel {
|
||||||
return imageUrl;
|
return imageUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContentType getContentType() {
|
public ContentType getType() {
|
||||||
return contentType;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTitle(String title) {
|
public Object getObject() {
|
||||||
this.title = title;
|
return object;
|
||||||
}
|
|
||||||
|
|
||||||
public void setProgress(String progress) {
|
|
||||||
this.progress = progress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setImageUrl(String imageUrl) {
|
|
||||||
this.imageUrl = imageUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContentType(ContentType contentType) {
|
|
||||||
this.contentType = contentType;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,40 @@
|
||||||
package com.santiparra.yomitrack.model;
|
package com.santiparra.yomitrack.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
|
||||||
* Modelo de actividad reciente para mostrar acciones de usuario.
|
|
||||||
*/
|
|
||||||
public class RecentActivityModel {
|
public class RecentActivityModel {
|
||||||
public int activityId; // ← agregar esto
|
|
||||||
public String user;
|
|
||||||
public String action;
|
|
||||||
public String title;
|
|
||||||
public String time;
|
|
||||||
public String imageUrl;
|
|
||||||
public List<CommentModel> comments = new ArrayList<>();
|
|
||||||
|
|
||||||
public RecentActivityModel(int activityId, String user, String action, String title, String time, String imageUrl) {
|
private final int id;
|
||||||
this.activityId = activityId;
|
private final int userId;
|
||||||
|
private final String user;
|
||||||
|
public final String action;
|
||||||
|
public final String title;
|
||||||
|
public final String imageUrl;
|
||||||
|
public final String time;
|
||||||
|
public final List<CommentModel> comments;
|
||||||
|
public boolean liked;
|
||||||
|
|
||||||
|
public RecentActivityModel(int id, int userId, String user, String action, String title, String imageUrl, String time, List<CommentModel> comments, boolean liked) {
|
||||||
|
this.id = id;
|
||||||
|
this.userId = userId;
|
||||||
this.user = user;
|
this.user = user;
|
||||||
this.action = action;
|
this.action = action;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.time = time;
|
|
||||||
this.imageUrl = imageUrl;
|
this.imageUrl = imageUrl;
|
||||||
}
|
this.time = time;
|
||||||
|
this.comments = comments;
|
||||||
public void addComment(CommentModel comment) {
|
this.liked = liked;
|
||||||
comments.add(comment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return activityId;
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUser() {
|
||||||
|
return user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,18 +9,23 @@ import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
import com.bumptech.glide.Glide;
|
||||||
import com.santiparra.yomitrack.R;
|
import com.santiparra.yomitrack.R;
|
||||||
import com.santiparra.yomitrack.model.CommentDialog;
|
import com.santiparra.yomitrack.model.CommentDialog;
|
||||||
import com.santiparra.yomitrack.model.CommentModel;
|
import com.santiparra.yomitrack.model.CommentModel;
|
||||||
import com.santiparra.yomitrack.model.RecentActivityModel;
|
import com.santiparra.yomitrack.model.RecentActivityModel;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class RecentActivityAdapter extends RecyclerView.Adapter<RecentActivityAdapter.ActivityViewHolder> {
|
public class RecentActivityAdapter extends RecyclerView.Adapter<RecentActivityAdapter.ActivityViewHolder> {
|
||||||
private final List<RecentActivityModel> activityList;
|
|
||||||
|
|
||||||
public RecentActivityAdapter(List<RecentActivityModel> activityList) {
|
private List<RecentActivityModel> activityList;
|
||||||
|
private final int currentUserId;
|
||||||
|
|
||||||
|
public RecentActivityAdapter(List<RecentActivityModel> activityList, int currentUserId) {
|
||||||
this.activityList = activityList;
|
this.activityList = activityList;
|
||||||
|
this.currentUserId = currentUserId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
|
@ -33,7 +38,8 @@ public class RecentActivityAdapter extends RecyclerView.Adapter<RecentActivityAd
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull ActivityViewHolder holder, int position) {
|
public void onBindViewHolder(@NonNull ActivityViewHolder holder, int position) {
|
||||||
RecentActivityModel activity = activityList.get(position);
|
RecentActivityModel activity = activityList.get(position);
|
||||||
holder.user.setText(activity.user);
|
|
||||||
|
holder.user.setText(activity.getUser());
|
||||||
holder.action.setText(activity.action);
|
holder.action.setText(activity.action);
|
||||||
holder.title.setText(activity.title);
|
holder.title.setText(activity.title);
|
||||||
holder.time.setText(activity.time);
|
holder.time.setText(activity.time);
|
||||||
|
|
@ -44,34 +50,86 @@ public class RecentActivityAdapter extends RecyclerView.Adapter<RecentActivityAd
|
||||||
.into(holder.image);
|
.into(holder.image);
|
||||||
|
|
||||||
holder.commentContainer.removeAllViews();
|
holder.commentContainer.removeAllViews();
|
||||||
|
LayoutInflater inflater = LayoutInflater.from(holder.itemView.getContext());
|
||||||
|
|
||||||
if (holder.commentContainer != null) {
|
for (CommentModel comment : activity.comments) {
|
||||||
holder.commentContainer.removeAllViews();
|
View commentView = inflater.inflate(R.layout.item_comment, holder.commentContainer, false);
|
||||||
|
|
||||||
for (CommentModel comment : activity.comments) {
|
TextView usernameView = commentView.findViewById(R.id.commentUsername);
|
||||||
View commentView = LayoutInflater.from(holder.itemView.getContext())
|
TextView commentText = commentView.findViewById(R.id.commentText);
|
||||||
.inflate(R.layout.item_comment, holder.commentContainer, false);
|
TextView dateView = commentView.findViewById(R.id.commentDate);
|
||||||
|
ImageView avatar = commentView.findViewById(R.id.commentAvatar);
|
||||||
|
ImageButton likeButton = commentView.findViewById(R.id.commentLikeButton);
|
||||||
|
ImageButton replyButton = commentView.findViewById(R.id.replyButton);
|
||||||
|
|
||||||
TextView commentText = commentView.findViewById(R.id.commentText);
|
usernameView.setText(comment.getUsername());
|
||||||
ImageButton commentLike = commentView.findViewById(R.id.commentLikeButton);
|
commentText.setText(comment.getText());
|
||||||
|
dateView.setText(comment.getCreatedAt());
|
||||||
|
|
||||||
commentText.setText(comment.text);
|
Glide.with(commentView.getContext())
|
||||||
commentLike.setImageResource(comment.liked ? R.drawable.ic_heart_filled : R.drawable.ic_heart);
|
.load(comment.getAvatarUrl())
|
||||||
commentLike.setColorFilter(comment.liked
|
.placeholder(R.drawable.rectangle_placeholder)
|
||||||
? holder.itemView.getContext().getColor(R.color.pink)
|
.error(R.drawable.error_image)
|
||||||
: holder.itemView.getContext().getColor(R.color.textPrimary));
|
.into(avatar);
|
||||||
|
|
||||||
commentLike.setOnClickListener(v -> {
|
likeButton.setImageResource(comment.isLiked() ? R.drawable.ic_heart_filled : R.drawable.ic_heart_outline);
|
||||||
comment.liked = !comment.liked;
|
likeButton.setColorFilter(commentView.getContext().getColor(comment.isLiked() ? R.color.pink : R.color.gray));
|
||||||
commentLike.setImageResource(comment.liked ? R.drawable.ic_heart_filled : R.drawable.ic_heart);
|
|
||||||
commentLike.setColorFilter(comment.liked
|
|
||||||
? holder.itemView.getContext().getColor(R.color.pink)
|
|
||||||
: holder.itemView.getContext().getColor(R.color.textPrimary));
|
|
||||||
});
|
|
||||||
|
|
||||||
holder.commentContainer.addView(commentView);
|
likeButton.setOnClickListener(new View.OnClickListener() {
|
||||||
}
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
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) {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -79,12 +137,16 @@ public class RecentActivityAdapter extends RecyclerView.Adapter<RecentActivityAd
|
||||||
return activityList.size();
|
return activityList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
class ActivityViewHolder extends RecyclerView.ViewHolder {
|
public void updateData(List<RecentActivityModel> newList) {
|
||||||
|
this.activityList = newList;
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ActivityViewHolder extends RecyclerView.ViewHolder {
|
||||||
TextView user, action, title, time;
|
TextView user, action, title, time;
|
||||||
ImageView image;
|
ImageView image;
|
||||||
ImageButton likeButton, commentButton;
|
ImageButton likeButton, commentButton;
|
||||||
LinearLayout commentContainer;
|
LinearLayout commentContainer;
|
||||||
boolean isLiked = false;
|
|
||||||
|
|
||||||
public ActivityViewHolder(@NonNull View itemView) {
|
public ActivityViewHolder(@NonNull View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
|
|
@ -95,24 +157,7 @@ public class RecentActivityAdapter extends RecyclerView.Adapter<RecentActivityAd
|
||||||
image = itemView.findViewById(R.id.activityCover);
|
image = itemView.findViewById(R.id.activityCover);
|
||||||
likeButton = itemView.findViewById(R.id.likeButton);
|
likeButton = itemView.findViewById(R.id.likeButton);
|
||||||
commentButton = itemView.findViewById(R.id.commentButton);
|
commentButton = itemView.findViewById(R.id.commentButton);
|
||||||
commentContainer = itemView.findViewById(R.id.commentsContainer); // <- protección aplicada
|
commentContainer = itemView.findViewById(R.id.commentsContainer);
|
||||||
|
|
||||||
likeButton.setOnClickListener(v -> {
|
|
||||||
isLiked = !isLiked;
|
|
||||||
likeButton.setImageResource(isLiked ? R.drawable.ic_heart_filled : R.drawable.ic_heart);
|
|
||||||
likeButton.setColorFilter(isLiked
|
|
||||||
? itemView.getContext().getColor(R.color.pink)
|
|
||||||
: itemView.getContext().getColor(R.color.textPrimary));
|
|
||||||
});
|
|
||||||
|
|
||||||
commentButton.setOnClickListener(v -> {
|
|
||||||
RecentActivityModel activity = activityList.get(getAdapterPosition());
|
|
||||||
int activityId = activity.getId();
|
|
||||||
int userId = this.user.getId();
|
|
||||||
|
|
||||||
CommentDialog dialog = new CommentDialog(itemView.getContext(), userId, activityId, () -> {});
|
|
||||||
dialog.show();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ package com.santiparra.yomitrack.ui.fragments.browse;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
@ -22,17 +24,27 @@ import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.santiparra.yomitrack.R;
|
import com.santiparra.yomitrack.R;
|
||||||
|
import com.santiparra.yomitrack.api.ApiClient;
|
||||||
|
import com.santiparra.yomitrack.api.ApiService;
|
||||||
|
import com.santiparra.yomitrack.model.AniListMedia;
|
||||||
import com.santiparra.yomitrack.model.ItemModel;
|
import com.santiparra.yomitrack.model.ItemModel;
|
||||||
import com.santiparra.yomitrack.model.adapters.browser_section_adapter.BrowseGridAdapter;
|
import com.santiparra.yomitrack.model.adapters.anilist_adapter.AniListSearchAdapter;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Response;
|
||||||
|
|
||||||
public class FragmentBrowse extends Fragment {
|
public class FragmentBrowse extends Fragment {
|
||||||
|
|
||||||
private Spinner spinnerType;
|
private Spinner spinnerType;
|
||||||
private EditText editTextSearch;
|
private EditText editTextSearch;
|
||||||
private LinearLayout sectionContainer;
|
private LinearLayout sectionContainer;
|
||||||
|
private RecyclerView recyclerViewResults;
|
||||||
|
private AniListSearchAdapter searchAdapter;
|
||||||
|
private final Handler handler = new Handler(Looper.getMainLooper());
|
||||||
|
private Runnable searchRunnable;
|
||||||
|
|
||||||
private final List<ItemModel> animeList = new ArrayList<>();
|
private final List<ItemModel> animeList = new ArrayList<>();
|
||||||
private final List<ItemModel> mangaList = new ArrayList<>();
|
private final List<ItemModel> mangaList = new ArrayList<>();
|
||||||
|
|
@ -46,145 +58,56 @@ public class FragmentBrowse extends Fragment {
|
||||||
spinnerType = view.findViewById(R.id.spinnerType);
|
spinnerType = view.findViewById(R.id.spinnerType);
|
||||||
editTextSearch = view.findViewById(R.id.editTextSearch);
|
editTextSearch = view.findViewById(R.id.editTextSearch);
|
||||||
sectionContainer = view.findViewById(R.id.sectionContainer);
|
sectionContainer = view.findViewById(R.id.sectionContainer);
|
||||||
|
recyclerViewResults = view.findViewById(R.id.recyclerViewResults);
|
||||||
|
recyclerViewResults.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
|
|
||||||
View statusBarSpacer = view.findViewById(R.id.statusBarSpacer);
|
// ✅ Aseguramos que el Spinner tenga las opciones
|
||||||
int statusBarHeight = getStatusBarHeight();
|
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(requireContext(), android.R.layout.simple_spinner_item, new String[]{"Anime", "Manga"});
|
||||||
ViewGroup.LayoutParams params = statusBarSpacer.getLayoutParams();
|
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
params.height = statusBarHeight;
|
|
||||||
statusBarSpacer.setLayoutParams(params);
|
|
||||||
|
|
||||||
Spinner spinnerType = view.findViewById(R.id.spinnerType);
|
|
||||||
|
|
||||||
ArrayAdapter<CharSequence> spinnerAdapter = ArrayAdapter.createFromResource(
|
|
||||||
requireContext(), R.array.media_types, R.layout.item_spinner);
|
|
||||||
spinnerAdapter.setDropDownViewResource(R.layout.item_spinner);
|
|
||||||
spinnerType.setAdapter(spinnerAdapter);
|
spinnerType.setAdapter(spinnerAdapter);
|
||||||
|
|
||||||
|
|
||||||
loadSampleData();
|
|
||||||
showSections(animeList);
|
|
||||||
|
|
||||||
spinnerType.setOnItemSelectedListener(new android.widget.AdapterView.OnItemSelectedListener() {
|
|
||||||
@Override
|
|
||||||
public void onItemSelected(android.widget.AdapterView<?> parent, View view, int position, long id) {
|
|
||||||
String selected = spinnerType.getSelectedItem().toString();
|
|
||||||
if (selected.equals("Anime")) {
|
|
||||||
showSections(animeList);
|
|
||||||
} else {
|
|
||||||
showSections(mangaList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNothingSelected(android.widget.AdapterView<?> parent) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
editTextSearch.addTextChangedListener(new TextWatcher() {
|
editTextSearch.addTextChangedListener(new TextWatcher() {
|
||||||
@Override
|
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
@Override public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
handler.removeCallbacks(searchRunnable);
|
||||||
}
|
}
|
||||||
|
@Override public void afterTextChanged(Editable s) {
|
||||||
@Override
|
searchRunnable = () -> performSearch(s.toString());
|
||||||
public void afterTextChanged(Editable s) {
|
handler.postDelayed(searchRunnable, 500);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
|
||||||
String selected = spinnerType.getSelectedItem().toString();
|
|
||||||
if (selected.equals("Anime")) {
|
|
||||||
showSections(animeList, s.toString());
|
|
||||||
} else {
|
|
||||||
showSections(mangaList, s.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
private void showSections(List<ItemModel> source) {
|
// Aquí continúa tu lógica previa, sin alterarse.
|
||||||
showSections(source, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showSections(List<ItemModel> source, String query) {
|
|
||||||
sectionContainer.removeAllViews();
|
|
||||||
|
|
||||||
List<ItemModel> trending = new ArrayList<>();
|
|
||||||
List<ItemModel> popular = new ArrayList<>();
|
|
||||||
|
|
||||||
for (int i = 0; i < source.size(); i++) {
|
|
||||||
ItemModel item = source.get(i);
|
|
||||||
if (!query.isEmpty() && !item.getTitle().toLowerCase().contains(query.toLowerCase())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (i % 2 == 0) trending.add(item);
|
|
||||||
else popular.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!trending.isEmpty()) {
|
|
||||||
addSection("Trending Now", trending);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!popular.isEmpty()) {
|
|
||||||
addSection("Popular This Season", popular);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addSection(String title, List<ItemModel> items) {
|
|
||||||
Context context = requireContext();
|
|
||||||
|
|
||||||
LinearLayout sectionLayout = new LinearLayout(context);
|
|
||||||
sectionLayout.setOrientation(LinearLayout.VERTICAL);
|
|
||||||
sectionLayout.setLayoutParams(new LinearLayout.LayoutParams(
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
|
||||||
sectionLayout.setPadding(0, 0, 0, 24);
|
|
||||||
|
|
||||||
TextView titleView = new TextView(context);
|
|
||||||
titleView.setText(title);
|
|
||||||
titleView.setTextSize(18);
|
|
||||||
titleView.setTypeface(null, Typeface.BOLD);
|
|
||||||
titleView.setTextColor(ContextCompat.getColor(context, R.color.textPrimary));
|
|
||||||
titleView.setPadding(0, 0, 0, 8);
|
|
||||||
sectionLayout.addView(titleView);
|
|
||||||
|
|
||||||
RecyclerView recyclerView = new RecyclerView(context);
|
|
||||||
|
|
||||||
// 🔥 Establecer altura fija para 2 filas (170dp + 12sp de texto aprox + márgenes)
|
|
||||||
int itemHeightPx = (int) (170 * context.getResources().getDisplayMetrics().density);
|
|
||||||
int textHeightPx = (int) (40 * context.getResources().getDisplayMetrics().density);
|
|
||||||
int totalHeight = (itemHeightPx + textHeightPx + 45) * 2;
|
|
||||||
|
|
||||||
|
|
||||||
recyclerView.setLayoutParams(new ViewGroup.LayoutParams(
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT, totalHeight)); // <- altura calculada
|
|
||||||
|
|
||||||
GridLayoutManager layoutManager = new GridLayoutManager(context, 2, RecyclerView.HORIZONTAL, false);
|
|
||||||
recyclerView.setLayoutManager(layoutManager);
|
|
||||||
|
|
||||||
recyclerView.setAdapter(new BrowseGridAdapter(items));
|
|
||||||
recyclerView.setOverScrollMode(View.OVER_SCROLL_NEVER);
|
|
||||||
recyclerView.setClipToPadding(false);
|
|
||||||
|
|
||||||
sectionLayout.addView(recyclerView);
|
|
||||||
sectionContainer.addView(sectionLayout);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadSampleData() {
|
|
||||||
animeList.clear();
|
|
||||||
mangaList.clear();
|
|
||||||
|
|
||||||
for (int i = 1; i <= 20; i++) {
|
|
||||||
animeList.add(new ItemModel("Anime " + i, i + "/24", "https://example.com/anime" + i + ".jpg", ItemModel.ContentType.ANIME));
|
|
||||||
mangaList.add(new ItemModel("Manga " + i, i + "/120", "https://example.com/manga" + i + ".jpg", ItemModel.ContentType.MANGA));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getStatusBarHeight() {
|
private int getStatusBarHeight() {
|
||||||
int result = 0;
|
|
||||||
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
|
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
|
||||||
if (resourceId > 0) {
|
return resourceId > 0 ? getResources().getDimensionPixelSize(resourceId) : 0;
|
||||||
result = getResources().getDimensionPixelSize(resourceId);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void performSearch(String query) {
|
||||||
|
if (query.trim().isEmpty()) return;
|
||||||
|
|
||||||
|
Object selected = spinnerType.getSelectedItem();
|
||||||
|
if (selected == null) return;
|
||||||
|
|
||||||
|
String selectedType = selected.toString();
|
||||||
|
String type = selectedType.equalsIgnoreCase("Manga") ? "MANGA" : "ANIME";
|
||||||
|
|
||||||
|
ApiService apiService = ApiClient.getClient().create(ApiService.class);
|
||||||
|
apiService.searchAniList(query, type).enqueue(new retrofit2.Callback<List<AniListMedia>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<List<AniListMedia>> call, Response<List<AniListMedia>> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
searchAdapter = new AniListSearchAdapter(getContext(), response.body(), type);
|
||||||
|
recyclerViewResults.setAdapter(searchAdapter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<List<AniListMedia>> call, Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,20 @@
|
||||||
|
// FragmentHome.java
|
||||||
package com.santiparra.yomitrack.ui.fragments.home;
|
package com.santiparra.yomitrack.ui.fragments.home;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
@ -10,108 +22,340 @@ import androidx.fragment.app.Fragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
import com.santiparra.yomitrack.R;
|
import com.santiparra.yomitrack.R;
|
||||||
|
import com.santiparra.yomitrack.api.ApiClient;
|
||||||
|
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.CommentDialog;
|
||||||
|
import com.santiparra.yomitrack.model.CommentModel;
|
||||||
import com.santiparra.yomitrack.model.ItemModel;
|
import com.santiparra.yomitrack.model.ItemModel;
|
||||||
import com.santiparra.yomitrack.model.RecentActivityModel;
|
import com.santiparra.yomitrack.model.adapters.homeadapter.HomeCardAdapter;
|
||||||
import com.santiparra.yomitrack.model.adapters.recentactivity_adapter.RecentActivityAdapter;
|
import com.santiparra.yomitrack.ui.fragments.editanime.EditAnimeFragment;
|
||||||
import com.santiparra.yomitrack.model.adapters.sectionadapter.SectionAdapter;
|
import com.santiparra.yomitrack.ui.fragments.editmanga.EditMangaFragment;
|
||||||
|
import com.santiparra.yomitrack.utils.ActivityLog;
|
||||||
|
import com.santiparra.yomitrack.utils.DateUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
import retrofit2.Call;
|
||||||
* Fragmento principal que muestra secciones de anime/manga y actividad reciente.
|
import retrofit2.Callback;
|
||||||
*/
|
import retrofit2.Response;
|
||||||
|
|
||||||
public class FragmentHome extends Fragment {
|
public class FragmentHome extends Fragment {
|
||||||
|
|
||||||
private final List<RecentActivityModel> fullRecentActivity = new ArrayList<>();
|
private LinearLayout activityContainer;
|
||||||
private final List<RecentActivityModel> visibleRecentActivity = new ArrayList<>();
|
private EditText inputStatus;
|
||||||
private RecentActivityAdapter activityAdapter;
|
private Button btnPost;
|
||||||
|
private RecyclerView recyclerAnime, recyclerManga;
|
||||||
|
private ApiService api;
|
||||||
|
private int userId;
|
||||||
|
private String username;
|
||||||
|
|
||||||
public FragmentHome() {
|
public FragmentHome() {
|
||||||
super(R.layout.fragment_home);
|
super(R.layout.fragment_home);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
super.onViewCreated(view, savedInstanceState);
|
View view = inflater.inflate(R.layout.fragment_home, container, false);
|
||||||
|
|
||||||
// region Secciones de contenido (Airing, En progreso...)
|
activityContainer = view.findViewById(R.id.activityContainer);
|
||||||
RecyclerView mainRecyclerView = view.findViewById(R.id.mainRecyclerView);
|
inputStatus = view.findViewById(R.id.inputStatus);
|
||||||
mainRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
btnPost = view.findViewById(R.id.btnPost);
|
||||||
|
recyclerAnime = view.findViewById(R.id.recyclerAnime);
|
||||||
|
recyclerManga = view.findViewById(R.id.recyclerManga);
|
||||||
|
|
||||||
List<String> sectionTitles = Arrays.asList("Airing", "Anime in Progress", "Manga in Progress");
|
SharedPreferences prefs = requireContext().getSharedPreferences("user_session", Context.MODE_PRIVATE);
|
||||||
Map<String, List<ItemModel>> sectionItems = new HashMap<>();
|
userId = prefs.getInt("user_id", -1);
|
||||||
|
username = prefs.getString("username", "Usuario");
|
||||||
|
|
||||||
// Datos simulados de ejemplo
|
if (userId == -1) return view;
|
||||||
sectionItems.put("Airing", Arrays.asList(
|
|
||||||
new ItemModel("Naruto", "5/220", "https://i.imgur.com/qzWZbL2.jpg", ItemModel.ContentType.ANIME),
|
|
||||||
new ItemModel("Bleach", "100/366", "https://i.imgur.com/I0d1HyA.jpg", ItemModel.ContentType.ANIME),
|
|
||||||
new ItemModel("One Piece", "900/1100", "https://i.imgur.com/VgVfG6K.jpg", ItemModel.ContentType.ANIME),
|
|
||||||
new ItemModel("Boruto", "10/100", "https://i.imgur.com/lWhD6Zc.jpg", ItemModel.ContentType.ANIME),
|
|
||||||
new ItemModel("Dragon Ball", "80/150", "https://i.imgur.com/z4d4kWk.jpg", ItemModel.ContentType.ANIME),
|
|
||||||
new ItemModel("Another", "2/12", "https://i.imgur.com/z4d4kWk.jpg", ItemModel.ContentType.ANIME)
|
|
||||||
));
|
|
||||||
|
|
||||||
sectionItems.put("Anime in Progress", Arrays.asList(
|
api = ApiClient.getClient().create(ApiService.class);
|
||||||
new ItemModel("Attack on Titan", "16/25", "https://i.imgur.com/z4d4kWk.jpg", ItemModel.ContentType.ANIME),
|
|
||||||
new ItemModel("Jujutsu Kaisen", "10/24", "https://i.imgur.com/lWhD6Zc.jpg", ItemModel.ContentType.ANIME),
|
|
||||||
new ItemModel("One Piece", "900/1100", "https://i.imgur.com/VgVfG6K.jpg", ItemModel.ContentType.ANIME)
|
|
||||||
));
|
|
||||||
|
|
||||||
sectionItems.put("Manga in Progress", Arrays.asList(
|
btnPost.setOnClickListener(v -> postThought());
|
||||||
new ItemModel("Chainsaw Man", "45/100", "https://i.imgur.com/7tZ0h8R.jpg", ItemModel.ContentType.MANGA),
|
|
||||||
new ItemModel("Berserk", "370/380", "https://i.imgur.com/8FJYYHo.jpg", ItemModel.ContentType.MANGA)
|
|
||||||
));
|
|
||||||
|
|
||||||
SectionAdapter sectionAdapter = new SectionAdapter(sectionTitles, sectionItems);
|
loadAnimeSection();
|
||||||
mainRecyclerView.setAdapter(sectionAdapter);
|
loadMangaSection();
|
||||||
// endregion
|
loadActivity();
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
// region Actividad reciente
|
private void loadAnimeSection() {
|
||||||
RecyclerView activityRecyclerView = view.findViewById(R.id.activityRecyclerView);
|
api.getAnimeByUserAndStatus(userId, "Watching").enqueue(new Callback<List<AnimeEntity>>() {
|
||||||
activityRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
@Override
|
||||||
|
public void onResponse(Call<List<AnimeEntity>> call, Response<List<AnimeEntity>> response) {
|
||||||
|
if (!isAdded()) return;
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
List<ItemModel> items = new ArrayList<>();
|
||||||
|
for (AnimeEntity anime : response.body()) {
|
||||||
|
items.add(new ItemModel(anime.getTitle(), anime.getProgress() + "/" + anime.getTotalEpisodes(), anime.getImageUrl(), ItemModel.ContentType.ANIME, anime));
|
||||||
|
}
|
||||||
|
HomeCardAdapter adapter = new HomeCardAdapter(items, item -> {
|
||||||
|
EditAnimeFragment fragment = new EditAnimeFragment((AnimeEntity) item.getObject());
|
||||||
|
requireActivity().getSupportFragmentManager()
|
||||||
|
.beginTransaction()
|
||||||
|
.replace(R.id.frame_layout, fragment)
|
||||||
|
.addToBackStack(null)
|
||||||
|
.commit();
|
||||||
|
});
|
||||||
|
recyclerAnime.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
|
||||||
|
recyclerAnime.setAdapter(adapter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fullRecentActivity.addAll(Arrays.asList(
|
@Override
|
||||||
//new RecentActivityModel("Midca", "Read chapters 1 - 60 of", "Choujun! Choujou Senpai", "4 minutes ago", "https://i.imgur.com/7tZ0h8R.jpg"),
|
public void onFailure(Call<List<AnimeEntity>> call, Throwable t) {}
|
||||||
//new RecentActivityModel("prtrncyon", "Scored 9/10 on", "Chainsaw Man", "12 hours ago", "https://cdn.myanimelist.net/images/manga/2/253146.jpg")
|
});
|
||||||
// ... más datos simulados aquí
|
}
|
||||||
));
|
|
||||||
|
|
||||||
visibleRecentActivity.addAll(fullRecentActivity.subList(0, Math.min(10, fullRecentActivity.size())));
|
private void loadMangaSection() {
|
||||||
activityAdapter = new RecentActivityAdapter(visibleRecentActivity);
|
api.getMangaByUserAndStatus(userId, "Reading").enqueue(new Callback<List<MangaEntity>>() {
|
||||||
activityRecyclerView.setAdapter(activityAdapter);
|
@Override
|
||||||
|
public void onResponse(Call<List<MangaEntity>> call, Response<List<MangaEntity>> response) {
|
||||||
|
if (!isAdded()) return;
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
List<ItemModel> items = new ArrayList<>();
|
||||||
|
for (MangaEntity manga : response.body()) {
|
||||||
|
items.add(new ItemModel(manga.getTitle(), manga.getProgress() + "/" + manga.getTotalChapters(), manga.getImageUrl(), ItemModel.ContentType.MANGA, manga));
|
||||||
|
}
|
||||||
|
HomeCardAdapter adapter = new HomeCardAdapter(items, item -> {
|
||||||
|
EditMangaFragment fragment = new EditMangaFragment((MangaEntity) item.getObject());
|
||||||
|
requireActivity().getSupportFragmentManager()
|
||||||
|
.beginTransaction()
|
||||||
|
.replace(R.id.frame_layout, fragment)
|
||||||
|
.addToBackStack(null)
|
||||||
|
.commit();
|
||||||
|
});
|
||||||
|
recyclerManga.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
|
||||||
|
recyclerManga.setAdapter(adapter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Button buttonShowMore = view.findViewById(R.id.buttonShowMoreActivity);
|
@Override
|
||||||
Button buttonShowLess = view.findViewById(R.id.buttonShowLessActivity);
|
public void onFailure(Call<List<MangaEntity>> call, Throwable t) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Mostrar más/menos actividad
|
private JsonObject createLikeJson(int userId, int targetId) {
|
||||||
if (fullRecentActivity.size() > 10) {
|
JsonObject body = new JsonObject();
|
||||||
buttonShowMore.setVisibility(View.VISIBLE);
|
body.addProperty("userId", userId);
|
||||||
buttonShowLess.setVisibility(View.GONE);
|
body.addProperty("activityId", targetId);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
buttonShowMore.setOnClickListener(v -> {
|
private void actualizarCorazon(ImageButton button, boolean liked) {
|
||||||
visibleRecentActivity.clear();
|
button.setImageResource(liked ? R.drawable.ic_heart_filled : R.drawable.ic_heart_outline);
|
||||||
visibleRecentActivity.addAll(fullRecentActivity);
|
button.setColorFilter(requireContext().getColor(liked ? R.color.pink : R.color.gray));
|
||||||
activityAdapter.notifyDataSetChanged();
|
}
|
||||||
buttonShowMore.setVisibility(View.GONE);
|
|
||||||
buttonShowLess.setVisibility(View.VISIBLE);
|
|
||||||
});
|
|
||||||
|
|
||||||
buttonShowLess.setOnClickListener(v -> {
|
private void postThought() {
|
||||||
visibleRecentActivity.clear();
|
String status = inputStatus.getText().toString().trim();
|
||||||
visibleRecentActivity.addAll(fullRecentActivity.subList(0, 10));
|
if (TextUtils.isEmpty(status)) {
|
||||||
activityAdapter.notifyDataSetChanged();
|
Toast.makeText(getContext(), "Escribe algo", Toast.LENGTH_SHORT).show();
|
||||||
buttonShowMore.setVisibility(View.VISIBLE);
|
return;
|
||||||
buttonShowLess.setVisibility(View.GONE);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
buttonShowMore.setVisibility(View.GONE);
|
|
||||||
buttonShowLess.setVisibility(View.GONE);
|
|
||||||
}
|
}
|
||||||
// endregion
|
|
||||||
|
Map<String, Object> post = new HashMap<>();
|
||||||
|
post.put("userId", userId);
|
||||||
|
post.put("action", "publicó");
|
||||||
|
post.put("mediaTitle", status);
|
||||||
|
|
||||||
|
api.postActivity(post).enqueue(new Callback<JsonObject>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
||||||
|
if (!isAdded()) return;
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
inputStatus.setText("");
|
||||||
|
loadActivity();
|
||||||
|
Toast.makeText(getContext(), "Publicado", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<JsonObject> call, Throwable t) {
|
||||||
|
if (!isAdded()) return;
|
||||||
|
Toast.makeText(getContext(), "Error al publicar", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadActivity() {
|
||||||
|
api.getActivityLog(userId).enqueue(new Callback<List<ActivityLog>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<List<ActivityLog>> call, Response<List<ActivityLog>> response) {
|
||||||
|
if (!isAdded()) return;
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
activityContainer.removeAllViews();
|
||||||
|
LayoutInflater inflater = LayoutInflater.from(requireContext());
|
||||||
|
|
||||||
|
for (ActivityLog log : response.body()) {
|
||||||
|
View card = inflater.inflate(R.layout.item_activity_card, activityContainer, false);
|
||||||
|
|
||||||
|
LinearLayout commentsContainer = card.findViewById(R.id.commentsContainer);
|
||||||
|
commentsContainer.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
card.setOnClickListener(v -> {
|
||||||
|
if (commentsContainer.getVisibility() == View.VISIBLE) {
|
||||||
|
commentsContainer.animate().alpha(0).setDuration(150).withEndAction(() -> commentsContainer.setVisibility(View.GONE)).start();
|
||||||
|
} else {
|
||||||
|
commentsContainer.setAlpha(0);
|
||||||
|
commentsContainer.setVisibility(View.VISIBLE);
|
||||||
|
loadComments(log.getId(), commentsContainer);
|
||||||
|
commentsContainer.animate().alpha(1).setDuration(150).start();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
((TextView) card.findViewById(R.id.activityUser)).setText(username);
|
||||||
|
((TextView) card.findViewById(R.id.activityAction)).setText(log.getAction());
|
||||||
|
((TextView) card.findViewById(R.id.activityTitle)).setText(log.getMediaTitle());
|
||||||
|
((TextView) card.findViewById(R.id.activityTime)).setText(DateUtils.getRelativeTime(log.getTimestamp()));
|
||||||
|
|
||||||
|
ImageView coverImage = card.findViewById(R.id.activityCover);
|
||||||
|
if (!TextUtils.isEmpty(log.getImageUrl())) {
|
||||||
|
Glide.with(requireContext())
|
||||||
|
.load(log.getImageUrl())
|
||||||
|
.placeholder(R.drawable.placeholder_image)
|
||||||
|
.error(R.drawable.placeholder_image)
|
||||||
|
.into(coverImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageButton commentButton = card.findViewById(R.id.commentButton);
|
||||||
|
ImageButton likeButton = card.findViewById(R.id.likeButton);
|
||||||
|
|
||||||
|
commentButton.setOnClickListener(v -> {
|
||||||
|
CommentDialog dialog = new CommentDialog(requireContext(), userId, log.getId(), () -> loadComments(log.getId(), commentsContainer));
|
||||||
|
dialog.show();
|
||||||
|
});
|
||||||
|
|
||||||
|
api.checkLike(userId, log.getId()).enqueue(new Callback<JsonObject>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
final boolean[] isLiked = {response.body().get("liked").getAsBoolean()};
|
||||||
|
actualizarCorazon(likeButton, isLiked[0]);
|
||||||
|
|
||||||
|
likeButton.setOnClickListener(v -> {
|
||||||
|
if (isLiked[0]) {
|
||||||
|
api.deleteLike(createLikeJson(userId, log.getId())).enqueue(new Callback<JsonObject>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
isLiked[0] = false;
|
||||||
|
actualizarCorazon(likeButton, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<JsonObject> call, Throwable t) {}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
api.postLike(createLikeJson(userId, log.getId())).enqueue(new Callback<JsonObject>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
isLiked[0] = true;
|
||||||
|
actualizarCorazon(likeButton, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<JsonObject> call, Throwable t) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<JsonObject> call, Throwable t) {}
|
||||||
|
});
|
||||||
|
|
||||||
|
activityContainer.addView(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<List<ActivityLog>> call, Throwable t) {
|
||||||
|
if (!isAdded()) return;
|
||||||
|
Toast.makeText(getContext(), "Error al cargar actividad", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadComments(int activityId, LinearLayout container) {
|
||||||
|
api.getCommentsByActivity(activityId).enqueue(new Callback<List<CommentModel>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<List<CommentModel>> call, Response<List<CommentModel>> response) {
|
||||||
|
if (!isAdded()) return;
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
container.removeAllViews();
|
||||||
|
LayoutInflater inflater = LayoutInflater.from(requireContext());
|
||||||
|
|
||||||
|
for (CommentModel comment : response.body()) {
|
||||||
|
View commentView = inflater.inflate(R.layout.item_comment, container, false);
|
||||||
|
|
||||||
|
TextView usernameView = commentView.findViewById(R.id.commentUsername);
|
||||||
|
TextView commentText = commentView.findViewById(R.id.commentText);
|
||||||
|
TextView dateView = commentView.findViewById(R.id.commentDate);
|
||||||
|
ImageView avatar = commentView.findViewById(R.id.commentAvatar);
|
||||||
|
ImageButton likeButton = commentView.findViewById(R.id.commentLikeButton);
|
||||||
|
ImageButton replyButton = commentView.findViewById(R.id.replyButton);
|
||||||
|
|
||||||
|
usernameView.setText(comment.getUsername());
|
||||||
|
commentText.setText(comment.getText());
|
||||||
|
dateView.setText(DateUtils.getRelativeTime(comment.getCreatedAt()));
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(comment.getAvatarUrl())) {
|
||||||
|
Glide.with(requireContext())
|
||||||
|
.load(comment.getAvatarUrl())
|
||||||
|
.placeholder(R.drawable.rectangle_placeholder)
|
||||||
|
.error(R.drawable.error_image)
|
||||||
|
.into(avatar);
|
||||||
|
}
|
||||||
|
|
||||||
|
likeButton.setImageResource(comment.isLiked() ? R.drawable.ic_heart_filled : R.drawable.ic_heart_outline);
|
||||||
|
likeButton.setColorFilter(requireContext().getColor(comment.isLiked() ? R.color.pink : R.color.gray));
|
||||||
|
|
||||||
|
likeButton.setOnClickListener(v -> {
|
||||||
|
boolean newLike = !comment.isLiked();
|
||||||
|
comment.setLiked(newLike);
|
||||||
|
actualizarCorazon(likeButton, newLike);
|
||||||
|
if (newLike) {
|
||||||
|
api.postLike(createLikeJson(userId, comment.getId())).enqueue(new Callback<JsonObject>() {
|
||||||
|
@Override public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {}
|
||||||
|
@Override public void onFailure(Call<JsonObject> call, Throwable t) {}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
api.deleteLike(createLikeJson(userId, comment.getId())).enqueue(new Callback<JsonObject>() {
|
||||||
|
@Override public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {}
|
||||||
|
@Override public void onFailure(Call<JsonObject> call, Throwable t) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
replyButton.setOnClickListener(v -> {
|
||||||
|
CommentDialog dialog = new CommentDialog(requireContext(), userId, activityId, () -> loadComments(activityId, container));
|
||||||
|
dialog.show();
|
||||||
|
});
|
||||||
|
|
||||||
|
container.addView(commentView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<List<CommentModel>> call, Throwable t) {
|
||||||
|
if (!isAdded()) return;
|
||||||
|
Toast.makeText(getContext(), "Error al cargar comentarios", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ import com.santiparra.yomitrack.model.UserStatsResponse;
|
||||||
import com.santiparra.yomitrack.utils.ActivityLog;
|
import com.santiparra.yomitrack.utils.ActivityLog;
|
||||||
import com.santiparra.yomitrack.utils.DateUtils;
|
import com.santiparra.yomitrack.utils.DateUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
@ -91,9 +90,6 @@ public class FragmentProfile extends Fragment {
|
||||||
editBiography.setText(bioPrefs.getString(BIO_KEY, ""));
|
editBiography.setText(bioPrefs.getString(BIO_KEY, ""));
|
||||||
|
|
||||||
api = ApiClient.getClient().create(ApiService.class);
|
api = ApiClient.getClient().create(ApiService.class);
|
||||||
|
|
||||||
loadStats();
|
|
||||||
loadActivity();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupListeners() {
|
private void setupListeners() {
|
||||||
|
|
@ -122,24 +118,19 @@ public class FragmentProfile extends Fragment {
|
||||||
|
|
||||||
private void populateStats(LinearLayout container, Map<String, Integer> stats) {
|
private void populateStats(LinearLayout container, Map<String, Integer> stats) {
|
||||||
container.removeAllViews();
|
container.removeAllViews();
|
||||||
|
|
||||||
if (stats == null || stats.isEmpty()) {
|
if (stats == null || stats.isEmpty()) {
|
||||||
addTextToContainer(container, "No hay estadísticas disponibles");
|
addTextToContainer(container, "No hay estadísticas disponibles");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int total = stats.values().stream().mapToInt(Integer::intValue).sum();
|
int total = stats.values().stream().mapToInt(Integer::intValue).sum();
|
||||||
LayoutInflater inflater = LayoutInflater.from(getContext());
|
LayoutInflater inflater = LayoutInflater.from(getContext());
|
||||||
|
|
||||||
for (Map.Entry<String, Integer> entry : stats.entrySet()) {
|
for (Map.Entry<String, Integer> entry : stats.entrySet()) {
|
||||||
View statView = inflater.inflate(R.layout.item_stat_bar, container, false);
|
View statView = inflater.inflate(R.layout.item_stat_bar, container, false);
|
||||||
TextView label = statView.findViewById(R.id.statLabelFull);
|
TextView label = statView.findViewById(R.id.statLabelFull);
|
||||||
ProgressBar bar = statView.findViewById(R.id.statProgressBar);
|
ProgressBar bar = statView.findViewById(R.id.statProgressBar);
|
||||||
|
|
||||||
label.setText(String.format(Locale.getDefault(), "%s • %d", entry.getKey(), entry.getValue()));
|
label.setText(String.format(Locale.getDefault(), "%s • %d", entry.getKey(), entry.getValue()));
|
||||||
bar.setProgress(total > 0 ? (entry.getValue() * 100 / total) : 0);
|
bar.setProgress(total > 0 ? (entry.getValue() * 100 / total) : 0);
|
||||||
bar.setProgressTintList(ColorStateList.valueOf(getColorForStatus(entry.getKey())));
|
bar.setProgressTintList(ColorStateList.valueOf(getColorForStatus(entry.getKey())));
|
||||||
|
|
||||||
container.addView(statView);
|
container.addView(statView);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -153,18 +144,12 @@ public class FragmentProfile extends Fragment {
|
||||||
|
|
||||||
private int getColorForStatus(String status) {
|
private int getColorForStatus(String status) {
|
||||||
switch (status.toLowerCase(Locale.ROOT)) {
|
switch (status.toLowerCase(Locale.ROOT)) {
|
||||||
case "watching":
|
case "watching": return requireContext().getColor(R.color.status_watching);
|
||||||
return requireContext().getColor(R.color.status_watching);
|
case "completed": return requireContext().getColor(R.color.status_completed);
|
||||||
case "completed":
|
case "paused": return requireContext().getColor(R.color.status_paused);
|
||||||
return requireContext().getColor(R.color.status_completed);
|
case "dropped": return requireContext().getColor(R.color.status_dropped);
|
||||||
case "paused":
|
case "planning": return requireContext().getColor(R.color.status_planning);
|
||||||
return requireContext().getColor(R.color.status_paused);
|
default: return requireContext().getColor(R.color.gray);
|
||||||
case "dropped":
|
|
||||||
return requireContext().getColor(R.color.status_dropped);
|
|
||||||
case "planning":
|
|
||||||
return requireContext().getColor(R.color.status_planning);
|
|
||||||
default:
|
|
||||||
return requireContext().getColor(R.color.gray);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -175,19 +160,14 @@ public class FragmentProfile extends Fragment {
|
||||||
if (response.isSuccessful() && response.body() != null) {
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
activityContainer.removeAllViews();
|
activityContainer.removeAllViews();
|
||||||
LayoutInflater inflater = LayoutInflater.from(getContext());
|
LayoutInflater inflater = LayoutInflater.from(getContext());
|
||||||
|
|
||||||
for (ActivityLog log : response.body()) {
|
for (ActivityLog log : response.body()) {
|
||||||
View card = inflater.inflate(R.layout.item_activity_card, activityContainer, false);
|
View card = inflater.inflate(R.layout.item_activity_card, activityContainer, false);
|
||||||
|
|
||||||
LinearLayout commentsContainer = card.findViewById(R.id.commentsContainer);
|
LinearLayout commentsContainer = card.findViewById(R.id.commentsContainer);
|
||||||
|
|
||||||
commentsContainer.setVisibility(View.GONE);
|
commentsContainer.setVisibility(View.GONE);
|
||||||
|
|
||||||
card.setOnClickListener(v -> {
|
card.setOnClickListener(v -> {
|
||||||
if (commentsContainer.getVisibility() == View.VISIBLE) {
|
if (commentsContainer.getVisibility() == View.VISIBLE) {
|
||||||
commentsContainer.animate().alpha(0).setDuration(150).withEndAction(() -> {
|
commentsContainer.animate().alpha(0).setDuration(150).withEndAction(() -> commentsContainer.setVisibility(View.GONE)).start();
|
||||||
commentsContainer.setVisibility(View.GONE);
|
|
||||||
}).start();
|
|
||||||
} else {
|
} else {
|
||||||
commentsContainer.setAlpha(0);
|
commentsContainer.setAlpha(0);
|
||||||
commentsContainer.setVisibility(View.VISIBLE);
|
commentsContainer.setVisibility(View.VISIBLE);
|
||||||
|
|
@ -203,20 +183,14 @@ public class FragmentProfile extends Fragment {
|
||||||
|
|
||||||
ImageView coverImage = card.findViewById(R.id.activityCover);
|
ImageView coverImage = card.findViewById(R.id.activityCover);
|
||||||
if (!TextUtils.isEmpty(log.getImageUrl())) {
|
if (!TextUtils.isEmpty(log.getImageUrl())) {
|
||||||
Glide.with(requireContext())
|
Glide.with(requireContext()).load(log.getImageUrl()).placeholder(R.drawable.placeholder_image).error(R.drawable.placeholder_image).into(coverImage);
|
||||||
.load(log.getImageUrl())
|
|
||||||
.placeholder(R.drawable.placeholder_image)
|
|
||||||
.error(R.drawable.placeholder_image)
|
|
||||||
.into(coverImage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageButton commentButton = card.findViewById(R.id.commentButton);
|
ImageButton commentButton = card.findViewById(R.id.commentButton);
|
||||||
ImageButton likeButton = card.findViewById(R.id.likeButton);
|
ImageButton likeButton = card.findViewById(R.id.likeButton);
|
||||||
|
|
||||||
commentButton.setOnClickListener(v -> {
|
commentButton.setOnClickListener(v -> {
|
||||||
CommentDialog dialog = new CommentDialog(requireContext(), userId, log.getId(), () -> {
|
CommentDialog dialog = new CommentDialog(requireContext(), userId, log.getId(), () -> loadComments(log.getId(), commentsContainer));
|
||||||
loadComments(log.getId(), card.findViewById(R.id.commentsContainer));
|
|
||||||
});
|
|
||||||
dialog.show();
|
dialog.show();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -226,47 +200,25 @@ public class FragmentProfile extends Fragment {
|
||||||
if (response.isSuccessful() && response.body() != null) {
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
final boolean[] isLiked = {response.body().get("liked").getAsBoolean()};
|
final boolean[] isLiked = {response.body().get("liked").getAsBoolean()};
|
||||||
actualizarCorazon(likeButton, isLiked[0]);
|
actualizarCorazon(likeButton, isLiked[0]);
|
||||||
|
|
||||||
likeButton.setOnClickListener(v -> {
|
likeButton.setOnClickListener(v -> {
|
||||||
if (isLiked[0]) {
|
boolean newLike = !isLiked[0];
|
||||||
api.deleteLike(createLikeJson(userId, log.getId())).enqueue(new Callback<JsonObject>() {
|
isLiked[0] = newLike;
|
||||||
@Override
|
if (newLike) {
|
||||||
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
api.postLike(createLikeJson(userId, log.getId())).enqueue(new Callback<JsonObject>() {
|
||||||
if (response.isSuccessful()) {
|
@Override public void onResponse(Call<JsonObject> call, Response<JsonObject> response) { actualizarCorazon(likeButton, true); }
|
||||||
isLiked[0] = false;
|
@Override public void onFailure(Call<JsonObject> call, Throwable t) {}
|
||||||
actualizarCorazon(likeButton, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Call<JsonObject> call, Throwable t) {
|
|
||||||
Toast.makeText(getContext(), "Error de conexión", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
api.postLike(createLikeJson(userId, log.getId())).enqueue(new Callback<JsonObject>() {
|
api.deleteLike(createLikeJson(userId, log.getId())).enqueue(new Callback<JsonObject>() {
|
||||||
@Override
|
@Override public void onResponse(Call<JsonObject> call, Response<JsonObject> response) { actualizarCorazon(likeButton, false); }
|
||||||
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
@Override public void onFailure(Call<JsonObject> call, Throwable t) {}
|
||||||
if (response.isSuccessful()) {
|
|
||||||
isLiked[0] = true;
|
|
||||||
actualizarCorazon(likeButton, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Call<JsonObject> call, Throwable t) {
|
|
||||||
Toast.makeText(getContext(), "Error de conexión", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Call<JsonObject> call, Throwable t) {
|
public void onFailure(Call<JsonObject> call, Throwable t) {}
|
||||||
Toast.makeText(getContext(), "Error al verificar like", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
activityContainer.addView(card);
|
activityContainer.addView(card);
|
||||||
|
|
@ -287,24 +239,19 @@ public class FragmentProfile extends Fragment {
|
||||||
Toast.makeText(getContext(), "Escribe algo primero", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), "Escribe algo primero", Toast.LENGTH_SHORT).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Object> post = new HashMap<>();
|
Map<String, Object> post = new HashMap<>();
|
||||||
post.put("userId", userId);
|
post.put("userId", userId);
|
||||||
post.put("action", "publicó");
|
post.put("action", "publicó");
|
||||||
post.put("mediaTitle", status);
|
post.put("mediaTitle", status);
|
||||||
|
|
||||||
api.postActivity(post).enqueue(new Callback<JsonObject>() {
|
api.postActivity(post).enqueue(new Callback<JsonObject>() {
|
||||||
@Override
|
@Override public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
||||||
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
editStatus.setText("");
|
editStatus.setText("");
|
||||||
loadActivity();
|
loadActivity();
|
||||||
Toast.makeText(getContext(), "Publicado", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), "Publicado", Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@Override public void onFailure(Call<JsonObject> call, Throwable t) {
|
||||||
@Override
|
|
||||||
public void onFailure(Call<JsonObject> call, Throwable t) {
|
|
||||||
Toast.makeText(getContext(), "Error al publicar", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), "Error al publicar", Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -312,61 +259,78 @@ public class FragmentProfile extends Fragment {
|
||||||
|
|
||||||
private void loadComments(int activityId, LinearLayout container) {
|
private void loadComments(int activityId, LinearLayout container) {
|
||||||
api.getCommentsByActivity(activityId).enqueue(new Callback<List<CommentModel>>() {
|
api.getCommentsByActivity(activityId).enqueue(new Callback<List<CommentModel>>() {
|
||||||
@Override
|
@Override public void onResponse(Call<List<CommentModel>> call, Response<List<CommentModel>> response) {
|
||||||
public void onResponse(Call<List<CommentModel>> call, Response<List<CommentModel>> response) {
|
|
||||||
if (response.isSuccessful() && response.body() != null) {
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
container.removeAllViews();
|
container.removeAllViews();
|
||||||
LayoutInflater inflater = LayoutInflater.from(getContext());
|
LayoutInflater inflater = LayoutInflater.from(getContext());
|
||||||
|
|
||||||
for (CommentModel comment : response.body()) {
|
for (CommentModel comment : response.body()) {
|
||||||
View commentView = LayoutInflater.from(getContext())
|
View view = inflater.inflate(R.layout.item_comment, container, false);
|
||||||
.inflate(R.layout.item_comment, container, false);
|
((TextView) view.findViewById(R.id.commentUsername)).setText(comment.getUsername());
|
||||||
|
((TextView) view.findViewById(R.id.commentText)).setText(comment.getText());
|
||||||
TextView usernameView = commentView.findViewById(R.id.commentUsername);
|
((TextView) view.findViewById(R.id.commentDate)).setText(DateUtils.getRelativeTime(comment.getCreatedAt()));
|
||||||
TextView commentText = commentView.findViewById(R.id.commentText);
|
ImageView avatar = view.findViewById(R.id.commentAvatar);
|
||||||
TextView dateView = commentView.findViewById(R.id.commentDate);
|
|
||||||
ImageView avatar = commentView.findViewById(R.id.commentAvatar);
|
|
||||||
|
|
||||||
usernameView.setText(comment.getUsername());
|
|
||||||
commentText.setText(comment.getText());
|
|
||||||
dateView.setText(DateUtils.getRelativeTime(comment.getCreatedAt())); // usa tu util
|
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(comment.getAvatarUrl())) {
|
if (!TextUtils.isEmpty(comment.getAvatarUrl())) {
|
||||||
Glide.with(getContext())
|
Glide.with(requireContext()).load(comment.getAvatarUrl()).placeholder(R.drawable.rectangle_placeholder).error(R.drawable.error_image).into(avatar);
|
||||||
.load(comment.getAvatarUrl())
|
|
||||||
.placeholder(R.drawable.rectangle_placeholder)
|
|
||||||
.error(R.drawable.error_image)
|
|
||||||
.into(avatar);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
container.addView(commentView);
|
ImageButton replyButton = view.findViewById(R.id.replyButton);
|
||||||
}
|
replyButton.setOnClickListener(v -> {
|
||||||
|
CommentDialog dialog = new CommentDialog(requireContext(), userId, activityId, () -> loadComments(activityId, container), comment.getUsername());
|
||||||
|
dialog.show();
|
||||||
|
});
|
||||||
|
|
||||||
|
ImageButton likeButton = view.findViewById(R.id.commentLikeButton);
|
||||||
|
api.checkLike(userId, comment.getId()).enqueue(new Callback<JsonObject>() {
|
||||||
|
@Override public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
final boolean[] isLiked = {response.body().get("liked").getAsBoolean()};
|
||||||
|
actualizarCorazon(likeButton, isLiked[0]);
|
||||||
|
|
||||||
|
likeButton.setOnClickListener(v -> {
|
||||||
|
boolean newLike = !isLiked[0];
|
||||||
|
isLiked[0] = newLike;
|
||||||
|
|
||||||
|
if (newLike) {
|
||||||
|
api.postLike(createLikeJson(userId, comment.getId())).enqueue(new Callback<JsonObject>() {
|
||||||
|
@Override public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
||||||
|
actualizarCorazon(likeButton, true);
|
||||||
|
}
|
||||||
|
@Override public void onFailure(Call<JsonObject> call, Throwable t) {}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
api.deleteLike(createLikeJson(userId, comment.getId())).enqueue(new Callback<JsonObject>() {
|
||||||
|
@Override public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
||||||
|
actualizarCorazon(likeButton, false);
|
||||||
|
}
|
||||||
|
@Override public void onFailure(Call<JsonObject> call, Throwable t) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override public void onFailure(Call<JsonObject> call, Throwable t) {}
|
||||||
|
});
|
||||||
|
|
||||||
|
container.addView(view);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@Override public void onFailure(Call<List<CommentModel>> call, Throwable t) {
|
||||||
@Override
|
|
||||||
public void onFailure(Call<List<CommentModel>> call, Throwable t) {
|
|
||||||
Toast.makeText(getContext(), "Error al cargar comentarios", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), "Error al cargar comentarios", Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonObject createLikeJson(int userId, int activityId) {
|
private JsonObject createLikeJson(int userId, int targetId) {
|
||||||
JsonObject body = new JsonObject();
|
JsonObject json = new JsonObject();
|
||||||
body.addProperty("userId", userId);
|
json.addProperty("userId", userId);
|
||||||
body.addProperty("activityId", activityId);
|
json.addProperty("commentId", targetId);
|
||||||
return body;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void actualizarCorazon(ImageButton likeButton, boolean liked) {
|
private void actualizarCorazon(ImageButton btn, boolean liked) {
|
||||||
if (liked) {
|
btn.setImageResource(liked ? R.drawable.ic_heart_filled : R.drawable.ic_heart_outline);
|
||||||
likeButton.setImageResource(R.drawable.ic_heart_filled);
|
btn.setColorFilter(requireContext().getColor(liked ? R.color.pink : R.color.gray));
|
||||||
likeButton.setColorFilter(requireContext().getColor(R.color.pink));
|
|
||||||
} else {
|
|
||||||
likeButton.setImageResource(R.drawable.ic_heart_outline);
|
|
||||||
likeButton.setColorFilter(requireContext().getColor(R.color.gray));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveBiography() {
|
private void saveBiography() {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,13 @@ public class ActivityLog {
|
||||||
|
|
||||||
@SerializedName("id")
|
@SerializedName("id")
|
||||||
private int id;
|
private int id;
|
||||||
|
|
||||||
|
@SerializedName("userId")
|
||||||
|
private int userId;
|
||||||
|
|
||||||
|
@SerializedName("username")
|
||||||
|
private String username;
|
||||||
|
|
||||||
@SerializedName("action")
|
@SerializedName("action")
|
||||||
private String action;
|
private String action;
|
||||||
|
|
||||||
|
|
@ -22,6 +29,14 @@ public class ActivityLog {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
public String getAction() {
|
public String getAction() {
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,4 +59,10 @@ public class DateUtils {
|
||||||
return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
|
return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
|
||||||
cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR);
|
cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getCurrentTimestamp() {
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault());
|
||||||
|
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||||
|
return sdf.format(new Date());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,20 +1,36 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:padding="16dp"
|
android:id="@+id/commentDialogLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:background="?android:attr/windowBackground">
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/commentInput"
|
android:id="@+id/commentInput"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="Escribe tu comentario" />
|
android:hint="Escribe tu comentario..."
|
||||||
|
android:minHeight="80dp"
|
||||||
|
android:gravity="top|start"
|
||||||
|
android:inputType="textMultiLine"
|
||||||
|
android:maxLines="5"
|
||||||
|
android:background="@color/primary"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:textColor="@color/textPrimary"
|
||||||
|
android:textColorHint="@color/textPrimary"
|
||||||
|
android:textSize="15sp" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/sendComment"
|
android:id="@+id/sendComment"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Enviar"
|
android:text="Enviar"
|
||||||
|
android:textAllCaps="false"
|
||||||
android:layout_gravity="end"
|
android:layout_gravity="end"
|
||||||
android:layout_marginTop="8dp"/>
|
android:layout_marginTop="12dp"
|
||||||
|
android:backgroundTint="@color/primary"
|
||||||
|
android:textColor="@android:color/white" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
||||||
|
|
@ -1,69 +1,72 @@
|
||||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
android:id="@+id/scrollView"
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="@color/background"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:fillViewport="true"
|
android:padding="16dp">
|
||||||
android:fitsSystemWindows="true"
|
|
||||||
android:background="@color/background"
|
|
||||||
android:paddingStart="16dp"
|
|
||||||
android:paddingEnd="16dp"
|
|
||||||
android:paddingBottom="16dp">
|
|
||||||
|
|
||||||
|
<!-- Título y spinner -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginTop="75dp"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
<!-- Espaciador reducido -->
|
<TextView
|
||||||
<View
|
android:text="Browse"
|
||||||
android:id="@+id/statusBarSpacer"
|
android:textStyle="bold"
|
||||||
android:layout_width="match_parent"
|
android:textSize="24sp"
|
||||||
android:layout_height="12dp" />
|
android:textColor="@android:color/white"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
<!-- Encabezado -->
|
<Spinner
|
||||||
<LinearLayout
|
android:id="@+id/spinnerType"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:backgroundTint="@android:color/white"
|
||||||
android:gravity="center_vertical">
|
android:popupBackground="@color/primary"
|
||||||
|
android:theme="@style/ThemeOverlay.AppCompat.Dark"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<!-- Caja de búsqueda -->
|
||||||
android:id="@+id/textViewBrowse"
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Browse"
|
android:background="@drawable/bg_search_box"
|
||||||
android:textSize="24sp"
|
android:orientation="horizontal"
|
||||||
android:textStyle="bold"
|
android:layout_marginTop="16dp"
|
||||||
android:textColor="@color/textPrimary"
|
android:padding="12dp">
|
||||||
android:layout_marginEnd="8dp" />
|
|
||||||
|
|
||||||
<Spinner
|
<ImageView
|
||||||
android:id="@+id/spinnerType"
|
android:src="@android:drawable/ic_menu_search"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:backgroundTint="@color/primary" />
|
app:tint="@android:color/darker_gray" />
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- Buscador -->
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/editTextSearch"
|
android:id="@+id/editTextSearch"
|
||||||
android:layout_width="match_parent"
|
android:hint="Buscar..."
|
||||||
android:layout_height="48dp"
|
|
||||||
android:layout_marginTop="12dp"
|
|
||||||
android:hint="Search"
|
|
||||||
android:drawableStart="@android:drawable/ic_menu_search"
|
|
||||||
android:background="@drawable/edittext_background"
|
|
||||||
android:paddingStart="12dp"
|
|
||||||
android:paddingEnd="12dp"
|
|
||||||
android:textColor="@color/textPrimary"
|
|
||||||
android:textColorHint="@color/textPrimary" />
|
|
||||||
|
|
||||||
<!-- Contenedor de secciones -->
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/sectionContainer"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:paddingStart="8dp"
|
||||||
android:layout_marginTop="16dp" />
|
android:textColor="@android:color/white"
|
||||||
|
android:textColorHint="@android:color/white"
|
||||||
|
android:background="@android:color/transparent"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
||||||
|
<!-- Resultados -->
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recyclerViewResults"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:paddingBottom="16dp"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
|
||||||
|
|
@ -1,90 +1,102 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
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="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@color/background"
|
android:fillViewport="true">
|
||||||
tools:context=".ui.fragments.home.FragmentHome">
|
|
||||||
|
|
||||||
<androidx.core.widget.NestedScrollView
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:clipToPadding="false"
|
android:orientation="vertical"
|
||||||
android:fillViewport="true">
|
android:paddingTop="80dp"
|
||||||
|
android:paddingBottom="100dp">
|
||||||
|
|
||||||
<LinearLayout
|
<!-- Sección Anime en progreso -->
|
||||||
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:text="Watching"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/textPrimary" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recyclerAnime"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingBottom="16dp"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
|
android:nestedScrollingEnabled="false"
|
||||||
|
android:orientation="horizontal" />
|
||||||
|
|
||||||
|
<!-- Sección Manga en progreso -->
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:text="Reading"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/textPrimary" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recyclerManga"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingBottom="16dp"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:nestedScrollingEnabled="false"
|
||||||
|
android:orientation="horizontal" />
|
||||||
|
|
||||||
|
<!-- EditText para estado -->
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/inputStatus"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:background="@drawable/edit_text_background"
|
||||||
|
android:hint="Write a status..."
|
||||||
|
android:minHeight="60dp"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:textColor="@color/textPrimary"
|
||||||
|
android:textColorHint="@color/textPrimary"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<!-- Botón publicar -->
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnPost"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Publicar"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginBottom="16dp" />
|
||||||
|
|
||||||
|
<!-- Actividad reciente -->
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:text="Recent Activity"
|
||||||
|
android:textColor="@color/textPrimary"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/activityContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingTop="80dp"
|
android:paddingHorizontal="16dp" />
|
||||||
android:paddingBottom="100dp">
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
</LinearLayout>
|
||||||
android:id="@+id/mainRecyclerView"
|
</ScrollView>
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:clipToPadding="false"
|
|
||||||
android:contentDescription="@string/home_section_list"
|
|
||||||
android:nestedScrollingEnabled="false"
|
|
||||||
android:overScrollMode="never"
|
|
||||||
android:paddingHorizontal="16dp"
|
|
||||||
android:paddingTop="8dp" />
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/editStatus"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginHorizontal="16dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:background="@drawable/edit_text_background"
|
|
||||||
android:hint="Write a status..."
|
|
||||||
android:minHeight="60dp"
|
|
||||||
android:padding="16dp"
|
|
||||||
android:textColor="@color/textPrimary"
|
|
||||||
android:textColorHint="@color/textPrimary"
|
|
||||||
android:textSize="16sp" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginTop="24dp"
|
|
||||||
android:text="Recent Activity"
|
|
||||||
android:textColor="@color/textPrimary"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
|
||||||
android:id="@+id/activityRecyclerView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginBottom="32dp"
|
|
||||||
android:nestedScrollingEnabled="false"
|
|
||||||
android:paddingHorizontal="16dp" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/buttonShowMoreActivity"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="end"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginBottom="32dp"
|
|
||||||
android:text="Mostrar más"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/buttonShowLessActivity"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="end"
|
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginBottom="32dp"
|
|
||||||
android:text="Mostrar menos"
|
|
||||||
android:visibility="gone" />
|
|
||||||
</LinearLayout>
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
|
||||||
|
|
@ -4,66 +4,81 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:padding="8dp"
|
android:padding="8dp"
|
||||||
|
android:gravity="top"
|
||||||
android:background="@color/primary">
|
android:background="@color/primary">
|
||||||
|
|
||||||
<!-- Avatar del usuario -->
|
<!-- Avatar del usuario -->
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/commentAvatar"
|
android:id="@+id/commentAvatar"
|
||||||
android:layout_width="32dp"
|
android:layout_width="36dp"
|
||||||
android:layout_height="32dp"
|
android:layout_height="36dp"
|
||||||
android:scaleType="centerCrop"
|
|
||||||
android:src="@drawable/ic_profile"
|
android:src="@drawable/ic_profile"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:background="@drawable/circle_mask" />
|
android:background="@drawable/circle_mask"
|
||||||
|
android:clipToOutline="true" />
|
||||||
|
|
||||||
<!-- Contenido del comentario -->
|
<!-- Contenido del comentario -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1">
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<!-- Nombre del usuario -->
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/commentUsername"
|
android:id="@+id/commentUsername"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Username"
|
android:text="Usuario"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:textSize="13sp" />
|
android:textColor="@color/textPrimary"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
<!-- Texto del comentario -->
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/commentText"
|
android:id="@+id/commentText"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Comentario aquí"
|
android:text="Comentario de prueba"
|
||||||
android:textColor="@color/textPrimary"
|
android:textColor="@color/textPrimary"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:lineSpacingExtra="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:maxLines="5"
|
android:layout_marginBottom="2dp" />
|
||||||
android:ellipsize="end"
|
|
||||||
android:paddingEnd="8dp" />
|
|
||||||
|
|
||||||
<!-- Fecha -->
|
<LinearLayout
|
||||||
<TextView
|
|
||||||
android:id="@+id/commentDate"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="hace 5 min"
|
android:orientation="horizontal"
|
||||||
android:textSize="11sp"
|
android:gravity="center_vertical">
|
||||||
android:textColor="@color/gray" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- Botón de like -->
|
<TextView
|
||||||
<ImageButton
|
android:id="@+id/commentDate"
|
||||||
android:id="@+id/commentLikeButton"
|
android:layout_width="wrap_content"
|
||||||
android:layout_width="32dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="32dp"
|
android:text="hace 5 min"
|
||||||
android:src="@drawable/ic_heart"
|
android:textSize="12sp"
|
||||||
android:background="?attr/selectableItemBackgroundBorderless"
|
android:textColor="@color/gray" />
|
||||||
android:contentDescription="@string/like_comment"
|
|
||||||
app:tint="@color/gray" />
|
<ImageButton
|
||||||
|
android:id="@+id/commentLikeButton"
|
||||||
|
android:layout_width="32dp"
|
||||||
|
android:layout_height="32dp"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:src="@drawable/ic_heart"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:contentDescription="@string/like_comment"
|
||||||
|
app:tint="@color/gray" />
|
||||||
|
|
||||||
|
<!-- Botón opcional para responder -->
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/replyButton"
|
||||||
|
android:layout_width="32dp"
|
||||||
|
android:layout_height="32dp"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:src="@drawable/ic_reply"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:contentDescription="Responder comentario"
|
||||||
|
app:tint="@color/gray" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
||||||
|
|
@ -56,4 +56,8 @@
|
||||||
<item name="commentButton" type="id" />
|
<item name="commentButton" type="id" />
|
||||||
<item name="likeButton" type="id" />
|
<item name="likeButton" type="id" />
|
||||||
<item name="activityCover" type="id" />
|
<item name="activityCover" type="id" />
|
||||||
|
<item name="itemTitle" type="id" />
|
||||||
|
<item name="btnAdd" type="id" />
|
||||||
|
<item name="itemImage" type="id" />
|
||||||
|
<item name="commentDialogLayout" type="id" />
|
||||||
</resources>
|
</resources>
|
||||||
Loading…
Reference in New Issue