Skip to content

Commit

Permalink
Merge pull request #9 from RITIK-CHAUDHRY/Implement-the-Calendar-Trac…
Browse files Browse the repository at this point in the history
…ker-Feature

Implement the calendar tracker feature
  • Loading branch information
mukul-dev authored Oct 26, 2024
2 parents 18296a5 + a410712 commit 57ff998
Show file tree
Hide file tree
Showing 10 changed files with 233 additions and 34 deletions.
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

0 comments on commit 57ff998

Please sign in to comment.