-
diff --git a/app/src/main/java/com/example/vortex_app/controller/NotificationActionReceiver.java b/app/src/main/java/com/example/vortex_app/controller/NotificationActionReceiver.java
index a883140..03b71ea 100644
--- a/app/src/main/java/com/example/vortex_app/controller/NotificationActionReceiver.java
+++ b/app/src/main/java/com/example/vortex_app/controller/NotificationActionReceiver.java
@@ -3,111 +3,80 @@
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.util.Log;
import android.widget.Toast;
-import com.google.firebase.firestore.FirebaseFirestore;
+import com.example.vortex_app.controller.adapter.NotificationActionHandler;
-/**
- * {@code NotificationActionReceiver} is a {@link BroadcastReceiver} that handles actions
- * from notification buttons, such as accepting or declining an invitation, staying on or leaving a waiting list.
- * It updates the invitation status in Firestore based on the user's response.
- *
- * This receiver allows the app to perform actions in response to user interactions with notifications
- * without needing to open an activity.
- */
public class NotificationActionReceiver extends BroadcastReceiver {
- private FirebaseFirestore db;
+ // Define unique action strings
+ public static final String ACTION_ACCEPT = "com.example.vortex_app.ACTION_ACCEPT";
+ public static final String ACTION_DECLINE = "com.example.vortex_app.ACTION_DECLINE";
+ public static final String ACTION_STAY = "com.example.vortex_app.ACTION_STAY";
+ public static final String ACTION_LEAVE = "com.example.vortex_app.ACTION_LEAVE";
+
- /**
- * Called when the receiver receives a broadcasted intent. It determines the action taken
- * by the user and calls the appropriate method to handle the action.
- *
- * @param context The {@link Context} in which the receiver is running.
- * @param intent The {@link Intent} being received, containing the action and invitation ID.
- */
@Override
public void onReceive(Context context, Intent intent) {
- db = FirebaseFirestore.getInstance(); // Initialize Firestore
-
String action = intent.getAction();
- String invitationId = intent.getStringExtra("invitationId"); // Retrieve the invitation ID
+ String userID = intent.getStringExtra("userID");
+ String eventID = intent.getStringExtra("eventID");
+
+ Log.d("NotificationActionReceiver", "Received action: " + action + ", userID: " + userID + ", eventID: " + eventID);
+
+ if (userID == null || eventID == null) {
+ Log.e("NotificationActionReceiver", "Missing userID or eventID.");
+ return;
+ }
+
+ NotificationActionHandler handler = new NotificationActionHandler();
switch (action) {
- case "ACTION_ACCEPT":
- handleAccept(context, invitationId);
+ case ACTION_ACCEPT:
+ Log.d("NotificationActionReceiver", "Handling ACTION_ACCEPT");
+ handler.moveDocument(
+ "selected_but_not_confirmed",
+ "final",
+ userID,
+ eventID,
+ context,
+ "You have been enrolled!",
+ "Error enrolling in the event."
+ );
break;
- case "ACTION_DECLINE":
- handleDecline(context, invitationId);
+ case ACTION_DECLINE:
+ Log.d("NotificationActionReceiver", "Handling ACTION_DECLINE");
+ handler.moveDocument(
+ "selected_but_not_confirmed",
+ "waitlisted",
+ userID,
+ eventID,
+ context,
+ "You have declined the invitation.",
+ "Error declining the invitation."
+ );
break;
- case "ACTION_STAY":
- handleStay(context);
+ case ACTION_STAY:
+ Log.d("NotificationActionReceiver", "Handling ACTION_STAY");
+ Toast.makeText(context, "You remain on the waiting list.", Toast.LENGTH_SHORT).show();
+ Log.d("NotificationActionReceiver", "User chose to stay on the waiting list.");
break;
- case "ACTION_LEAVE":
- handleLeave(context, invitationId);
+ case ACTION_LEAVE:
+ Log.d("NotificationActionReceiver", "Handling ACTION_LEAVE");
+ handler.moveDocument(
+ "waitlisted",
+ "cancelled",
+ userID,
+ eventID,
+ context,
+ "You have left the waiting list.",
+ "Error leaving the waiting list."
+ );
break;
default:
+ Log.w("NotificationActionReceiver", "Unknown action received: " + action);
break;
}
}
- /**
- * Handles the "Accept" action for an invitation. Updates the invitation status in Firestore to "accepted".
- *
- * @param context The {@link Context} in which the receiver is running.
- * @param invitationId The ID of the invitation to be updated.
- */
- private void handleAccept(Context context, String invitationId) {
- db.collection("invitations").document(invitationId)
- .update("status", "accepted")
- .addOnSuccessListener(aVoid -> {
- Toast.makeText(context, "Invitation Accepted", Toast.LENGTH_SHORT).show();
- })
- .addOnFailureListener(e -> {
- Toast.makeText(context, "Error accepting invitation", Toast.LENGTH_SHORT).show();
- });
- }
-
- /**
- * Handles the "Decline" action for an invitation. Updates the invitation status in Firestore to "declined".
- *
- * @param context The {@link Context} in which the receiver is running.
- * @param invitationId The ID of the invitation to be updated.
- */
- private void handleDecline(Context context, String invitationId) {
- db.collection("invitations").document(invitationId)
- .update("status", "declined")
- .addOnSuccessListener(aVoid -> {
- Toast.makeText(context, "Invitation Declined", Toast.LENGTH_SHORT).show();
- })
- .addOnFailureListener(e -> {
- Toast.makeText(context, "Error declining invitation", Toast.LENGTH_SHORT).show();
- });
- }
-
- /**
- * Handles the "Stay" action, which keeps the user on the waiting list. No Firestore update is required;
- * this method simply shows a confirmation message to the user.
- *
- * @param context The {@link Context} in which the receiver is running.
- */
- private void handleStay(Context context) {
- Toast.makeText(context, "You have chosen to stay on the waiting list.", Toast.LENGTH_SHORT).show();
- }
-
- /**
- * Handles the "Leave" action for a waiting list. Updates the invitation status in Firestore to "left_waitlist".
- *
- * @param context The {@link Context} in which the receiver is running.
- * @param invitationId The ID of the invitation to be updated.
- */
- private void handleLeave(Context context, String invitationId) {
- db.collection("invitations").document(invitationId)
- .update("status", "left_waitlist")
- .addOnSuccessListener(aVoid -> {
- Toast.makeText(context, "You have left the waiting list", Toast.LENGTH_SHORT).show();
- })
- .addOnFailureListener(e -> {
- Toast.makeText(context, "Error leaving the waiting list", Toast.LENGTH_SHORT).show();
- });
- }
}
diff --git a/app/src/main/java/com/example/vortex_app/controller/adapter/NotificationActionHandler.java b/app/src/main/java/com/example/vortex_app/controller/adapter/NotificationActionHandler.java
new file mode 100644
index 0000000..e6c1399
--- /dev/null
+++ b/app/src/main/java/com/example/vortex_app/controller/adapter/NotificationActionHandler.java
@@ -0,0 +1,66 @@
+package com.example.vortex_app.controller.adapter;
+
+
+import android.content.Context;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.google.firebase.firestore.DocumentReference;
+import com.google.firebase.firestore.FirebaseFirestore;
+import com.google.firebase.firestore.DocumentSnapshot;
+import com.google.firebase.firestore.WriteBatch;
+
+public class NotificationActionHandler {
+
+ private FirebaseFirestore db;
+
+ public NotificationActionHandler() {
+ db = FirebaseFirestore.getInstance();
+ }
+
+ /**
+ * Moves a document from sourceCollection to targetCollection.
+ *
+ * @param sourceCollection The source Firestore collection.
+ * @param targetCollection The target Firestore collection.
+ * @param userID The user ID.
+ * @param eventID The event ID.
+ * @param context The context to show Toast messages.
+ * @param successMessage The message to show on success.
+ * @param failureMessage The message to show on failure.
+ */
+ public void moveDocument(String sourceCollection, String targetCollection, String userID, String eventID, Context context, String successMessage, String failureMessage) {
+ db.collection(sourceCollection)
+ .whereEqualTo("userID", userID)
+ .whereEqualTo("eventID", eventID)
+ .get()
+ .addOnSuccessListener(querySnapshot -> {
+ if (!querySnapshot.isEmpty()) {
+ DocumentSnapshot doc = querySnapshot.getDocuments().get(0);
+ DocumentReference sourceRef = doc.getReference();
+ DocumentReference targetRef = db.collection(targetCollection).document();
+
+ WriteBatch batch = db.batch();
+ batch.set(targetRef, doc.getData());
+ batch.delete(sourceRef);
+
+ batch.commit()
+ .addOnSuccessListener(aVoid -> {
+ Toast.makeText(context, successMessage, Toast.LENGTH_SHORT).show();
+ Log.d("NotificationActionHandler", "User moved to '" + targetCollection + "'.");
+ })
+ .addOnFailureListener(e -> {
+ Toast.makeText(context, failureMessage, Toast.LENGTH_SHORT).show();
+ Log.e("NotificationActionHandler", "Transaction failed: " + e.getMessage());
+ });
+ } else {
+ Toast.makeText(context, "Document not found.", Toast.LENGTH_SHORT).show();
+ Log.e("NotificationActionHandler", "Document not found for userID: " + userID + ", eventID: " + eventID);
+ }
+ })
+ .addOnFailureListener(e -> {
+ Toast.makeText(context, "Error fetching document.", Toast.LENGTH_SHORT).show();
+ Log.e("NotificationActionHandler", "Error fetching document: ", e);
+ });
+ }
+}
diff --git a/app/src/main/java/com/example/vortex_app/controller/adapter/NotificationAdapter.java b/app/src/main/java/com/example/vortex_app/controller/adapter/NotificationAdapter.java
index ca867b6..8b31bdc 100644
--- a/app/src/main/java/com/example/vortex_app/controller/adapter/NotificationAdapter.java
+++ b/app/src/main/java/com/example/vortex_app/controller/adapter/NotificationAdapter.java
@@ -1,3 +1,4 @@
+
package com.example.vortex_app.controller.adapter;
import android.content.Context;
diff --git a/app/src/main/java/com/example/vortex_app/model/NotificationModel.java b/app/src/main/java/com/example/vortex_app/model/NotificationModel.java
index 2353d1f..ec73f09 100644
--- a/app/src/main/java/com/example/vortex_app/model/NotificationModel.java
+++ b/app/src/main/java/com/example/vortex_app/model/NotificationModel.java
@@ -17,6 +17,11 @@ public class NotificationModel {
private String status;
private String id; // Firestore document ID
private Date TimeStamp;
+ private String eventID;
+ private String userID;
+ private String Type;
+
+
/**
* Constructs a {@code NotificationModel} instance with the specified parameters.
@@ -27,6 +32,17 @@ public class NotificationModel {
* @param id The Firestore document ID associated with the notification.
* @param Timestamp The timestamp indicating when the notification was created or last updated.
*/
+ public NotificationModel(String title, String message, String status, String id, Date Timestamp, String eventID, String userID, String Type) {
+ this.title = title;
+ this.message = message;
+ this.status = status;
+ this.id = id;
+ this.TimeStamp = Timestamp;
+ this.eventID = eventID;
+ this.userID = userID;
+ this.Type = Type;
+ }
+
public NotificationModel(String title, String message, String status, String id, Date Timestamp) {
this.title = title;
this.message = message;
@@ -35,6 +51,7 @@ public NotificationModel(String title, String message, String status, String id,
this.TimeStamp = Timestamp;
}
+
/**
* Returns the title of the notification.
*
@@ -71,6 +88,9 @@ public String getId() {
return id;
}
+ public void setId(String id) {
+ this.id = id;
+ }
/**
* Returns the timestamp of the notification.
*
@@ -79,4 +99,17 @@ public String getId() {
public Date getTimeStamp() {
return TimeStamp;
}
+
+ public String getEventID() {return eventID;}
+
+
+ public String getUserID() {return userID;}
+
+ public String getType() {return Type;}
+
+ public void SetType(String type) {this.Type = Type;}
+
}
+
+
+
diff --git a/app/src/main/java/com/example/vortex_app/view/notification/NotificationClickListener.java b/app/src/main/java/com/example/vortex_app/view/notification/NotificationClickListener.java
new file mode 100644
index 0000000..cbf6844
--- /dev/null
+++ b/app/src/main/java/com/example/vortex_app/view/notification/NotificationClickListener.java
@@ -0,0 +1,9 @@
+package com.example.vortex_app.view.notification;
+
+
+
+import com.example.vortex_app.model.NotificationModel;
+
+public interface NotificationClickListener {
+ void onNotificationClick(NotificationModel notification);
+}
diff --git a/app/src/main/java/com/example/vortex_app/view/notification/NotificationDetailActivity.java b/app/src/main/java/com/example/vortex_app/view/notification/NotificationDetailActivity.java
index cb1d47b..0663aad 100644
--- a/app/src/main/java/com/example/vortex_app/view/notification/NotificationDetailActivity.java
+++ b/app/src/main/java/com/example/vortex_app/view/notification/NotificationDetailActivity.java
@@ -1,29 +1,44 @@
package com.example.vortex_app.view.notification;
+import android.content.Intent;
import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
import android.widget.TextView;
+import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.example.vortex_app.R;
+import com.example.vortex_app.controller.NotificationActionReceiver;
/**
* {@code NotificationDetailActivity} displays detailed information about a specific notification.
- * It retrieves the notification's title, message, and other relevant data passed through an intent
- * and displays it within the activity's layout.
+ * It retrieves the notification's title, message, date, and other relevant data passed through an intent
+ * and displays them within the activity's layout.
*
*
This activity also includes a back button in the action bar to allow users to return to the previous screen.
+ * Additionally, it displays action buttons (e.g., Accept, Decline, Stay, Leave) based on the notification type.
*/
public class NotificationDetailActivity extends AppCompatActivity {
- /**
- * Initializes the activity and sets up the view to display notification details.
- * Retrieves the title and message data from the intent and assigns them to the appropriate TextViews.
- *
- * @param savedInstanceState If the activity is being re-initialized after previously being shut down,
- * then this Bundle contains the most recent data supplied by
- * {@link #onSaveInstanceState(Bundle)}.
- */
+ // Constants for logging
+ private static final String TAG = "NotificationDetailActivity";
+
+ // Notification data
+ private String title;
+ private String message;
+ private String userID;
+ private String eventID;
+ private String notificationType;
+ private String Date;
+
+ // UI Components
+ private TextView titleTextView, messageTextView, dateTextView;
+ private Button buttonAction1, buttonAction2;
+ private View actionButtonsLayout;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -35,18 +50,107 @@ protected void onCreate(Bundle savedInstanceState) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
- // Retrieve data from the intent
- String title = getIntent().getStringExtra("title");
- String message = getIntent().getStringExtra("message");
+ // Initialize views
+ titleTextView = findViewById(R.id.titleTextView);
+ messageTextView = findViewById(R.id.messageTextView);
+ dateTextView = findViewById(R.id.dateTextView);
+ buttonAction1 = findViewById(R.id.detailButtonPrimary);
+ buttonAction2 = findViewById(R.id.detailButtonSecondary);
+ actionButtonsLayout = findViewById(R.id.actionButtonsLayout);
+
+ // Retrieve data from the intent and assign to class variables
+ Intent intent = getIntent();
+ if (intent != null) {
+ title = intent.getStringExtra("title");
+ message = intent.getStringExtra("message");
+ Date = intent.getStringExtra("date"); // Optional: Handle if not provided
+ userID = intent.getStringExtra("userID");
+ eventID = intent.getStringExtra("eventID");
+ notificationType = intent.getStringExtra("notificationType"); // Ensure this key matches sender
+
+ // Debugging: Log the received data
+ Log.d(TAG, "Title: " + title);
+ Log.d(TAG, "Message: " + message);
+ Log.d(TAG, "UserID: " + userID);
+ Log.d(TAG, "EventID: " + eventID);
+ Log.d(TAG, "NotificationType: " + notificationType);
+
+ // Optional: Show a Toast for debugging
+ Toast.makeText(this, "Type: " + notificationType, Toast.LENGTH_SHORT).show();
+ } else {
+ Log.e(TAG, "No intent received.");
+ Toast.makeText(this, "No notification data received.", Toast.LENGTH_SHORT).show();
+ }
// Set data to TextViews
- TextView titleTextView = findViewById(R.id.titleTextView);
- TextView messageTextView = findViewById(R.id.messageTextView);
- TextView dateTextView = findViewById(R.id.dateTextView);
+ titleTextView.setText(title != null ? title : "No Title");
+ messageTextView.setText(message != null ? message : "No Message");
+
+ if (intent != null && intent.hasExtra("date")) {
+ dateTextView.setText(intent.getStringExtra("date"));
+ } else {
+ // Set to current date or a default value if date is not provided
+ dateTextView.setText(Date);
+ }
+
+ // Configure action buttons based on notification type
+ configureActionButtons();
+ }
+
+ /**
+ * Configures the action buttons based on the notification type.
+ * Shows the buttons and sets their text and click listeners accordingly.
+ */
+ private void configureActionButtons() {
+ if ("selected".equalsIgnoreCase(notificationType)) {
+ // Show Accept and Decline buttons
+ actionButtonsLayout.setVisibility(View.VISIBLE);
+ buttonAction1.setText("Accept");
+ buttonAction2.setText("Decline");
+
+ buttonAction1.setOnClickListener(v -> sendActionBroadcast(NotificationActionReceiver.ACTION_ACCEPT, userID, eventID));
+ buttonAction2.setOnClickListener(v -> sendActionBroadcast(NotificationActionReceiver.ACTION_DECLINE, userID, eventID));
+
+ Log.d(TAG, "Configured buttons for 'selected' type.");
+ Toast.makeText(this, "Configured buttons for 'selected' type.", Toast.LENGTH_SHORT).show();
+ } else if ("lost".equalsIgnoreCase(notificationType)) {
+ // Show Stay and Leave buttons
+ actionButtonsLayout.setVisibility(View.VISIBLE);
+ buttonAction1.setText("Stay");
+ buttonAction2.setText("Leave");
+
+ buttonAction1.setOnClickListener(v -> sendActionBroadcast(NotificationActionReceiver.ACTION_STAY, userID, eventID));
+ buttonAction2.setOnClickListener(v -> sendActionBroadcast(NotificationActionReceiver.ACTION_LEAVE, userID, eventID));
+
+ Log.d(TAG, "Configured buttons for 'lost' type.");
+ Toast.makeText(this, "Configured buttons for 'lost' type.", Toast.LENGTH_SHORT).show();
+ } else {
+ // Hide buttons if notification type is unknown or not provided
+ actionButtonsLayout.setVisibility(View.GONE);
+ Log.d(TAG, "Unknown notification type. Buttons hidden.");
+ Toast.makeText(this, "Unknown notification type. Buttons hidden.", Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ /**
+ * Sends a broadcast intent to NotificationActionReceiver with the specified action.
+ *
+ * @param action The action string to be handled by the receiver.
+ * @param userID The ID of the user.
+ * @param eventID The ID of the event.
+ */
+ private void sendActionBroadcast(String action, String userID, String eventID) {
+ Intent intent = new Intent(this, NotificationActionReceiver.class);
+ intent.setAction(action);
+ intent.putExtra("userID", userID);
+ intent.putExtra("eventID", eventID);
+ sendBroadcast(intent);
+
+ // Provide user feedback
+ Toast.makeText(this, action.replace("ACTION_", "") + " clicked.", Toast.LENGTH_SHORT).show();
- titleTextView.setText(title);
- messageTextView.setText(message);
- dateTextView.setText("2025-01-01"); // Example date, replace with actual date if available
+ // Optionally, finish the activity or navigate elsewhere
+ finish();
}
/**
diff --git a/app/src/main/java/com/example/vortex_app/view/notification/NotificationsActivity.java b/app/src/main/java/com/example/vortex_app/view/notification/NotificationsActivity.java
index 47fc208..19684f1 100644
--- a/app/src/main/java/com/example/vortex_app/view/notification/NotificationsActivity.java
+++ b/app/src/main/java/com/example/vortex_app/view/notification/NotificationsActivity.java
@@ -1,28 +1,49 @@
package com.example.vortex_app.view.notification;
-
+import android.Manifest;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Build;
import android.os.Bundle;
import android.util.Log;
+import android.widget.Toast;
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.SwitchCompat;
+import androidx.core.app.ActivityCompat;
+import androidx.core.app.NotificationCompat;
+import androidx.core.app.NotificationManagerCompat;
+import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
+
import com.example.vortex_app.R;
+import com.example.vortex_app.controller.NotificationActionReceiver;
import com.example.vortex_app.model.NotificationModel;
import com.example.vortex_app.controller.adapter.NotificationAdapter;
import com.example.vortex_app.view.entrant.EntrantActivity;
-import com.example.vortex_app.view.event.EventInfoActivity;
import com.example.vortex_app.view.event.ManageEventsActivity;
import com.example.vortex_app.view.profile.ProfileActivity;
import com.google.android.material.bottomnavigation.BottomNavigationView;
+import com.google.firebase.auth.FirebaseAuth;
+import com.google.firebase.auth.FirebaseUser;
+import com.google.firebase.firestore.DocumentChange;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
+import com.google.firebase.firestore.ListenerRegistration;
import com.google.firebase.firestore.Query;
import java.util.ArrayList;
import java.util.Date;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* {@code NotificationsActivity} displays a list of notifications for the user.
@@ -38,6 +59,34 @@ public class NotificationsActivity extends AppCompatActivity {
private NotificationAdapter adapter;
private List notificationList = new ArrayList<>();
private FirebaseFirestore db;
+ private static final int REQUEST_CODE_POST_NOTIFICATIONS = 1001;
+ private ListenerRegistration notificationListener;
+
+
+ private FirebaseAuth mAuth;
+
+
+ // Define action strings
+ public static final String ACTION_ACCEPT = "ACTION_ACCEPT";
+ public static final String ACTION_DECLINE = "ACTION_DECLINE";
+ public static final String ACTION_STAY = "ACTION_STAY";
+ public static final String ACTION_LEAVE = "ACTION_LEAVE";
+
+
+ private SwitchCompat switchNotifications;
+
+
+
+ @Override protected void onStart() {
+ super.onStart();
+
+ }
+ @Override protected void onStop(){
+ super.onStop();
+ if (notificationListener != null) {
+ notificationListener.remove();
+ }
+ }
/**
* Called when the activity is first created.
@@ -53,46 +102,431 @@ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notifications);
+ // Initialize Firestore
+ db = FirebaseFirestore.getInstance();
+
+ // Initialize RecyclerView
+ recyclerView = findViewById(R.id.recyclerView);
+ recyclerView.setLayoutManager(new LinearLayoutManager(this));
+ adapter = new NotificationAdapter(notificationList, this);
+ recyclerView.setAdapter(adapter);
+
// Set up bottom navigation
- // Set up bottom navigation and handle item selection
BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation);
- bottomNavigationView.setSelectedItemId(R.id.nav_notifications);
-
+ bottomNavigationView.setSelectedItemId(R.id.nav_events);
bottomNavigationView.setOnItemSelectedListener(item -> {
int itemId = item.getItemId();
if (itemId == R.id.nav_home) {
startActivity(new Intent(this, EntrantActivity.class));
finish();
return true;
- } else if (itemId == R.id.nav_events) {
- startActivity(new Intent(this, ManageEventsActivity.class));
- finish();
- return true;
} else if (itemId == R.id.nav_profile) {
- Intent intent = new Intent(this, ProfileActivity.class);
- startActivity(intent);
+ startActivity(new Intent(this, ProfileActivity.class));
finish();
return true;
-
-
} else if (itemId == R.id.nav_notifications) {
- // Current activity; do nothing
return true;
+ } else if (itemId == R.id.nav_events) {
+ startActivity(new Intent(this, ManageEventsActivity.class));
}
return false;
});
- // Initialize RecyclerView
- recyclerView = findViewById(R.id.recyclerView);
- recyclerView.setLayoutManager(new LinearLayoutManager(this));
- adapter = new NotificationAdapter(notificationList, this);
- recyclerView.setAdapter(adapter);
- // Initialize Firestore
- db = FirebaseFirestore.getInstance();
+
+
+ // Check and request notification permission
+ checkAndRequestNotificationPermission();
+
+ // Initialize the switch state based on Firestore data
+ //initializeNotificationPreference();
+
+ // Set a listener to handle toggle changes
+
+
+
+
+ // Fetch existing notifications
fetchNotifications();
+
+ // Listen for new notifications in Firestore
+ listenForNotifications();
+ }
+
+
+ /**
+ * Updates the user's notification preference in Firestore.
+ *
+ * @param isEnabled Whether the user has enabled notifications.
+ */
+ private void updateNotificationPreference(boolean isEnabled) {
+ FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser();
+ if (currentUser == null) {
+ // Handle unauthenticated user
+ Log.e("NotificationsActivity", "User not authenticated.");
+ return;
+ }
+
+ String currentUserID = currentUser.getUid();
+
+ db.collection("user_profile")
+ .document(currentUserID)
+ .update("notificationsEnabled", isEnabled)
+ .addOnSuccessListener(aVoid -> {
+ if (isEnabled) {
+ Toast.makeText(this, "Notifications enabled.", Toast.LENGTH_SHORT).show();
+ // Re-initialize the listener
+ listenForNotifications();
+ } else {
+ Toast.makeText(this, "Notifications disabled.", Toast.LENGTH_SHORT).show();
+ // Remove existing notifications from device
+ clearLocalNotifications();
+ // Remove listener
+ if (notificationListener != null) {
+ notificationListener.remove();
+ notificationListener = null;
+ }
+ // Optionally, update Firestore to mark notifications as read or delete them
+ //clearFirestoreNotifications(currentUserID);
+ }
+ })
+ .addOnFailureListener(e -> {
+ Toast.makeText(this, "Failed to update notification preference.", Toast.LENGTH_SHORT).show();
+ Log.e("NotificationsActivity", "Error updating notification preference.", e);
+ });
+ }
+
+
+ /**
+ * Clears all local notifications from the device.
+ */
+
+ private void clearLocalNotifications() {
+ NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+ if (notificationManager != null) {
+ notificationManager.cancelAll();
+ }
}
+
+ /**
+ * Initializes the notification preference switch based on Firestore data.
+ */
+ private void initializeNotificationPreference() {
+ FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser();
+ if (currentUser == null) {
+ // Handle unauthenticated user
+ Log.e("NotificationsActivity", "User not authenticated.");
+ return;
+ }
+
+ String currentUserID = currentUser.getUid();
+
+ db.collection("user_profile")
+ .document(currentUserID)
+ .get()
+ .addOnSuccessListener(documentSnapshot -> {
+ if (documentSnapshot.exists()) {
+ Boolean notificationsEnabled = documentSnapshot.getBoolean("notificationsEnabled");
+ if (notificationsEnabled != null) {
+ switchNotifications.setChecked(notificationsEnabled);
+ } else {
+ // Field doesn't exist, set default to true
+ switchNotifications.setChecked(true);
+ //Set default notification preference
+ Map defaultPref = new HashMap<>();
+ defaultPref.put("notificationsEnabled", true);
+ db.collection("user_profile")
+ .document(currentUserID)
+ .update(defaultPref)
+ .addOnSuccessListener(aVoid -> Log.d("NotificationsActivity", "Default notification preference set."))
+ .addOnFailureListener(e -> Log.e("NotificationsActivity", "Failed to set default notification preference.", e));
+ }
+ } else {
+ // User document doesn't exist, create it with default notification preference
+
+
+ Map userData = new HashMap<>();
+ userData.put("notificationsEnabled", true);
+ // Add other necessary fields as per your User class, e.g., firstName, lastName, etc.
+ // For example:
+ userData.put("firstName", currentUser.getDisplayName() != null ? currentUser.getDisplayName() : "FirstName");
+ userData.put("lastName", "LastName"); // Replace with actual data if available
+ userData.put("email", currentUser.getEmail());
+
+ db.collection("user_profile")
+ .document(currentUserID)
+ .set(userData)
+ .addOnSuccessListener(aVoid -> {
+ switchNotifications.setChecked(true);
+ Log.d("NotificationsActivity", "User profile created with default notification preference.");
+ })
+ .addOnFailureListener(e -> {
+ Toast.makeText(this, "Error creating user profile.", Toast.LENGTH_SHORT).show();
+ Log.e("NotificationsActivity", "Error creating user profile.", e);
+ });
+ }
+ })
+ .addOnFailureListener(e -> {
+ Toast.makeText(this, "Error fetching user data.", Toast.LENGTH_SHORT).show();
+ Log.e("NotificationsActivity", "Error fetching user data.", e);
+ });
+
+ }
+
+
+
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
+ @NonNull int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+
+ if (requestCode == REQUEST_CODE_POST_NOTIFICATIONS) {
+ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ // Permission granted
+ Toast.makeText(this, "Notification permission granted.", Toast.LENGTH_SHORT).show();
+ } else {
+ // Permission denied
+ Toast.makeText(this, "Notification permission denied. Notifications will not be displayed.", Toast.LENGTH_SHORT).show();
+ // You may still proceed, but notifications won't be displayed
+ }
+ }
+ }
+
+ /**
+ * Checks and requests notification permission if necessary (for Android 13+).
+ */
+ private void checkAndRequestNotificationPermission() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { // Android 13 or higher
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS)
+ != PackageManager.PERMISSION_GRANTED) {
+
+ if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.POST_NOTIFICATIONS)) {
+ // Show an explanation to the user
+ new AlertDialog.Builder(this)
+ .setTitle("Notification Permission Needed")
+ .setMessage("This app requires notification permission to inform you about important updates.")
+ .setPositiveButton("OK", (dialog, which) -> {
+ ActivityCompat.requestPermissions(this,
+ new String[]{Manifest.permission.POST_NOTIFICATIONS},
+ REQUEST_CODE_POST_NOTIFICATIONS);
+ })
+ .setNegativeButton("Cancel", null)
+ .create()
+ .show();
+ } else {
+ // No explanation needed; request the permission
+ ActivityCompat.requestPermissions(this,
+ new String[]{Manifest.permission.POST_NOTIFICATIONS},
+ REQUEST_CODE_POST_NOTIFICATIONS);
+ }
+ } else {
+ // Permission already granted
+ // No action needed
+ }
+ } else {
+ // Permission is automatically granted on SDK versions below 33
+ // No action needed
+ }
+ }
+
+
+
+
+
+
+ /**
+ * Listens for new notifications in the 'notifications' collection and sends local notifications accordingly,
+ * only if the user has enabled notifications.
+ */
+ private void listenForNotifications() {
+ FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser();
+ if (currentUser == null) {
+ Log.e("NotificationsActivity", "User not authenticated.");
+ return;
+ }
+ String currentUserId = currentUser.getUid();
+
+ // Set up a listener on the 'notifications' collection for the current user
+ notificationListener = db.collection("notifications")
+ .whereEqualTo("userID", currentUserId)
+ .orderBy("timestamp", Query.Direction.DESCENDING)
+ .addSnapshotListener((querySnapshot, e) -> {
+ if (e != null) {
+ // Handle any errors
+ Log.w("NotificationsActivity", "Listen failed.", e);
+ return;
+ }
+
+ if (querySnapshot != null) {
+ // Loop through the document changes
+ for (DocumentChange dc : querySnapshot.getDocumentChanges()) {
+ switch (dc.getType()) {
+ case ADDED:
+ // Deserialize the document into a NotificationModel object
+ NotificationModel notification = dc.getDocument().toObject(NotificationModel.class);
+
+ // Add the notification to the list and update the adapter
+ notificationList.add(0, notification); // Add to the top of the list
+ adapter.notifyItemInserted(0);
+
+ // Determine the notification type based on title or other fields
+ String Type = "lost"; // Default
+ if (notification.getTitle().contains("Congratulations")) {
+ Type = "selected";
+ }
+
+ // Send a local notification using the title and message from the notification
+ sendNotification(notification.getTitle(), notification.getMessage(),
+ notification.getUserID(), notification.getEventID(), Type);
+ break;
+
+ case MODIFIED:
+ // Handle modified notifications if necessary
+ break;
+
+ case REMOVED:
+ // Handle removed notifications if necessary
+ break;
+ }
+ }
+ }
+ });
+ }
+
+
+
+ /**
+ * Sends a local notification with action buttons based on the notification type.
+ *
+ * @param title The title of the notification.
+ * @param message The message/content of the notification.
+ * @param userID The ID of the user receiving the notification.
+ * @param eventID The ID of the associated event.
+ * @param Type The type of notification ("selected" for winners, "lost" for non-winners).
+ */
+ private void sendNotification(String title, String message, String userID, String eventID, String Type) {
+ createNotificationChannel();
+
+ // Intent to open NotificationDetailActivity
+ Intent intent = new Intent(this, NotificationDetailActivity.class);
+ intent.putExtra("title", title);
+ intent.putExtra("message", message);
+ intent.putExtra("userID", userID);
+ intent.putExtra("eventID", eventID);
+ intent.putExtra("notificationType", Type); // Ensure key matches in Detail Activity
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+
+ PendingIntent pendingIntent = PendingIntent.getActivity(
+ this,
+ 0,
+ intent,
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
+ );
+
+ // Create action intents based on notification type
+ PendingIntent actionIntent1 = null;
+ PendingIntent actionIntent2 = null;
+ String actionButton1 = "";
+ String actionButton2 = "";
+
+ if ("selected".equalsIgnoreCase(Type)) {
+ // For winners: Accept and Decline
+ Intent acceptIntent = new Intent(this, NotificationActionReceiver.class);
+ acceptIntent.setAction(NotificationActionReceiver.ACTION_ACCEPT);
+ acceptIntent.putExtra("userID", userID);
+ acceptIntent.putExtra("eventID", eventID);
+
+ Intent declineIntent = new Intent(this, NotificationActionReceiver.class);
+ declineIntent.setAction(NotificationActionReceiver.ACTION_DECLINE);
+ declineIntent.putExtra("userID", userID);
+ declineIntent.putExtra("eventID", eventID);
+
+ actionIntent1 = PendingIntent.getBroadcast(this, 0, acceptIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
+ actionIntent2 = PendingIntent.getBroadcast(this, 1, declineIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
+
+ actionButton1 = "Accept";
+ actionButton2 = "Decline";
+ } else if ("lost".equalsIgnoreCase(Type)) {
+ // For non-winners: Stay and Leave
+ Intent stayIntent = new Intent(this, NotificationActionReceiver.class);
+ stayIntent.setAction(NotificationActionReceiver.ACTION_STAY);
+ stayIntent.putExtra("userID", userID);
+ stayIntent.putExtra("eventID", eventID);
+
+ Intent leaveIntent = new Intent(this, NotificationActionReceiver.class);
+ leaveIntent.setAction(NotificationActionReceiver.ACTION_LEAVE);
+ leaveIntent.putExtra("userID", userID);
+ leaveIntent.putExtra("eventID", eventID);
+
+ actionIntent1 = PendingIntent.getBroadcast(this, 2, stayIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
+ actionIntent2 = PendingIntent.getBroadcast(this, 3, leaveIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
+
+ actionButton1 = "Stay";
+ actionButton2 = "Leave";
+ }
+
+ // Build the notification
+ NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "status_channel_id")
+ .setSmallIcon(R.drawable.notification) // Ensure this icon exists
+ .setContentTitle(title)
+ .setContentText(message)
+ .setPriority(NotificationCompat.PRIORITY_HIGH) // High priority for action buttons
+ .setContentIntent(pendingIntent)
+ .setAutoCancel(true);
+
+ // Add action buttons if applicable
+ if (actionIntent1 != null && actionIntent2 != null) {
+ // Use distinct icons for actions if available
+ builder.addAction(R.drawable.ic_acceptt, actionButton1, actionIntent1);
+ builder.addAction(R.drawable.ic_decline, actionButton2, actionIntent2);
+ }
+
+ NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
+
+ int notificationId = (int) System.currentTimeMillis(); // Unique ID
+
+ // Check notification permission for Android 13+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS)
+ == PackageManager.PERMISSION_GRANTED) {
+ notificationManager.notify(notificationId, builder.build());
+ } else {
+ Log.w("NotificationsActivity", "POST_NOTIFICATIONS permission not granted, cannot display notification.");
+ }
+ } else {
+ notificationManager.notify(notificationId, builder.build());
+ }
+
+ Log.d("NotificationsActivity", "Notification sent: " + title);
+ }
+
+
+
+ /**
+ * Creates a notification channel for Android Oreo and above.
+ */
+ private void createNotificationChannel(){
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ CharSequence name = "Status Updates";
+ String description = "Notifications for status changes in events";
+ int importance = NotificationManager.IMPORTANCE_HIGH; // Use high importance for action buttons
+ NotificationChannel channel = new NotificationChannel("status_channel_id", name, importance);
+ channel.setDescription(description);
+
+ NotificationManager notificationManager = getSystemService(NotificationManager.class);
+ notificationManager.createNotificationChannel(channel);
+ }}
+
+
+
+
+
+
+
+
+
/**
* Fetches notifications from Firestore and updates the {@link RecyclerView} with the retrieved data.
* This method orders notifications by timestamp in descending order and refreshes the UI upon data retrieval.
@@ -110,8 +544,11 @@ private void fetchNotifications() {
String status = document.getString("status");
Date Date = document.getDate("timestamp");
String id = document.getId();
+ String userID = document.getString("userID");
+ String eventID = document.getString("eventID");
+ String type = document.getString("notificationType");
- NotificationModel notification = new NotificationModel(title, message, status, id, Date);
+ NotificationModel notification = new NotificationModel(title, message, status, id, Date, eventID, userID, type);
notificationList.add(notification);
}
adapter.notifyDataSetChanged();
@@ -137,6 +574,12 @@ private void handleNotificationClick(NotificationModel notification) {
.addOnFailureListener(e -> Log.e("Firestore", "Error updating status", e));
}
+ /**
+ * Opens the detailed view of a selected notification in {@link NotificationDetailActivity}.
+ * Marks the notification as read in Firestore before transitioning to the detailed view.
+ *
+ * @param notification The {@link NotificationModel} object representing the notification to be opened in detail view.
+ */
/**
* Opens the detailed view of a selected notification in {@link NotificationDetailActivity}.
* Marks the notification as read in Firestore before transitioning to the detailed view.
@@ -152,10 +595,13 @@ private void openNotificationDetail(NotificationModel notification) {
Intent intent = new Intent(this, NotificationDetailActivity.class);
intent.putExtra("title", notification.getTitle());
intent.putExtra("message", notification.getMessage());
- intent.putExtra("status", notification.getStatus());
+ intent.putExtra("date", notification.getTimeStamp() != null ? notification.getTimeStamp().toString() : "Unknown Date");
+ intent.putExtra("userID", notification.getUserID());
+ intent.putExtra("eventID", notification.getEventID());
+ intent.putExtra("notificationType", notification.getType()); // Ensure this key is set
+
startActivity(intent);
}
-
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/vortex_app/view/waitinglist/OrgWaitingListActivity.java b/app/src/main/java/com/example/vortex_app/view/waitinglist/OrgWaitingListActivity.java
index a680743..62c6093 100644
--- a/app/src/main/java/com/example/vortex_app/view/waitinglist/OrgWaitingListActivity.java
+++ b/app/src/main/java/com/example/vortex_app/view/waitinglist/OrgWaitingListActivity.java
@@ -1,6 +1,7 @@
package com.example.vortex_app.view.waitinglist;
import android.os.Bundle;
+import android.util.Log;
import android.widget.Button;
import android.widget.Toast;
@@ -11,13 +12,19 @@
import com.example.vortex_app.controller.adapter.OrgWaitingListAdapter;
import com.example.vortex_app.R;
import com.example.vortex_app.model.User;
+import com.example.vortex_app.model.orgList;
+import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.QuerySnapshot;
import com.google.firebase.firestore.DocumentSnapshot;
+import com.google.firebase.firestore.WriteBatch;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
public class OrgWaitingListActivity extends AppCompatActivity {
@@ -82,6 +89,11 @@ private void fetchWaitingList(String eventID) {
});
}
+ /**
+ * Selects users from the waiting list based on the event's maxPeople limit,
+ * moves them to the 'selected' collection, removes them from the 'waitlisted' collection,
+ * and logs notifications for each selected and non-selected user based on their preference.
+ */
private void selectAndStoreUsers() {
db.collection("events")
.document(eventID)
@@ -97,15 +109,64 @@ private void selectAndStoreUsers() {
List shuffledList = new ArrayList<>(waitingListEntrants);
Collections.shuffle(shuffledList);
List selectedUsers = shuffledList.subList(0, usersToSelect);
+ List nonSelectedUsers = shuffledList.subList(usersToSelect, shuffledList.size());
+ WriteBatch batch = db.batch();
+
+ // Process selected users
for (User user : selectedUsers) {
+ String userID = user.getUserID();
// Save the User object directly to the Firestore
db.collection("selected_but_not_confirmed")
.add(user)
.addOnSuccessListener(documentReference -> removeFromWaitlisted(user))
.addOnFailureListener(e -> Toast.makeText(this, "Failed to store selected user", Toast.LENGTH_SHORT).show());
+
+ // Reference to log notification
+ Map selectedNotificationData = new HashMap<>();
+ selectedNotificationData.put("eventID", eventID);
+ selectedNotificationData.put("timestamp", new Date());
+ selectedNotificationData.put("title", "Congratulations!");
+ selectedNotificationData.put("message", "You've been selected for the event.");
+ selectedNotificationData.put("userID", userID);
+ selectedNotificationData.put("status", "unread");
+ selectedNotificationData.put("notificationType", "selected");
+
+ // storing in notifications collection using batch operations
+ DocumentReference selectedNotificationRef = db.collection("notifications").document();
+ batch.set(selectedNotificationRef, selectedNotificationData);
+ }
+
+ // Process non-selected users
+ for (User user : nonSelectedUsers) {
+ String userID = user.getUserID();
+
+ // Log "Better Luck Next Time" notification
+ Map lostNotificationData = new HashMap<>();
+ lostNotificationData.put("eventID", eventID);
+ lostNotificationData.put("timestamp", new Date());
+ lostNotificationData.put("title", "Better Luck Next Time");
+ lostNotificationData.put("message", "You have not been selected for the event.");
+ lostNotificationData.put("userID", userID);
+ lostNotificationData.put("status", "unread");
+ lostNotificationData.put("notificationType", "lost");
+
+ DocumentReference lostNotificationRef = db.collection("notifications").document();
+ batch.set(lostNotificationRef, lostNotificationData);
}
+ // Commit the batch for notifications
+ batch.commit()
+ .addOnSuccessListener(aVoid -> {
+ Toast.makeText(this, "Notifications sent successfully.", Toast.LENGTH_SHORT).show();
+ })
+ .addOnFailureListener(e -> {
+ Toast.makeText(this, "Failed to send notifications.", Toast.LENGTH_SHORT).show();
+ Log.e("OrgWaitingListActivity", "Error committing batch: ", e);
+ });
+
+ // Refresh the waiting list
+ fetchWaitingList(eventID);
Toast.makeText(this, "Selected users stored successfully.", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "No users to select or invalid maxPeople.", Toast.LENGTH_SHORT).show();
diff --git a/app/src/main/res/drawable/ic_acceptt.xml b/app/src/main/res/drawable/ic_acceptt.xml
new file mode 100644
index 0000000..9a1521a
--- /dev/null
+++ b/app/src/main/res/drawable/ic_acceptt.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_decline.xml b/app/src/main/res/drawable/ic_decline.xml
new file mode 100644
index 0000000..ad9f9f0
--- /dev/null
+++ b/app/src/main/res/drawable/ic_decline.xml
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/notification.xml b/app/src/main/res/drawable/notification.xml
index fd1545f..ce88999 100644
--- a/app/src/main/res/drawable/notification.xml
+++ b/app/src/main/res/drawable/notification.xml
@@ -1,5 +1,6 @@
+
-
+
-
+
diff --git a/app/src/main/res/layout/activity_notification_detail.xml b/app/src/main/res/layout/activity_notification_detail.xml
index 0405b59..021c688 100644
--- a/app/src/main/res/layout/activity_notification_detail.xml
+++ b/app/src/main/res/layout/activity_notification_detail.xml
@@ -1,10 +1,11 @@
-
-
+ android:layout_height="match_parent">
+
+ app:layout_constraintEnd_toEndOf="parent">
+ android:layout_marginBottom="8dp"
+ android:background="#DDDDDD" />
+ android:lineSpacingExtra="4dp" />
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_notifications.xml b/app/src/main/res/layout/activity_notifications.xml
index 6155703..80db4c8 100644
--- a/app/src/main/res/layout/activity_notifications.xml
+++ b/app/src/main/res/layout/activity_notifications.xml
@@ -1,5 +1,6 @@
-
+
+
+
+
+
+
+
+
+
+
-
+
+
diff --git a/app/src/main/res/layout/item_notification.xml b/app/src/main/res/layout/item_notification.xml
index 3ab8416..f3f968d 100644
--- a/app/src/main/res/layout/item_notification.xml
+++ b/app/src/main/res/layout/item_notification.xml
@@ -1,37 +1,45 @@
-
+
-
-
-
-
+
+
-
-
-
-
-
+ android:layout_marginBottom="4dp" />
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/refs.xml b/app/src/main/res/values/refs.xml
deleted file mode 100644
index a6b3dae..0000000
--- a/app/src/main/res/values/refs.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
\ No newline at end of file