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

Month calendars #207

Merged
merged 1 commit into from
Nov 29, 2024
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
2 changes: 1 addition & 1 deletion Guppi.Console/Guppi.Console.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<PackageProjectUrl>https://github.com/rprouse/guppi</PackageProjectUrl>
<RepositoryUrl>https://github.com/rprouse/guppi</RepositoryUrl>
<PackageId>dotnet-guppi</PackageId>
<Version>6.3.3</Version>
<Version>6.4.0</Version>
<PackAsTool>true</PackAsTool>
<ToolCommandName>guppi</ToolCommandName>
<PackageOutputPath>./nupkg</PackageOutputPath>
Expand Down
2 changes: 1 addition & 1 deletion Guppi.Console/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"profiles": {
"Guppi.Console": {
"commandName": "Project",
"commandLineArgs": "weather daily"
"commandLineArgs": "calendar month"
}
}
}
77 changes: 77 additions & 0 deletions Guppi.Console/Skills/CalendarSkill.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Google.Apis.Calendar.v3.Data;
using Guppi.Core.Exceptions;
using Guppi.Core.Extensions;
using Guppi.Core.Interfaces.Services;
Expand Down Expand Up @@ -43,6 +44,13 @@ public IEnumerable<Command> GetCommands()
await Agenda(midnight, "Tomorrow's agenda", markdown, table);
}, markdown, table);

var month = new Command("month", "Displays this month's calendar") { markdown };
month.SetHandler(async (bool markdown) =>
{
if (markdown) await MonthMarkdown();
else Month();
}, markdown);

var free = new Command("free", "Displays free time for a given day");
free.AddArgument(new Argument<DateTime>("date", "The date to check"));
free.Handler = CommandHandler.Create<DateTime>(FreeTime);
Expand All @@ -59,6 +67,7 @@ public IEnumerable<Command> GetCommands()
next,
today,
tomorrow,
month,
free,
logout,
configure
Expand Down Expand Up @@ -260,4 +269,72 @@ private static string JoinLink(Core.Entities.Calendar.Event eventItem) =>

private static string TableLinkedSummary(Core.Entities.Calendar.Event eventItem) =>
string.IsNullOrEmpty(eventItem.MeetingUrl) ? eventItem.Summary : $"[{eventItem.Summary}]({eventItem.MeetingUrl})";

private static void Month()
{
(DateOnly start, DateOnly end) = GetMonthRange();

AnsiConsoleHelper.TitleRule($":calendar: {start:MMMM yyyy}");

var table = new Table();
table.Border(TableBorder.Rounded);

table.AddColumn(new TableColumn(new Markup("[yellow]Sun[/]")).RightAligned());
table.AddColumn(new TableColumn(new Markup("[yellow]Mon[/]")).RightAligned());
table.AddColumn(new TableColumn(new Markup("[yellow]Tue[/]")).RightAligned());
table.AddColumn(new TableColumn(new Markup("[yellow]Wed[/]")).RightAligned());
table.AddColumn(new TableColumn(new Markup("[yellow]Thu[/]")).RightAligned());
table.AddColumn(new TableColumn(new Markup("[yellow]Fri[/]")).RightAligned());
table.AddColumn(new TableColumn(new Markup("[yellow]Sat[/]")).RightAligned());

// Add empty cells for the last days of the previous month
var row = Enumerable.Range(0, 7).Select(_ => "").ToArray();
for (var day = start; day <= end; day = day.AddDays(1))
{
row[(int)day.DayOfWeek] = day.Day.ToString();
if (day.DayOfWeek == DayOfWeek.Saturday)
{
table.AddRow(row);
row = Enumerable.Range(0, 7).Select(_ => "").ToArray();
}
}
if (end.DayOfWeek != DayOfWeek.Saturday)
table.AddRow(row);

AnsiConsole.Write(table);

AnsiConsole.WriteLine();
AnsiConsoleHelper.Rule("white");
}
Comment on lines +273 to +308
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance calendar display with current day highlight and events.

The calendar display implementation is functional but could be improved:

  1. Highlight the current day for better user experience
  2. Include all-day events as mentioned in the PR objectives
  3. Consider adding padding for better number alignment

Here's a suggested improvement:

 private static void Month()
 {
     (DateOnly start, DateOnly end) = GetMonthRange();
+    var today = DateOnly.FromDateTime(DateTime.Now);
 
     AnsiConsoleHelper.TitleRule($":calendar: {start:MMMM yyyy}");
 
     var table = new Table();
     table.Border(TableBorder.Rounded);
+    table.Padding(1, 1);
 
     // ... column definitions ...
 
     var row = Enumerable.Range(0, 7).Select(_ => "").ToArray();
     for (var day = start; day <= end; day = day.AddDays(1))
     {
-        row[(int)day.DayOfWeek] = day.Day.ToString();
+        var dayStr = day.Day.ToString().PadLeft(2);
+        row[(int)day.DayOfWeek] = day == today 
+            ? $"[green]{dayStr}[/]" 
+            : dayStr;
         if (day.DayOfWeek == DayOfWeek.Saturday)
         {
             table.AddRow(row);
             row = Enumerable.Range(0, 7).Select(_ => "").ToArray();
         }
     }
     // ... rest of the method
 }

Would you like me to provide an implementation for including all-day events in the calendar display?

Committable suggestion skipped: line range outside the PR's diff.


private static async Task MonthMarkdown()
{
(DateOnly start, DateOnly end) = GetMonthRange();
StringBuilder cal = new();
cal.AppendLine("| Day | Date | Habits | Notes |");
cal.AppendLine("| --- | ---- | ------ | ----- |");
for (var day = start; day <= end; day = day.AddDays(1))
{
cal.AppendLine($"| **{day:ddd}** | [[{day:yyyy-MM-dd}]] | | |");
}

AnsiConsoleHelper.TitleRule($":calendar: {start:MMMM yyyy}");

AnsiConsole.WriteLine();
AnsiConsole.WriteLine(cal.ToString());
await TextCopy.ClipboardService.SetTextAsync(cal.ToString());
AnsiConsole.WriteLine();
AnsiConsole.MarkupLine("[green]:green_circle: Copied to clipboard[/]");

AnsiConsole.WriteLine();
AnsiConsoleHelper.Rule("white");
}

private static (DateOnly start, DateOnly end) GetMonthRange()
{
var now = DateTime.Now;
var start = new DateOnly(now.Year, now.Month, 1);
var end = new DateOnly(now.Year, now.Month, DateTime.DaysInMonth(now.Year, now.Month));
return (start, end);
}
Comment on lines +273 to +339
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add unit tests and improve error handling.

The new calendar functionality needs test coverage and better error handling:

  1. Unit tests should cover:

    • Calendar display logic
    • Markdown generation
    • Date range calculations
    • Edge cases (month transitions, leap years)
  2. Error handling:

    • Clipboard operations should be wrapped in try-catch
    • User feedback for clipboard failures

Would you like me to help create:

  1. Unit test templates for the new functionality?
  2. Error handling implementation for clipboard operations?

}