Fix icon rendering, DB reload processing, and planner bugs#23
Open
Fix icon rendering, DB reload processing, and planner bugs#23
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Updates StudySync’s JavaFX UI and Drive reload behavior to improve cross-platform icon rendering and fix planner/recurring-task edge cases, especially on systems without reliable per-glyph font fallback.
Changes:
- Standardize icon rendering by moving emoji/symbol glyphs into
setGraphic()using Noto Emoji labels across multiple panels and badges. - After Google Drive DB download/reload, re-run delayed-task and delayed-goal processing so overdue state updates immediately.
- Adjust recurring-task logic: exclude POSTPONED from “active recurring,” and add
Task.appliesToDate()for date-aware filtering in the re-plan dropdown; fix ComboBox cell factory to clear text withnull.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/main/java/com/studysync/presentation/ui/components/TaskStyleUtils.java | Adds iconLabel() helper and updates badge rendering to use setGraphic() with Noto Emoji. |
| src/main/java/com/studysync/presentation/ui/components/TaskManagementPanel.java | Switches status/error icon rendering to setGraphic() for better emoji reliability. |
| src/main/java/com/studysync/presentation/ui/components/StudyPlannerPanel.java | Updates many UI glyphs to graphics, fixes ComboBox cell clearing, tweaks session handling and error display. |
| src/main/java/com/studysync/presentation/ui/components/ProfileViewPanel.java | Converts several Drive/profile UI icons to graphics; adjusts Drive status messaging. |
| src/main/java/com/studysync/presentation/ui/components/CalendarViewPanel.java | Moves header/tab/button glyphs to graphics and applies emoji font for small glyph labels. |
| src/main/java/com/studysync/presentation/ui/StudySyncUI.java | Re-runs delayed task/goal startup processing after DB reload from Drive and improves reload overlay rendering. |
| src/main/java/com/studysync/integration/drive/GoogleDriveSettingsLoader.java | Ensures default paths resolve to absolute paths for deterministic Drive IO. |
| src/main/java/com/studysync/integration/drive/GoogleDriveService.java | Makes Drive upload safer by aborting on failed H2 checkpoint; conditionally skips shutdown upload if checkpoint fails. |
| src/main/java/com/studysync/integration/drive/GoogleDriveGateway.java | Adds diagnostic logging (file size/mtime) before uploading DB to Drive. |
| src/main/java/com/studysync/domain/service/StudyService.java | Filters delayed goals eligible for replanning using Task.appliesToDate(today) for recurring tasks. |
| src/main/java/com/studysync/domain/entity/Task.java | Adds appliesToDate() and updates findActiveRecurring() to exclude POSTPONED tasks. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/main/java/com/studysync/presentation/ui/components/ProfileViewPanel.java
Outdated
Show resolved
Hide resolved
src/main/java/com/studysync/presentation/ui/components/StudyPlannerPanel.java
Show resolved
Hide resolved
Owner
Author
|
Downloaded up-to-date DB from Drive on Ubuntu 24.04 LTS. Calendar Panel does not refresh to the latest version. |
Abort upload when CHECKPOINT SYNC fails instead of uploading stale data, resolve Drive settings path to absolute to prevent CWD-dependent mismatch, fix double startSession() call that desynchronised in-memory/DB state, and add exception handling around session save in the UI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…pport JavaFX CSS font-family does not perform per-glyph fallback like browsers, so emoji/symbol characters fail to render on systems missing the right font (e.g. Kubuntu 24.04). Fix by separating icon glyphs into dedicated Label nodes using setGraphic() with the bundled Noto Emoji font, keeping regular text in the default system font. Adds TaskStyleUtils.iconLabel() helper and updates all panels: StudyPlannerPanel, CalendarViewPanel, ProfileViewPanel, TaskManagementPanel, and the reload overlay in StudySyncUI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After downloading a new database from Google Drive, the reload listener only reset caches and refreshed panels but did not re-run the startup processing steps (markDelayedTasks, processAllDelayedGoals). This meant overdue tasks were not marked DELAYED and delayed goals were not processed until the next app restart. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tasks with POSTPONED status were still returned by findActiveRecurring(), causing them to appear as missed in the study planner even though the user intentionally paused them. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add Task.appliesToDate() to check if a recurring task is scheduled on a given date based on its recurrence pattern and anchor - Filter re-plan dropdown to hide recurring-task goals when the task already applies today (it will naturally re-occur) - Fix ComboBox cell factory to use setText(null)/setGraphic(null) for empty items instead of empty strings, preventing phantom empty boxes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract duplicate ComboBox cell factory into shared Callback variable - Cache dateNavLabel icon as instance field to avoid re-creating on every updateDisplay() call - Narrow catch(Exception) in appliesToDate() to specific exception types and add warning log for invalid recurring patterns Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace surrogate-pair emoji (U+1F512, U+1F510) and extended arrows (U+2B06, U+2B07) on Drive sync buttons with basic Unicode symbols (arrows, cross mark) that Noto Emoji reliably renders. Also limit re-plan ComboBox visible row count to item count to prevent phantom empty row in dropdown. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of date-checking recurring patterns, simply exclude any delayed goal whose parent task already appears in today's tasks section. This covers both recurring and non-recurring tasks — if the task is visible today, its goals are already accessible directly and don't need re-planning. Removes the now-unused Task.appliesToDate() method. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…abel - Move the warning symbol out of the Drive status text string and into setGraphic() so it renders via Noto Emoji like all other icons - Replace stacking error labels in the end-session dialog with a single reusable label that updates its text on repeated failures Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace all remaining inline emoji and surrogate pair characters with setGraphic(iconLabel(...)) using basic Unicode symbols rendered via Noto Emoji font. Covers ProjectManagementPanel, ReflectionDiaryPanel, and the last surrogate pair in StudyPlannerPanel. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…picker - TaskService.matchesCategory(): NPE when task.getCategory() is null - TaskService.searchTasksAdvanced(): same null category issue - ProjectService.searchProjects(): same pattern - TaskReminder.toString(): NPE when computeReminderDate() returns null - ReflectionDiaryPanel.onDateChanged(): NPE if datePicker value is null - StudySyncUI: close icon InputStream via try-with-resources Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Root cause: CSS `.button { -fx-content-display: center; }` forced all
button graphics to render centered, overlapping with the button text.
Changed to `left` so icons render beside text. Also converted planner
prev/next nav buttons from fontEmoji-on-text to setGraphic pattern, and
used inline style for the CalendarView "Next" button (CSS overrides
setContentDisplay).
For re-plan dropdown: added CSS rule to collapse empty combo-box-popup
list cells (zero height + transparent) so phantom rows are invisible.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the two-option exit dialog with three choices: - "Push to Drive & Exit" — checkpoint + upload + exit - "Save Locally & Exit" — checkpoint + exit (no upload) - "Exit without Saving" — exit immediately, no DB flush Default shutdownSaveEnabled to false so Drive is never silently overwritten by @PreDestroy. Add saveLocally() method and a "Save Locally" button in the Profile panel for explicit disk flush. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Acquire an exclusive file lock on ~/.local/share/studysync/.studysync.lock at startup. If another StudySync process holds the lock, print a message to stderr and exit immediately — preventing duplicate windows and DB corruption from concurrent H2 access. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Set -Dglass.appClassName=StudySync in the launcher script so JavaFX reports "StudySync" as the X11 WM_CLASS. Update StartupWMClass in the .desktop entry to match. This prevents GNOME from showing the app as a separate dock icon instead of grouping it with its launcher. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Set StartupWMClass to the actual WM_CLASS that JavaFX reports: "com.studysync.application.StudySyncJavaFXApp" (verified via xprop). The previous glass.appClassName approach didn't override JavaFX's default. Remove the unused JVM flag from the launcher. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GNOME's Mutter ignores JavaFX DialogPane pref/min size hints, causing sub-windows to open at their minimum content size. Fix by explicitly setting width/height on the dialog window via onShown handler, and setting explicit dimensions on the Profile stage. KDE is unaffected. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Review fixes: - Always SHUTDOWN H2 engine on exit regardless of save choice, preventing DB corruption from racy JVM shutdown hooks. The "Exit without Saving" option now only skips the Drive upload, not the disk flush. - Remove skipShutdownCheckpoint flag (unnecessary with the above). - Remove logDbSnapshot diagnostic method and its call sites — was debug-only code left in production. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove the auto-carry-forward clause from findByTaskIdForDate and findUnlinkedForDate. Delayed goals now only appear if explicitly re-planned (replanned_for_date = today) or originally scheduled (date = today). The old clause caused two bugs: 1. Re-planning one goal pulled ALL delayed goals for that task 2. Achieved delayed goals vanished (achieved=TRUE excluded by clause) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8b5ee17 to
22a1e07
Compare
…ving Goals are never deleted from the database. Overdue goals (14+ days) are now marked as FAILED instead of being physically removed, preserving them for historical logging. User-initiated "delete" also soft-deletes by setting the failed flag. Each task card in Task Management now has a "Goal History" toggle that shows all goals ever linked to that task — achieved, active, delayed, and failed — with summary statistics. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Codex review flagged that soft-deleting an already-achieved goal left both achieved=true and failed=true, causing it to still count as a completion in ProfileViewPanel, hasAchievedGoalForTask(), and findAchievedTaskDatePairs(). Fix: reset achieved=false when marking failed, and add failed=FALSE filters to all achievement-based queries. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…em vanish Goals re-planned to a specific date disappeared from all views once that date passed, because queries only match on date or replanned_for_date equal to the display date. Now processAllDelayedGoals() marks these goals as failed immediately when the replan date passes, so they appear in goal history with proper failed status. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…iled - Calendar delete is now permanent (hard delete from DB), not soft-delete - Added "Mark as Failed" button on calendar for explicit soft-deletion - Calendar shows all goals for their planned date including failed ones, with distinct red styling and status indicator for failed goals - Added findAllByDate/findAllByDateIncludingDelayed queries that include failed goals, used exclusively by calendar view - Split deleteStudyGoal (hard delete) from markGoalAsFailed (soft-delete) - Failed and delayed goals count against the profile goal completion rate - Fixes all Codex-identified blind spots: unlinked failed goals are now visible on the calendar for the day they were originally planned Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
feat: goal history per task + soft-delete goals
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Pre-Landing Review
Pre-Landing Review: 2 issues — 2 auto-fixed (H2 SHUTDOWN always runs on exit, debug diagnostics removed)
Test plan