From 02995f415380836090ecaff8bd5d997d01b8e1e1 Mon Sep 17 00:00:00 2001 From: Yun Chan Date: Tue, 18 Aug 2026 07:13:18 +0900 Subject: [PATCH] =?UTF-8?q?MEDIABROWSER=20=EA=B0=9C=EB=AA=85=C2=B7?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EC=B1=84=EB=84=90=20?= =?UTF-8?q?=EC=A0=84=ED=99=98=C2=B7=EC=95=84=EC=9D=B4=EC=BD=98=20tofu=20?= =?UTF-8?q?=EA=B7=BC=EB=B3=B8=20=EC=88=98=EC=A0=95=20(BACKLOG=2013?= =?UTF-8?q?=EC=B0=A8)=20=E2=80=94=20=E2=91=A0=EA=B0=9C=EB=AA=85:=20install?= =?UTF-8?q?er.iss=20AppName/=EC=B6=9C=EB=A0=A5=20MediaBrowser-Setup-*(AppI?= =?UTF-8?q?d=C2=B7exe=C2=B7=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=20=EC=9C=A0=EC=A7=80=EB=A1=9C=20=EC=97=85=EA=B7=B8?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EB=93=9C=20=ED=98=B8=ED=99=98),=20=EC=9B=8C?= =?UTF-8?q?=ED=81=AC=ED=94=8C=EB=A1=9C=20=EC=82=B0=EC=B6=9C=EB=AC=BC?= =?UTF-8?q?=EB=AA=85(mediabrowser-*.tar.gz,=20MediaBrowser--arm64.apk?= =?UTF-8?q?),=20=EC=B0=BD=20=ED=83=80=EC=9D=B4=ED=8B=80=C2=B7=EB=AA=A8?= =?UTF-8?q?=EB=B0=94=EC=9D=BC=20=ED=91=9C=EC=8B=9C=EB=AA=85=C2=B7obtainium?= =?UTF-8?q?.json=C2=B7README.=20=E2=91=A1UpdateChecker:=20apiBase=20?= =?UTF-8?q?=EC=A3=BC=EC=9E=85(=EA=B8=B0=EB=B3=B8=3D=EC=9E=90=EC=B2=B4=20Fo?= =?UTF-8?q?rgejo=20/api/v1,=20GitHub=20=EB=8A=94=20apiBase=20=EB=A1=9C=20?= =?UTF-8?q?=ED=98=B8=ED=99=98),=20osx=20=EC=9E=90=EC=82=B0=20tar.gz=20?= =?UTF-8?q?=ED=97=88=EC=9A=A9(=EA=B8=B0=EC=A1=B4=20dmg=20=EB=A7=8C=20?= =?UTF-8?q?=E2=86=92=20mac=20=EC=98=81=EC=9B=90=ED=9E=88=20=EC=9E=90?= =?UTF-8?q?=EC=82=B0=20=EC=97=86=EC=9D=8C=20=EA=B2=B0=ED=95=A8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95),=20AppConfig=20=EA=B8=B0=EB=B3=B8=20UpdateRepo=3DVid?= =?UTF-8?q?eo-Downloader/releases+UpdateApiBase=20=E2=80=94=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=204=EA=B1=B4.=20=E2=91=A2=EC=95=84=EC=9D=B4?= =?UTF-8?q?=EC=BD=98=20tofu(=EC=82=AC=EC=9A=A9=EC=9E=90=20=EB=B3=B4?= =?UTF-8?q?=EA=B3=A0=20"=EC=A0=88=EB=8C=80=20=EC=95=88=EA=B3=A0=EC=B3=90?= =?UTF-8?q?=EC=A7=80=EB=84=A4")=20=EA=B7=BC=EB=B3=B8=20=EC=9B=90=EC=9D=B8:?= =?UTF-8?q?=20Shared.xaml=20=EC=95=94=EC=8B=9C=EC=A0=81=20TextBlock=20?= =?UTF-8?q?=EC=8A=A4=ED=83=80=EC=9D=BC=EC=9D=98=20FontFamily=3DUiFont=20?= =?UTF-8?q?=EA=B0=95=EC=A0=9C=EA=B0=80=20=EB=B2=84=ED=8A=BC=20ContentPrese?= =?UTF-8?q?nter=20=EC=9E=90=EB=8F=99=20TextBlock=20=EC=9D=98=20IconFont=20?= =?UTF-8?q?=EC=83=81=EC=86=8D=EC=9D=84=20=EB=8D=AE=EC=96=B4=20=EB=AA=A8?= =?UTF-8?q?=EB=93=A0=20PUA=20=EA=B8=80=EB=A6=AC=ED=94=84=EA=B0=80=20notdef?= =?UTF-8?q?=20=E2=80=94=20=ED=8F=B0=ED=8A=B8=20=EC=84=A4=EC=B9=98/?= =?UTF-8?q?=EA=B8=80=EB=A6=AC=ED=94=84=20=EC=A1=B4=EC=9E=AC/HW=C2=B7SW=20?= =?UTF-8?q?=EB=A0=8C=EB=8D=94/RTB/DPI/=EB=9F=B0=ED=83=80=EC=9E=84=208?= =?UTF-8?q?=C2=B710/=EC=9E=90=EC=B2=B4=ED=8F=AC=ED=95=A8=C2=B7=EA=B3=B5?= =?UTF-8?q?=EC=9C=A0=20=EC=A0=84=EB=B6=80=20=EB=B0=B0=EC=A0=9C=20=ED=9B=84?= =?UTF-8?q?=20=EC=8B=A4=EC=B0=BD=20=ED=94=BD=EC=85=80=20=EB=B9=84=EA=B5=90?= =?UTF-8?q?=EB=A1=9C=20=EA=B2=A9=EB=A6=AC,=20=EC=BD=98=ED=85=90=EC=B8=A0?= =?UTF-8?q?=20TextBlock=20=EC=9D=98=20=EC=8B=A4=ED=8F=B0=ED=8A=B8=EA=B0=80?= =?UTF-8?q?=20Pretendard=20=EC=B2=B4=EC=9D=B8=EC=9E=84=EC=9D=84=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=EB=A1=9C=20=EC=8B=A4=EC=A6=9D.=20?= =?UTF-8?q?=EC=88=98=EC=A0=95:=20=EC=95=94=EC=8B=9C=20=EC=8A=A4=ED=83=80?= =?UTF-8?q?=EC=9D=BC=20FontFamily=20=EC=A0=9C=EA=B1=B0(=EC=B0=BD=20?= =?UTF-8?q?=EB=A3=A8=ED=8A=B8=20=EC=83=81=EC=86=8D=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=ED=86=B5=EC=9D=BC,=20PairingWindow/PlayerWindow=20=EB=8A=94=20?= =?UTF-8?q?SetResourceReference),=20PUA+=ED=85=8D=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=ED=98=BC=ED=95=A9=20=EC=BD=98=ED=85=90=EC=B8=A0=207=EA=B3=B3+?= =?UTF-8?q?=EC=BD=94=EB=93=9C=201=EA=B3=B3=20=EC=A0=95=EB=A6=AC,=20?= =?UTF-8?q?=EC=88=9C=EC=88=98=20=EA=B8=80=EB=A6=AC=ED=94=84=202=EA=B3=B3?= =?UTF-8?q?=20IconFont=20=EB=AA=85=EC=8B=9C.=20=ED=9A=8C=EA=B7=80=20?= =?UTF-8?q?=EB=B0=A9=EC=96=B4:=20IconGlyphXamlTests(=EC=A0=95=EC=A0=81=20?= =?UTF-8?q?=EC=8A=A4=EC=BA=94)=C2=B7IconContentFontTests(=EC=8B=A4?= =?UTF-8?q?=EC=B0=BD=20=ED=8F=B0=ED=8A=B8=20=EB=8B=A8=EC=A0=95)=C2=B7IconG?= =?UTF-8?q?lyphRenderTests(=ED=94=BD=EC=85=80=20=EB=B9=84=EA=B5=90)=20?= =?UTF-8?q?=E2=80=94=20462/462=20GREEN,=20=EC=88=98=EC=A0=95=20=EC=A0=84?= =?UTF-8?q?=ED=9B=84=20=EC=8B=A4=EC=B0=BD=20=EC=BA=A1=EC=B2=98=EB=A1=9C=20?= =?UTF-8?q?=EA=B8=80=EB=A6=AC=ED=94=84=20=EB=A0=8C=EB=8D=94=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/rules/desktop-wpf.md | 10 ++ .claude/skills/release/SKILL.md | 2 +- .forgejo/workflows/release.yml | 14 +-- .github/workflows/release.yml | 10 +- README.md | 2 +- VideoDownloader.App/Browser/PairingWindow.cs | 4 +- VideoDownloader.App/Browser/PlayerWindow.cs | 4 +- VideoDownloader.App/MainWindow.Usecases.cs | 4 +- VideoDownloader.App/MainWindow.xaml | 22 ++-- VideoDownloader.App/MainWindow.xaml.cs | 2 +- VideoDownloader.App/SettingsWindow.xaml.cs | 4 +- VideoDownloader.App/Themes/Shared.xaml | 5 +- VideoDownloader.Core/Config/AppConfig.cs | 8 +- VideoDownloader.Core/Update/UpdateChecker.cs | 21 ++-- .../VideoDownloader.Mobile.csproj | 2 +- .../E2E/IconContentFontTests.cs | 71 +++++++++++ .../E2E/IconGlyphRenderTests.cs | 116 ++++++++++++++++++ .../Infrastructure/IconGlyphXamlTests.cs | 89 ++++++++++++++ .../Platform/UpdateCheckerTests.cs | 56 ++++++++- build/installer.iss | 13 +- build/obtainium.json | 8 +- build/publish.ps1 | 8 +- docs/BACKLOG.md | 28 +++++ docs/DEPLOYMENT_PLAN.md | 12 +- 24 files changed, 451 insertions(+), 64 deletions(-) create mode 100644 VideoDownloader.Tests/E2E/IconContentFontTests.cs create mode 100644 VideoDownloader.Tests/E2E/IconGlyphRenderTests.cs create mode 100644 VideoDownloader.Tests/Infrastructure/IconGlyphXamlTests.cs diff --git a/.claude/rules/desktop-wpf.md b/.claude/rules/desktop-wpf.md index 6e9799a..ff91f0a 100644 --- a/.claude/rules/desktop-wpf.md +++ b/.claude/rules/desktop-wpf.md @@ -38,3 +38,13 @@ Grep 으로 심볼 위치를 찾고 해당 구간만 Read 한다. 분할 리팩 `VideoDownloader.App` 은 `InternalsVisibleTo("VideoDownloader.Tests")` 가 걸려 있다. 테스트를 위해 멤버를 `public` 으로 승격하지 말고 `internal` 로 두면 된다. + +## 아이콘 글리프 (PUA · Segoe Fluent Icons) + +- **암시적(키 없는) TextBlock 스타일에 FontFamily 를 넣지 않는다.** 버튼 ContentPresenter 가 만드는 + 자동 TextBlock 이 IconFont 상속을 잃어 모든 아이콘이 tofu(□)가 된다(2026-08-18 실결함 — 원인 규명에 + 실캡처·픽셀 비교까지 필요했다). UI 폰트 통일은 각 창 루트의 `FontFamily="{DynamicResource UiFont}"` + 상속으로 한다. 코드 생성 창은 `SetResourceReference(FontFamilyProperty, "UiFont")`. +- PUA 글리프는 IconFont 보장 스타일(IconButton·FluentIcon·CaptionButton 계열)이나 명시 + `FontFamily="{DynamicResource IconFont}"` 에서만 쓴다. **한 문자열에 PUA 와 일반 텍스트를 섞지 않는다.** + `Infrastructure/IconGlyphXamlTests` 가 정적으로, `E2E/IconContentFontTests` 가 실창에서 이를 강제한다. diff --git a/.claude/skills/release/SKILL.md b/.claude/skills/release/SKILL.md index 13b832f..7df4259 100644 --- a/.claude/skills/release/SKILL.md +++ b/.claude/skills/release/SKILL.md @@ -25,7 +25,7 @@ git status --short ``` - 하는 일: `VideoDownloader.App` 을 `win-x64`/`win-arm64` self-contained 로 publish (`publish//`) - → Inno Setup 으로 설치자 컴파일 → `out/VideoDownloader-Setup-.exe` + → Inno Setup 으로 설치자 컴파일 → `out/MediaBrowser-Setup-.exe` - 필요: **Inno Setup 6** (`winget install --id JRSoftware.InnoSetup -e`). 없으면 스크립트가 명시적으로 throw 한다. - 특정 아키텍처만: `-Archs x64` diff --git a/.forgejo/workflows/release.yml b/.forgejo/workflows/release.yml index b58009b..09502a7 100644 --- a/.forgejo/workflows/release.yml +++ b/.forgejo/workflows/release.yml @@ -74,7 +74,7 @@ jobs: run: ./build/publish.ps1 -Config Release -Version $env:APP_VERSION - name: 릴리스 업로드 env: { RELEASE_TOKEN: "${{ secrets.RELEASE_TOKEN }}" } - run: ./build/ci/upload-release-asset.ps1 -Tag $env:RELTAG -Files out/VideoDownloader-Setup-x64.exe, out/VideoDownloader-Setup-arm64.exe + run: ./build/ci/upload-release-asset.ps1 -Tag $env:RELTAG -Files out/MediaBrowser-Setup-x64.exe, out/MediaBrowser-Setup-arm64.exe # ── Android APK (키스토어 시크릿 없으면 디버그 서명 APK) ── android: @@ -126,10 +126,10 @@ jobs: $apk = Get-ChildItem out/android/*-Signed.apk | Select-Object -First 1 if (-not $apk) { $apk = Get-ChildItem out/android/*.apk | Select-Object -First 1 } if (-not $apk) { throw "APK 산출물 없음" } - Copy-Item $apk.FullName "out/VideoDownloader-$env:APP_VERSION-arm64.apk" + Copy-Item $apk.FullName "out/MediaBrowser-$env:APP_VERSION-arm64.apk" - name: 릴리스 업로드 env: { RELEASE_TOKEN: "${{ secrets.RELEASE_TOKEN }}" } - run: ./build/ci/upload-release-asset.ps1 -Tag $env:RELTAG -Files "out/VideoDownloader-$env:APP_VERSION-arm64.apk" + run: ./build/ci/upload-release-asset.ps1 -Tag $env:RELTAG -Files "out/MediaBrowser-$env:APP_VERSION-arm64.apk" # ── Linux 셸 (tar.gz self-contained — Cli + Avalonia, x64 네이티브 + arm64 교차) ── linux: @@ -163,11 +163,11 @@ jobs: for rid in linux-x64 linux-arm64; do dotnet publish VideoDownloader.Cli -c Release -r "$rid" --self-contained -o "out/cli-$rid" dotnet publish VideoDownloader.Avalonia -c Release -r "$rid" --self-contained -o "out/avalonia-$rid" - tar -C out -czf "out/videodownloader-$rid.tar.gz" "cli-$rid" "avalonia-$rid" + tar -C out -czf "out/mediabrowser-$rid.tar.gz" "cli-$rid" "avalonia-$rid" done - name: 릴리스 업로드 env: { RELEASE_TOKEN: "${{ secrets.RELEASE_TOKEN }}" } - run: ./build/ci/upload-release-asset.sh "$RELTAG" out/videodownloader-linux-x64.tar.gz out/videodownloader-linux-arm64.tar.gz + run: ./build/ci/upload-release-asset.sh "$RELTAG" out/mediabrowser-linux-x64.tar.gz out/mediabrowser-linux-arm64.tar.gz # ── macOS 셸 (tar.gz — arm64 네이티브 + x64 교차. 서명·공증은 D4, Apple Developer Program 후) ── macos: @@ -201,8 +201,8 @@ jobs: for rid in osx-arm64 osx-x64; do dotnet publish VideoDownloader.Cli -c Release -r "$rid" --self-contained -o "out/cli-$rid" dotnet publish VideoDownloader.Avalonia -c Release -r "$rid" --self-contained -o "out/avalonia-$rid" - tar -C out -czf "out/videodownloader-$rid.tar.gz" "cli-$rid" "avalonia-$rid" + tar -C out -czf "out/mediabrowser-$rid.tar.gz" "cli-$rid" "avalonia-$rid" done - name: 릴리스 업로드 env: { RELEASE_TOKEN: "${{ secrets.RELEASE_TOKEN }}" } - run: ./build/ci/upload-release-asset.sh "$RELTAG" out/videodownloader-osx-arm64.tar.gz out/videodownloader-osx-x64.tar.gz + run: ./build/ci/upload-release-asset.sh "$RELTAG" out/mediabrowser-osx-arm64.tar.gz out/mediabrowser-osx-x64.tar.gz diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 969703e..3a67cd0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -52,7 +52,7 @@ jobs: - uses: actions/upload-artifact@v4 with: name: win-${{ matrix.arch }} - path: out/VideoDownloader-Setup-${{ matrix.arch }}.exe + path: out/MediaBrowser-Setup-${{ matrix.arch }}.exe # ── Linux 셸 (tar.gz self-contained — Avalonia + Cli) ── linux: @@ -74,11 +74,11 @@ jobs: run: | dotnet publish VideoDownloader.Cli -c Release -r ${{ matrix.rid }} --self-contained -o out/cli-${{ matrix.rid }} dotnet publish VideoDownloader.Avalonia -c Release -r ${{ matrix.rid }} --self-contained -o out/avalonia-${{ matrix.rid }} - tar -C out -czf out/videodownloader-${{ matrix.rid }}.tar.gz cli-${{ matrix.rid }} avalonia-${{ matrix.rid }} + tar -C out -czf out/mediabrowser-${{ matrix.rid }}.tar.gz cli-${{ matrix.rid }} avalonia-${{ matrix.rid }} - uses: actions/upload-artifact@v4 with: name: ${{ matrix.rid }} - path: out/videodownloader-${{ matrix.rid }}.tar.gz + path: out/mediabrowser-${{ matrix.rid }}.tar.gz # ── macOS 셸 (tar.gz — D4 서명·공증은 Developer ID 시크릿 등록 후 확장) ── macos: @@ -100,12 +100,12 @@ jobs: run: | dotnet publish VideoDownloader.Cli -c Release -r ${{ matrix.rid }} --self-contained -o out/cli-${{ matrix.rid }} dotnet publish VideoDownloader.Avalonia -c Release -r ${{ matrix.rid }} --self-contained -o out/avalonia-${{ matrix.rid }} - tar -C out -czf out/videodownloader-${{ matrix.rid }}.tar.gz cli-${{ matrix.rid }} avalonia-${{ matrix.rid }} + tar -C out -czf out/mediabrowser-${{ matrix.rid }}.tar.gz cli-${{ matrix.rid }} avalonia-${{ matrix.rid }} # D4: MACOS_P12/KEYCHAIN_PASS/NOTARY_PROFILE 시크릿 등록 시 codesign+notarytool+DMG 스텝 추가 - uses: actions/upload-artifact@v4 with: name: ${{ matrix.rid }} - path: out/videodownloader-${{ matrix.rid }}.tar.gz + path: out/mediabrowser-${{ matrix.rid }}.tar.gz # ── Android APK (D2 — 서명 키스토어 시크릿 없으면 미서명 APK) ── android: diff --git a/README.md b/README.md index 7732f2b..6b906f4 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ dotnet build VideoDownloader.Mobile -f net10.0-android ## 배포 ```powershell -# Windows 설치자 (x64 + arm64) → out/VideoDownloader-Setup-{arch}.exe +# Windows 설치자 (x64 + arm64) → out/MediaBrowser-Setup-{arch}.exe ./build/publish.ps1 -Config Release -Version 1.0.0 # macOS / Linux 원격 빌드 (.env 의 빌드머신 자격 증명 사용) → out/remote// diff --git a/VideoDownloader.App/Browser/PairingWindow.cs b/VideoDownloader.App/Browser/PairingWindow.cs index f8fe93a..8e044c2 100644 --- a/VideoDownloader.App/Browser/PairingWindow.cs +++ b/VideoDownloader.App/Browser/PairingWindow.cs @@ -15,9 +15,11 @@ public sealed class PairingWindow : Window { public PairingWindow(ServerHost server, string deviceName) { - Title = "기기 연결 — Video Downloader"; + Title = "기기 연결 - MediaBrowser"; Width = 420; Height = 560; WindowStartupLocation = WindowStartupLocation.CenterOwner; + SetResourceReference(FontFamilyProperty, "UiFont"); // 암시 스타일 폰트 강제 제거 후 창 루트 상속으로 통일 + Background = System.Windows.Media.Brushes.White; var lanIp = GetLanIp(); diff --git a/VideoDownloader.App/Browser/PlayerWindow.cs b/VideoDownloader.App/Browser/PlayerWindow.cs index b116cd1..17f7c44 100644 --- a/VideoDownloader.App/Browser/PlayerWindow.cs +++ b/VideoDownloader.App/Browser/PlayerWindow.cs @@ -28,9 +28,11 @@ public sealed class PlayerWindow : Window _config = config; _playlist = playlist; - Title = "재생목록 — Video Downloader"; + Title = "재생목록 - MediaBrowser"; Width = 900; Height = 620; WindowStartupLocation = WindowStartupLocation.CenterOwner; + SetResourceReference(FontFamilyProperty, "UiFont"); // 암시 스타일 폰트 강제 제거 후 창 루트 상속으로 통일 + var bar = new Border { Background = System.Windows.Media.Brushes.Black, Padding = new Thickness(8, 6, 8, 6) }; var dock = new DockPanel(); diff --git a/VideoDownloader.App/MainWindow.Usecases.cs b/VideoDownloader.App/MainWindow.Usecases.cs index ef226e7..db3b801 100644 --- a/VideoDownloader.App/MainWindow.Usecases.cs +++ b/VideoDownloader.App/MainWindow.Usecases.cs @@ -164,7 +164,7 @@ public partial class MainWindow try { var current = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version?.ToString(3) ?? "0.0.0"; - var result = await new VideoDownloader.Core.Update.UpdateChecker().CheckAsync(repo, current, "win-x64"); + var result = await new VideoDownloader.Core.Update.UpdateChecker().CheckAsync(repo, current, "win-x64", _config.UpdateApiBase); if (result.IsNewer) { UpdateBadge.Visibility = Visibility.Visible; @@ -656,7 +656,7 @@ public partial class MainWindow private void LibraryViewToggle_Click(object sender, RoutedEventArgs e) { _libraryGrid = !_libraryGrid; - LibraryViewToggle.Content = _libraryGrid ? "\uE8FD; 그리드" : "\uE71B; 리스트"; + LibraryViewToggle.Content = _libraryGrid ? "그리드" : "리스트"; RefreshLibrary(); } diff --git a/VideoDownloader.App/MainWindow.xaml b/VideoDownloader.App/MainWindow.xaml index 1fb88ca..657ec3f 100644 --- a/VideoDownloader.App/MainWindow.xaml +++ b/VideoDownloader.App/MainWindow.xaml @@ -9,13 +9,13 @@ xmlns:feat="clr-namespace:VideoDownloader.App.Browser.Features" mc:Ignorable="d" FontFamily="{DynamicResource UiFont}" - Title="Video Downloader" Height="820" Width="1300" + Title="MediaBrowser" Height="820" Width="1300" Background="{DynamicResource WindowBgGradient}" WindowStartupLocation="CenterScreen" UseLayoutRounding="True" ToolTipService.InitialShowDelay="400" ToolTipService.ShowDuration="8000" - AutomationProperties.Name="Video Downloader 메인 창" + AutomationProperties.Name="MediaBrowser 메인 창" WindowStyle="None" ResizeMode="CanResize"> @@ -273,7 +273,7 @@ - @@ -389,7 +389,7 @@ Background="Transparent" BorderThickness="0" Padding="0" AutomationProperties.Name="클립보드 링크 받기 제안"> - + @@ -500,7 +500,7 @@ Foreground="{DynamicResource TextMuted}" Visibility="Collapsed" AutomationProperties.Name="잠긴 탭"/>