Primeiro commit

This commit is contained in:
MeuNome
2026-04-20 14:24:12 +01:00
parent 4d5a034272
commit 9ff7ada370
25 changed files with 595 additions and 663 deletions

36
.gitignore vendored Normal file
View File

@@ -0,0 +1,36 @@
# Android Studio
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/app/build
/captures
.externalNativeBuild
.cxx
*.apk
*.aar
*.keystore
# Gradle
.gradle/
build/
app/build/
# IDE
.idea/
.vscode/
# Build logs
build_error.txt
build_log.txt
build_output.txt
build_output_2.txt
build_output_3.txt
build_output_4.txt

View File

@@ -1,2 +0,0 @@
#Wed Mar 25 11:05:18 WET 2026
gradle.version=9.3.1

View File

@@ -1,2 +0,0 @@
#Wed Mar 18 09:24:04 WET 2026
java.home=/Applications/Android Studio.app/Contents/jbr/Contents/Home

Binary file not shown.

View File

@@ -0,0 +1,27 @@
package com.fluxup.app;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
public class ConnectivityUtils {
/**
* Verifica se existe uma ligação ativa à internet (Wi-Fi ou Dados Móveis).
*/
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
Network activeNetwork = connectivityManager.getActiveNetwork();
if (activeNetwork != null) {
NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork);
return networkCapabilities != null && (
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET));
}
}
return false;
}
}

View File

@@ -0,0 +1,169 @@
package com.fluxup.app;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import com.google.android.material.switchmaterial.SwitchMaterial;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import java.util.Locale;
public class SettingsActivity extends AppCompatActivity {
private ImageButton btnBack;
private SwitchMaterial switchDarkMode, switchPrivacy, switchNotifications;
private TextView tvEmail, btnChangePassword;
private Spinner spinnerLanguage;
private View btnLogout;
private SharedPreferences sharedPreferences;
private static final String PREFS_NAME = "FluxupSettings";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sharedPreferences = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
// Aplicar o idioma guardado antes de carregar o layout
String lang = sharedPreferences.getString("language", "pt");
updateLocaleSilent(lang);
// Aplicar tema guardado
applyTheme(sharedPreferences.getBoolean("darkMode", false));
setContentView(R.layout.activity_settings);
initViews();
setupListeners();
loadSettings();
}
private void applyTheme(boolean isDarkMode) {
if (isDarkMode) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}
}
private void initViews() {
btnBack = findViewById(R.id.btnBack);
switchDarkMode = findViewById(R.id.switchDarkMode);
switchPrivacy = findViewById(R.id.switchPrivacy);
switchNotifications = findViewById(R.id.switchNotifications);
tvEmail = findViewById(R.id.tvEmail);
btnChangePassword = findViewById(R.id.btnChangePassword);
spinnerLanguage = findViewById(R.id.spinnerLanguage);
btnLogout = findViewById(R.id.btnLogout);
// Configurar Spinner de Idiomas
String[] languages = {"Português", "English", "Español"};
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, languages);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerLanguage.setAdapter(adapter);
// Mostrar email do utilizador
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
tvEmail.setText(user.getEmail());
}
}
private void setupListeners() {
btnBack.setOnClickListener(v -> finish());
switchDarkMode.setOnCheckedChangeListener((buttonView, isChecked) -> {
applyTheme(isChecked);
saveSetting("darkMode", isChecked);
});
switchPrivacy.setOnCheckedChangeListener((buttonView, isChecked) -> saveSetting("privacy", isChecked));
switchNotifications.setOnCheckedChangeListener((buttonView, isChecked) -> saveSetting("notifications", isChecked));
btnLogout.setOnClickListener(v -> {
FirebaseAuth.getInstance().signOut();
Intent intent = new Intent(SettingsActivity.this, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
});
spinnerLanguage.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String selectedLang = "pt";
if (position == 1) selectedLang = "en";
else if (position == 2) selectedLang = "es";
String currentLang = sharedPreferences.getString("language", "pt");
if (!selectedLang.equals(currentLang)) {
saveSetting("language", selectedLang);
updateLocale(selectedLang);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
});
btnChangePassword.setOnClickListener(v -> {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null && user.getEmail() != null) {
FirebaseAuth.getInstance().sendPasswordResetEmail(user.getEmail())
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
Toast.makeText(this, "Email de redefinição enviado!", Toast.LENGTH_SHORT).show();
}
});
}
});
}
private void loadSettings() {
switchDarkMode.setChecked(sharedPreferences.getBoolean("darkMode", false));
switchPrivacy.setChecked(sharedPreferences.getBoolean("privacy", false));
switchNotifications.setChecked(sharedPreferences.getBoolean("notifications", true));
String lang = sharedPreferences.getString("language", "pt");
if (lang.equals("en")) spinnerLanguage.setSelection(1, false);
else if (lang.equals("es")) spinnerLanguage.setSelection(2, false);
else spinnerLanguage.setSelection(0, false);
}
private void updateLocaleSilent(String langCode) {
Locale locale = new Locale(langCode);
Locale.setDefault(locale);
Resources resources = getResources();
Configuration config = resources.getConfiguration();
config.setLocale(locale);
resources.updateConfiguration(config, resources.getDisplayMetrics());
}
private void updateLocale(String langCode) {
updateLocaleSilent(langCode);
Intent intent = new Intent(this, SettingsActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
private void saveSetting(String key, boolean value) {
sharedPreferences.edit().putBoolean(key, value).apply();
}
private void saveSetting(String key, String value) {
sharedPreferences.edit().putString(key, value).apply();
}
}

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M19.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94L14.4,2.81c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41L9.25,5.35C8.66,5.59 8.13,5.91 7.63,6.29L5.24,5.33c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87c-0.12,0.21 -0.08,0.47 0.12,0.61l2.03,1.58C4.84,11.36 4.81,11.67 4.81,12c0,0.33 0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5s3.5,1.57 3.5,3.5S13.93,15.5 12,15.5z"/>
</vector>

View File

@@ -0,0 +1,303 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/background_light">
<!-- Header -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="64dp"
android:paddingHorizontal="16dp"
android:background="@color/white"
android:elevation="4dp">
<ImageButton
android:id="@+id/btnBack"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_centerVertical="true"
android:background="?attr/selectableItemBackgroundBorderless"
android:src="@drawable/ic_back"
app:tint="@color/icon_light" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/settings"
android:textColor="@color/text_light"
android:textSize="20sp"
android:textStyle="bold" />
</RelativeLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="20dp">
<!-- Preferences Section -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/preferences"
android:textColor="@color/text_muted_light"
android:textAllCaps="true"
android:textSize="12sp"
android:textStyle="bold"
android:layout_marginBottom="8dp" />
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="16dp"
app:cardElevation="0dp"
android:backgroundTint="@color/white"
android:layout_marginBottom="24dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/dark_mode"
android:textColor="@color/text_light"
android:textSize="16sp"
android:textStyle="bold" />
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/switchDarkMode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true" />
</RelativeLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
<!-- Account Section -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/account"
android:textColor="@color/text_muted_light"
android:textAllCaps="true"
android:textSize="12sp"
android:textStyle="bold"
android:layout_marginBottom="8dp" />
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="16dp"
app:cardElevation="0dp"
android:backgroundTint="@color/white"
android:layout_marginBottom="24dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/tvEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="email@exemplo.com"
android:textColor="@color/text_light"
android:textSize="15sp"
android:textStyle="bold" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/border_light"
android:layout_marginVertical="12dp" />
<TextView
android:id="@+id/btnChangePassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/change_password"
android:textColor="@color/primary_light"
android:textSize="14sp"
android:textStyle="bold"
android:clickable="true"
android:focusable="true" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<!-- Privacy Section -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/privacy"
android:textColor="@color/text_muted_light"
android:textAllCaps="true"
android:textSize="12sp"
android:textStyle="bold"
android:layout_marginBottom="8dp" />
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="16dp"
app:cardElevation="0dp"
android:backgroundTint="@color/white"
android:layout_marginBottom="24dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/private_account"
android:textColor="@color/text_light"
android:textSize="16sp"
android:textStyle="bold" />
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/switchPrivacy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true" />
</RelativeLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
<!-- Notifications Section -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/notifications"
android:textColor="@color/text_muted_light"
android:textAllCaps="true"
android:textSize="12sp"
android:textStyle="bold"
android:layout_marginBottom="8dp" />
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="16dp"
app:cardElevation="0dp"
android:backgroundTint="@color/white"
android:layout_marginBottom="24dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/notifications"
android:textColor="@color/text_light"
android:textSize="16sp"
android:textStyle="bold" />
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/switchNotifications"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true" />
</RelativeLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
<!-- App Section -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/app_section"
android:textColor="@color/text_muted_light"
android:textAllCaps="true"
android:textSize="12sp"
android:textStyle="bold"
android:layout_marginBottom="8dp" />
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="16dp"
app:cardElevation="0dp"
android:backgroundTint="@color/white"
android:layout_marginBottom="40dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/language"
android:textColor="@color/text_light"
android:textSize="16sp"
android:textStyle="bold" />
<Spinner
android:id="@+id/spinnerLanguage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:textAlignment="viewEnd" />
</RelativeLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
<!-- Logout Button -->
<com.google.android.material.button.MaterialButton
android:id="@+id/btnLogout"
android:layout_width="match_parent"
android:layout_height="60dp"
android:text="@string/logout"
android:textColor="@color/error_light"
android:textStyle="bold"
app:backgroundTint="#FEE2E2"
app:cornerRadius="16dp"
app:elevation="0dp"
app:icon="@drawable/ic_back"
app:iconGravity="textStart"
app:iconTint="@color/error_light"
android:layout_marginBottom="20dp"/>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>

View File

@@ -0,0 +1,21 @@
<resources>
<string name="app_name">Fluxup</string>
<string name="greeting">Today is a good day</string>
<string name="subtitle">Hello! Ready for your productivity day?</string>
<!-- Settings Strings -->
<string name="settings">Settings</string>
<string name="preferences">Preferences</string>
<string name="dark_mode">Dark Mode</string>
<string name="account">Account</string>
<string name="username">Username</string>
<string name="email">Email</string>
<string name="change_password">Change Password</string>
<string name="privacy">Privacy</string>
<string name="private_account">Private Account</string>
<string name="notifications">Notifications</string>
<string name="app_section">App</string>
<string name="language">Language</string>
<string name="logout">Log out</string>
<string name="back">Back</string>
</resources>

View File

@@ -0,0 +1,21 @@
<resources>
<string name="app_name">Fluxup</string>
<string name="greeting">Hoy es un buen día</string>
<string name="subtitle">¡Hola! ¿Preparado para tu día de productividad?</string>
<!-- Settings Strings -->
<string name="settings">Configuraciones</string>
<string name="preferences">Preferencias</string>
<string name="dark_mode">Modo Oscuro</string>
<string name="account">Cuenta</string>
<string name="username">Usuario</string>
<string name="email">Email</string>
<string name="change_password">Cambiar contraseña</string>
<string name="privacy">Privacidad</string>
<string name="private_account">Cuenta Privada</string>
<string name="notifications">Notificaciones</string>
<string name="app_section">App</string>
<string name="language">Idioma</string>
<string name="logout">Cerrar sesión</string>
<string name="back">Volver</string>
</resources>

File diff suppressed because one or more lines are too long