From 1891ec049cee87200549d1cf41d55ded83375c99 Mon Sep 17 00:00:00 2001 From: Yukon <126093594+baseGame@users.noreply.github.com> Date: Wed, 7 Oct 2026 03:05:39 +0800 Subject: [PATCH] Clarify Clipboard Compare empty states and capture errors Add stage-aware empty hints, an identical-texts hint, a Compare tip when two entries are missing, and plain clipboard capture errors so first-time users know the next step. --- src/i18n/locales/de-DE.ts | 15 +++++ src/i18n/locales/en-US.ts | 13 +++- src/i18n/locales/es-ES.ts | 14 ++++ src/i18n/locales/fr-FR.ts | 16 +++++ src/i18n/locales/ja-JP.ts | 10 +++ src/i18n/locales/ko-KR.ts | 12 ++++ src/i18n/locales/zh-CN.ts | 8 +++ src/i18n/locales/zh-TW.ts | 8 +++ src/views/ClipboardCompareView.test.ts | 91 ++++++++++++++++++++++++-- src/views/ClipboardCompareView.vue | 76 +++++++++++++++++---- 10 files changed, 241 insertions(+), 22 deletions(-) diff --git a/src/i18n/locales/de-DE.ts b/src/i18n/locales/de-DE.ts index 369473b2..972c16ea 100644 --- a/src/i18n/locales/de-DE.ts +++ b/src/i18n/locales/de-DE.ts @@ -989,6 +989,21 @@ export const deDE: LanguagePack = { 'ui.textPatchEmptyParsedHint': 'Dieser Patch enthält keine anzuzeigenden Dateiabschnitte.', 'ui.textPatchNeedsPatch': 'Fügen Sie zuerst einen Patch ein oder öffnen Sie einen.', 'ui.textPatchNeedsSource': 'Wählen Sie zuerst eine Quelldatei.', + 'ui.clipboardEmptyCaptureHint': + 'Kopieren Sie Text und klicken Sie auf Zwischenablage erfassen. Erfassen Sie die andere Seite erneut.', + 'ui.clipboardEmptySecondHint': + 'Erfassen Sie einen zweiten Zwischenablagetext (oder wählen Sie zwei Historieneinträge), dann Ausgewählte vergleichen.', + 'ui.clipboardEmptyReadyHint': + 'Klicken Sie auf Ausgewählte vergleichen, um die beiden Zwischenablagetexte zu vergleichen.', + 'ui.clipboardIdenticalHint': + 'Diese Zwischenablagetexte stimmen überein. Keine Unterschiede anzuzeigen.', + 'ui.clipboardNeedsTwoEntries': 'Erfassen und wählen Sie zuerst zwei Zwischenablagetexte.', + 'ui.clipboardEmptyError': + 'Die Zwischenablage ist leer. Kopieren Sie zuerst Text und klicken Sie dann auf Erfassen.', + 'ui.clipboardUnavailableError': + 'Der Zugriff auf die Zwischenablage ist in dieser Umgebung nicht verfügbar.', + 'ui.clipboardReadFailedError': + 'Zwischenablagetext konnte nicht gelesen werden. Prüfen Sie die Berechtigung und versuchen Sie es erneut.', 'ui.textPatchSourceTextPlaceholder': 'Originaltextdatei für „Patch anwenden“ einfügen', 'ui.applyPatchHint': 'Zeigt den gepatchten Text im Speicher an (schreibt keine Datei).', 'ui.applyToFileHint': 'Schreibt das Ergebnis in die Zieldatei (oder Quelle, wenn Ziel leer).', diff --git a/src/i18n/locales/en-US.ts b/src/i18n/locales/en-US.ts index 06cc34af..9e3c791c 100644 --- a/src/i18n/locales/en-US.ts +++ b/src/i18n/locales/en-US.ts @@ -92,7 +92,8 @@ export const enUS: LanguagePack = { 'ui.cancel': 'Cancel', 'ui.ok': 'OK', 'ui.captureClipboard': 'Capture Clipboard', - 'ui.captureTwoClipboardTextsAndCompareThem': 'Capture two clipboard texts and compare them.', + 'ui.captureTwoClipboardTextsAndCompareThem': + 'Copy text, click Capture Clipboard for each side, then click Compare Selected.', 'ui.case': 'Case', 'ui.change': 'Change', 'ui.changeRules': 'Change rules', @@ -956,6 +957,16 @@ export const enUS: LanguagePack = { 'ui.textPatchEmptyParsedHint': 'This patch has no file sections to show.', 'ui.textPatchNeedsPatch': 'Paste or open a patch first.', 'ui.textPatchNeedsSource': 'Choose a source file first.', + 'ui.clipboardEmptyCaptureHint': + 'Copy some text, then click Capture Clipboard. Capture again for the other side.', + 'ui.clipboardEmptySecondHint': + 'Capture a second clipboard text (or select two history entries), then Compare Selected.', + 'ui.clipboardEmptyReadyHint': 'Click Compare Selected to compare the two clipboard texts.', + 'ui.clipboardIdenticalHint': 'These clipboard texts match. No differences to show.', + 'ui.clipboardNeedsTwoEntries': 'Capture and select two clipboard texts first.', + 'ui.clipboardEmptyError': 'Clipboard is empty. Copy some text first, then click Capture.', + 'ui.clipboardUnavailableError': 'Clipboard access is unavailable in this environment.', + 'ui.clipboardReadFailedError': 'Could not read clipboard text. Check permission and try again.', 'ui.textPatchSourceTextPlaceholder': 'Paste the original file text for Apply Patch', 'ui.applyPatchHint': 'Preview the patched text in memory (does not write a file).', 'ui.applyToFileHint': diff --git a/src/i18n/locales/es-ES.ts b/src/i18n/locales/es-ES.ts index 5e9ece83..4bf7f15e 100644 --- a/src/i18n/locales/es-ES.ts +++ b/src/i18n/locales/es-ES.ts @@ -974,6 +974,20 @@ export const esES: LanguagePack = { 'ui.textPatchEmptyParsedHint': 'Este parche no tiene secciones de archivo que mostrar.', 'ui.textPatchNeedsPatch': 'Pegue o abra un parche primero.', 'ui.textPatchNeedsSource': 'Elija primero un archivo de origen.', + 'ui.clipboardEmptyCaptureHint': + 'Copie texto y haga clic en Capturar portapapeles. Capture de nuevo el otro lado.', + 'ui.clipboardEmptySecondHint': + 'Capture un segundo texto del portapapeles (o seleccione dos entradas del historial) y luego Comparar seleccionados.', + 'ui.clipboardEmptyReadyHint': + 'Haga clic en Comparar seleccionados para comparar los dos textos del portapapeles.', + 'ui.clipboardIdenticalHint': + 'Estos textos del portapapeles coinciden. No hay diferencias que mostrar.', + 'ui.clipboardNeedsTwoEntries': 'Capture y seleccione primero dos textos del portapapeles.', + 'ui.clipboardEmptyError': + 'El portapapeles está vacío. Copie texto primero y luego haga clic en Capturar.', + 'ui.clipboardUnavailableError': 'El acceso al portapapeles no está disponible en este entorno.', + 'ui.clipboardReadFailedError': + 'No se pudo leer el texto del portapapeles. Compruebe el permiso e inténtelo de nuevo.', 'ui.textPatchSourceTextPlaceholder': 'Pegue el texto del archivo original para Aplicar parche', 'ui.applyPatchHint': 'Previsualiza el texto parcheado en memoria (no escribe un archivo).', 'ui.applyToFileHint': diff --git a/src/i18n/locales/fr-FR.ts b/src/i18n/locales/fr-FR.ts index 4461e0cd..845574ae 100644 --- a/src/i18n/locales/fr-FR.ts +++ b/src/i18n/locales/fr-FR.ts @@ -982,6 +982,22 @@ export const frFR: LanguagePack = { 'ui.textPatchEmptyParsedHint': "Ce correctif n'a aucune section de fichier à afficher.", 'ui.textPatchNeedsPatch': "Collez ou ouvrez d'abord un correctif.", 'ui.textPatchNeedsSource': "Choisissez d'abord un fichier source.", + 'ui.clipboardEmptyCaptureHint': + "Copiez du texte, puis cliquez sur Capturer le presse-papiers. Capturez à nouveau l'autre côté.", + 'ui.clipboardEmptySecondHint': + "Capturez un second texte du presse-papiers (ou sélectionnez deux entrées d'historique), puis Comparer la sélection.", + 'ui.clipboardEmptyReadyHint': + 'Cliquez sur Comparer la sélection pour comparer les deux textes du presse-papiers.', + 'ui.clipboardIdenticalHint': + 'Ces textes du presse-papiers correspondent. Aucune différence à afficher.', + 'ui.clipboardNeedsTwoEntries': + "Capturez et sélectionnez d'abord deux textes du presse-papiers.", + 'ui.clipboardEmptyError': + "Le presse-papiers est vide. Copiez d'abord du texte, puis cliquez sur Capturer.", + 'ui.clipboardUnavailableError': + "L'accès au presse-papiers n'est pas disponible dans cet environnement.", + 'ui.clipboardReadFailedError': + "Impossible de lire le texte du presse-papiers. Vérifiez l'autorisation et réessayez.", 'ui.textPatchSourceTextPlaceholder': "Collez le texte du fichier d'origine pour Appliquer le correctif", 'ui.applyPatchHint': "Prévisualise le texte corrigé en mémoire (n'écrit pas de fichier).", diff --git a/src/i18n/locales/ja-JP.ts b/src/i18n/locales/ja-JP.ts index 367a3bc5..72a6e15e 100644 --- a/src/i18n/locales/ja-JP.ts +++ b/src/i18n/locales/ja-JP.ts @@ -954,6 +954,16 @@ export const jaJP: LanguagePack = { 'ui.textPatchEmptyParsedHint': 'This patch has no file sections to show.', 'ui.textPatchNeedsPatch': 'Paste or open a patch first.', 'ui.textPatchNeedsSource': 'Choose a source file first.', + 'ui.clipboardEmptyCaptureHint': + 'Copy some text, then click Capture Clipboard. Capture again for the other side.', + 'ui.clipboardEmptySecondHint': + 'Capture a second clipboard text (or select two history entries), then Compare Selected.', + 'ui.clipboardEmptyReadyHint': 'Click Compare Selected to compare the two clipboard texts.', + 'ui.clipboardIdenticalHint': 'These clipboard texts match. No differences to show.', + 'ui.clipboardNeedsTwoEntries': 'Capture and select two clipboard texts first.', + 'ui.clipboardEmptyError': 'Clipboard is empty. Copy some text first, then click Capture.', + 'ui.clipboardUnavailableError': 'Clipboard access is unavailable in this environment.', + 'ui.clipboardReadFailedError': 'Could not read clipboard text. Check permission and try again.', 'ui.textPatchSourceTextPlaceholder': 'Paste the original file text for Apply Patch', 'ui.applyPatchHint': 'Preview the patched text in memory (does not write a file).', 'ui.applyToFileHint': diff --git a/src/i18n/locales/ko-KR.ts b/src/i18n/locales/ko-KR.ts index fc971e84..ab29d1c0 100644 --- a/src/i18n/locales/ko-KR.ts +++ b/src/i18n/locales/ko-KR.ts @@ -947,6 +947,18 @@ export const koKR: LanguagePack = { 'ui.textPatchEmptyParsedHint': '이 패치에 표시할 파일 구간이 없습니다.', 'ui.textPatchNeedsPatch': '먼저 패치를 붙여넣거나 여세요.', 'ui.textPatchNeedsSource': '먼저 원본 파일을 선택하세요.', + 'ui.clipboardEmptyCaptureHint': + '텍스트를 복사한 다음 클립보드 캡처를 클릭하세요. 다른 쪽도 다시 캡처하세요.', + 'ui.clipboardEmptySecondHint': + '두 번째 클립보드 텍스트를 캡처하거나 기록에서 두 항목을 선택한 다음 선택 항목 비교를 클릭하세요.', + 'ui.clipboardEmptyReadyHint': '선택 항목 비교를 클릭하여 두 클립보드 텍스트를 비교하세요.', + 'ui.clipboardIdenticalHint': '이 클립보드 텍스트는 일치합니다. 표시할 차이가 없습니다.', + 'ui.clipboardNeedsTwoEntries': '먼저 클립보드 텍스트 두 개를 캡처하고 선택하세요.', + 'ui.clipboardEmptyError': + '클립보드가 비어 있습니다. 먼저 텍스트를 복사한 다음 캡처를 클릭하세요.', + 'ui.clipboardUnavailableError': '이 환경에서는 클립보드에 접근할 수 없습니다.', + 'ui.clipboardReadFailedError': + '클립보드 텍스트를 읽을 수 없습니다. 권한을 확인한 후 다시 시도하세요.', 'ui.textPatchSourceTextPlaceholder': '패치 적용을 위해 원본 파일 텍스트를 붙여넣으세요', 'ui.applyPatchHint': '메모리에서 패치된 텍스트를 미리 봅니다(파일에 쓰지 않음).', 'ui.applyToFileHint': '패치 결과를 대상 파일에 씁니다(대상이 비어 있으면 원본에 씀).', diff --git a/src/i18n/locales/zh-CN.ts b/src/i18n/locales/zh-CN.ts index 5a9d198e..cfb1c1b4 100644 --- a/src/i18n/locales/zh-CN.ts +++ b/src/i18n/locales/zh-CN.ts @@ -914,6 +914,14 @@ export const zhCN: LanguagePack = { 'ui.textPatchEmptyParsedHint': '此补丁没有可显示的文件分段。', 'ui.textPatchNeedsPatch': '请先粘贴或打开补丁。', 'ui.textPatchNeedsSource': '请先选择源文件。', + 'ui.clipboardEmptyCaptureHint': '复制一些文本,然后点捕获剪贴板。再捕获另一侧。', + 'ui.clipboardEmptySecondHint': '再捕获一段剪贴板文本(或选择两条历史),然后点比较所选。', + 'ui.clipboardEmptyReadyHint': '点比较所选以比较两段剪贴板文本。', + 'ui.clipboardIdenticalHint': '这些剪贴板文本一致。没有差异。', + 'ui.clipboardNeedsTwoEntries': '请先捕获并选择两段剪贴板文本。', + 'ui.clipboardEmptyError': '剪贴板为空。请先复制文本,再点捕获。', + 'ui.clipboardUnavailableError': '当前环境无法访问剪贴板。', + 'ui.clipboardReadFailedError': '无法读取剪贴板文本。请检查权限后重试。', 'ui.textPatchSourceTextPlaceholder': '粘贴原始文件文本以应用补丁', 'ui.applyPatchHint': '在内存中预览修补后的文本(不写入文件)。', 'ui.applyToFileHint': '将修补结果写入目标文件(若目标为空则写入源文件)。', diff --git a/src/i18n/locales/zh-TW.ts b/src/i18n/locales/zh-TW.ts index 7910c4bc..853a7ef6 100644 --- a/src/i18n/locales/zh-TW.ts +++ b/src/i18n/locales/zh-TW.ts @@ -916,6 +916,14 @@ export const zhTW: LanguagePack = { 'ui.textPatchEmptyParsedHint': '此修補沒有可顯示的檔案區段。', 'ui.textPatchNeedsPatch': '請先貼上或開啟修補。', 'ui.textPatchNeedsSource': '請先選擇來源檔案。', + 'ui.clipboardEmptyCaptureHint': '複製一些文字,然後按擷取剪貼簿。再擷取另一側。', + 'ui.clipboardEmptySecondHint': '再擷取一段剪貼簿文字(或選擇兩筆歷史),然後按比較所選。', + 'ui.clipboardEmptyReadyHint': '按比較所選以比較兩段剪貼簿文字。', + 'ui.clipboardIdenticalHint': '這些剪貼簿文字一致。沒有差異。', + 'ui.clipboardNeedsTwoEntries': '請先擷取並選擇兩段剪貼簿文字。', + 'ui.clipboardEmptyError': '剪貼簿為空。請先複製文字,再按擷取。', + 'ui.clipboardUnavailableError': '目前環境無法存取剪貼簿。', + 'ui.clipboardReadFailedError': '無法讀取剪貼簿文字。請檢查權限後重試。', 'ui.textPatchSourceTextPlaceholder': '貼上原始檔案文字以套用修補', 'ui.applyPatchHint': '在記憶體中預覽修補後的文字(不寫入檔案)。', 'ui.applyToFileHint': '將修補結果寫入目標檔案(若目標為空則寫入來源)。', diff --git a/src/views/ClipboardCompareView.test.ts b/src/views/ClipboardCompareView.test.ts index 27ceb154..bcb26df0 100644 --- a/src/views/ClipboardCompareView.test.ts +++ b/src/views/ClipboardCompareView.test.ts @@ -3,14 +3,20 @@ import { createPinia, setActivePinia } from 'pinia' import { beforeEach, describe, expect, it, vi } from 'vitest' import ClipboardCompareView from './ClipboardCompareView.vue' import { diffText } from '@/api/diff' -import { readClipboardTextSource } from '@/app/clipboardSource' +import type * as clipboardSource from '@/app/clipboardSource' +import { ClipboardSourceError, readClipboardTextSource } from '@/app/clipboardSource' import { useTabsStore } from '@/stores/tabs' import { useStatusBarStore } from '@/stores/statusBar' import { useViewActionsStore } from '@/stores/viewActions' -vi.mock('@/app/clipboardSource', () => ({ - readClipboardTextSource: vi.fn(), -})) +vi.mock('@/app/clipboardSource', async (importOriginal) => { + const actual = await importOriginal() + + return { + ...actual, + readClipboardTextSource: vi.fn(), + } +}) vi.mock('@/api/diff', () => ({ diffText: vi.fn().mockResolvedValue({ @@ -28,11 +34,18 @@ function mountClipboardCompareView(): VueWrapper { global: { stubs: { NButton: { - props: ['disabled', 'loading'], + props: { + disabled: { type: Boolean, default: false }, + loading: { type: Boolean, default: false }, + title: { type: String, default: undefined }, + type: { type: String, default: undefined }, + size: { type: String, default: undefined }, + }, emits: ['click'], - template: '', + template: + '', }, - NAlert: { template: '
' }, + NAlert: { template: '
' }, TextDiffPanel: { props: { lines: { @@ -71,6 +84,70 @@ describe('ClipboardCompareView', () => { vi.mocked(diffText).mockClear() }) + it('shows a friendly empty state and disabled Compare tip', () => { + const wrapper = mountClipboardCompareView() + + expect(wrapper.find('[data-testid="clipboard-empty-hint"]').text()).toContain( + 'Capture Clipboard', + ) + expect(wrapper.find('[data-testid="clipboard-compare"]').attributes('title')).toContain( + 'two clipboard texts first', + ) + expect(wrapper.find('[data-testid="clipboard-compare"]').attributes('disabled')).toBeDefined() + }) + + it('shows a ready hint after two captures are selected', async () => { + vi.mocked(readClipboardTextSource) + .mockResolvedValueOnce({ kind: 'clipboard-text', title: 'Clipboard Text', text: 'alpha' }) + .mockResolvedValueOnce({ kind: 'clipboard-text', title: 'Clipboard Text', text: 'beta' }) + + const wrapper = mountClipboardCompareView() + + await wrapper.find('[data-testid="clipboard-capture"]').trigger('click') + await wrapper.find('[data-testid="clipboard-capture"]').trigger('click') + await flushPromises() + + expect(wrapper.find('[data-testid="clipboard-empty-hint"]').text()).toContain( + 'Compare Selected', + ) + expect(wrapper.find('[data-testid="clipboard-compare"]').attributes('disabled')).toBeUndefined() + }) + + it('maps an empty clipboard capture to a plain error', async () => { + vi.mocked(readClipboardTextSource).mockRejectedValueOnce( + new ClipboardSourceError('clipboard-empty', 'Clipboard does not contain text.'), + ) + + const wrapper = mountClipboardCompareView() + + await wrapper.find('[data-testid="clipboard-capture"]').trigger('click') + await flushPromises() + + expect(wrapper.find('[data-testid="clipboard-compare-error"]').text()).toContain( + 'Clipboard is empty', + ) + }) + + it('shows an identical hint when the two clipboard texts match', async () => { + vi.mocked(readClipboardTextSource) + .mockResolvedValueOnce({ kind: 'clipboard-text', title: 'Clipboard Text', text: 'alpha' }) + .mockResolvedValueOnce({ kind: 'clipboard-text', title: 'Clipboard Text', text: 'beta' }) + vi.mocked(diffText).mockResolvedValueOnce({ + lines: [], + stats: { added: 0, deleted: 0, modified: 0, equal: 1 }, + }) + + const wrapper = mountClipboardCompareView() + + await wrapper.find('[data-testid="clipboard-capture"]').trigger('click') + await wrapper.find('[data-testid="clipboard-capture"]').trigger('click') + await wrapper.find('[data-testid="clipboard-compare"]').trigger('click') + await flushPromises() + + expect(wrapper.find('[data-testid="clipboard-identical-hint"]').text()).toContain('match') + expect(wrapper.find('[data-testid="clipboard-diff-panel"]').exists()).toBe(false) + }) + it('captures unique clipboard text entries into history', async () => { vi.mocked(readClipboardTextSource) .mockResolvedValueOnce({ kind: 'clipboard-text', title: 'Clipboard Text', text: 'alpha' }) diff --git a/src/views/ClipboardCompareView.vue b/src/views/ClipboardCompareView.vue index 038259cd..6437ff5e 100644 --- a/src/views/ClipboardCompareView.vue +++ b/src/views/ClipboardCompareView.vue @@ -2,7 +2,8 @@ import { computed, ref, watch, watchEffect } from 'vue' import { useRouter } from 'vue-router' import { diffText } from '@/api/diff' -import { readClipboardTextSource } from '@/app/clipboardSource' +import { ClipboardSourceError, readClipboardTextSource } from '@/app/clipboardSource' +import { formatCompareError } from '@/app/compareError' import { buildClipboardCompareToolbar, pathPairTitle } from '@/app/sessionToolbars' import TextDiffPanel from '@/components/diff/TextDiffPanel.vue' import PathMetaFooter from '@/components/workbench/PathMetaFooter.vue' @@ -42,6 +43,34 @@ const historyCount = computed(() => t('status.capturedCount', { count: history.v const canCompare = computed(() => leftEntryId.value !== null && rightEntryId.value !== null) const leftEntry = computed(() => history.value.find((entry) => entry.id === leftEntryId.value)) const rightEntry = computed(() => history.value.find((entry) => entry.id === rightEntryId.value)) +const differenceCount = computed(() => { + if (!result.value) { + return null + } + + const { added, deleted, modified } = result.value.stats + + return added + deleted + modified +}) +const clipboardsAreIdentical = computed(() => result.value !== null && differenceCount.value === 0) +const clipboardEmptyStateMessage = computed(() => { + if (result.value) { + return '' + } + + if (canCompare.value) { + return t('ui.clipboardEmptyReadyHint') + } + + if (history.value.length === 1 || leftEntryId.value !== null || rightEntryId.value !== null) { + return t('ui.clipboardEmptySecondHint') + } + + return t('ui.clipboardEmptyCaptureHint') +}) +const compareSelectedTip = computed(() => + canCompare.value ? t('ui.compareSelected') : t('ui.clipboardNeedsTwoEntries'), +) const leftClipboardStamp = computed(() => leftEntry.value ? { size: leftEntry.value.characterCount, modifiedAtMs: 0 } : null, ) @@ -86,13 +115,9 @@ watchEffect(() => { comparisonStatus = t('status.compared') } - const differenceCount = result.value - ? result.value.stats.added + result.value.stats.deleted + result.value.stats.modified - : null - statusBar.reportStatus({ comparisonStatus, - differenceCount, + differenceCount: differenceCount.value, filterStatus: t('status.allRows'), source: 'clipboard-compare', chromeKind: 'clipboard-session', @@ -133,10 +158,7 @@ async function captureClipboard(): Promise { rightEntryId.value ??= entry.id } catch (event) { - error.value = - typeof event === 'object' && event !== null && 'message' in event - ? String(event.message) - : String(event) + error.value = formatClipboardCaptureError(event) } finally { loading.value = false } @@ -160,7 +182,7 @@ async function compareClipboardHistory(): Promise { algorithm: 'myers', }) } catch (event) { - error.value = String(event) + error.value = formatCompareError(event, t) } finally { comparing.value = false } @@ -203,6 +225,22 @@ function countLines(text: string): number { return text.length === 0 ? 0 : text.split('\n').length } +function formatClipboardCaptureError(event: unknown): string { + if (event instanceof ClipboardSourceError) { + if (event.code === 'clipboard-empty') { + return t('ui.clipboardEmptyError') + } + + if (event.code === 'clipboard-unavailable') { + return t('ui.clipboardUnavailableError') + } + + return t('ui.clipboardReadFailedError') + } + + return formatCompareError(event, t) +} + function setCaptureStatus(key: string, params: Record = {}): void { captureStatusKey.value = key captureStatusParams.value = params @@ -283,6 +321,7 @@ watch( size="small" :disabled="!canCompare" :loading="comparing" + :title="compareSelectedTip" data-testid="clipboard-compare" @click="compareClipboardHistory" >{{ $t('ui.compareSelected') }}{{ error }} @@ -364,15 +404,23 @@ watch(
+

+ {{ $t('ui.clipboardIdenticalHint') }} +

- {{ $t('ui.captureTwoClipboardTextsAndCompareThem') }} + {{ clipboardEmptyStateMessage }}