# ReaderFooter

- File ID: file:1foudu6:readerfooter-razor
- Path: NexusReader.UI.Shared/Components/Organisms/ReaderFooter.razor
- Role: ui-component
- Layer: frontend

## Purpose

Blazor UI component that renders the reader footer: chapter navigation, progress bar and meta info; observes navigation changes to update UI.

## Key Details

Component is event-driven: subscribes to NavigationService.OnNavigationChanged to refresh UI; uses injected IReaderNavigationService for navigation commands and data; guards against single-chapter progress calculation.

## Symbols

- ReaderFooter: Blazor UI component that renders the reader footer: chapter navigation, progress bar and meta info; observes navigation changes to update UI.
- Render (Razor markup): Renders footer HTML: navigation buttons, chapter info, progress bar and meta info; wires button onclicks to navigation service methods and displays computed progress/time/battery.
- OnInitialized(): Component lifecycle init: subscribes to navigation change events to refresh UI.
- HandleNavigationChanged(): Async event handler invoked on navigation changes; requests a UI re-render on the component thread.
- CalculateProgress(): Computes and returns the reader progress percentage based on current chapter index and total chapters.
- Dispose(): Lifecycle cleanup: unsubscribes event handlers to avoid memory leaks.

## Dependencies

- imports NexusReader.UI.Shared/Services/IReaderNavigationService.cs

## Calls

- calls NexusReader.UI.Shared/Services/IReaderNavigationService.cs
- calls NexusReader.UI.Shared/Services/IReaderNavigationService.cs

## Unresolved References

- call-target: NexusReader.UI.Shared/Services/IReaderNavigationService.cs
- call-target: NexusReader.UI.Shared/Services/IReaderNavigationService.cs
- call-target: NexusReader.UI.Shared/Services/IReaderNavigationService.cs
- call-target: NexusReader.UI.Shared/Services/IReaderNavigationService.cs
- call-target: self
- call-target: NexusReader.UI.Shared/Services/IReaderNavigationService.cs
- call-target: self
- call-target: NexusReader.UI.Shared/Services/IReaderNavigationService.cs
- call-target: NexusReader.UI.Shared/Services/IReaderNavigationService.cs
- call-target: NexusReader.UI.Shared/Services/IReaderNavigationService.cs

## Coverage

- Symbols: 6
- Executable symbols: 5
- Executable symbols with control flow: 5
- Grounded edges: 9
- Unresolved references: 10
- Control-flow fragments: 5
- Unresolved jumps: 8
- Unsupported constructs: 0
- Control-flow coverage: 100%
- Required diagrams: 2
- Generated diagrams: 7

## Control Flow Fragments

- Render (Razor markup): 19 nodes, 20 edges, 7 jumps, 0 unsupported constructs
- OnInitialized: 5 nodes, 4 edges, 2 jumps, 0 unsupported constructs
- HandleNavigationChanged: 4 nodes, 3 edges, 0 jumps, 0 unsupported constructs
- CalculateProgress: 14 nodes, 15 edges, 2 jumps, 0 unsupported constructs
- Dispose: 4 nodes, 3 edges, 1 jumps, 0 unsupported constructs

## Diagrams

### ReaderFooter Neighborhood

```mermaid
flowchart LR
    class_gqmtg_readerfooter("ReaderFooter")
    file_1foudu6_readerfooter_razor("ReaderFooter")
    method_150wzsg_dispose[["Dispose()"]]
    method_1ac31ry_handlenavigationchanged[["HandleNavigationChanged()"]]
    method_1ak3em3_calculateprogress[["CalculateProgress()"]]
    method_1se6qsi_oninitialized[["OnInitialized()"]]
    method_tmysty_render_razor_markup[["Render (Razor markup)"]]
    file_wgkae9_ireadernavigationservice_cs[/"IReaderNavigationService"/]
    method_12odud7_gotopreviouschapter[/"IReaderNavigationService"/]
    method_1dvbk1u_gotonextchapter[/"IReaderNavigationService"/]
    file_1foudu6_readerfooter_razor -->|IReaderNavigationService| file_wgkae9_ireadernavigationservice_cs
    method_tmysty_render_razor_markup -->|IReaderNavigationService| method_12odud7_gotopreviouschapter
    method_tmysty_render_razor_markup -->|IReaderNavigationService| method_1dvbk1u_gotonextchapter
```

### ReaderFooter Execution Overview

```mermaid
flowchart TD
    class_gqmtg_readerfooter("ReaderFooter")
    method_150wzsg_dispose[["Dispose()"]]
    method_1ac31ry_handlenavigationchanged[["HandleNavigationChanged()"]]
    method_1ak3em3_calculateprogress[["CalculateProgress()"]]
    method_1se6qsi_oninitialized[["OnInitialized()"]]
    method_tmysty_render_razor_markup[["Render (Razor markup)"]]
    method_12odud7_gotopreviouschapter[/"IReaderNavigationService"/]
    method_1dvbk1u_gotonextchapter[/"IReaderNavigationService"/]
    unresolved_unresolved_16fjgig_call_target{"Unresolved: TotalChapters (property)"}
    unresolved_unresolved_19qrwhc_call_target{"Unresolved: TotalChapters (property)"}
    unresolved_unresolved_1bw9ru3_call_target{"Unresolved: HandleNavigationChanged"}
    unresolved_unresolved_1di6ghi_call_target{"Unresolved: CurrentChapterIndex (property)"}
    unresolved_unresolved_1rzriwn_call_target{"Unresolved: ChapterTitle (property)"}
    unresolved_unresolved_gjvq32_call_target{"Unresolved: CurrentChapterIndex (property)"}
    unresolved_unresolved_i4ys3x_call_target{"Unresolved: CalculateProgress"}
    unresolved_unresolved_pfzdgu_call_target{"Unresolved: OnNavigationChanged (event)"}
    unresolved_unresolved_t92f63_call_target{"Unresolved: OnNavigationChanged (event)"}
    class_gqmtg_readerfooter -->|contains| method_150wzsg_dispose
    class_gqmtg_readerfooter -->|contains| method_1ac31ry_handlenavigationchanged
    class_gqmtg_readerfooter -->|contains| method_1ak3em3_calculateprogress
    class_gqmtg_readerfooter -->|contains| method_1se6qsi_oninitialized
    class_gqmtg_readerfooter -->|contains| method_tmysty_render_razor_markup
    method_150wzsg_dispose -->|unresolved call| unresolved_unresolved_pfzdgu_call_target
    method_1ak3em3_calculateprogress -->|unresolved call| unresolved_unresolved_19qrwhc_call_target
    method_1ak3em3_calculateprogress -->|unresolved call| unresolved_unresolved_gjvq32_call_target
    method_1se6qsi_oninitialized -->|unresolved call| unresolved_unresolved_1bw9ru3_call_target
    method_1se6qsi_oninitialized -->|unresolved call| unresolved_unresolved_t92f63_call_target
    method_tmysty_render_razor_markup -->|IReaderNavigationService| method_12odud7_gotopreviouschapter
    method_tmysty_render_razor_markup -->|IReaderNavigationService| method_1dvbk1u_gotonextchapter
    method_tmysty_render_razor_markup -->|unresolved call| unresolved_unresolved_16fjgig_call_target
    method_tmysty_render_razor_markup -->|unresolved call| unresolved_unresolved_1di6ghi_call_target
    method_tmysty_render_razor_markup -->|unresolved call| unresolved_unresolved_1di6ghi_call_target
    method_tmysty_render_razor_markup -->|unresolved call| unresolved_unresolved_1rzriwn_call_target
    method_tmysty_render_razor_markup -->|unresolved call| unresolved_unresolved_i4ys3x_call_target
```

### ReaderFooter Method Interactions

```mermaid
flowchart LR
    method_150wzsg_dispose[["Dispose()"]]
    method_1ac31ry_handlenavigationchanged[["HandleNavigationChanged()"]]
    method_1ak3em3_calculateprogress[["CalculateProgress()"]]
    method_1se6qsi_oninitialized[["OnInitialized()"]]
    method_tmysty_render_razor_markup[["Render (Razor markup)"]]
    method_12odud7_gotopreviouschapter("IReaderNavigationService")
    method_1dvbk1u_gotonextchapter("IReaderNavigationService")
    method_tmysty_render_razor_markup -->|IReaderNavigationService| method_12odud7_gotopreviouschapter
    method_tmysty_render_razor_markup -->|IReaderNavigationService| method_1dvbk1u_gotonextchapter
```

### Render (Razor markup)() Control Flow

_Warnings: diagram method_tmysty_render_razor_markup__fragment_diagram exceeds preferred complexity thresholds (19 nodes, 20 edges)._

```mermaid
---
config:
  flowchart:
    defaultRenderer: "elk"
---
flowchart TD
    method_tmysty_render_razor_markup__call_13_ChapterTitle_property_[["ChapterTitle (property)"]]
    method_tmysty_render_razor_markup__call_14_CurrentChapterIndex_property_[["CurrentChapterIndex (property)"]]
    method_tmysty_render_razor_markup__call_14_TotalChapters_property_[["TotalChapters (property)"]]
    method_tmysty_render_razor_markup__call_17_GoToNextChapter[["GoToNextChapter"]]
    method_tmysty_render_razor_markup__call_23_CalculateProgress[["CalculateProgress"]]
    method_tmysty_render_razor_markup__call_8_CurrentChapterIndex_property_[["CurrentChapterIndex (property)"]]
    method_tmysty_render_razor_markup__call_8_GoToPreviousChapter[["GoToPreviousChapter"]]
    method_tmysty_render_razor_markup__action_13_ui_binding_13__linear("Displays chapter title and counts")
    method_tmysty_render_razor_markup__action_17_guard_clause_17__condition{"NavigationService.CurrentChapterIndex >= NavigationService.TotalChapters - 1"}
    method_tmysty_render_razor_markup__action_17_guard_clause_17__false("enabled")
    method_tmysty_render_razor_markup__action_17_guard_clause_17__merge("merge")
    method_tmysty_render_razor_markup__action_17_guard_clause_17__true("disabled")
    method_tmysty_render_razor_markup__action_23_render_call_23__linear("Requests progress percent")
    method_tmysty_render_razor_markup__action_8_guard_clause_8__condition{"NavigationService.CurrentChapterIndex == 0"}
    method_tmysty_render_razor_markup__action_8_guard_clause_8__false("enabled")
    method_tmysty_render_razor_markup__action_8_guard_clause_8__merge("merge")
    method_tmysty_render_razor_markup__action_8_guard_clause_8__true("disabled")
    method_tmysty_render_razor_markup__entry(["Render (Razor markup) entry"])
    method_tmysty_render_razor_markup__implicit_return(["return"])
    method_tmysty_render_razor_markup__action_13_ui_binding_13__linear -->|string title read for display| method_tmysty_render_razor_markup__call_13_ChapterTitle_property_
    method_tmysty_render_razor_markup__action_17_guard_clause_17__condition -->|enabled| method_tmysty_render_razor_markup__action_17_guard_clause_17__false
    method_tmysty_render_razor_markup__action_17_guard_clause_17__condition -->|disabled| method_tmysty_render_razor_markup__action_17_guard_clause_17__true
    method_tmysty_render_razor_markup__action_17_guard_clause_17__false -->|next| method_tmysty_render_razor_markup__action_17_guard_clause_17__merge
    method_tmysty_render_razor_markup__action_17_guard_clause_17__merge -->|none event handler| method_tmysty_render_razor_markup__call_17_GoToNextChapter
    method_tmysty_render_razor_markup__action_17_guard_clause_17__true -->|next| method_tmysty_render_razor_markup__action_17_guard_clause_17__merge
    method_tmysty_render_razor_markup__action_23_render_call_23__linear -->|no params returns width percentage| method_tmysty_render_razor_markup__call_23_CalculateProgress
    method_tmysty_render_razor_markup__action_8_guard_clause_8__condition -->|enabled| method_tmysty_render_razor_markup__action_8_guard_clause_8__false
    method_tmysty_render_razor_markup__action_8_guard_clause_8__condition -->|disabled| method_tmysty_render_razor_markup__action_8_guard_clause_8__true
    method_tmysty_render_razor_markup__action_8_guard_clause_8__false -->|next| method_tmysty_render_razor_markup__action_8_guard_clause_8__merge
    method_tmysty_render_razor_markup__action_8_guard_clause_8__merge -->|none event handler| method_tmysty_render_razor_markup__call_8_GoToPreviousChapter
    method_tmysty_render_razor_markup__action_8_guard_clause_8__true -->|next| method_tmysty_render_razor_markup__action_8_guard_clause_8__merge
    method_tmysty_render_razor_markup__call_13_ChapterTitle_property_ -->|integer index used for display| method_tmysty_render_razor_markup__call_14_CurrentChapterIndex_property_
    method_tmysty_render_razor_markup__call_14_CurrentChapterIndex_property_ -->|total chapters used for display| method_tmysty_render_razor_markup__call_14_TotalChapters_property_
    method_tmysty_render_razor_markup__call_14_TotalChapters_property_ -->|next| method_tmysty_render_razor_markup__action_17_guard_clause_17__condition
    method_tmysty_render_razor_markup__call_17_GoToNextChapter -->|next| method_tmysty_render_razor_markup__action_23_render_call_23__linear
    method_tmysty_render_razor_markup__call_23_CalculateProgress -->|return| method_tmysty_render_razor_markup__implicit_return
    method_tmysty_render_razor_markup__call_8_CurrentChapterIndex_property_ -->|next| method_tmysty_render_razor_markup__action_13_ui_binding_13__linear
    method_tmysty_render_razor_markup__call_8_GoToPreviousChapter -->|integer index used for button disable and display| method_tmysty_render_razor_markup__call_8_CurrentChapterIndex_property_
    method_tmysty_render_razor_markup__entry -->|next| method_tmysty_render_razor_markup__action_8_guard_clause_8__condition
```

### OnInitialized() Control Flow

```mermaid
flowchart TD
    method_1se6qsi_oninitialized__call_36_HandleNavigationChanged[["HandleNavigationChanged"]]
    method_1se6qsi_oninitialized__call_36_OnNavigationChanged_event_[["OnNavigationChanged (event)"]]
    method_1se6qsi_oninitialized__action_36_event_subscribe_36__linear("Subscribe to navigation changes")
    method_1se6qsi_oninitialized__entry(["OnInitialized entry"])
    method_1se6qsi_oninitialized__implicit_return(["return"])
    method_1se6qsi_oninitialized__action_36_event_subscribe_36__linear -->|adds HandleNavigationChanged delegate| method_1se6qsi_oninitialized__call_36_OnNavigationChanged_event_
    method_1se6qsi_oninitialized__call_36_HandleNavigationChanged -->|return| method_1se6qsi_oninitialized__implicit_return
    method_1se6qsi_oninitialized__call_36_OnNavigationChanged_event_ -->|delegate reference assigned to event| method_1se6qsi_oninitialized__call_36_HandleNavigationChanged
    method_1se6qsi_oninitialized__entry -->|next| method_1se6qsi_oninitialized__action_36_event_subscribe_36__linear
```

### CalculateProgress() Control Flow

```mermaid
flowchart TD
    method_1ak3em3_calculateprogress__call_46_TotalChapters_property_[["TotalChapters (property)"]]
    method_1ak3em3_calculateprogress__call_47_CurrentChapterIndex_property_[["CurrentChapterIndex (property)"]]
    method_1ak3em3_calculateprogress__action_46_calculateprogress_guard_clause_46_0__condition{"NavigationService.TotalChapters <= 1"}
    method_1ak3em3_calculateprogress__action_46_calculateprogress_guard_clause_46_0__false("continue")
    method_1ak3em3_calculateprogress__action_46_calculateprogress_guard_clause_46_0__merge("merge")
    method_1ak3em3_calculateprogress__action_46_calculateprogress_guard_clause_46_0__true("exit")
    method_1ak3em3_calculateprogress__action_46_guard_clause_46__condition{"NavigationService.TotalChapters <= 1"}
    method_1ak3em3_calculateprogress__action_46_guard_clause_46__false("continue")
    method_1ak3em3_calculateprogress__action_46_guard_clause_46__merge("merge")
    method_1ak3em3_calculateprogress__action_46_guard_clause_46__true("return 0")
    method_1ak3em3_calculateprogress__action_47_calculation_47__linear("Compute percentage")
    method_1ak3em3_calculateprogress__entry(["CalculateProgress entry"])
    method_1ak3em3_calculateprogress__action_47_calculateprogress_return_47_1__return(["Returns result"])
    method_1ak3em3_calculateprogress__implicit_return(["return"])
    method_1ak3em3_calculateprogress__action_46_calculateprogress_guard_clause_46_0__condition -->|continue| method_1ak3em3_calculateprogress__action_46_calculateprogress_guard_clause_46_0__false
    method_1ak3em3_calculateprogress__action_46_calculateprogress_guard_clause_46_0__condition -->|exit| method_1ak3em3_calculateprogress__action_46_calculateprogress_guard_clause_46_0__true
    method_1ak3em3_calculateprogress__action_46_calculateprogress_guard_clause_46_0__false -->|next| method_1ak3em3_calculateprogress__action_46_calculateprogress_guard_clause_46_0__merge
    method_1ak3em3_calculateprogress__action_46_calculateprogress_guard_clause_46_0__merge -->|reads total chapter count| method_1ak3em3_calculateprogress__call_46_TotalChapters_property_
    method_1ak3em3_calculateprogress__action_46_calculateprogress_guard_clause_46_0__true -->|next| method_1ak3em3_calculateprogress__action_46_calculateprogress_guard_clause_46_0__merge
    method_1ak3em3_calculateprogress__action_46_guard_clause_46__condition -->|continue| method_1ak3em3_calculateprogress__action_46_guard_clause_46__false
    method_1ak3em3_calculateprogress__action_46_guard_clause_46__condition -->|return 0| method_1ak3em3_calculateprogress__action_46_guard_clause_46__true
    method_1ak3em3_calculateprogress__action_46_guard_clause_46__false -->|next| method_1ak3em3_calculateprogress__action_46_guard_clause_46__merge
    method_1ak3em3_calculateprogress__action_46_guard_clause_46__merge -->|next| method_1ak3em3_calculateprogress__action_46_calculateprogress_guard_clause_46_0__condition
    method_1ak3em3_calculateprogress__action_46_guard_clause_46__true -->|next| method_1ak3em3_calculateprogress__action_46_guard_clause_46__merge
    method_1ak3em3_calculateprogress__action_47_calculateprogress_return_47_1__return -->|next| method_1ak3em3_calculateprogress__action_47_calculation_47__linear
    method_1ak3em3_calculateprogress__action_47_calculation_47__linear -->|reads current chapter index used in calculation| method_1ak3em3_calculateprogress__call_47_CurrentChapterIndex_property_
    method_1ak3em3_calculateprogress__call_46_TotalChapters_property_ -->|return| method_1ak3em3_calculateprogress__action_47_calculateprogress_return_47_1__return
    method_1ak3em3_calculateprogress__call_47_CurrentChapterIndex_property_ -->|return| method_1ak3em3_calculateprogress__implicit_return
    method_1ak3em3_calculateprogress__entry -->|next| method_1ak3em3_calculateprogress__action_46_guard_clause_46__condition
```

### Dispose() Control Flow

```mermaid
flowchart TD
    method_150wzsg_dispose__call_52_OnNavigationChanged_event_[["OnNavigationChanged (event)"]]
    method_150wzsg_dispose__action_52_event_unsubscribe_52__linear("Unsubscribe navigation change handler")
    method_150wzsg_dispose__entry(["Dispose entry"])
    method_150wzsg_dispose__implicit_return(["return"])
    method_150wzsg_dispose__action_52_event_unsubscribe_52__linear -->|removes HandleNavigationChanged delegate| method_150wzsg_dispose__call_52_OnNavigationChanged_event_
    method_150wzsg_dispose__call_52_OnNavigationChanged_event_ -->|return| method_150wzsg_dispose__implicit_return
    method_150wzsg_dispose__entry -->|next| method_150wzsg_dispose__action_52_event_unsubscribe_52__linear
```

## Diagram Validation

- Status: warn
- Warning: Control-flow extraction left 8 unresolved jumps.
- Warning: control-flow: diagram method_tmysty_render_razor_markup__fragment_diagram exceeds preferred complexity thresholds (19 nodes, 20 edges).
