continuar utilizador
This commit is contained in:
@@ -27,6 +27,8 @@
|
||||
<activity android:name=".MainActivity" />
|
||||
<activity android:name=".SettingsActivity" />
|
||||
<activity android:name=".StreakActivity" />
|
||||
<activity android:name=".FindFriendsActivity" />
|
||||
|
||||
|
||||
|
||||
</application>
|
||||
|
||||
@@ -11,6 +11,10 @@ import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import com.google.firebase.auth.FirebaseUser;
|
||||
import com.google.firebase.firestore.ListenerRegistration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -27,14 +31,16 @@ import java.util.List;
|
||||
|
||||
public class InicioFragment extends Fragment {
|
||||
|
||||
private TextView tvTimer, tvProgressText;
|
||||
private TextView tvTimer, tvProgressText, tvGreeting;
|
||||
private FrameLayout timerBlock;
|
||||
private LinearLayout tasksContainer;
|
||||
private ProgressBar pbDailyTasks;
|
||||
private CountDownTimer countDownTimer;
|
||||
private LinearLayout progressPathContainer;
|
||||
private List<View> dayNodes = new ArrayList<>();
|
||||
private int currentDayIndex = 0; // 0-based index for the current day in the path
|
||||
private int currentDayIndex = 0;
|
||||
private ListenerRegistration tasksListener, userListener;
|
||||
private List<Task> currentTasks = new ArrayList<>();
|
||||
|
||||
private boolean isTimerRunning = false;
|
||||
private long timeLeftInMillis = 25 * 60 * 1000; // 25 minutos
|
||||
@@ -46,14 +52,18 @@ public class InicioFragment extends Fragment {
|
||||
View view = inflater.inflate(R.layout.fragment_inicio, container, false);
|
||||
|
||||
tvTimer = view.findViewById(R.id.tvTimer);
|
||||
tvGreeting = view.findViewById(R.id.tvGreeting);
|
||||
timerBlock = view.findViewById(R.id.timerBlock);
|
||||
tasksContainer = view.findViewById(R.id.tasksContainer);
|
||||
tvProgressText = view.findViewById(R.id.tvProgressText);
|
||||
pbDailyTasks = view.findViewById(R.id.pbDailyTasks);
|
||||
progressPathContainer = view.findViewById(R.id.progressPathContainer);
|
||||
|
||||
progressPathContainer = view.findViewById(R.id.progressPathContainer);
|
||||
|
||||
initProgressPath();
|
||||
addSampleTasks();
|
||||
startObservingTasks();
|
||||
startObservingUser();
|
||||
|
||||
|
||||
View btnStartFocus = view.findViewById(R.id.btnStartFocus);
|
||||
@@ -87,20 +97,32 @@ public class InicioFragment extends Fragment {
|
||||
return view;
|
||||
}
|
||||
|
||||
private void addSampleTasks() {
|
||||
if(getContext() == null) return;
|
||||
String[] sampleTasks = {
|
||||
"Estudar para intermédio",
|
||||
"Ler artigo técnico",
|
||||
"Fazer exercícios"
|
||||
};
|
||||
private void startObservingTasks() {
|
||||
FirebaseUser currentUser = AuthManager.getInstance().getCurrentUser();
|
||||
if (currentUser != null) {
|
||||
tasksListener = FirestoreManager.getInstance().observeTasks(currentUser.getUid(), tasks -> {
|
||||
currentTasks = tasks;
|
||||
updateTasksUI();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void startObservingUser() {
|
||||
FirebaseUser currentUser = AuthManager.getInstance().getCurrentUser();
|
||||
if (currentUser != null) {
|
||||
userListener = FirestoreManager.getInstance().observeUser(currentUser.getUid(), user -> {
|
||||
if (tvGreeting != null) {
|
||||
tvGreeting.setText("Olá, " + user.usuario + "!");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTasksUI() {
|
||||
if (getContext() == null || tasksContainer == null) return;
|
||||
tasksContainer.removeAllViews();
|
||||
int completedCount = 0;
|
||||
|
||||
for (int i = 0; i < sampleTasks.length; i++) {
|
||||
String taskLabel = sampleTasks[i];
|
||||
|
||||
// Create a custom Duo-style card for each task
|
||||
for (Task task : currentTasks) {
|
||||
androidx.cardview.widget.CardView card = new androidx.cardview.widget.CardView(getContext());
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
@@ -117,45 +139,46 @@ public class InicioFragment extends Fragment {
|
||||
layout.setGravity(android.view.Gravity.CENTER_VERTICAL);
|
||||
|
||||
CheckBox cb = new CheckBox(getContext());
|
||||
cb.setText(taskLabel);
|
||||
cb.setText(task.title);
|
||||
cb.setTextColor(getResources().getColor(R.color.text_primary));
|
||||
cb.setTextSize(16);
|
||||
cb.setChecked(task.completed);
|
||||
|
||||
// Simulated check for one task
|
||||
if (i == 0) {
|
||||
cb.setChecked(true);
|
||||
completedCount++;
|
||||
card.setCardBackgroundColor(getResources().getColor(R.color.background_light));
|
||||
if (task.completed) {
|
||||
cb.setTextColor(getResources().getColor(R.color.success_green));
|
||||
}
|
||||
|
||||
cb.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
task.completed = isChecked;
|
||||
FirestoreManager.getInstance().updateTask(task);
|
||||
// The observer will trigger updateTasksUI again, so we don't need manual UI update here
|
||||
|
||||
if (isChecked) {
|
||||
addXP(task.xpReward);
|
||||
}
|
||||
});
|
||||
|
||||
layout.addView(cb);
|
||||
card.addView(layout);
|
||||
tasksContainer.addView(card);
|
||||
|
||||
final int finalI = i;
|
||||
cb.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
if (isChecked) {
|
||||
cb.setTextColor(getResources().getColor(R.color.success_green));
|
||||
} else {
|
||||
cb.setTextColor(getResources().getColor(R.color.text_primary));
|
||||
}
|
||||
updateProgress();
|
||||
});
|
||||
}
|
||||
|
||||
updateProgress();
|
||||
}
|
||||
|
||||
private void addXP(int amount) {
|
||||
FirebaseUser currentUser = AuthManager.getInstance().getCurrentUser();
|
||||
if (currentUser != null) {
|
||||
com.google.firebase.firestore.FirebaseFirestore.getInstance()
|
||||
.collection("users").document(currentUser.getUid())
|
||||
.update("xp", com.google.firebase.firestore.FieldValue.increment(amount));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateProgress() {
|
||||
int total = tasksContainer.getChildCount();
|
||||
int total = currentTasks.size();
|
||||
int completed = 0;
|
||||
for (int i = 0; i < total; i++) {
|
||||
View child = tasksContainer.getChildAt(i);
|
||||
if (child instanceof androidx.cardview.widget.CardView) {
|
||||
CheckBox cb = (CheckBox) ((LinearLayout)((androidx.cardview.widget.CardView) child).getChildAt(0)).getChildAt(0);
|
||||
if (cb.isChecked()) completed++;
|
||||
}
|
||||
for (Task task : currentTasks) {
|
||||
if (task.completed) completed++;
|
||||
}
|
||||
|
||||
if (tvProgressText != null) {
|
||||
@@ -271,7 +294,10 @@ public class InicioFragment extends Fragment {
|
||||
@Override
|
||||
public void onFinish() {
|
||||
isTimerRunning = false;
|
||||
if(getContext() != null) Toast.makeText(getContext(), "Foco concluído! +50 XP", Toast.LENGTH_LONG).show();
|
||||
if(getContext() != null) {
|
||||
Toast.makeText(getContext(), "Foco concluído! +50 XP", Toast.LENGTH_LONG).show();
|
||||
addXP(50);
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
@@ -297,6 +323,12 @@ public class InicioFragment extends Fragment {
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
if (tasksListener != null) {
|
||||
tasksListener.remove();
|
||||
}
|
||||
if (userListener != null) {
|
||||
userListener.remove();
|
||||
}
|
||||
pauseTimer(); // Parar o timer se a view for destruída
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,15 @@ import android.widget.ImageButton;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import android.widget.TextView;
|
||||
import com.google.firebase.auth.FirebaseUser;
|
||||
import com.google.firebase.firestore.ListenerRegistration;
|
||||
|
||||
public class ProfileFragment extends Fragment {
|
||||
|
||||
private TextView tvUsername, tvHandle, tvStreakValue, tvTotalXP, tvLeagueName, tvAchievementsCount;
|
||||
private ListenerRegistration userListener;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
@@ -24,6 +30,52 @@ public class ProfileFragment extends Fragment {
|
||||
startActivity(intent);
|
||||
});
|
||||
|
||||
View btnInviteCard = view.findViewById(R.id.btnInviteCard);
|
||||
btnInviteCard.setOnClickListener(v -> openFindFriends());
|
||||
|
||||
View btnInviteFriends = view.findViewById(R.id.btnInviteFriends);
|
||||
btnInviteFriends.setOnClickListener(v -> openFindFriends());
|
||||
|
||||
// Initialize UI components
|
||||
tvUsername = view.findViewById(R.id.tvUsername);
|
||||
tvHandle = view.findViewById(R.id.tvHandle);
|
||||
tvStreakValue = view.findViewById(R.id.tvStreakValue);
|
||||
tvTotalXP = view.findViewById(R.id.tvTotalXP);
|
||||
tvLeagueName = view.findViewById(R.id.tvLeagueName);
|
||||
tvAchievementsCount = view.findViewById(R.id.tvAchievementsCount);
|
||||
|
||||
startObservingUser();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void startObservingUser() {
|
||||
FirebaseUser currentUser = AuthManager.getInstance().getCurrentUser();
|
||||
if (currentUser != null) {
|
||||
userListener = FirestoreManager.getInstance().observeUser(currentUser.getUid(), this::updateUI);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUI(Usuario user) {
|
||||
if (getContext() == null) return;
|
||||
tvUsername.setText(user.usuario);
|
||||
tvHandle.setText(user.handle);
|
||||
tvStreakValue.setText(String.valueOf(user.streak));
|
||||
tvTotalXP.setText(String.valueOf(user.xp));
|
||||
tvLeagueName.setText(user.league);
|
||||
tvAchievementsCount.setText(String.valueOf(user.achievementsCount));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
if (userListener != null) {
|
||||
userListener.remove();
|
||||
}
|
||||
}
|
||||
|
||||
private void openFindFriends() {
|
||||
Intent intent = new Intent(getActivity(), FindFriendsActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,14 @@ public class Usuario {
|
||||
public String created_at;
|
||||
public String updated_at;
|
||||
|
||||
// Stats and Social
|
||||
public int xp = 0;
|
||||
public int streak = 0;
|
||||
public String league = "Bronze";
|
||||
public String handle = "";
|
||||
public String bio = "";
|
||||
public int achievementsCount = 0;
|
||||
|
||||
public Usuario() {}
|
||||
|
||||
public Usuario(String id_usuario, String usuario, String email, String palavra_passe, String numero) {
|
||||
@@ -18,5 +26,6 @@ public class Usuario {
|
||||
this.email = email;
|
||||
this.palavra_passe = palavra_passe;
|
||||
this.numero = numero;
|
||||
this.handle = "@" + usuario.toLowerCase().replace(" ", "_");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,8 @@ public class UsuariosService {
|
||||
android.util.Log.d("FLUXUP_SERVICE", "A guardar utilizador no Firestore (Coleção: users, ID: " + uid + ")...");
|
||||
getFirestore().collection("users").document(uid).set(usuario)
|
||||
.addOnSuccessListener(aVoid -> {
|
||||
android.util.Log.d("FLUXUP_SERVICE", "Utilizador guardado no Firestore com sucesso.");
|
||||
android.util.Log.d("FLUXUP_SERVICE", "Utilizador guardado no Firestore com sucesso. A criar tarefas iniciais...");
|
||||
createInitialTasks(uid);
|
||||
usuario.palavra_passe = tempPass;
|
||||
callback.onSuccess(usuario);
|
||||
})
|
||||
@@ -89,6 +90,19 @@ public class UsuariosService {
|
||||
});
|
||||
}
|
||||
|
||||
private static void createInitialTasks(String uid) {
|
||||
String[] defaultTasks = {
|
||||
"Completar o perfil",
|
||||
"Iniciar primeira sessão de foco",
|
||||
"Definir objetivo diário"
|
||||
};
|
||||
for (String title : defaultTasks) {
|
||||
String taskId = getFirestore().collection("tasks").document().getId();
|
||||
Task task = new Task(taskId, title, 50, uid);
|
||||
getFirestore().collection("tasks").document(taskId).set(task);
|
||||
}
|
||||
}
|
||||
|
||||
public static void recuperarPalavraPasse(Context context, String email, ServiceCallback<Void> callback) {
|
||||
FirebaseAuth.getInstance().sendPasswordResetEmail(email)
|
||||
.addOnCompleteListener(task -> {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#F9F9F9" />
|
||||
<stroke android:width="1dp" android:color="#DDDDDD" />
|
||||
<solid android:color="@color/white" />
|
||||
<stroke android:width="1dp" android:color="@color/border_color" />
|
||||
<corners android:radius="8dp" />
|
||||
</shape>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp"
|
||||
android:gravity="center"
|
||||
android:background="@color/white">
|
||||
android:background="@color/background_light">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp"
|
||||
android:gravity="center"
|
||||
android:background="@color/white">
|
||||
android:background="@color/background_light">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTitle"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/white">
|
||||
android:background="@color/background_light">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:background="@color/white"
|
||||
android:background="@color/card_background"
|
||||
android:elevation="4dp">
|
||||
|
||||
<ImageButton
|
||||
@@ -62,7 +62,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="0dp"
|
||||
android:backgroundTint="@color/white"
|
||||
android:backgroundTint="@color/card_background"
|
||||
android:layout_marginBottom="24dp">
|
||||
|
||||
<LinearLayout
|
||||
@@ -110,7 +110,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="0dp"
|
||||
android:backgroundTint="@color/white"
|
||||
android:backgroundTint="@color/card_background"
|
||||
android:layout_marginBottom="24dp">
|
||||
|
||||
<LinearLayout
|
||||
@@ -167,7 +167,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="0dp"
|
||||
android:backgroundTint="@color/white"
|
||||
android:backgroundTint="@color/card_background"
|
||||
android:layout_marginBottom="24dp">
|
||||
|
||||
<LinearLayout
|
||||
@@ -215,7 +215,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="0dp"
|
||||
android:backgroundTint="@color/white"
|
||||
android:backgroundTint="@color/card_background"
|
||||
android:layout_marginBottom="24dp">
|
||||
|
||||
<LinearLayout
|
||||
@@ -263,7 +263,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="0dp"
|
||||
android:backgroundTint="@color/white"
|
||||
android:backgroundTint="@color/card_background"
|
||||
android:layout_marginBottom="40dp">
|
||||
|
||||
<LinearLayout
|
||||
|
||||
@@ -231,7 +231,7 @@
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="?attr/selectableItemBackground"
|
||||
app:cardBackgroundColor="@color/white"
|
||||
app:cardBackgroundColor="@color/card_background"
|
||||
app:cardCornerRadius="20dp"
|
||||
app:cardElevation="2dp">
|
||||
|
||||
|
||||
@@ -296,11 +296,15 @@
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/btnInviteCard"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
app:cardCornerRadius="30dp"
|
||||
app:cardElevation="0dp"
|
||||
app:cardBackgroundColor="@color/border_color">
|
||||
app:cardBackgroundColor="@color/border_color"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="?attr/selectableItemBackground">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.Fluxup" parent="Theme.MaterialComponents.Light.NoActionBar">
|
||||
<style name="Theme.Fluxup" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">#7C3AED</item>
|
||||
<item name="colorPrimaryVariant">#6D28D9</item>
|
||||
|
||||
Reference in New Issue
Block a user