Untitled
package com.example.czatapp; import android.graphics.Color; import android.os.Bundle; import android.util.Log; import android.view.Gravity; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.ScrollView; import android.widget.TextView; import android.widget.Toast; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import com.google.firebase.auth.FirebaseAuth; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; public class GroupChatActivity extends AppCompatActivity { private String groupId, groupName; TextView tvGroupName; EditText etGroupChatInput; Button buttonGroupChatWyslij; LinearLayout linearLayoutGroupChatMessages; ScrollView scrollViewGroupChatMessages; DbHelper dbHelper; String currentUserUid; Map<String, String> userCache = new HashMap<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EdgeToEdge.enable(this); setContentView(R.layout.activity_group_chat); ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); dbHelper = new DbHelper(); currentUserUid = FirebaseAuth.getInstance().getUid(); groupId = getIntent().getStringExtra("groupId"); groupName = getIntent().getStringExtra("groupName"); tvGroupName = findViewById(R.id.tvGroupName); etGroupChatInput = findViewById(R.id.etGroupChatInput); buttonGroupChatWyslij = findViewById(R.id.buttonGroupChatWyslij); scrollViewGroupChatMessages = findViewById(R.id.scrollViewGroupChatMessages); linearLayoutGroupChatMessages = findViewById(R.id.linearLayoutGroupChatMessages); tvGroupName.setText(groupName); dbHelper.listenForGroupMessages(groupId, new DbHelper.OnGroupChatMessagesCallback() { @Override public void onSuccess(List<Map<String, Object>> messages) { // Sortowanie wiadomości według znacznika czasu Collections.sort(messages, new Comparator<Map<String, Object>>() { @Override public int compare(Map<String, Object> m1, Map<String, Object> m2) { return Long.compare((long) m1.get("timestamp"), (long) m2.get("timestamp")); } }); // Wyczyszczenie poprzednich wiadomości linearLayoutGroupChatMessages.removeAllViews(); // Pre-fetch all usernames prefetchUsernames(messages, new OnUsernamesPrefetchedCallback() { @Override public void onUsernamesPrefetched() { // Dodanie wiadomości do interfejsu for (Map<String, Object> message : messages) { String content = (String) message.get("content"); String sender = (String) message.get("senderUid"); long timestamp = (long) message.get("timestamp"); displayMessage(content, sender, timestamp); } } }); } @Override public void onError(Exception e) { Log.e("listenForGroupMessages", "Błąd w czasie rzeczywistym", e); } }); buttonGroupChatWyslij.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String message = etGroupChatInput.getText().toString(); if (!message.isEmpty()) { dbHelper.sendGroupChatMessage(groupId, currentUserUid, message); etGroupChatInput.setText(""); // Czyścimy pole tekstowe po wysłaniu } else { Toast.makeText(getApplicationContext(), "Wiadomość nie może być pusta!", Toast.LENGTH_SHORT).show(); } } }); } private void prefetchUsernames(List<Map<String, Object>> messages, OnUsernamesPrefetchedCallback callback) { int[] remaining = {messages.size()}; // Use an array to hold the count of remaining messages to fetch for (Map<String, Object> message : messages) { String sender = (String) message.get("senderUid"); if (!userCache.containsKey(sender)) { dbHelper.findUserById(sender, new DbHelper.OnUserFoundCallback() { @Override public void onUserFound(Map<String, Object> user) { String username = (String) user.get("nickname"); userCache.put(sender, username); // Dodanie do cache remaining[0]--; if (remaining[0] == 0) { callback.onUsernamesPrefetched(); } } @Override public void onUserNotFound() { Log.e("prefetchUsernames", "Nie znaleziono użytkownika o UID: " + sender); remaining[0]--; if (remaining[0] == 0) { callback.onUsernamesPrefetched(); } } @Override public void onError(Exception e) { Log.e("prefetchUsernames", "Błąd podczas pobierania danych użytkownika", e); remaining[0]--; if (remaining[0] == 0) { callback.onUsernamesPrefetched(); } } }); } else { remaining[0]--; if (remaining[0] == 0) { callback.onUsernamesPrefetched(); } } } } private void displayMessage(String content, String sender, long timestamp) { // Identyfikacja bieżącego użytkownika boolean isCurrentUser = sender.equals(currentUserUid); // Tworzenie LinearLayout dla wiadomości LinearLayout messageLayout = new LinearLayout(this); messageLayout.setOrientation(LinearLayout.VERTICAL); messageLayout.setPadding(10, 10, 10, 10); // Ustawienie parametrów LayoutParams LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT ); if (isCurrentUser) { // Wiadomość użytkownika po prawej layoutParams.gravity = Gravity.END; messageLayout.setBackgroundResource(R.drawable.chat_bubble_right); } else { // Wiadomość innego użytkownika po lewej layoutParams.gravity = Gravity.START; messageLayout.setBackgroundResource(R.drawable.chat_bubble_left); } layoutParams.bottomMargin = 10; messageLayout.setLayoutParams(layoutParams); messageLayout.setPadding(16, 8, 16, 8); // Tworzenie TextView dla treści wiadomości TextView textViewMessage = new TextView(this); textViewMessage.setText(content); textViewMessage.setTextColor(Color.WHITE); textViewMessage.setTextSize(18); textViewMessage.setPadding(8, 8, 8, 8); // Pobieranie nazwy użytkownika z cache String username = userCache.get(sender); addMessageToLayout(messageLayout, textViewMessage, username, timestamp); } private void addMessageToLayout(LinearLayout messageLayout, TextView textViewMessage, String username, long timestamp) { // Tworzenie TextView dla znacznika czasu z nazwą użytkownika TextView textViewTimestamp = new TextView(GroupChatActivity.this); textViewTimestamp.setText(username + " - " + new Date(timestamp).toString()); textViewTimestamp.setTextColor(Color.GRAY); textViewTimestamp.setTextSize(12); textViewTimestamp.setPadding(8, 8, 8, 8); // Dodawanie widoków do układu wiadomości messageLayout.addView(textViewMessage); messageLayout.addView(textViewTimestamp); // Dodanie układu wiadomości do głównego kontenera linearLayoutGroupChatMessages.addView(messageLayout); scrollViewGroupChatMessages.post(() -> scrollViewGroupChatMessages.fullScroll(View.FOCUS_DOWN)); } private interface OnUsernamesPrefetchedCallback { void onUsernamesPrefetched(); } }
Leave a Comment