60 private static final int PICK_IMAGE_REQUEST = 1;
61 private TextView tvNombre, tvEmail;
62 private CircleImageView profileImage;
72 public View
onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
73 View view = inflater.inflate(R.layout.fragment_profile, container,
false);
76 tvNombre = view.findViewById(R.id.user_name);
77 tvEmail = view.findViewById(R.id.user_email);
78 profileImage = view.findViewById(R.id.profile_image);
87 profileImage.setOnClickListener(v -> selectImage());
90 TextView personalData = view.findViewById(R.id.personal_data);
93 personalData.setOnClickListener(v -> {
96 getParentFragmentManager().beginTransaction()
97 .replace(R.id.fragment_container_view, personalDataFragment)
103 TextView closeSession = view.findViewById(R.id.logout);
106 closeSession.setOnClickListener(v -> {
108 new AlertDialog.Builder(requireContext())
109 .setTitle(
"Cerrar sesión")
110 .setMessage(
"¿Estás seguro de que deseas cerrar tu sesión?")
111 .setPositiveButton(
"Sí", (dialog, which) -> {
113 sessionManager.logout();
116 Toast.makeText(requireContext(),
"Sesión cerrada exitosamente", Toast.LENGTH_SHORT).show();
119 Intent intent =
new Intent(requireActivity(),
MainActivity.class);
120 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
121 startActivity(intent);
122 requireActivity().finish();
124 .setNegativeButton(
"No",
null)
129 TextView viewOrders = view.findViewById(R.id.view_orders);
130 viewOrders.setOnClickListener(v -> {
131 String url =
"https://backmobile1.onrender.com/appCART/ver_dashboard/";
132 RequestQueue queue = Volley.newRequestQueue(requireContext());
133 JsonObjectRequest request =
new JsonObjectRequest(Request.Method.GET, url,
null,
136 Log.d(
"DASHBOARD",
"Respuesta cruda: " + response.toString());
137 if (response.has(
"results")) {
138 org.json.JSONArray pedidos = response.getJSONArray(
"results");
139 Log.d(
"DASHBOARD",
"Pedidos recibidos: " + pedidos.length());
140 if (pedidos.length() == 0) {
141 mostrarMensajeNoPedidos();
143 mostrarDialogoConPedidos(pedidos);
146 Log.e(
"DASHBOARD",
"No hay campo 'results' en la respuesta: " + response.toString());
147 mostrarMensajeSinResultados(response);
149 } catch (Exception e) {
150 Log.e(
"DASHBOARD",
"Error parseando respuesta: " + Log.getStackTraceString(e));
151 mostrarMensajeError(e, response);
155 String msg =
"Error al obtener pedidos";
156 if (error.networkResponse !=
null) {
157 msg +=
". Código: " + error.networkResponse.statusCode;
159 String body =
new String(error.networkResponse.data,
"UTF-8");
160 Log.e(
"DASHBOARD",
"Respuesta error: " + body);
162 }
catch (Exception ex) {
163 Log.e(
"DASHBOARD",
"Error leyendo body de error", ex);
166 Log.e(
"DASHBOARD",
"Volley error sin networkResponse", error);
168 Toast.makeText(requireContext(), msg, Toast.LENGTH_LONG).show();
172 public Map<String, String> getHeaders()
throws AuthFailureError {
173 Map<String, String> headers =
new HashMap<>();
174 String token = sessionManager.getToken();
176 headers.put(
"Authorization",
"Bearer " + token);
183 request.setRetryPolicy(
new com.android.volley.DefaultRetryPolicy(
191 TextView legalInfo = view.findViewById(R.id.legal_info);
192 legalInfo.setOnClickListener(v -> {
195 getParentFragmentManager().beginTransaction()
196 .replace(R.id.fragment_container_view, eulaFragment)
197 .addToBackStack(
null)
202 Button btnDeleteAccount = view.findViewById(R.id.btn_delete_account);
203 btnDeleteAccount.setOnClickListener(v -> {
204 new AlertDialog.Builder(requireContext())
205 .setTitle(
"Eliminar cuenta")
206 .setMessage(
"¿Estás seguro de que deseas eliminar tu cuenta? Esta acción no se puede deshacer.")
207 .setPositiveButton(
"Sí, eliminar", (dialog, which) -> eliminarCuenta())
208 .setNegativeButton(
"Cancelar",
null)
218 private void mostrarMensajeNoPedidos() {
219 new AlertDialog.Builder(requireContext())
220 .setTitle(
"Mis pedidos")
221 .setMessage(
"No tienes pedidos registrados.")
222 .setPositiveButton(
"OK",
null)
229 private void mostrarMensajeSinResultados(JSONObject response) {
230 new AlertDialog.Builder(requireContext())
231 .setTitle(
"Sin resultados")
232 .setMessage(
"No se encontraron pedidos.\n\nRespuesta del servidor: " + response.toString())
233 .setPositiveButton(
"OK",
null)
240 private void mostrarMensajeError(Exception e, JSONObject response) {
241 new AlertDialog.Builder(requireContext())
243 .setMessage(
"Ocurrió un problema al procesar los pedidos: " + e.getMessage() +
244 "\n\nRespuesta: " + response.toString())
245 .setPositiveButton(
"OK",
null)
252 private void mostrarDialogoConPedidos(org.json.JSONArray pedidos)
throws JSONException {
254 LinearLayout contenedorPrincipal =
new LinearLayout(requireContext());
255 contenedorPrincipal.setOrientation(LinearLayout.VERTICAL);
256 contenedorPrincipal.setLayoutParams(
new LinearLayout.LayoutParams(
257 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
258 contenedorPrincipal.setPadding(32, 32, 32, 32);
261 ScrollView scrollView =
new ScrollView(requireContext());
262 scrollView.setLayoutParams(
new ViewGroup.LayoutParams(
263 ViewGroup.LayoutParams.MATCH_PARENT,
264 (
int) (350 * getResources().getDisplayMetrics().density)));
267 LinearLayout contenedorPedidos =
new LinearLayout(requireContext());
268 contenedorPedidos.setOrientation(LinearLayout.VERTICAL);
269 contenedorPedidos.setLayoutParams(
new LinearLayout.LayoutParams(
270 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
273 for (
int i = 0; i < pedidos.length(); i++) {
274 org.json.JSONObject pedido = pedidos.getJSONObject(i);
277 int numeroPedido = pedido.has(
"id_pedidos") ?
278 pedido.getInt(
"id_pedidos") : (i + 1);
281 CardView cardPedido =
new CardView(requireContext());
282 cardPedido.setLayoutParams(
new CardView.LayoutParams(
283 CardView.LayoutParams.MATCH_PARENT, CardView.LayoutParams.WRAP_CONTENT));
284 cardPedido.setRadius(16);
285 cardPedido.setCardElevation(8);
286 cardPedido.setCardBackgroundColor(Color.parseColor(
"#FFFFFF"));
287 cardPedido.setUseCompatPadding(
true);
290 LinearLayout contenidoCard =
new LinearLayout(requireContext());
291 contenidoCard.setOrientation(LinearLayout.VERTICAL);
292 contenidoCard.setLayoutParams(
new LinearLayout.LayoutParams(
293 LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
294 contenidoCard.setPadding(16, 16, 16, 16);
297 TextView tvTituloPedido =
new TextView(requireContext());
298 tvTituloPedido.setText(
"\uD83D\uDCC5 Pedido #" + numeroPedido);
299 tvTituloPedido.setTextSize(18);
300 tvTituloPedido.setTypeface(Typeface.DEFAULT_BOLD);
301 tvTituloPedido.setLayoutParams(
new LinearLayout.LayoutParams(
302 LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
303 tvTituloPedido.setPadding(0, 0, 0, 8);
304 contenidoCard.addView(tvTituloPedido);
307 if (pedido.has(
"fecha_pedido")) {
308 TextView tvFecha =
new TextView(requireContext());
309 tvFecha.setText(
"Fecha: " + pedido.getString(
"fecha_pedido"));
310 tvFecha.setLayoutParams(
new LinearLayout.LayoutParams(
311 LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
312 tvFecha.setPadding(16, 4, 0, 4);
313 contenidoCard.addView(tvFecha);
317 if (pedido.has(
"estado")) {
318 TextView tvEstado =
new TextView(requireContext());
319 tvEstado.setText(
"Estado: " + pedido.getString(
"estado"));
320 tvEstado.setLayoutParams(
new LinearLayout.LayoutParams(
321 LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
322 tvEstado.setPadding(16, 4, 0, 4);
323 contenidoCard.addView(tvEstado);
331 LinearLayout layoutDireccion =
new LinearLayout(requireContext());
332 layoutDireccion.setOrientation(LinearLayout.HORIZONTAL);
333 layoutDireccion.setLayoutParams(
new LinearLayout.LayoutParams(
334 LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
341 final int pedidoId = numeroPedido;
347 if (pedido.has(
"detalles")) {
348 org.json.JSONArray detalles = pedido.getJSONArray(
"detalles");
349 if (detalles.length() > 0) {
350 TextView tvProductosHeader =
new TextView(requireContext());
351 tvProductosHeader.setText(
"Productos:");
352 tvProductosHeader.setTypeface(Typeface.DEFAULT_BOLD);
353 tvProductosHeader.setLayoutParams(
new LinearLayout.LayoutParams(
354 LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
355 tvProductosHeader.setPadding(16, 8, 0, 4);
356 contenidoCard.addView(tvProductosHeader);
358 for (
int j = 0; j < detalles.length(); j++) {
359 org.json.JSONObject detalle = detalles.getJSONObject(j);
360 TextView tvProducto =
new TextView(requireContext());
361 StringBuilder productoInfo =
new StringBuilder();
362 productoInfo.append(
"- Cantidad: ").append(detalle.optInt(
"cantidad_productos", 0));
363 productoInfo.append(
", Precio: $").append(detalle.optDouble(
"precio_producto", 0));
364 productoInfo.append(
", Subtotal: $").append(detalle.optDouble(
"subtotal", 0));
366 tvProducto.setText(productoInfo.toString());
367 tvProducto.setLayoutParams(
new LinearLayout.LayoutParams(
368 LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
369 tvProducto.setPadding(32, 2, 0, 2);
370 contenidoCard.addView(tvProducto);
376 cardPedido.addView(contenidoCard);
379 contenedorPedidos.addView(cardPedido);
383 scrollView.addView(contenedorPedidos);
386 contenedorPrincipal.addView(scrollView);
389 new AlertDialog.Builder(requireContext())
390 .setTitle(
"Mis pedidos")
391 .setView(contenedorPrincipal)
392 .setPositiveButton(
"Cerrar",
null)
402 private void mostrarDialogoEditarDireccion(
int pedidoId, String direccionActual, TextView tvDireccion) {
404 final EditText input =
new EditText(requireContext());
405 input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE);
406 input.setText(direccionActual);
407 input.setSingleLine(
false);
409 input.setMaxLines(5);
410 input.setGravity(Gravity.TOP | Gravity.START);
413 new AlertDialog.Builder(requireContext())
414 .setTitle(
"Editar dirección de entrega")
416 .setPositiveButton(
"Guardar", (dialog, which) -> {
417 String nuevaDireccion = input.getText().toString().trim();
418 if (!nuevaDireccion.isEmpty()) {
420 actualizarDireccionEnBackend(pedidoId, nuevaDireccion, tvDireccion);
422 Toast.makeText(requireContext(),
"La dirección no puede estar vacía", Toast.LENGTH_SHORT).show();
425 .setNegativeButton(
"Cancelar",
null)
435 private void actualizarDireccionEnBackend(
int pedidoId, String nuevaDireccion, TextView tvDireccion) {
437 String url =
"https://backmobile1.onrender.com/appCART/actualizar_direccion/";
440 ProgressDialog progressDialog =
new ProgressDialog(requireContext());
441 progressDialog.setMessage(
"Actualizando dirección...");
442 progressDialog.setCancelable(
false);
443 progressDialog.show();
446 JSONObject requestBody =
new JSONObject();
448 requestBody.put(
"id_pedidos", pedidoId);
449 requestBody.put(
"direccion_entrega", nuevaDireccion);
450 }
catch (JSONException e) {
451 progressDialog.dismiss();
452 Toast.makeText(requireContext(),
"Error al preparar los datos", Toast.LENGTH_SHORT).show();
457 JsonObjectRequest request =
new JsonObjectRequest(
462 progressDialog.dismiss();
464 boolean success = response.optBoolean(
"success", true);
467 tvDireccion.setText(
"Dirección: " + nuevaDireccion);
468 Toast.makeText(requireContext(),
"Dirección actualizada correctamente", Toast.LENGTH_SHORT).show();
470 String message = response.optString(
"message",
"Error desconocido");
471 Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show();
473 } catch (Exception e) {
474 Toast.makeText(requireContext(),
"Error al procesar la respuesta", Toast.LENGTH_SHORT).show();
478 progressDialog.dismiss();
480 String mensaje =
"Error al actualizar la dirección";
481 if (error.networkResponse !=
null) {
482 mensaje +=
" (Código: " + error.networkResponse.statusCode +
")";
484 String responseBody =
new String(error.networkResponse.data,
"utf-8");
485 JSONObject errorObj =
new JSONObject(responseBody);
486 if (errorObj.has(
"message")) {
487 mensaje +=
": " + errorObj.getString(
"message");
489 }
catch (Exception e) {
494 Toast.makeText(requireContext(), mensaje, Toast.LENGTH_SHORT).show();
498 public Map<String, String> getHeaders() throws AuthFailureError {
499 Map<String, String> headers =
new HashMap<>();
500 String token = sessionManager.
getToken();
502 headers.put(
"Authorization",
"Bearer " + token);
504 headers.put(
"Content-Type",
"application/json");
510 RequestQueue requestQueue = Volley.newRequestQueue(requireContext());
511 requestQueue.add(request);
514 private void displayUserProfile() {
516 String name = profileManager.
getName();
518 String email = profileManager.
getEmail();
522 tvNombre.setText(name +
" " + surname);
523 tvEmail.setText(email);
526 if (imageUrl !=
null && !imageUrl.isEmpty()) {
527 Log.d(
"ImagenPerfil",
"Cargando imagen en ProfileFragment: " + imageUrl);
530 com.example.food_front.utils.ImageCacheManager.clearGlideCache(requireContext());
536 String imageUrlNoCache = imageUrl +
"?nocache=" + System.currentTimeMillis() +
"&random=" + Math.random();
539 java.net.URL url =
new java.net.URL(imageUrlNoCache);
540 java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
541 connection.setUseCaches(
false);
542 connection.addRequestProperty(
"Cache-Control",
"no-cache, no-store, must-revalidate");
543 connection.addRequestProperty(
"Pragma",
"no-cache");
544 connection.addRequestProperty(
"Expires",
"0");
545 connection.connect();
548 final android.graphics.Bitmap bitmap = android.graphics.BitmapFactory.decodeStream(connection.getInputStream());
551 if (getActivity() !=
null && !getActivity().isFinishing()) {
552 getActivity().runOnUiThread(() -> {
553 if (bitmap !=
null) {
554 profileImage.setImageBitmap(bitmap);
555 Log.d(
"ImagenPerfil",
"Imagen cargada exitosamente mediante HttpURLConnection");
558 cargarImagenConGlide(imageUrl);
562 }
catch (Exception e) {
563 Log.e(
"ImagenPerfil",
"Error al descargar imagen: " + e.getMessage());
564 if (getActivity() !=
null && !getActivity().isFinishing()) {
565 getActivity().runOnUiThread(() -> cargarImagenConGlide(imageUrl));
570 Log.d(
"ImagenPerfil",
"No hay URL de imagen, usando imagen predeterminada en ProfileFragment");
572 profileImage.setImageResource(R.drawable.default_profile);
576 private void cargarImagenConGlide(String imageUrl) {
578 String imageUrlWithTimestamp = imageUrl +
"?t=" + System.currentTimeMillis() +
"&r=" + Math.random();
579 Log.d(
"ImagenPerfil",
"Intentando cargar con Glide como respaldo: " + imageUrlWithTimestamp);
582 Glide.with(requireContext())
583 .load(imageUrlWithTimestamp)
584 .skipMemoryCache(
true)
585 .diskCacheStrategy(com.bumptech.glide.load.engine.DiskCacheStrategy.NONE)
586 .placeholder(R.drawable.default_profile)
587 .error(R.drawable.default_profile)
591 private void selectImage() {
592 Intent intent =
new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
593 intent.setType(
"image/*");
594 startActivityForResult(Intent.createChooser(intent,
"Selecciona una imagen"), PICK_IMAGE_REQUEST);
599 super.onActivityResult(requestCode, resultCode, data);
600 if (requestCode == PICK_IMAGE_REQUEST && resultCode == Activity.RESULT_OK && data !=
null && data.getData() !=
null) {
601 Uri imageUri = data.getData();
604 android.graphics.Bitmap bitmap = android.provider.MediaStore.Images.Media.getBitmap(requireContext().getContentResolver(), imageUri);
607 android.graphics.Bitmap resizedBitmap = resizeImage(bitmap, 800);
610 ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream();
611 resizedBitmap.compress(android.graphics.Bitmap.CompressFormat.JPEG, 70, byteArrayOutputStream);
612 byte[] imageBytes = byteArrayOutputStream.toByteArray();
615 Log.d(
"ImagenPerfil",
"Tamaño de la imagen comprimida: " + (imageBytes.length / 1024) +
" KB");
618 uploadImage(imageBytes);
619 }
catch (FileNotFoundException e) {
621 Toast.makeText(requireContext(),
"Archivo no encontrado", Toast.LENGTH_SHORT).show();
622 }
catch (IOException e) {
624 Toast.makeText(requireContext(),
"Error al leer el archivo", Toast.LENGTH_SHORT).show();
635 private android.graphics.Bitmap resizeImage(android.graphics.Bitmap image,
int maxSize) {
636 int width = image.getWidth();
637 int height = image.getHeight();
639 float ratio = (float) width / (
float) height;
644 if (width > height) {
646 newHeight = Math.round(maxSize / ratio);
649 newWidth = Math.round(maxSize * ratio);
652 return android.graphics.Bitmap.createScaledBitmap(image, newWidth, newHeight,
true);
655 private void uploadImage(
byte[] imageBytes) {
657 ProgressDialog progressDialog =
new ProgressDialog(requireContext());
658 progressDialog.setMessage(
"Preparando imagen...");
659 progressDialog.setCancelable(
false);
660 progressDialog.show();
663 if (imageBytes.length > 1024 * 1024) {
664 progressDialog.dismiss();
665 new AlertDialog.Builder(requireContext())
666 .setTitle(
"Imagen demasiado grande")
667 .setMessage(
"La imagen seleccionada es de " + (imageBytes.length / 1024 / 1024) +
"MB. Es posible que la subida sea lenta. ¿Deseas intentar subir la imagen de todos modos?")
668 .setPositiveButton(
"Sí, intentar", (dialog, which) -> {
670 uploadToCloudinary(imageBytes, progressDialog);
672 .setNegativeButton(
"No, cancelar", (dialog, which) -> {
673 Toast.makeText(requireContext(),
"Subida cancelada", Toast.LENGTH_SHORT).show();
678 uploadToCloudinary(imageBytes, progressDialog);
687 private void uploadToCloudinary(
byte[] imageBytes, ProgressDialog progressDialog) {
688 if (progressDialog ==
null) {
689 progressDialog =
new ProgressDialog(requireContext());
690 progressDialog.setMessage(
"Subiendo imagen...");
691 progressDialog.setCancelable(
false);
692 progressDialog.show();
694 progressDialog.setMessage(
"Subiendo imagen a Cloudinary...");
697 final ProgressDialog finalProgressDialog = progressDialog;
700 com.example.food_front.utils.CloudinaryManager.uploadImage(
704 new com.example.food_front.utils.CloudinaryManager.CloudinaryUploadCallback() {
706 public void onStart() {
707 if (getActivity() != null && !getActivity().isFinishing()) {
708 getActivity().runOnUiThread(() -> {
709 finalProgressDialog.setMessage(
"Iniciando subida...");
715 public void onProgress(
double progress) {
716 if (getActivity() !=
null && !getActivity().isFinishing()) {
717 getActivity().runOnUiThread(() -> {
718 int progressInt = (int) (progress * 100);
719 finalProgressDialog.setMessage(
"Subiendo imagen: " + progressInt +
"%");
725 public void onSuccess(String imageUrl) {
726 if (getActivity() !=
null && !getActivity().isFinishing()) {
727 getActivity().runOnUiThread(() -> {
728 finalProgressDialog.dismiss();
734 cargarImagenConGlide(imageUrl);
737 MainActivity mainActivity = (MainActivity) getActivity();
738 if (mainActivity !=
null) {
739 mainActivity.actualizarTodasLasImagenes();
742 Toast.makeText(requireContext(),
"Imagen subida correctamente", Toast.LENGTH_SHORT).show();
745 actualizarImagenEnBackend(imageUrl);
751 public void onError(String errorMessage) {
752 if (getActivity() !=
null && !getActivity().isFinishing()) {
753 getActivity().runOnUiThread(() -> {
754 finalProgressDialog.dismiss();
755 Toast.makeText(requireContext(),
"Error: " + errorMessage, Toast.LENGTH_LONG).show();
758 new AlertDialog.Builder(requireContext())
759 .setTitle(
"Error con Cloudinary")
760 .setMessage(
"¿Deseas intentar subir la imagen usando el método alternativo?")
761 .setPositiveButton(
"Sí, intentar", (dialog, which) -> {
763 continueUpload(imageBytes,
"https://backmobile1.onrender.com/appUSERS/upload_profile_image/");
765 .setNegativeButton(
"Cancelar",
null)
778 private void actualizarImagenEnBackend(String imageUrl) {
779 String url =
"https://backmobile1.onrender.com/appUSERS/update_profile_image_url/";
783 JSONObject jsonBody =
new JSONObject();
784 jsonBody.put(
"imagen_perfil_url", imageUrl);
787 JsonObjectRequest request =
new JsonObjectRequest(
792 Log.d(
"ImagenPerfil",
"URL actualizada en backend: " + response.toString());
795 Log.e(
"ImagenPerfil",
"Error al actualizar URL en backend", error);
799 public Map<String, String> getHeaders() throws AuthFailureError {
800 Map<String, String> headers =
new HashMap<>();
801 String token = sessionManager.
getToken();
803 headers.put(
"Authorization",
"Bearer " + token);
810 RequestQueue requestQueue = Volley.newRequestQueue(requireContext());
811 requestQueue.add(request);
813 }
catch (Exception e) {
814 Log.e(
"ImagenPerfil",
"Error al crear solicitud para actualizar URL", e);
823 if (imageUrl ==
null || imageUrl.isEmpty())
return;
825 Log.d(
"ImagenPerfil",
"actualizarImagenDePerfil llamado con URL: " + imageUrl);
828 com.example.food_front.utils.ImageCacheManager.clearGlideCache(requireContext());
831 profileManager.saveProfileImageUrl(imageUrl);
834 if (profileImage !=
null) {
835 cargarImagenConGlide(imageUrl);
844 private void continueUpload(
byte[] imageBytes, String url) {
846 ProgressDialog progressDialog =
new ProgressDialog(requireContext());
847 progressDialog.setMessage(
"Subiendo imagen...");
848 progressDialog.setCancelable(
false);
849 progressDialog.show();
854 progressDialog.dismiss();
857 String responseBody = new String(response.data);
858 Log.d(
"ImagenPerfil",
"Respuesta del servidor: " + responseBody);
861 JSONObject jsonObject = new JSONObject(responseBody);
864 if (jsonObject.has(
"error")) {
865 String error = jsonObject.getString(
"error");
866 Log.e(
"ImagenPerfil",
"Error del servidor: " + error);
867 Toast.makeText(requireContext(),
"Error: " + error, Toast.LENGTH_LONG).show();
872 String imageUrl = null;
873 if (jsonObject.has(
"imagen_perfil_url")) {
874 imageUrl = jsonObject.getString(
"imagen_perfil_url");
875 } else if (jsonObject.has(
"image_url")) {
876 imageUrl = jsonObject.getString(
"image_url");
877 } else if (jsonObject.has(
"url")) {
878 imageUrl = jsonObject.getString(
"url");
881 if (imageUrl == null || imageUrl.isEmpty()) {
882 Log.e(
"ImagenPerfil",
"URL de imagen no encontrada en la respuesta: " + responseBody);
883 Toast.makeText(requireContext(),
"Error: No se recibió la URL de la imagen", Toast.LENGTH_SHORT).show();
888 final String finalImageUrl = imageUrl;
889 Log.d(
"ImagenPerfil",
"URL de imagen recibida: " + finalImageUrl);
892 com.example.food_front.utils.ImageCacheManager.clearGlideCache(requireContext());
895 profileManager.saveProfileImageUrl(finalImageUrl);
898 cargarImagenConGlide(finalImageUrl);
901 MainActivity mainActivity = (MainActivity) getActivity();
902 if (mainActivity != null) {
903 mainActivity.actualizarTodasLasImagenes();
906 Toast.makeText(requireContext(),
"Imagen de perfil actualizada", Toast.LENGTH_SHORT).show();
907 } catch (JSONException e) {
908 Log.e(
"ImagenPerfil",
"Error al procesar la respuesta JSON: " + e.getMessage() +
"\nRespuesta: " + responseBody);
909 Toast.makeText(requireContext(),
"Error al procesar la respuesta del servidor", Toast.LENGTH_SHORT).show();
913 progressDialog.dismiss();
914 handleNetworkError(error);
918 protected Map<String, String> getParams() {
919 Map<String, String> params =
new HashMap<>();
924 public Map<String, String> getHeaders() throws AuthFailureError {
925 Map<String, String> headers =
new HashMap<>();
927 String token = sessionManager.
getToken();
929 headers.put(
"Authorization",
"Bearer " + token);
936 multipartRequest.
addByteData(
"image", imageBytes,
"profile_image.jpg",
"image/jpeg");
939 multipartRequest.setRetryPolicy(
new com.android.volley.DefaultRetryPolicy(
946 RequestQueue requestQueue = Volley.newRequestQueue(requireContext());
947 requestQueue.add(multipartRequest);
954 private void handleNetworkError(VolleyError error) {
955 String errorMsg =
"Error al subir la imagen: ";
957 if (error.networkResponse !=
null) {
958 int statusCode = error.networkResponse.statusCode;
959 errorMsg +=
"Código: " + statusCode;
963 String responseBody =
new String(error.networkResponse.data,
"utf-8");
964 Log.e(
"ImagenPerfil",
"Error response body: " + responseBody);
967 if (statusCode == 502) {
968 showCloudflareErrorDialog();
972 errorMsg +=
" - " + responseBody;
973 }
catch (Exception e) {
974 Log.e(
"ImagenPerfil",
"Error al leer el cuerpo de la respuesta de error", e);
976 }
else if (error instanceof com.android.volley.TimeoutError) {
977 errorMsg =
"El servidor tardó demasiado en responder. La imagen podría ser demasiado grande.";
978 showCloudflareErrorDialog();
980 }
else if (error instanceof com.android.volley.NoConnectionError) {
981 errorMsg =
"No hay conexión a internet. Por favor, verifica tu conexión e intenta nuevamente.";
983 errorMsg += error.toString();
986 Log.e(
"ImagenPerfil", errorMsg, error);
987 Toast.makeText(requireContext(), errorMsg, Toast.LENGTH_LONG).show();
993 private void showCloudflareErrorDialog() {
994 if (getContext() ==
null)
return;
996 new AlertDialog.Builder(requireContext())
997 .setTitle(
"Problema con el servidor")
998 .setMessage(
"El servidor está experimentando problemas temporales (Error 502 Bad Gateway). Esto puede deberse a que:\n\n" +
999 "1. El servidor está ocupado o en mantenimiento\n" +
1000 "2. La imagen es demasiado grande para ser procesada\n\n" +
1001 "¿Qué deseas hacer?")
1002 .setPositiveButton(
"Intentar con otra imagen", (dialog, which) -> {
1006 .setNegativeButton(
"Cancelar",
null)
1011 private void eliminarCuenta() {
1012 String url =
"https://backmobile1.onrender.com/appUSERS/delete/";
1013 ProgressDialog progressDialog =
new ProgressDialog(requireContext());
1014 progressDialog.setMessage(
"Eliminando cuenta...");
1015 progressDialog.setCancelable(
false);
1016 progressDialog.show();
1018 com.android.volley.toolbox.StringRequest request =
new com.android.volley.toolbox.StringRequest(
1019 com.android.volley.Request.Method.DELETE,
1022 progressDialog.dismiss();
1023 Toast.makeText(requireContext(),
"Cuenta eliminada satisfactoriamente", Toast.LENGTH_LONG).show();
1024 sessionManager.logout();
1025 Intent intent = new Intent(requireActivity(), MainActivity.class);
1026 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
1027 startActivity(intent);
1028 requireActivity().finish();
1031 progressDialog.dismiss();
1034 String errorMsg =
"Error al eliminar la cuenta: ";
1036 if (error.networkResponse != null) {
1037 int statusCode = error.networkResponse.statusCode;
1038 errorMsg +=
"Código: " + statusCode;
1042 String responseBody = new String(error.networkResponse.data,
"utf-8");
1043 Log.e(
"EliminarCuenta",
"Error response body: " + responseBody);
1044 errorMsg +=
" - " + responseBody;
1047 if (statusCode == 500 && responseBody.contains(
"Cuenta desactivada correctamente")) {
1049 Toast.makeText(requireContext(),
"Cuenta eliminada satisfactoriamente", Toast.LENGTH_LONG).show();
1050 sessionManager.logout();
1051 Intent intent = new Intent(requireActivity(), MainActivity.class);
1052 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
1053 startActivity(intent);
1054 requireActivity().finish();
1057 } catch (Exception e) {
1058 Log.e(
"EliminarCuenta",
"Error al leer el cuerpo de la respuesta de error", e);
1060 }
else if (error instanceof com.android.volley.TimeoutError) {
1061 errorMsg =
"El servidor tardó demasiado en responder.";
1062 }
else if (error instanceof com.android.volley.NoConnectionError) {
1063 errorMsg =
"No hay conexión a internet. Por favor, verifica tu conexión e intenta nuevamente.";
1065 errorMsg += error.toString();
1068 Log.e(
"EliminarCuenta", errorMsg, error);
1069 Toast.makeText(requireContext(), errorMsg, Toast.LENGTH_LONG).show();
1073 public Map<String, String> getHeaders() throws AuthFailureError {
1074 Map<String, String> headers =
new HashMap<>();
1075 String token = sessionManager.
getToken();
1076 if (token !=
null) {
1077 headers.put(
"Authorization",
"Bearer " + token);
1084 request.setRetryPolicy(
new com.android.volley.DefaultRetryPolicy(
1090 com.android.volley.toolbox.Volley.newRequestQueue(requireContext()).add(request);