# ReaderInteractionService

- File ID: file:1jnstne:readerinteractionservice-cs
- Path: NexusReader.UI.Shared/Services/ReaderInteractionService.cs
- Role: service
- Layer: frontend

## Purpose

A small UI-shared interaction service that exposes events for UI components (node selection, scrolling, highlighting, text selection) and provides methods to raise those events for subscribers.

## Key Details

Thin event-forwarding service used by UI components to publish interaction events; methods are simple async guards that await subscriber delegates.

## Symbols

- ReaderInteractionService: A small UI-shared interaction service that exposes events for UI components (node selection, scrolling, highlighting, text selection) and provides methods to raise those events for subscribers.
- NotifyNodeSelected(): Raises the OnNodeSelected event if any subscriber is attached.
- RequestScrollToBlock(): Requests scrolling to a block by raising the OnScrollToBlockRequested event when subscribers exist.
- RequestHighlightBlock(): Requests highlight of a block by raising the OnHighlightBlockRequested event when subscribers exist.
- NotifyTextSelected(): Raises the OnTextSelected event with the selected text, block id and selection coordinates when subscribers exist.

## Dependencies

- No resolved dependencies.

## Calls

- No resolved calls.

## Unresolved References

- dependency-target: IReaderInteractionService (interface, not defined in this file)
- dependency-target: SelectionCoordinates (type, referenced but not declared here)
- call-target: self
- call-target: self
- call-target: self
- call-target: self

## Coverage

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

## Control Flow Fragments

- NotifyNodeSelected: 14 nodes, 15 edges, 1 jumps, 0 unsupported constructs
- RequestScrollToBlock: 13 nodes, 14 edges, 1 jumps, 0 unsupported constructs
- RequestHighlightBlock: 13 nodes, 14 edges, 1 jumps, 0 unsupported constructs
- NotifyTextSelected: 14 nodes, 15 edges, 1 jumps, 0 unsupported constructs

## Diagrams

### ReaderInteractionService Neighborhood

```mermaid
flowchart LR
    class_18r7noo_readerinteractionservice("ReaderInteractionService")
    file_1jnstne_readerinteractionservice_cs("ReaderInteractionService")
    method_15ros9m_notifytextselected[["NotifyTextSelected()"]]
    method_1om56u0_requesthighlightblock[["RequestHighlightBlock()"]]
    method_nvgthi_requestscrolltoblock[["RequestScrollToBlock()"]]
    method_qegcuf_notifynodeselected[["NotifyNodeSelected()"]]
```

### ReaderInteractionService Execution Overview

```mermaid
flowchart TD
    class_18r7noo_readerinteractionservice("ReaderInteractionService")
    method_15ros9m_notifytextselected[["NotifyTextSelected()"]]
    method_1om56u0_requesthighlightblock[["RequestHighlightBlock()"]]
    method_nvgthi_requestscrolltoblock[["RequestScrollToBlock()"]]
    method_qegcuf_notifynodeselected[["NotifyNodeSelected()"]]
    unresolved_unresolved_12jxtai_call_target{"Unresolved: OnScrollToBlockRequested"}
    unresolved_unresolved_1dmnpxy_call_target{"Unresolved: OnTextSelected"}
    unresolved_unresolved_33g61b_call_target{"Unresolved: OnNodeSelected"}
    unresolved_unresolved_zz75qd_call_target{"Unresolved: OnHighlightBlockRequested"}
    class_18r7noo_readerinteractionservice -->|contains| method_15ros9m_notifytextselected
    class_18r7noo_readerinteractionservice -->|contains| method_1om56u0_requesthighlightblock
    class_18r7noo_readerinteractionservice -->|contains| method_nvgthi_requestscrolltoblock
    class_18r7noo_readerinteractionservice -->|contains| method_qegcuf_notifynodeselected
    method_15ros9m_notifytextselected -->|unresolved call| unresolved_unresolved_1dmnpxy_call_target
    method_1om56u0_requesthighlightblock -->|unresolved call| unresolved_unresolved_zz75qd_call_target
    method_nvgthi_requestscrolltoblock -->|unresolved call| unresolved_unresolved_12jxtai_call_target
    method_qegcuf_notifynodeselected -->|unresolved call| unresolved_unresolved_33g61b_call_target
```

### NotifyNodeSelected() Control Flow

```mermaid
flowchart TD
    method_qegcuf_notifynodeselected__call_12_OnNodeSelected[["OnNodeSelected"]]
    method_qegcuf_notifynodeselected__action_12_guard_clause_12__condition{"OnNodeSelected != null"}
    method_qegcuf_notifynodeselected__action_12_guard_clause_12__false("skip")
    method_qegcuf_notifynodeselected__action_12_guard_clause_12__merge("merge")
    method_qegcuf_notifynodeselected__action_12_guard_clause_12__true("invoke")
    method_qegcuf_notifynodeselected__action_12_invoke_event_12__linear("Invoke OnNodeSelected")
    method_qegcuf_notifynodeselected__action_12_notifynodeselected_await_12_2__await[["Waits for async work"]]
    method_qegcuf_notifynodeselected__action_12_notifynodeselected_branch_12_1__condition{"OnNodeSelected != null) await OnNodeSelected(nodeId"}
    method_qegcuf_notifynodeselected__action_12_notifynodeselected_branch_12_1__false("false")
    method_qegcuf_notifynodeselected__action_12_notifynodeselected_branch_12_1__merge("merge")
    method_qegcuf_notifynodeselected__action_12_notifynodeselected_branch_12_1__true("true")
    method_qegcuf_notifynodeselected__entry(["NotifyNodeSelected entry"])
    method_qegcuf_notifynodeselected__action_10_notifynodeselected_notification_10_0__linear[/"Sends notification"/]
    method_qegcuf_notifynodeselected__implicit_return(["return"])
    method_qegcuf_notifynodeselected__action_10_notifynodeselected_notification_10_0__linear -->|next| method_qegcuf_notifynodeselected__action_12_notifynodeselected_await_12_2__await
    method_qegcuf_notifynodeselected__action_12_guard_clause_12__condition -->|skip| method_qegcuf_notifynodeselected__action_12_guard_clause_12__false
    method_qegcuf_notifynodeselected__action_12_guard_clause_12__condition -->|invoke| method_qegcuf_notifynodeselected__action_12_guard_clause_12__true
    method_qegcuf_notifynodeselected__action_12_guard_clause_12__false -->|next| method_qegcuf_notifynodeselected__action_12_guard_clause_12__merge
    method_qegcuf_notifynodeselected__action_12_guard_clause_12__merge -->|nodeId string| method_qegcuf_notifynodeselected__call_12_OnNodeSelected
    method_qegcuf_notifynodeselected__action_12_guard_clause_12__true -->|next| method_qegcuf_notifynodeselected__action_12_guard_clause_12__merge
    method_qegcuf_notifynodeselected__action_12_invoke_event_12__linear -->|next| method_qegcuf_notifynodeselected__action_12_notifynodeselected_branch_12_1__condition
    method_qegcuf_notifynodeselected__action_12_notifynodeselected_await_12_2__await -->|next| method_qegcuf_notifynodeselected__action_12_invoke_event_12__linear
    method_qegcuf_notifynodeselected__action_12_notifynodeselected_branch_12_1__condition -->|false| method_qegcuf_notifynodeselected__action_12_notifynodeselected_branch_12_1__false
    method_qegcuf_notifynodeselected__action_12_notifynodeselected_branch_12_1__condition -->|true| method_qegcuf_notifynodeselected__action_12_notifynodeselected_branch_12_1__true
    method_qegcuf_notifynodeselected__action_12_notifynodeselected_branch_12_1__false -->|next| method_qegcuf_notifynodeselected__action_12_notifynodeselected_branch_12_1__merge
    method_qegcuf_notifynodeselected__action_12_notifynodeselected_branch_12_1__merge -->|next| method_qegcuf_notifynodeselected__action_12_guard_clause_12__condition
    method_qegcuf_notifynodeselected__action_12_notifynodeselected_branch_12_1__true -->|next| method_qegcuf_notifynodeselected__action_12_notifynodeselected_branch_12_1__merge
    method_qegcuf_notifynodeselected__call_12_OnNodeSelected -->|return| method_qegcuf_notifynodeselected__implicit_return
    method_qegcuf_notifynodeselected__entry -->|next| method_qegcuf_notifynodeselected__action_10_notifynodeselected_notification_10_0__linear
```

### RequestScrollToBlock() Control Flow

```mermaid
flowchart TD
    method_nvgthi_requestscrolltoblock__call_17_OnScrollToBlockRequested[["OnScrollToBlockRequested"]]
    method_nvgthi_requestscrolltoblock__action_17_guard_clause_17__condition{"OnScrollToBlockRequested != null"}
    method_nvgthi_requestscrolltoblock__action_17_guard_clause_17__false("skip")
    method_nvgthi_requestscrolltoblock__action_17_guard_clause_17__merge("merge")
    method_nvgthi_requestscrolltoblock__action_17_guard_clause_17__true("invoke")
    method_nvgthi_requestscrolltoblock__action_17_invoke_event_17__linear("Invoke OnScrollToBlockRequested")
    method_nvgthi_requestscrolltoblock__action_17_requestscrolltoblock_await_17_1__await[["Waits for async work"]]
    method_nvgthi_requestscrolltoblock__action_17_requestscrolltoblock_branch_17_0__condition{"OnScrollToBlockRequested != null) await OnScrollToBlockRequested(blockId"}
    method_nvgthi_requestscrolltoblock__action_17_requestscrolltoblock_branch_17_0__false("false")
    method_nvgthi_requestscrolltoblock__action_17_requestscrolltoblock_branch_17_0__merge("merge")
    method_nvgthi_requestscrolltoblock__action_17_requestscrolltoblock_branch_17_0__true("true")
    method_nvgthi_requestscrolltoblock__entry(["RequestScrollToBlock entry"])
    method_nvgthi_requestscrolltoblock__implicit_return(["return"])
    method_nvgthi_requestscrolltoblock__action_17_guard_clause_17__condition -->|skip| method_nvgthi_requestscrolltoblock__action_17_guard_clause_17__false
    method_nvgthi_requestscrolltoblock__action_17_guard_clause_17__condition -->|invoke| method_nvgthi_requestscrolltoblock__action_17_guard_clause_17__true
    method_nvgthi_requestscrolltoblock__action_17_guard_clause_17__false -->|next| method_nvgthi_requestscrolltoblock__action_17_guard_clause_17__merge
    method_nvgthi_requestscrolltoblock__action_17_guard_clause_17__merge -->|blockId string| method_nvgthi_requestscrolltoblock__call_17_OnScrollToBlockRequested
    method_nvgthi_requestscrolltoblock__action_17_guard_clause_17__true -->|next| method_nvgthi_requestscrolltoblock__action_17_guard_clause_17__merge
    method_nvgthi_requestscrolltoblock__action_17_invoke_event_17__linear -->|next| method_nvgthi_requestscrolltoblock__action_17_requestscrolltoblock_branch_17_0__condition
    method_nvgthi_requestscrolltoblock__action_17_requestscrolltoblock_await_17_1__await -->|next| method_nvgthi_requestscrolltoblock__action_17_invoke_event_17__linear
    method_nvgthi_requestscrolltoblock__action_17_requestscrolltoblock_branch_17_0__condition -->|false| method_nvgthi_requestscrolltoblock__action_17_requestscrolltoblock_branch_17_0__false
    method_nvgthi_requestscrolltoblock__action_17_requestscrolltoblock_branch_17_0__condition -->|true| method_nvgthi_requestscrolltoblock__action_17_requestscrolltoblock_branch_17_0__true
    method_nvgthi_requestscrolltoblock__action_17_requestscrolltoblock_branch_17_0__false -->|next| method_nvgthi_requestscrolltoblock__action_17_requestscrolltoblock_branch_17_0__merge
    method_nvgthi_requestscrolltoblock__action_17_requestscrolltoblock_branch_17_0__merge -->|next| method_nvgthi_requestscrolltoblock__action_17_guard_clause_17__condition
    method_nvgthi_requestscrolltoblock__action_17_requestscrolltoblock_branch_17_0__true -->|next| method_nvgthi_requestscrolltoblock__action_17_requestscrolltoblock_branch_17_0__merge
    method_nvgthi_requestscrolltoblock__call_17_OnScrollToBlockRequested -->|return| method_nvgthi_requestscrolltoblock__implicit_return
    method_nvgthi_requestscrolltoblock__entry -->|next| method_nvgthi_requestscrolltoblock__action_17_requestscrolltoblock_await_17_1__await
```

### RequestHighlightBlock() Control Flow

```mermaid
flowchart TD
    method_1om56u0_requesthighlightblock__call_22_OnHighlightBlockRequested[["OnHighlightBlockRequested"]]
    method_1om56u0_requesthighlightblock__action_22_guard_clause_22__condition{"OnHighlightBlockRequested != null"}
    method_1om56u0_requesthighlightblock__action_22_guard_clause_22__false("skip")
    method_1om56u0_requesthighlightblock__action_22_guard_clause_22__merge("merge")
    method_1om56u0_requesthighlightblock__action_22_guard_clause_22__true("invoke")
    method_1om56u0_requesthighlightblock__action_22_invoke_event_22__linear("Invoke OnHighlightBlockRequested")
    method_1om56u0_requesthighlightblock__action_22_requesthighlightblock_await_22_1__await[["Waits for async work"]]
    method_1om56u0_requesthighlightblock__action_22_requesthighlightblock_branch_22_0__condition{"OnHighlightBlockRequested != null) await OnHighlightBlockRequested(blockId"}
    method_1om56u0_requesthighlightblock__action_22_requesthighlightblock_branch_22_0__false("false")
    method_1om56u0_requesthighlightblock__action_22_requesthighlightblock_branch_22_0__merge("merge")
    method_1om56u0_requesthighlightblock__action_22_requesthighlightblock_branch_22_0__true("true")
    method_1om56u0_requesthighlightblock__entry(["RequestHighlightBlock entry"])
    method_1om56u0_requesthighlightblock__implicit_return(["return"])
    method_1om56u0_requesthighlightblock__action_22_guard_clause_22__condition -->|skip| method_1om56u0_requesthighlightblock__action_22_guard_clause_22__false
    method_1om56u0_requesthighlightblock__action_22_guard_clause_22__condition -->|invoke| method_1om56u0_requesthighlightblock__action_22_guard_clause_22__true
    method_1om56u0_requesthighlightblock__action_22_guard_clause_22__false -->|next| method_1om56u0_requesthighlightblock__action_22_guard_clause_22__merge
    method_1om56u0_requesthighlightblock__action_22_guard_clause_22__merge -->|blockId string| method_1om56u0_requesthighlightblock__call_22_OnHighlightBlockRequested
    method_1om56u0_requesthighlightblock__action_22_guard_clause_22__true -->|next| method_1om56u0_requesthighlightblock__action_22_guard_clause_22__merge
    method_1om56u0_requesthighlightblock__action_22_invoke_event_22__linear -->|next| method_1om56u0_requesthighlightblock__action_22_requesthighlightblock_branch_22_0__condition
    method_1om56u0_requesthighlightblock__action_22_requesthighlightblock_await_22_1__await -->|next| method_1om56u0_requesthighlightblock__action_22_invoke_event_22__linear
    method_1om56u0_requesthighlightblock__action_22_requesthighlightblock_branch_22_0__condition -->|false| method_1om56u0_requesthighlightblock__action_22_requesthighlightblock_branch_22_0__false
    method_1om56u0_requesthighlightblock__action_22_requesthighlightblock_branch_22_0__condition -->|true| method_1om56u0_requesthighlightblock__action_22_requesthighlightblock_branch_22_0__true
    method_1om56u0_requesthighlightblock__action_22_requesthighlightblock_branch_22_0__false -->|next| method_1om56u0_requesthighlightblock__action_22_requesthighlightblock_branch_22_0__merge
    method_1om56u0_requesthighlightblock__action_22_requesthighlightblock_branch_22_0__merge -->|next| method_1om56u0_requesthighlightblock__action_22_guard_clause_22__condition
    method_1om56u0_requesthighlightblock__action_22_requesthighlightblock_branch_22_0__true -->|next| method_1om56u0_requesthighlightblock__action_22_requesthighlightblock_branch_22_0__merge
    method_1om56u0_requesthighlightblock__call_22_OnHighlightBlockRequested -->|return| method_1om56u0_requesthighlightblock__implicit_return
    method_1om56u0_requesthighlightblock__entry -->|next| method_1om56u0_requesthighlightblock__action_22_requesthighlightblock_await_22_1__await
```

### NotifyTextSelected() Control Flow

```mermaid
flowchart TD
    method_15ros9m_notifytextselected__call_27_OnTextSelected[["OnTextSelected"]]
    method_15ros9m_notifytextselected__action_27_guard_clause_27__condition{"OnTextSelected != null"}
    method_15ros9m_notifytextselected__action_27_guard_clause_27__false("skip")
    method_15ros9m_notifytextselected__action_27_guard_clause_27__merge("merge")
    method_15ros9m_notifytextselected__action_27_guard_clause_27__true("invoke")
    method_15ros9m_notifytextselected__action_27_invoke_event_27__linear("Invoke OnTextSelected")
    method_15ros9m_notifytextselected__action_27_notifytextselected_await_27_2__await[["Waits for async work"]]
    method_15ros9m_notifytextselected__action_27_notifytextselected_branch_27_1__condition{"OnTextSelected != null) await OnTextSelected(text, blockId, coords"}
    method_15ros9m_notifytextselected__action_27_notifytextselected_branch_27_1__false("false")
    method_15ros9m_notifytextselected__action_27_notifytextselected_branch_27_1__merge("merge")
    method_15ros9m_notifytextselected__action_27_notifytextselected_branch_27_1__true("true")
    method_15ros9m_notifytextselected__entry(["NotifyTextSelected entry"])
    method_15ros9m_notifytextselected__action_25_notifytextselected_notification_25_0__linear[/"Sends notification"/]
    method_15ros9m_notifytextselected__implicit_return(["return"])
    method_15ros9m_notifytextselected__action_25_notifytextselected_notification_25_0__linear -->|next| method_15ros9m_notifytextselected__action_27_notifytextselected_await_27_2__await
    method_15ros9m_notifytextselected__action_27_guard_clause_27__condition -->|skip| method_15ros9m_notifytextselected__action_27_guard_clause_27__false
    method_15ros9m_notifytextselected__action_27_guard_clause_27__condition -->|invoke| method_15ros9m_notifytextselected__action_27_guard_clause_27__true
    method_15ros9m_notifytextselected__action_27_guard_clause_27__false -->|next| method_15ros9m_notifytextselected__action_27_guard_clause_27__merge
    method_15ros9m_notifytextselected__action_27_guard_clause_27__merge -->|text string , blockId string , coords SelectionCoordinates| method_15ros9m_notifytextselected__call_27_OnTextSelected
    method_15ros9m_notifytextselected__action_27_guard_clause_27__true -->|next| method_15ros9m_notifytextselected__action_27_guard_clause_27__merge
    method_15ros9m_notifytextselected__action_27_invoke_event_27__linear -->|next| method_15ros9m_notifytextselected__action_27_notifytextselected_branch_27_1__condition
    method_15ros9m_notifytextselected__action_27_notifytextselected_await_27_2__await -->|next| method_15ros9m_notifytextselected__action_27_invoke_event_27__linear
    method_15ros9m_notifytextselected__action_27_notifytextselected_branch_27_1__condition -->|false| method_15ros9m_notifytextselected__action_27_notifytextselected_branch_27_1__false
    method_15ros9m_notifytextselected__action_27_notifytextselected_branch_27_1__condition -->|true| method_15ros9m_notifytextselected__action_27_notifytextselected_branch_27_1__true
    method_15ros9m_notifytextselected__action_27_notifytextselected_branch_27_1__false -->|next| method_15ros9m_notifytextselected__action_27_notifytextselected_branch_27_1__merge
    method_15ros9m_notifytextselected__action_27_notifytextselected_branch_27_1__merge -->|next| method_15ros9m_notifytextselected__action_27_guard_clause_27__condition
    method_15ros9m_notifytextselected__action_27_notifytextselected_branch_27_1__true -->|next| method_15ros9m_notifytextselected__action_27_notifytextselected_branch_27_1__merge
    method_15ros9m_notifytextselected__call_27_OnTextSelected -->|return| method_15ros9m_notifytextselected__implicit_return
    method_15ros9m_notifytextselected__entry -->|next| method_15ros9m_notifytextselected__action_25_notifytextselected_notification_25_0__linear
```

## Diagram Validation

- Status: warn
- Warning: Control-flow extraction left 4 unresolved jumps.
