|
| 1 | +using Microsoft.AspNetCore.Components; |
| 2 | +using PrompterOne.Shared.Learn.Services; |
| 3 | +using PrompterOne.Shared.Localization; |
| 4 | + |
| 5 | +namespace PrompterOne.Shared.Pages; |
| 6 | + |
| 7 | +public partial class LearnPage |
| 8 | +{ |
| 9 | + private sealed record LearnPrepNoteContext( |
| 10 | + string ScriptKey, |
| 11 | + string SectionKey, |
| 12 | + string SectionLabel, |
| 13 | + string AnchorWord, |
| 14 | + int WordIndex); |
| 15 | + |
| 16 | + private IReadOnlyList<LearnPrepNote> CurrentSectionPrepNotes => |
| 17 | + _prepNotes |
| 18 | + .Where(note => string.Equals(note.SectionKey, CurrentPrepNoteContext.SectionKey, StringComparison.Ordinal)) |
| 19 | + .OrderBy(note => note.CreatedAt) |
| 20 | + .ToArray(); |
| 21 | + |
| 22 | + private LearnPrepNoteContext CurrentPrepNoteContext => BuildCurrentPrepNoteContext(); |
| 23 | + |
| 24 | + private string CurrentPrepNotesSectionLabel => |
| 25 | + Format(UiTextKey.LearnNotesSectionFormat, CurrentPrepNoteContext.SectionLabel); |
| 26 | + |
| 27 | + private bool CanAddPrepNote => !string.IsNullOrWhiteSpace(_prepNoteDraft); |
| 28 | + |
| 29 | + private async Task LoadPrepNotesAsync() |
| 30 | + { |
| 31 | + var scriptKey = ResolvePrepNotesScriptKey(); |
| 32 | + _prepNotes = string.IsNullOrWhiteSpace(scriptKey) |
| 33 | + ? [] |
| 34 | + : await PrepNotesStore.LoadForScriptAsync(scriptKey); |
| 35 | + } |
| 36 | + |
| 37 | + private void HandlePrepNoteDraftChanged(ChangeEventArgs args) => |
| 38 | + _prepNoteDraft = args.Value?.ToString() ?? string.Empty; |
| 39 | + |
| 40 | + private async Task AddPrepNoteAsync() |
| 41 | + { |
| 42 | + if (!CanAddPrepNote) |
| 43 | + { |
| 44 | + return; |
| 45 | + } |
| 46 | + |
| 47 | + var context = CurrentPrepNoteContext; |
| 48 | + var note = await PrepNotesStore.AddAsync(new LearnPrepNoteDraft( |
| 49 | + context.ScriptKey, |
| 50 | + context.SectionKey, |
| 51 | + context.SectionLabel, |
| 52 | + context.AnchorWord, |
| 53 | + context.WordIndex, |
| 54 | + _prepNoteDraft)); |
| 55 | + |
| 56 | + if (note is null) |
| 57 | + { |
| 58 | + return; |
| 59 | + } |
| 60 | + |
| 61 | + _prepNoteDraft = string.Empty; |
| 62 | + _prepNotes = _prepNotes.Append(note).ToArray(); |
| 63 | + } |
| 64 | + |
| 65 | + private LearnPrepNoteContext BuildCurrentPrepNoteContext() |
| 66 | + { |
| 67 | + var scriptKey = ResolvePrepNotesScriptKey(); |
| 68 | + if (_timeline.Count == 0) |
| 69 | + { |
| 70 | + return new LearnPrepNoteContext( |
| 71 | + scriptKey, |
| 72 | + "empty", |
| 73 | + Text(UiTextKey.LearnReadyWord), |
| 74 | + Text(UiTextKey.LearnReadyWord), |
| 75 | + 0); |
| 76 | + } |
| 77 | + |
| 78 | + var safeIndex = Math.Clamp(_currentIndex, 0, _timeline.Count - 1); |
| 79 | + var entry = _timeline[safeIndex]; |
| 80 | + var sentenceRange = ResolveSentenceRange(_timeline, safeIndex); |
| 81 | + var sectionLabel = BuildSectionLabel(sentenceRange.StartIndex, sentenceRange.EndIndex); |
| 82 | + var anchorWord = NormalizeDisplayWord(entry.Word); |
| 83 | + return new LearnPrepNoteContext( |
| 84 | + scriptKey, |
| 85 | + $"{sentenceRange.StartIndex}-{sentenceRange.EndIndex}", |
| 86 | + sectionLabel, |
| 87 | + string.IsNullOrWhiteSpace(anchorWord) ? entry.Word : anchorWord, |
| 88 | + Math.Max(0, entry.WordIndex)); |
| 89 | + } |
| 90 | + |
| 91 | + private string BuildSectionLabel(int startIndex, int endIndex) |
| 92 | + { |
| 93 | + var words = BuildDisplayContextWords(_timeline, startIndex, endIndex + 1); |
| 94 | + var label = words.Count == 0 ? _screenSubtitle : string.Join(' ', words); |
| 95 | + if (string.IsNullOrWhiteSpace(label)) |
| 96 | + { |
| 97 | + label = _screenTitle; |
| 98 | + } |
| 99 | + |
| 100 | + return string.IsNullOrWhiteSpace(label) |
| 101 | + ? Text(UiTextKey.LearnReadyWord) |
| 102 | + : label; |
| 103 | + } |
| 104 | + |
| 105 | + private string ResolvePrepNotesScriptKey() |
| 106 | + { |
| 107 | + if (!string.IsNullOrWhiteSpace(SessionService.State.ScriptId)) |
| 108 | + { |
| 109 | + return SessionService.State.ScriptId; |
| 110 | + } |
| 111 | + |
| 112 | + if (!string.IsNullOrWhiteSpace(SessionService.State.DocumentName)) |
| 113 | + { |
| 114 | + return SessionService.State.DocumentName; |
| 115 | + } |
| 116 | + |
| 117 | + return SessionService.State.Title; |
| 118 | + } |
| 119 | +} |
0 commit comments