UI 복잡 버전 234 RED→GREEN 완료(docs/UI_USECASES.md §A~§J): 라이브 테마 전환(DynamicResource 전환+ThemeResolver+HighContrast 테마, 재시작 없음), 디자인 토큰 체계·WCAG 대비 결함 5건 수정, 설정창 카테고리 내비/검색 재구성+AppConfig 40여 속성, 다운로드 관리자(속도/ETA/세그먼트맵/전체 일시정지-이어받기/CSV 내보내기/예약 게이트/중복 확인), 라이브러리·아카이브·작업공간·재생목록·즐겨찾기 편집 뷰, 접근성(자동화 속성 30여 개·커스텀 피어·docs/ACCESSIBILITY.md), 인터랙션(휠 클릭 새 탭·XButton 탐색·F12·영역 캡처·프로필 전환), 상태/알림(토스트·알림센터·온보딩·CrashReportDialog). 보강 테스트 35건+실창 E2E 4건(StaDispatcher 기반 — 프록시 설정이 기시작 핸들러를 건드리는 크래시 실결함 수정 포함) — 453/453 GREEN. 이전 미커밋 작업(CI 워크플로·Mdns·QueueHub·UpdateChecker·AGENTS/CLAUDE·빌드 스크립트) 일괄 포함
This commit is contained in:
parent
5a0ce730b2
commit
17f2f91152
88 changed files with 9463 additions and 1127 deletions
|
|
@ -100,6 +100,20 @@ public sealed class PageDownloadTracker
|
|||
public void Resume(PageDownloadItem item) => item.Op.Resume();
|
||||
public void Cancel(PageDownloadItem item) => item.Op.Cancel();
|
||||
|
||||
/// <summary>UC-D28 페이지 파일 다운로드 전체 일시정지.</summary>
|
||||
public void PauseAll()
|
||||
{
|
||||
foreach (var item in Items.Where(i => i.CanControl).ToList())
|
||||
try { item.Op.Pause(); } catch { }
|
||||
}
|
||||
|
||||
/// <summary>UC-D28 짝 맞춤: 일시정지 항목 전체 재개(Interrupted 포함).</summary>
|
||||
public void ResumeAll()
|
||||
{
|
||||
foreach (var item in Items.Where(i => !i.IsFinished).ToList())
|
||||
try { item.Op.Resume(); } catch { }
|
||||
}
|
||||
|
||||
public void ClearCompleted()
|
||||
{
|
||||
foreach (var done in Items.Where(i => i.IsFinished).ToList())
|
||||
|
|
|
|||
|
|
@ -69,18 +69,22 @@ public sealed class ReaderMode
|
|||
tab.IsReader = true;
|
||||
tab.Title = string.IsNullOrWhiteSpace(title) ? tab.Title : title + " (리더)";
|
||||
|
||||
cv.NavigateToString(BuildReaderHtml(title ?? "", byline ?? "", excerpt ?? "", contentEl.GetString() ?? "", lightTheme));
|
||||
cv.NavigateToString(BuildReaderHtml(title ?? "", byline ?? "", excerpt ?? "", contentEl.GetString() ?? "", lightTheme, AppFontStack));
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>호스트가 주입하는 앱 폰트 스택(UC-F17 — 폰트 하드코딩 제거). 기본값은 WPF 기본 스택.</summary>
|
||||
public static string AppFontStack { get; set; } = "Segoe UI, sans-serif";
|
||||
|
||||
/// <summary>리더 HTML(Firefox 스타일 — 폰트/여백/테마). trusted-types 회피를 위해 iframe srcdoc 형태 대신 직접 문서.</summary>
|
||||
public static string BuildReaderHtml(string title, string byline, string excerpt, string contentHtml, bool lightTheme)
|
||||
public static string BuildReaderHtml(string title, string byline, string excerpt, string contentHtml, bool lightTheme, string? fontStack = null)
|
||||
{
|
||||
var bg = lightTheme ? "#faf8f5" : "#1b1c24";
|
||||
var fg = lightTheme ? "#1b1c24" : "#e6e6ec";
|
||||
var muted = lightTheme ? "#666" : "#9a9ab0";
|
||||
var font = string.IsNullOrWhiteSpace(fontStack) ? AppFontStack : fontStack;
|
||||
var css = $@"
|
||||
body {{ background: {bg}; color: {fg}; font-family: 'Segoe UI', 'Malgun Gothic', sans-serif; max-width: 720px; margin: 0 auto; padding: 40px 24px 80px; line-height: 1.75; }}
|
||||
body {{ background: {bg}; color: {fg}; font-family: '{font.Replace("'", "")}', sans-serif; max-width: 720px; margin: 0 auto; padding: 40px 24px 80px; line-height: 1.75; }}
|
||||
h1 {{ font-size: 1.7em; line-height: 1.3; margin-bottom: 6px; }}
|
||||
.byline {{ color: {muted}; font-size: 0.9em; margin-bottom: 4px; }}
|
||||
.excerpt {{ color: {muted}; font-style: italic; margin: 14px 0 26px; padding-left: 12px; border-left: 3px solid {muted}; }}
|
||||
|
|
@ -92,6 +96,7 @@ blockquote {{ border-left: 3px solid {muted}; margin-left: 0; padding-left: 14px
|
|||
var titleEsc = System.Net.WebUtility.HtmlEncode(title);
|
||||
var bylineEsc = System.Net.WebUtility.HtmlEncode(byline);
|
||||
var excerptEsc = System.Net.WebUtility.HtmlEncode(excerpt);
|
||||
return $"""<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>{titleEsc}</title><style>{css}</style></head><body><h1>{titleEsc}</h1>{(bylineEsc.Length > 0 ? $"<div class=\"byline\">{bylineEsc}</div>" : "")}{(excerptEsc.Length > 0 ? $"<p class=\"excerpt\">{excerptEsc}</p>" : "")}{contentHtml}</body></html>""";
|
||||
// UC-A17: lang="ko" 선언으로 화면 낭독기가 한국어 음성으로 읽는다.
|
||||
return $"""<!DOCTYPE html><html lang="ko"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>{titleEsc}</title><style>{css}</style></head><body><h1>{titleEsc}</h1>{(bylineEsc.Length > 0 ? $"<div class=\"byline\">{bylineEsc}</div>" : "")}{(excerptEsc.Length > 0 ? $"<p class=\"excerpt\">{excerptEsc}</p>" : "")}{contentHtml}</body></html>""";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,11 @@ public sealed class PlayerWindow : Window
|
|||
{
|
||||
var cur = _playlist.Current;
|
||||
if (cur != null) _playlist.MarkPlayed(cur);
|
||||
// UC-M12 반복 모드: one=현 트랙 재생, all=끝에서 처음으로 순환, none=끝에서 정지
|
||||
var mode = _config.PlaylistLoopMode;
|
||||
if (mode == "one") { PlayCurrent(); return; }
|
||||
var atEnd = _playlist.Tracks.Count > 0 && _playlist.CurrentIndex >= _playlist.Tracks.Count - 1;
|
||||
if (atEnd && mode != "all") return;
|
||||
_playlist.Next();
|
||||
PlayCurrent();
|
||||
}));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue