Skip to content

fix: notifications, session notes display, and add resume session button#139

Merged
gfauredev merged 2 commits intomainfrom
copilot/fix-notifications-and-session-notes
Apr 15, 2026
Merged

fix: notifications, session notes display, and add resume session button#139
gfauredev merged 2 commits intomainfrom
copilot/fix-notifications-and-session-notes

Conversation

@gfauredev
Copy link
Copy Markdown
Owner

@gfauredev gfauredev commented Apr 14, 2026

Agent-Logs-Url: https://github.com/gfauredev/LogOut/sessions/0da072c0-a66a-488a-9fae-ea480a0065c5

This Pull Request…

Engineering Principles

  • PR only contains changes strictly related to the requested feature or fix,
    scope is focused (no unrelated dependency updates or formatting)
  • This code totally respects README’s Engineering Principles

CI/CD Readiness

  • Branch follows Conventional Branch: feat/…, fix/…, refactor/…, …
  • Code is formatted with dx fmt; cargo fmt
  • All checks pass, nix flake checks succeeds without warnings
    • Code compiles, dx build with necessary platform flags succeeds
    • cargo clippy -- -D warnings -W clippy::all -W clippy::pedantic
      produces zero warnings
    • All unit tests pass without warnings
      cargo llvm-cov nextest --ignore-filename-regex '(src/components/|\.cargo/registry/|nix/store)'
    • End-to-end tests pass maestro test --headless maestro/web
      maestro test --headless maestro/android

Summary by CodeRabbit

Release Notes

  • New Features

    • Added ability to resume your most recently completed session directly from the home screen.
  • Improvements

    • Updated duration achievement notification message to display "All Time High duration" instead of previous wording.
    • Enhanced rest period notifications during active sessions for better feedback.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 14, 2026

📝 Walkthrough

Walkthrough

This PR introduces a "resume last session" feature, refactors notification scheduling logic into a shared helper, updates UI translations across multiple languages, and normalises loop destructuring formatting throughout the codebase.

Changes

Cohort / File(s) Summary
Translations
assets/en.ftl, assets/es.ftl, assets/fr.ftl
Added new translation key session-resume-last-title for resuming the last session. Updated notif-duration-body message semantics from "Target exercise duration reached" to "All Time High duration reached" across all three language files.
Loop Formatting Cleanup
src/components/active_session/completed_exercises.rs, src/components/active_session/pending_exercises.rs, src/components/analytics/chart.rs, src/components/analytics/selector.rs, src/components/exercise_form_fields.rs, src/components/exercises.rs
Normalised whitespace in tuple destructuring patterns within for loops (e.g., for (idx , log)for (idx, log)). No logic changes.
Home Page Resume Feature
src/components/home.rs
Added memoized last_session derived from completed_sessions. Rendered a new "resume last session" button that clones the most recent session, clears end_time and paused_at, and persists via storage. Minor loop formatting adjustment in SessionCard.
Active Session Refactoring
src/components/active_session/mod.rs
Replaced use_hook for textarea prefilling with onmounted handler. Introduced rest-over notification system in GlobalSessionHeader with rest_key memo, rest_bell_count signal, memoized notification strings, and effects for scheduling initial and repeated interval-exceeded notifications (separate wasm/non-wasm logic).
Notification Scheduling Helper
src/components/session_timers.rs
Extracted schedule_duration_notification(...) helper function to centralise "duration reached" notification logic. Removed per-component scheduling code from RestTimer, ExerciseElapsedTimer, and InlineExerciseTimer, replacing with calls to the new helper. Updated component documentation to clarify notification handling responsibilities.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 A session resumed with a click so fleet,
Notifications ring when duration's sweet,
Rest intervals tick and bell again,
Translations bloom in English, French, and Spanish amen!
Loops now formatted, neat as can be—
Code hops along in harmony!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description is essentially a blank template with no actual content describing the changes, objectives, or implementation details. Complete the description by explaining what was fixed in notifications, how session notes display was corrected, and what the resume session button does. Add context about the changes made across translation files and component updates.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarises the three main changes: notifications fix, session notes display fix, and resume session button addition.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch copilot/fix-notifications-and-session-notes

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

📊 Coverage Report

Lines: 3754/5005 (75.004995004995%)

⏱️ Tests: 255 tests in 0.498s

FilenameFunction CoverageLine CoverageRegion CoverageBranch Coverage
main.rs
  22.00% (11/50)
  58.94% (155/263)
  60.56% (218/360)
- (0/0)
models/analytics.rs
   0.00% (0/6)
   0.00% (0/34)
   0.00% (0/46)
- (0/0)
models/enums.rs
 100.00% (28/28)
 100.00% (147/147)
 100.00% (337/337)
- (0/0)
models/exercise.rs
  92.00% (46/50)
  92.10% (548/595)
  91.01% (749/823)
- (0/0)
models/log.rs
 100.00% (12/12)
 100.00% (118/118)
 100.00% (144/144)
- (0/0)
models/mod.rs
 100.00% (11/11)
 100.00% (68/68)
 100.00% (98/98)
- (0/0)
models/session.rs
  72.22% (13/18)
  84.36% (151/179)
  83.33% (210/252)
- (0/0)
models/units.rs
 100.00% (28/28)
 100.00% (167/167)
  98.88% (353/357)
- (0/0)
services/app_state.rs
   1.89% (1/53)
   2.54% (11/433)
   2.32% (15/646)
- (0/0)
services/exercise_db.rs
  88.81% (127/143)
  90.30% (1210/1340)
  89.61% (1924/2147)
- (0/0)
services/exercise_loader.rs
   0.00% (0/14)
   0.00% (0/100)
   0.00% (0/135)
- (0/0)
services/native_queue.rs
   0.00% (0/15)
   0.00% (0/145)
   0.00% (0/197)
- (0/0)
services/notifications.rs
   0.00% (0/3)
   0.00% (0/9)
   0.00% (0/10)
- (0/0)
services/service_worker.rs
 100.00% (2/2)
 100.00% (6/6)
 100.00% (6/6)
- (0/0)
services/storage.rs
  63.77% (88/138)
  80.97% (766/946)
  83.53% (1187/1421)
- (0/0)
services/wake_lock.rs
 100.00% (2/2)
 100.00% (5/5)
 100.00% (5/5)
- (0/0)
utils.rs
  89.61% (69/77)
  89.33% (402/450)
  90.14% (640/710)
- (0/0)
Totals
  67.38% (438/650)
  75.00% (3754/5005)
  76.50% (5886/7694)
- (0/0)

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/active_session/mod.rs`:
- Around line 500-545: The scheduled rest notification in the use_effect closure
must be made cancelable and pause-aware: capture the current rest_key()
generation (or start+duration tuple) and paused_at into the spawned task, and
before calling crate::services::notifications::send_notification verify the
generation still matches and paused_at is not set (or use an
AbortHandle/Abortable task/AbortController to cancel the pending timer whenever
rest_key(), paused_at, rest_notif_title/body, or the session end changes); apply
this for both the tokio::spawn branch (use tokio::sync::oneshot/AbortHandle or
check the captured generation after sleep) and the
wasm_bindgen_futures::spawn_local branch (use AbortController or check the
captured generation/paused_at after the TimeoutFuture) so stale notifications
are never delivered when the rest is changed, paused, canceled, or a new rest
period starts.
- Around line 547-569: The loop currently fires when intervals > prev which
duplicates the first rest-over alert if a one-shot notification has already
occurred; change the condition in the coroutine (the block using
rest_key.peek(), rest_bell_count.peek(), and send_notification) to ignore the
first interval when prev == 0 (e.g. require not (prev == 0 && intervals == 1))
so the first interval is excluded here, and when you do send a notification
still call rest_bell_count.set(intervals) to advance the counter; alternatively,
ensure the scheduled one-shot notifier updates rest_bell_count to the current
intervals when it fires so this coroutine won't resend.

In `@src/components/home.rs`:
- Around line 87-94: The current use_memo for last_session uses
completed_sessions.read().first().filter(...) which only checks the first cached
row; change it to search the collection for the first resumable session by
iterating and finding the first entry whose exercise_logs is non-empty. Update
the closure used by last_session (the use_memo block) to call
completed_sessions.read().iter().find(|s| !s.exercise_logs.is_empty()).cloned()
(or the equivalent iterator/find call for the collection type) so the resume
button picks the first resumable session rather than only the first loaded row.
- Around line 154-171: Resuming a session by re-saving the same id via
storage::save_session from the onclick in the last_session branch leaves
completed_sessions and viewed_ids stale; update the onclick handler that uses
session_to_resume so that after calling storage::save_session you also remove or
update the corresponding entry in completed_sessions (or clear the id from
viewed_ids) so the sync effect that deduplicates by viewed_ids will see the
resumed changes, or alternatively generate a new session id when creating
session_to_resume; locate the onclick closure around session_to_resume and
ensure it updates completed_sessions/viewed_ids or assigns a new id before
saving.

In `@src/components/session_timers.rs`:
- Around line 15-61: The spawned WASM timeout can fire for a stale exercise
because it isn't validated when it wakes; in schedule_duration_notification
capture the original identifiers (exercise_start/last_duration or an explicit
exercise_id/generation) and, inside the spawn_local callback before setting
duration_bell_rung and calling send_notification, re-check the current active
exercise/generation (e.g. compare the current exercise_start or a passed
generation token read from the same Signal/store used to drive the UI) and only
set duration_bell_rung/send_notification if they still match; otherwise do
nothing so the old timeout is effectively cancelled. Ensure the check uses the
same Signal types (duration_bell_rung.peek/read) so you don't mutate state for a
different exercise.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 981caf71-dcef-4dac-8375-09485c253d09

📥 Commits

Reviewing files that changed from the base of the PR and between cb26fad and d61d5d4.

📒 Files selected for processing (12)
  • assets/en.ftl
  • assets/es.ftl
  • assets/fr.ftl
  • src/components/active_session/completed_exercises.rs
  • src/components/active_session/mod.rs
  • src/components/active_session/pending_exercises.rs
  • src/components/analytics/chart.rs
  • src/components/analytics/selector.rs
  • src/components/exercise_form_fields.rs
  • src/components/exercises.rs
  • src/components/home.rs
  • src/components/session_timers.rs

Comment on lines +500 to +545
// Schedule a precise one-shot rest-over notification whenever a new rest
// period begins. Fires ~250 ms early to compensate for jitter.
use_effect(move || {
let Some((start, duration)) = rest_key() else {
return;
};
if duration == 0 {
return;
}
// Reset the exceeded-interval counter for the new rest period.
rest_bell_count.set(0);

let title = rest_notif_title.peek().clone();
let body = rest_notif_body.peek().clone();
let fire_at_secs = start + duration;

#[cfg(not(target_arch = "wasm32"))]
{
let now = crate::models::get_current_timestamp();
if fire_at_secs > now {
let delay_ms = ((fire_at_secs - now) * 1_000)
.saturating_sub(crate::components::session_timers::NOTIF_EARLY_MS);
tokio::spawn(async move {
tokio::time::sleep(std::time::Duration::from_millis(delay_ms)).await;
crate::services::notifications::send_notification(&title, &body, "logout-rest");
});
} else {
crate::services::notifications::send_notification(&title, &body, "logout-rest");
}
}
#[cfg(target_arch = "wasm32")]
{
let now = crate::models::get_current_timestamp();
let delay_ms = if fire_at_secs > now {
((fire_at_secs - now) * 1_000)
.saturating_sub(crate::components::session_timers::NOTIF_EARLY_MS)
.min(u32::MAX as u64) as u32
} else {
0
};
wasm_bindgen_futures::spawn_local(async move {
gloo_timers::future::TimeoutFuture::new(delay_ms).await;
crate::services::notifications::send_notification(&title, &body, "logout-rest");
});
}
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

The scheduled rest alert is neither cancelled nor pause-aware.

The spawned task always fires once start + duration is reached, even if the user pauses the session, changes the rest duration, starts a new rest period, or finishes the session first. That can produce stale “rest over” notifications. This needs a generation/key check or explicit cancellation, and the schedule must stop whilst paused_at is set.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/active_session/mod.rs` around lines 500 - 545, The scheduled
rest notification in the use_effect closure must be made cancelable and
pause-aware: capture the current rest_key() generation (or start+duration tuple)
and paused_at into the spawned task, and before calling
crate::services::notifications::send_notification verify the generation still
matches and paused_at is not set (or use an AbortHandle/Abortable
task/AbortController to cancel the pending timer whenever rest_key(), paused_at,
rest_notif_title/body, or the session end changes); apply this for both the
tokio::spawn branch (use tokio::sync::oneshot/AbortHandle or check the captured
generation after sleep) and the wasm_bindgen_futures::spawn_local branch (use
AbortController or check the captured generation/paused_at after the
TimeoutFuture) so stale notifications are never delivered when the rest is
changed, paused, canceled, or a new rest period starts.

Comment on lines +547 to +569
// Tick-based coroutine: fires a notification for every completed exceeded
// interval (2nd, 3rd, … ring) so the user keeps being reminded.
use_coroutine(move |_: UnboundedReceiver<()>| async move {
loop {
crate::utils::sleep_ms(1_000).await;
let Some((start, duration)) = *rest_key.peek() else {
continue;
};
if duration == 0 {
continue;
}
let now = crate::models::get_current_timestamp();
let elapsed = now.saturating_sub(start);
let intervals = elapsed / duration;
let prev = *rest_bell_count.peek();
if intervals > prev {
rest_bell_count.set(intervals);
crate::services::notifications::send_notification(
&rest_notif_title.peek(),
&rest_notif_body.peek(),
"logout-rest",
);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

The first rest bell now fires twice.

rest_bell_count stays at 0 after the one-shot notification, so this loop sends again as soon as elapsed / duration == 1. The first rest-over alert will therefore be duplicated; the counter needs to be advanced when the scheduled notification wins, or the first interval must be excluded here.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/active_session/mod.rs` around lines 547 - 569, The loop
currently fires when intervals > prev which duplicates the first rest-over alert
if a one-shot notification has already occurred; change the condition in the
coroutine (the block using rest_key.peek(), rest_bell_count.peek(), and
send_notification) to ignore the first interval when prev == 0 (e.g. require not
(prev == 0 && intervals == 1)) so the first interval is excluded here, and when
you do send a notification still call rest_bell_count.set(intervals) to advance
the counter; alternatively, ensure the scheduled one-shot notifier updates
rest_bell_count to the current intervals when it fires so this coroutine won't
resend.

Comment thread src/components/home.rs
Comment thread src/components/home.rs
Comment on lines +154 to +171
if let Some(ref last_sess) = *last_session.read() {
{
let session_to_resume = {
let mut s = last_sess.clone();
s.end_time = None;
s.paused_at = None;
s
};
rsx! {
button {
class: "icon edit",
onclick: move |_| {
storage::save_session(session_to_resume.clone());
},
title: t!("session-resume-last-title"),
"▶️"
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Resuming in place leaves the completed-session cache stale.

This saves the resumed session with the same id, but completed_sessions still holds the old clone. When it is finished again, the sync effect at Lines 56-82 ignores the updated row because viewed_ids already contains that id, so the home list can keep showing pre-resume data until a full reload. Remove/update the cached entry on resume, or resume into a new session id.

One possible fix if the id must stay stable
                             button {
                                 class: "icon edit",
                                 onclick: move |_| {
+                                    let new_len = {
+                                        let mut cs = completed_sessions.write();
+                                        cs.retain(|s| s.id != session_to_resume.id);
+                                        cs.len()
+                                    };
+                                    sessions_loaded_offset.set(new_len);
                                     storage::save_session(session_to_resume.clone());
                                 },
                                 title: t!("session-resume-last-title"),
                                 "▶️"
                             }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if let Some(ref last_sess) = *last_session.read() {
{
let session_to_resume = {
let mut s = last_sess.clone();
s.end_time = None;
s.paused_at = None;
s
};
rsx! {
button {
class: "icon edit",
onclick: move |_| {
storage::save_session(session_to_resume.clone());
},
title: t!("session-resume-last-title"),
"▶️"
}
}
if let Some(ref last_sess) = *last_session.read() {
{
let session_to_resume = {
let mut s = last_sess.clone();
s.end_time = None;
s.paused_at = None;
s
};
rsx! {
button {
class: "icon edit",
onclick: move |_| {
let new_len = {
let mut cs = completed_sessions.write();
cs.retain(|s| s.id != session_to_resume.id);
cs.len()
};
sessions_loaded_offset.set(new_len);
storage::save_session(session_to_resume.clone());
},
title: t!("session-resume-last-title"),
"▶️"
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/home.rs` around lines 154 - 171, Resuming a session by
re-saving the same id via storage::save_session from the onclick in the
last_session branch leaves completed_sessions and viewed_ids stale; update the
onclick handler that uses session_to_resume so that after calling
storage::save_session you also remove or update the corresponding entry in
completed_sessions (or clear the id from viewed_ids) so the sync effect that
deduplicates by viewed_ids will see the resumed changes, or alternatively
generate a new session id when creating session_to_resume; locate the onclick
closure around session_to_resume and ensure it updates
completed_sessions/viewed_ids or assigns a new id before saving.

Comment on lines +15 to +61
/// Schedule a one-shot duration-reached notification for the given exercise.
///
/// * On **WASM**: uses `gloo_timers` in a `spawn_local` task so the timeout
/// fires accurately without blocking the UI. `duration_bell_rung` is set
/// inside the callback to prevent the tick-based fallback from sending a
/// duplicate.
/// * On **native**: the tick-based path is accurate enough (±1 s) and avoids
/// the complexity of crossing Dioxus signal boundaries from a `tokio::spawn`
/// thread; no extra task is spawned here.
#[allow(unused_mut)]
fn schedule_duration_notification(
exercise_start: Option<u64>,
last_duration: Option<u64>,
mut duration_bell_rung: Signal<bool>,
) {
#[cfg(target_arch = "wasm32")]
{
let Some(start) = exercise_start else { return };
let Some(dur) = last_duration else { return };
if dur == 0 || *duration_bell_rung.read() {
return;
}
let fire_at_secs = start + dur;
let now = get_current_timestamp();
// Only schedule if the duration hasn't already elapsed; the tick-based
// fallback fires immediately when elapsed >= dur on the next tick.
if fire_at_secs <= now {
return;
}
let delay_ms = ((fire_at_secs - now) * 1_000)
.saturating_sub(NOTIF_EARLY_MS)
.min(u32::MAX as u64) as u32;
let title = t!("notif-duration-title").to_string();
let body = t!("notif-duration-body").to_string();
wasm_bindgen_futures::spawn_local(async move {
gloo_timers::future::TimeoutFuture::new(delay_ms).await;
// Re-check to avoid a duplicate if the tick fired first.
if !*duration_bell_rung.peek() {
duration_bell_rung.set(true);
crate::services::notifications::send_notification(&title, &body, "logout-duration");
}
});
}
// On native, suppress unused-variable warnings; the tick handles it.
#[cfg(not(target_arch = "wasm32"))]
let _ = (exercise_start, last_duration, duration_bell_rung);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

The WASM duration timeout can ring for the wrong exercise.

This timeout is never cancelled or keyed to the current exercise. If the user completes/cancels the exercise, starts another one, or pauses before it fires, the old task can still send logout-duration, and because duration_bell_rung gets reused it can suppress the real alert for the new exercise. The callback needs to validate the active exercise/generation before sending.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/session_timers.rs` around lines 15 - 61, The spawned WASM
timeout can fire for a stale exercise because it isn't validated when it wakes;
in schedule_duration_notification capture the original identifiers
(exercise_start/last_duration or an explicit exercise_id/generation) and, inside
the spawn_local callback before setting duration_bell_rung and calling
send_notification, re-check the current active exercise/generation (e.g. compare
the current exercise_start or a passed generation token read from the same
Signal/store used to drive the UI) and only set
duration_bell_rung/send_notification if they still match; otherwise do nothing
so the old timeout is effectively cancelled. Ensure the check uses the same
Signal types (duration_bell_rung.peek/read) so you don't mutate state for a
different exercise.

…med session UI, stale ATH notification

Agent-Logs-Url: https://github.com/gfauredev/LogOut/sessions/feeac486-69ef-4414-beff-795baf8bb24b

Co-authored-by: gfauredev <19304085+gfauredev@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown

📊 Coverage Report

Lines: 3754/5005 (75.004995004995%)

⏱️ Tests: 255 tests in 0.597s

FilenameFunction CoverageLine CoverageRegion CoverageBranch Coverage
main.rs
  22.00% (11/50)
  58.94% (155/263)
  60.56% (218/360)
- (0/0)
models/analytics.rs
   0.00% (0/6)
   0.00% (0/34)
   0.00% (0/46)
- (0/0)
models/enums.rs
 100.00% (28/28)
 100.00% (147/147)
 100.00% (337/337)
- (0/0)
models/exercise.rs
  92.00% (46/50)
  92.10% (548/595)
  91.01% (749/823)
- (0/0)
models/log.rs
 100.00% (12/12)
 100.00% (118/118)
 100.00% (144/144)
- (0/0)
models/mod.rs
 100.00% (11/11)
 100.00% (68/68)
 100.00% (98/98)
- (0/0)
models/session.rs
  72.22% (13/18)
  84.36% (151/179)
  83.33% (210/252)
- (0/0)
models/units.rs
 100.00% (28/28)
 100.00% (167/167)
  98.88% (353/357)
- (0/0)
services/app_state.rs
   1.89% (1/53)
   2.54% (11/433)
   2.32% (15/646)
- (0/0)
services/exercise_db.rs
  88.81% (127/143)
  90.30% (1210/1340)
  89.61% (1924/2147)
- (0/0)
services/exercise_loader.rs
   0.00% (0/14)
   0.00% (0/100)
   0.00% (0/135)
- (0/0)
services/native_queue.rs
   0.00% (0/15)
   0.00% (0/145)
   0.00% (0/197)
- (0/0)
services/notifications.rs
   0.00% (0/3)
   0.00% (0/9)
   0.00% (0/10)
- (0/0)
services/service_worker.rs
 100.00% (2/2)
 100.00% (6/6)
 100.00% (6/6)
- (0/0)
services/storage.rs
  63.77% (88/138)
  80.97% (766/946)
  83.53% (1187/1421)
- (0/0)
services/wake_lock.rs
 100.00% (2/2)
 100.00% (5/5)
 100.00% (5/5)
- (0/0)
utils.rs
  89.61% (69/77)
  89.33% (402/450)
  90.14% (640/710)
- (0/0)
Totals
  67.38% (438/650)
  75.00% (3754/5005)
  76.50% (5886/7694)
- (0/0)

@gfauredev gfauredev merged commit b209626 into main Apr 15, 2026
6 checks passed
@gfauredev gfauredev deleted the copilot/fix-notifications-and-session-notes branch April 15, 2026 21:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants