Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the calendar tracker feature #9

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .idea/deploymentTargetSelector.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/runConfigurations.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"java.configuration.updateBuildConfiguration": "interactive"
}
173 changes: 162 additions & 11 deletions app/src/main/java/com/mukudev/easy2do/Fragments/Fragment2DayRule.java
Original file line number Diff line number Diff line change
@@ -1,40 +1,191 @@

package com.mukudev.easy2do.Fragments;

import android.os.Bundle;
import android.content.Context;
import android.content.SharedPreferences;
import android.widget.Button;
import java.util.Set;
import java.util.HashSet;
import java.util.Calendar;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CalendarView;
import android.widget.Toast;
import android.widget.TextView;

import com.mukudev.easy2do.R;

public class Fragment2DayRule extends Fragment {
private Button markDoneButton;
private Set<String> markedDays;
private SharedPreferences sharedPreferences;
private CalendarView calendarView;
private TextView streakTextView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {

View view = inflater.inflate(R.layout.fragment_2day_rule, container, false);

// Initialize the CalendarView
CalendarView calendarView = view.findViewById(R.id.calendarView);
calendarView = view.findViewById(R.id.calendarView);
markDoneButton = view.findViewById(R.id.markDoneButton);
streakTextView = view.findViewById(R.id.streakTextView);

// Set OnDateChangeListener to capture date changes
calendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
@Override
public void onSelectedDayChange(CalendarView view, int year, int month, int dayOfMonth) {
sharedPreferences = requireContext().getSharedPreferences("HabitTracker", Context.MODE_PRIVATE);
markedDays = new HashSet<>(sharedPreferences.getStringSet("markedDays", new HashSet<>()));

String selectedDate = dayOfMonth + "/" + (month + 1) + "/" + year;
setupCalendarView();
setupMarkDoneButton();
updateStreak();

return view;
}

// Add functionality to save the mark date and it should be asserted because it cannot change after its marked
Toast.makeText(getContext(), "Selected Date: " + selectedDate, Toast.LENGTH_SHORT).show();
private void setupCalendarView() {
Calendar today = Calendar.getInstance();
calendarView.setMaxDate(today.getTimeInMillis());

calendarView.setOnDateChangeListener((view, year, month, dayOfMonth) -> {
Calendar selectedDate = Calendar.getInstance();
selectedDate.set(year, month, dayOfMonth);
Calendar currentDate = Calendar.getInstance();

if (selectedDate.before(currentDate)) {
showPastDatePopup();
} else if (selectedDate.after(currentDate)) {
Toast.makeText(getContext(), "You cannot select future dates", Toast.LENGTH_SHORT).show();
} else {
updateMarkDoneButtonState(selectedDate);
if (!isCurrentDateMarked()) {
showMarkAsDoneConfirmation();
} else {
Toast.makeText(getContext(), "This day is already marked as done!", Toast.LENGTH_SHORT).show();
}
}
});

return view;
calendarView.setDate(today.getTimeInMillis(), false, true);
highlightDates();
}

private void setupMarkDoneButton() {
markDoneButton.setOnClickListener(v -> showMarkAsDoneConfirmation());
updateMarkDoneButtonState(Calendar.getInstance());
}

private void showPastDatePopup() {
new AlertDialog.Builder(requireContext())
.setTitle("Past Date")
.setMessage("You cannot select previous dates.")
.setPositiveButton("OK", null)
.show();
}

private void showMarkAsDoneConfirmation() {
new AlertDialog.Builder(requireContext())
.setTitle("Mark as Done")
.setMessage("Are you sure you want to mark this day as done? This action cannot be undone.")
.setPositiveButton("Yes", (dialog, which) -> markTodayAsDone())
.setNegativeButton("No", null)
.show();
}

private void markTodayAsDone() {
Calendar calendar = Calendar.getInstance();
String currentDate = formatDate(calendar);

if (!markedDays.contains(currentDate)) {
markedDays.add(currentDate);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putStringSet("markedDays", markedDays);
editor.apply();

Toast.makeText(getContext(), "Marked as done!", Toast.LENGTH_SHORT).show();
}
updateMarkDoneButtonState(calendar);
updateStreak();
highlightDates();
}

private void updateMarkDoneButtonState(Calendar selectedDate) {
boolean isToday = isToday(selectedDate);
String currentDate = formatDate(selectedDate);
markDoneButton.setEnabled(isToday && !markedDays.contains(currentDate));
}

private String formatDate(Calendar calendar) {
return calendar.get(Calendar.DAY_OF_MONTH) + "/" +
(calendar.get(Calendar.MONTH) + 1) + "/" +
calendar.get(Calendar.YEAR);
}

private boolean isToday(Calendar date) {
Calendar today = Calendar.getInstance();
return date.get(Calendar.YEAR) == today.get(Calendar.YEAR) &&
date.get(Calendar.MONTH) == today.get(Calendar.MONTH) &&
date.get(Calendar.DAY_OF_MONTH) == today.get(Calendar.DAY_OF_MONTH);
}

private boolean isCurrentDateMarked() {
Calendar calendar = Calendar.getInstance();
String currentDate = formatDate(calendar);
return markedDays.contains(currentDate);
}

private void updateStreak() {
int streak = calculateStreak();
streakTextView.setText("Current Streak: " + streak + " days");
}

private int calculateStreak() {
Calendar today = Calendar.getInstance();
int streak = 0;

while (markedDays.contains(formatDate(today))) {
streak++;
today.add(Calendar.DAY_OF_MONTH, -1);
}

return streak;
}

private View getDayViewByDate(long dateInMillis) {
// Implement the logic to get the day view by date
// This is a placeholder implementation and may need to be adjusted based on your CalendarView implementation
return calendarView.findViewWithTag(dateInMillis);
}

private void highlightDates() {
for (String date : markedDays) {
// Logic to highlight the marked dates
String[] parts = date.split("/");
int day = Integer.parseInt(parts[0]);
int month = Integer.parseInt(parts[1]) - 1; // Calendar months are 0-based
int year = Integer.parseInt(parts[2]);

Calendar calendar = Calendar.getInstance();
calendar.set(year, month, day);

long dateInMillis = calendar.getTimeInMillis();
calendarView.setDate(dateInMillis, false, true);

// Assuming you have a method to get the day view by date
View dayView = getDayViewByDate(dateInMillis);
if (dayView != null) {
dayView.setBackgroundResource(R.drawable.dark_red_circle);
}
}
}

@Override
public void onResume() {
super.onResume();
setupCalendarView();
updateMarkDoneButtonState(Calendar.getInstance());
updateStreak();
}
}
8 changes: 8 additions & 0 deletions app/src/main/res/drawable/dark_red_circle.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#8B0000"/> <!-- Dark Red Color -->
<stroke
android:width="2dp"
android:color="#8B0000"/> <!-- Dark Red Border -->
<corners android:radius="50dp"/>
</shape>
46 changes: 28 additions & 18 deletions app/src/main/res/layout/fragment_2day_rule.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
Expand All @@ -11,15 +12,30 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp"
android:layout_marginTop="7dp"
android:text="\n\nDon't let more than 2 days go by without doing the activity you're trying to make a habit!"
android:layout_marginTop="4dp"
android:paddingTop="7dp"
android:text="Don't let more than 2 days go by without doing the activity you're trying to make a habit!"
android:textAlignment="center"
android:textColor="?attr/colorOnPrimary"
android:textSize="18sp"
android:textStyle="bold"
android:paddingTop="7dp"
app:layout_constraintTop_toTopOf="parent"
android:textColor="?attr/colorOnPrimary"/>
tools:layout_editor_absoluteX="0dp" />

<TextView
android:id="@+id/streakTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp"
android:layout_marginTop="4dp"
android:paddingTop="7dp"
android:text="Current Streak: 0 days"
android:textAlignment="center"
android:textColor="?attr/colorOnPrimary"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintTop_toBottomOf="@+id/textView"
tools:layout_editor_absoluteX="0dp" />

<CalendarView
android:id="@+id/calendarView"
Expand All @@ -29,22 +45,16 @@
android:dateTextAppearance="@style/customCalendarTheme"
android:weekDayTextAppearance="@style/customCalendarTheme"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="@+id/textView"
app:layout_constraintTop_toBottomOf="@+id/streakTextView"
android:background="@drawable/rectangle"/>

<TextView
android:textStyle="bold"
android:id="@+id/textView2"
android:layout_width="match_parent"
<Button
android:id="@+id/markDoneButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Stay on track and don't break the chain!"
android:textAlignment="center"
android:textSize="18sp"
android:layout_marginHorizontal="15dp"
app:layout_constraintBottom_toBottomOf="parent"
android:text="Mark as Done"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@+id/calendarView"
android:textColor="?attr/colorOnPrimary"/>



app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
2 changes: 1 addition & 1 deletion app/src/main/res/layout/fragment_2priority_task_rule.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
android:textAlignment="center"
android:textSize="20sp"
android:text="2-Priority Tasks for Today!\n(--To be Implemented--)" />
</LinearLayout>
</LinearLayout>
16 changes: 15 additions & 1 deletion app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,19 @@
<item name="colorControlHighlight">@color/white</item>
<item name="android:textColor">@drawable/selector</item>
</style>
<style name="MarkedDateStyle">
<item name="android:textColor">#FF0000</item> <!-- Red color for marked dates -->
<item name="android:textStyle">bold</item>
</style>
<style name="DarkRedCircle">
<item name="android:background">@drawable/dark_red_circle</item>
</style>

</resources>
<style name="GrayOutDateStyle">
<item name="android:textColor">#A9A9A9</item> <!-- Gray color for upcoming dates -->
</style>

<style name="DefaultDateStyle">
<item name="android:textColor">#000000</item> <!-- Default color for other dates -->
</style>
</resources>
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[versions]
agp = "8.7.0"
agp = "8.7.1"
junit = "4.13.2"
junitVersion = "1.2.1"
espressoCore = "3.6.1"
Expand Down