chore: Added new settings to configure which items to preserve when clearing clipboard history, including options to retain pinned and starred items during both manual and automatic clear operations.

This commit is contained in:
Sergey Kurdin 2025-06-18 21:18:17 -04:00
parent 4a722d494f
commit 64bdb03781
25 changed files with 411 additions and 45 deletions

View File

@ -0,0 +1,5 @@
---
'pastebar-app-ui': patch
---
Added settings to preserve pinned and starred items when clearing clipboard history

View File

@ -212,6 +212,10 @@ function App() {
isSingleClickToCopyPaste: settings.isSingleClickToCopyPaste?.valueBool ?? false,
isSingleClickToCopyPasteQuickWindow:
settings.isSingleClickToCopyPasteQuickWindow?.valueBool ?? false,
isKeepPinnedOnClearEnabled:
settings.isKeepPinnedOnClearEnabled?.valueBool ?? false,
isKeepStarredOnClearEnabled:
settings.isKeepStarredOnClearEnabled?.valueBool ?? false,
isAppReady: true,
})
settingsStore.initConstants({

View File

@ -372,7 +372,12 @@ export function useDeleteClipboardHistoryByIds() {
export function useClearClipboardHistoryOlderThan() {
const queryClient = useQueryClient()
const { mutate: clearClipboardHistoryOlderThan } = useInvokeMutation<
{ durationType: string; olderThen: string },
{
durationType: string
olderThen: string
keepPinned?: boolean
keepStarred?: boolean
},
UniqueIdentifier
>('clear_clipboard_history_older_than', {
onSuccess: data => {
@ -398,7 +403,12 @@ export function useClearClipboardHistoryOlderThan() {
export function useClearRecentClipboardHistory() {
const queryClient = useQueryClient()
const { mutate: clearRecentClipboardHistory } = useInvokeMutation<
{ durationType: string; duration: string },
{
durationType: string
duration: string
keepPinned?: boolean
keepStarred?: boolean
},
UniqueIdentifier
>('clear_recent_clipboard_history', {
onSuccess: data => {

View File

@ -10,6 +10,7 @@ Clear History: Verlauf löschen
Confirm Clear All History: Gesamten Verlauf löschen bestätigen
Do you really want to remove ALL clipboard history items?: Möchten Sie wirklich ALLE Zwischenablage-Verlaufselemente entfernen?
Do you want to remove clipboard history items older than {{olderThen}} {{durationType}}: Möchten Sie Zwischenablage-Verlaufselemente älter als {{olderThen}} {{durationType}} entfernen?
Do you want to remove all recent clipboard history older than {{olderThen}} {{durationType}}: Möchten Sie alle kürzlichen Zwischenablage-Verlaufselemente entfernen, die älter als {{olderThen}} {{durationType}} sind?
Enable Capture History: Verlaufserfassung aktivieren
Enable Image Capture: Bilderfassung aktivieren
Filters:

View File

@ -58,3 +58,9 @@ When enabled, the Quick Paste window will automatically close after copying or p
: Wenn aktiviert, werden beim Klicken oder Drücken der Eingabetaste auf Elemente im Schnelleinfügen-Fenster diese nur in die Zwischenablage kopiert, ohne sie automatisch einzufügen.
? When enabled, single click will copy/paste items in Quick Paste window. If global single click is also enabled, both settings work together.
: Wenn aktiviert, werden Elemente im Schnelleinfügen-Fenster mit einem einfachen Klick kopiert/eingefügt. Wenn globaler Einfachklick ebenfalls aktiviert ist, funktionieren beide Einstellungen zusammen.
Configure which items to preserve when clearing clipboard history (both manual and auto-clear operations).: Konfigurieren Sie, welche Elemente beim Löschen des Zwischenablageverlaufs beibehalten werden sollen (sowohl manuell als auch automatisch).
Keep Items on Clear: Elemente beim Löschen beibehalten
Keep Pinned Items: Angehängte Elemente beibehalten
Keep Starred Items: Mit Stern markierte Elemente beibehalten
Preserve pinned items when clearing history: Angehängte Elemente beim Löschen des Verlaufs beibehalten
Preserve starred items when clearing history: Mit Stern markierte Elemente beim Löschen des Verlaufs beibehalten

View File

@ -9,6 +9,7 @@ Clear All History: Clear All History
Clear History: Clear History
Confirm Clear All History: Confirm Clear All History
Do you really want to remove ALL clipboard history items?: Do you really want to remove ALL clipboard history items?
Do you want to remove all recent clipboard history older than {{olderThen}} {{durationType}}: Do you want to remove all recent clipboard history older than {{olderThen}} {{durationType}}
Do you want to remove clipboard history items older than {{olderThen}} {{durationType}}: Do you want to remove clipboard history items older than {{olderThen}} {{durationType}}
Enable Capture History: Enable Capture History
Enable Image Capture: Enable Image Capture

View File

@ -60,3 +60,9 @@ This sets the default icon type for new clips with notes. You can customize indi
: When enabled, clicking or pressing Enter on items in Quick Paste window will only copy them to clipboard without automatically pasting.
? When enabled, single click will copy/paste items in Quick Paste window. If global single click is also enabled, both settings work together.
: When enabled, single click will copy/paste items in Quick Paste window. If global single click is also enabled, both settings work together.
Configure which items to preserve when clearing clipboard history (both manual and auto-clear operations).: Configure which items to preserve when clearing clipboard history (both manual and auto-clear operations).
Keep Items on Clear: Keep Items on Clear
Keep Pinned Items: Keep Pinned Items
Keep Starred Items: Keep Starred Items
Preserve pinned items when clearing history: Preserve pinned items when clearing history
Preserve starred items when clearing history: Preserve starred items when clearing history

View File

@ -10,6 +10,7 @@ Clear History: Borrar Historial
Confirm Clear All History: Confirmar Borrar Todo el Historial
Do you really want to remove ALL clipboard history items?: ¿Realmente quieres eliminar TODOS los elementos del historial?
Do you want to remove clipboard history items older than {{olderThen}} {{durationType}}: ¿Quieres eliminar los elementos del historial más antiguos que {{olderThen}} {{durationType}}?
Do you want to remove all recent clipboard history older than {{olderThen}} {{durationType}}: ¿Quieres eliminar todos los elementos recientes del historial del portapapeles anteriores a {{olderThen}} {{durationType}}?
Enable Capture History: Habilitar Captura de Historial
Enable Image Capture: Habilitar Captura de Imágenes
Filters:

View File

@ -58,3 +58,9 @@ This sets the default icon type for new clips with notes. You can customize indi
: Cuando está habilitado, hacer clic o presionar Enter en elementos de la ventana de pegado rápido solo los copiará al portapapeles sin pegarlos automáticamente.
? When enabled, single click will copy/paste items in Quick Paste window. If global single click is also enabled, both settings work together.
: Cuando está habilitado, el clic simple copiará/pegará elementos en la ventana de pegado rápido. Si el clic simple global también está habilitado, ambas configuraciones funcionan juntas.
Configure which items to preserve when clearing clipboard history (both manual and auto-clear operations).: Configure qué elementos conservar al borrar el historial del portapapeles (tanto manual como automáticamente).
Keep Items on Clear: Conservar elementos al borrar
Keep Pinned Items: Conservar elementos fijados
Keep Starred Items: Conservar elementos destacados
Preserve pinned items when clearing history: Conservar elementos fijados al borrar el historial
Preserve starred items when clearing history: Conservar elementos destacados al borrar el historial

View File

@ -10,6 +10,7 @@ Clear History: Effacer l'historique
Confirm Clear All History: Confirmer l'effacement de tout l'historique
Do you really want to remove ALL clipboard history items?: Voulez-vous vraiment supprimer TOUS les éléments de l'historique du presse-papier ?
Do you want to remove clipboard history items older than {{olderThen}} {{durationType}}: Voulez-vous supprimer les éléments de l'historique du presse-papier antérieurs à {{olderThen}} {{durationType}}
Do you want to remove all recent clipboard history older than {{olderThen}} {{durationType}}: Voulez-vous supprimer tous les éléments récents de l'historique du presse-papiers antérieurs à {{olderThen}} {{durationType}} ?
Enable Capture History: Activer la capture de l'historique
Enable Image Capture: Activer la capture d'images
Filters:

View File

@ -58,3 +58,9 @@ This sets the default icon type for new clips with notes. You can customize indi
: Lorsqu'activé, cliquer ou appuyer sur Entrée sur les éléments dans la fenêtre de collage rapide les copiera uniquement dans le presse-papiers sans les coller automatiquement.
? When enabled, single click will copy/paste items in Quick Paste window. If global single click is also enabled, both settings work together.
: Lorsqu'activé, un clic simple copiera/collera les éléments dans la fenêtre de collage rapide. Si le clic simple global est également activé, les deux paramètres fonctionnent ensemble.
Configure which items to preserve when clearing clipboard history (both manual and auto-clear operations).: Configurez les éléments à conserver lors de l'effacement de l'historique du presse-papiers (manuellement ou automatiquement).
Keep Items on Clear: Conserver les éléments lors de l'effacement
Keep Pinned Items: Conserver les éléments épinglés
Keep Starred Items: Conserver les éléments favoris
Preserve pinned items when clearing history: Conserver les éléments épinglés lors de l'effacement de l'historique
Preserve starred items when clearing history: Conserver les éléments favoris lors de l'effacement de l'historique

View File

@ -10,6 +10,7 @@ Clear History: Cancella Cronologia
Confirm Clear All History: Conferma Cancellazione di Tutta la Cronologia
Do you really want to remove ALL clipboard history items?: Vuoi davvero rimuovere TUTTI gli elementi della cronologia degli appunti?
Do you want to remove clipboard history items older than {{olderThen}} {{durationType}}: Vuoi rimuovere gli elementi della cronologia degli appunti più vecchi di {{olderThen}} {{durationType}}
Do you want to remove all recent clipboard history older than {{olderThen}} {{durationType}}: Vuoi rimuovere tutti gli elementi recenti della cronologia degli appunti più vecchi di {{olderThen}} {{durationType}}?
Enable Capture History: Abilita Cattura Cronologia
Enable Image Capture: Abilita Cattura Immagini
Filters:

View File

@ -58,3 +58,9 @@ This sets the default icon type for new clips with notes. You can customize indi
: Quando abilitato, cliccando o premendo Invio sugli elementi nella finestra incolla rapido li copierà solo negli appunti senza incollarli automaticamente.
? When enabled, single click will copy/paste items in Quick Paste window. If global single click is also enabled, both settings work together.
: Quando abilitato, il clic singolo copierà/incollerà elementi nella finestra incolla rapido. Se anche il clic singolo globale è abilitato, entrambe le impostazioni funzionano insieme.
Configure which items to preserve when clearing clipboard history (both manual and auto-clear operations).: Configura quali elementi conservare durante la cancellazione della cronologia degli appunti (sia manuale che automatica).
Keep Items on Clear: Conserva elementi durante la cancellazione
Keep Pinned Items: Conserva elementi fissati
Keep Starred Items: Conserva elementi preferiti
Preserve pinned items when clearing history: Conserva elementi fissati durante la cancellazione della cronologia
Preserve starred items when clearing history: Conserva elementi preferiti durante la cancellazione della cronologia

View File

@ -58,3 +58,9 @@ This sets the default icon type for new clips with notes. You can customize indi
: Когда включено, нажатие или нажатие Enter на элементы в окне быстрой вставки будет только копировать их в буфер обмена без автоматической вставки.
? When enabled, single click will copy/paste items in Quick Paste window. If global single click is also enabled, both settings work together.
: Когда включено, одним кликом будут копироваться/вставляться элементы в окне быстрой вставки. Если глобальный одиночный клик также включен, обе настройки работают вместе.
Configure which items to preserve when clearing clipboard history (both manual and auto-clear operations).: Настройте, какие элементы сохранять при очистке истории буфера обмена (как вручную, так и автоматически).
Keep Items on Clear: Сохранять элементы при очистке
Keep Pinned Items: Сохранять закрепленные элементы
Keep Starred Items: Сохранять избранные элементы
Preserve pinned items when clearing history: Сохранять закрепленные элементы при очистке истории
Preserve starred items when clearing history: Сохранять избранные элементы при очистке истории

View File

@ -10,6 +10,7 @@ Clear History: Geçmişi Temizle
Confirm Clear All History: Tüm Geçmişi Temizle'yi Onayla
Do you really want to remove ALL clipboard history items?: Gerçekten TÜM pano geçmişi öğelerini kaldırmak istiyormusunuz?
Do you want to remove clipboard history items older than {{olderThen}} {{durationType}}: Şu tarihten önceki pano geçmişi öğelerini kaldırmak ister misiniz? {{olderThen}} {{durationType}}
Do you want to remove all recent clipboard history older than {{olderThen}} {{durationType}}: {{olderThen}} {{durationType}} tarihinden önceki tüm son pano geçmişi öğelerini kaldırmak istiyor musunuz?
Enable Capture History: Yakalama Geçmişini Etkinleştir
Enable Image Capture: Görüntü Yakalamayı Etkinleştir
Filters:

View File

@ -58,3 +58,9 @@ This sets the default icon type for new clips with notes. You can customize indi
: Etkinleştirildiğinde, Hızlı Yapıştır penceresindeki öğelere tıklamak veya Enter tuşuna basmak bunları otomatik olarak yapıştırmadan yalnızca panoya kopyalar.
? When enabled, single click will copy/paste items in Quick Paste window. If global single click is also enabled, both settings work together.
: Etkinleştirildiğinde, tek tıklama Hızlı Yapıştır penceresindeki öğeleri kopyalar/yapıştırır. Global tek tıklama da etkinleştirilmişse, her iki ayar birlikte çalışır.
Configure which items to preserve when clearing clipboard history (both manual and auto-clear operations).: Pano geçmişini temizlerken hangi öğelerin korunacağını yapılandırın (hem manuel hem de otomatik temizleme işlemleri).
Keep Items on Clear: Temizlerken öğeleri koru
Keep Pinned Items: Sabitlenmiş öğeleri koru
Keep Starred Items: Favorilenmiş öğeleri koru
Preserve pinned items when clearing history: Geçmişi temizlerken sabitlenmiş öğeleri koru
Preserve starred items when clearing history: Geçmişi temizlerken favorilenmiş öğeleri koru

View File

@ -58,3 +58,9 @@ This sets the default icon type for new clips with notes. You can customize indi
: Коли увімкнено, натискання або натискання Enter на елементи у вікні швидкої вставки буде тільки копіювати їх до буфера обміну без автоматичної вставки.
? When enabled, single click will copy/paste items in Quick Paste window. If global single click is also enabled, both settings work together.
: Коли увімкнено, одним кліком будуть копіюватися/вставлятися елементи у вікні швидкої вставки. Якщо глобальний одиночний клік також увімкнено, обидва налаштування працюють разом.
Configure which items to preserve when clearing clipboard history (both manual and auto-clear operations).: Налаштуйте, які елементи зберігати під час очищення історії буфера обміну (як вручну, так і автоматично).
Keep Items on Clear: Зберігати елементи під час очищення
Keep Pinned Items: Зберігати закріплені елементи
Keep Starred Items: Зберігати обрані елементи
Preserve pinned items when clearing history: Зберігати закріплені елементи під час очищення історії
Preserve starred items when clearing history: Зберігати обрані елементи під час очищення історії

View File

@ -10,6 +10,7 @@ Clear History: 清除历史
Confirm Clear All History: 确认清除所有历史
Do you really want to remove ALL clipboard history items?: 确定要删除所有剪贴板历史记录吗?
'Do you want to remove clipboard history items older than {{olderThen}} {{durationType}}': 您想删除早于 {{olderThen}} {{durationType}} 的剪贴板历史项目吗
Do you want to remove all recent clipboard history older than {{olderThen}} {{durationType}}: 您是否要删除早于 {{olderThen}} {{durationType}} 的所有最近剪贴板历史记录?
Enable Capture History: 启用捕获历史
Enable Image Capture: 启用图像捕获
Filters:

View File

@ -58,3 +58,9 @@ This sets the default icon type for new clips with notes. You can customize indi
: 启用后在快速粘贴窗口中点击或按Enter键只会将项目复制到剪贴板而不会自动粘贴。
? When enabled, single click will copy/paste items in Quick Paste window. If global single click is also enabled, both settings work together.
: 启用后,单击将在快速粘贴窗口中复制/粘贴项目。如果全局单击也启用了,两个设置会一起工作。
Configure which items to preserve when clearing clipboard history (both manual and auto-clear operations).: 配置在清除剪贴板历史记录时要保留的项目(包括手动和自动清除操作)。
Keep Items on Clear: 清除时保留项目
Keep Pinned Items: 保留已固定项目
Keep Starred Items: 保留已星标项目
Preserve pinned items when clearing history: 清除历史记录时保留已固定项目
Preserve starred items when clearing history: 清除历史记录时保留已星标项目

View File

@ -77,6 +77,8 @@ export const ClipboardHistoryIconMenu = ({
setIsHistoryEnabled,
isHistoryAutoUpdateOnCaputureEnabled,
setIsHistoryAutoUpdateOnCaputureEnabled,
isKeepPinnedOnClearEnabled,
isKeepStarredOnClearEnabled,
} = useAtomValue(settingsStoreAtom)
useHotkeys(['alt+s'], () => {
@ -179,9 +181,19 @@ export const ClipboardHistoryIconMenu = ({
}
}
if (isRecent) {
await clearRecentClipboardHistory({ durationType, duration: olderThen })
await clearRecentClipboardHistory({
durationType,
duration: olderThen,
keepPinned: isKeepPinnedOnClearEnabled,
keepStarred: isKeepStarredOnClearEnabled
})
} else {
await clearClipboardHistoryOlderThan({ durationType, olderThen })
await clearClipboardHistoryOlderThan({
durationType,
olderThen,
keepPinned: isKeepPinnedOnClearEnabled,
keepStarred: isKeepStarredOnClearEnabled
})
}
setTimeout(() => {
setSelectedHistoryItems([])

View File

@ -125,6 +125,10 @@ export default function ClipboardHistorySettings() {
setAutoClearSettingsDuration,
autoClearSettingsDurationType,
setAutoClearSettingsDurationType,
isKeepPinnedOnClearEnabled,
setIsKeepPinnedOnClearEnabled,
isKeepStarredOnClearEnabled,
setIsKeepStarredOnClearEnabled,
isAppReady,
CONST: { APP_DETECT_LANGUAGES_SUPPORTED: languageList },
} = useAtomValue(settingsStoreAtom)
@ -984,6 +988,62 @@ export default function ClipboardHistorySettings() {
</Card>
</Box>
<Box className="mt-4 max-w-xl animate-in fade-in">
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-1">
<CardTitle className="animate-in fade-in text-md font-medium w-full">
{t('Keep Items on Clear', { ns: 'settings2' })}
</CardTitle>
</CardHeader>
<CardContent>
<Text className="text-sm text-muted-foreground mb-4">
{t(
'Configure which items to preserve when clearing clipboard history (both manual and auto-clear operations).',
{ ns: 'settings' }
)}
</Text>
<Flex className="flex-col gap-4">
<Flex className="items-center justify-between w-full">
<Flex className="flex-col justify-start items-start">
<Text className="text-[15px] font-semibold">
{t('Keep Pinned Items', { ns: 'settings2' })}
</Text>
<Text className="text-xs text-muted-foreground">
{t('Preserve pinned items when clearing history', {
ns: 'settings2',
})}
</Text>
</Flex>
<Switch
checked={isKeepPinnedOnClearEnabled}
onCheckedChange={checked => {
setIsKeepPinnedOnClearEnabled(checked)
}}
/>
</Flex>
<Flex className="items-center justify-between w-full">
<Flex className="flex-col justify-start items-start">
<Text className="text-[15px] font-semibold">
{t('Keep Starred Items', { ns: 'settings2' })}
</Text>
<Text className="text-xs text-muted-foreground">
{t('Preserve starred items when clearing history', {
ns: 'settings2',
})}
</Text>
</Flex>
<Switch
checked={isKeepStarredOnClearEnabled}
onCheckedChange={checked => {
setIsKeepStarredOnClearEnabled(checked)
}}
/>
</Flex>
</Flex>
</CardContent>
</Card>
</Box>
<Spacer h={6} />
<Link to={returnRoute} replace>

View File

@ -101,6 +101,8 @@ type Settings = {
isSingleClickToCopyPasteQuickWindow: boolean
isQuickPasteCopyOnly: boolean
isQuickPasteAutoClose: boolean
isKeepPinnedOnClearEnabled: boolean
isKeepStarredOnClearEnabled: boolean
}
type Constants = {
@ -188,6 +190,8 @@ export interface SettingsStoreState {
setIsQuickPasteAutoClose: (isEnabled: boolean) => void
setIsSingleClickToCopyPaste: (isEnabled: boolean) => void
setIsSingleClickToCopyPasteQuickWindow: (isEnabled: boolean) => void
setIsKeepPinnedOnClearEnabled: (isEnabled: boolean) => void
setIsKeepStarredOnClearEnabled: (isEnabled: boolean) => void
hashPassword: (pass: string) => Promise<string>
isNotTourCompletedOrSkipped: (tourName: string) => boolean
verifyPassword: (pass: string, hash: string) => Promise<boolean>
@ -284,6 +288,8 @@ const initialState: SettingsStoreState & Settings = {
isSingleClickToCopyPasteQuickWindow: false,
isQuickPasteCopyOnly: false,
isQuickPasteAutoClose: true,
isKeepPinnedOnClearEnabled: false,
isKeepStarredOnClearEnabled: false,
CONST: {
APP_DETECT_LANGUAGES_SUPPORTED: [],
},
@ -353,6 +359,8 @@ const initialState: SettingsStoreState & Settings = {
setIsSingleClickToCopyPasteQuickWindow: () => {},
setIsQuickPasteCopyOnly: () => {},
setIsQuickPasteAutoClose: () => {},
setIsKeepPinnedOnClearEnabled: () => {},
setIsKeepStarredOnClearEnabled: () => {},
initConstants: () => {},
setAppDataDir: () => {}, // Keep if used for other general app data
setCustomDbPath: () => {},
@ -737,6 +745,14 @@ export const settingsStore = createStore<SettingsStoreState & Settings>()((set,
get().syncStateUpdate('isQuickPasteAutoClose', isEnabled)
return get().updateSetting('isQuickPasteAutoClose', isEnabled)
},
setIsKeepPinnedOnClearEnabled: async (isEnabled: boolean) => {
get().syncStateUpdate('isKeepPinnedOnClearEnabled', isEnabled)
return get().updateSetting('isKeepPinnedOnClearEnabled', isEnabled)
},
setIsKeepStarredOnClearEnabled: async (isEnabled: boolean) => {
get().syncStateUpdate('isKeepStarredOnClearEnabled', isEnabled)
return get().updateSetting('isKeepStarredOnClearEnabled', isEnabled)
},
isNotTourCompletedOrSkipped: (tourName: string) => {
const { appToursCompletedList, appToursSkippedList } = get()
return (

View File

@ -139,7 +139,12 @@ pub fn get_clipboard_histories_within_date_range(
}
#[tauri::command]
pub fn clear_clipboard_history_older_than(duration_type: String, older_then: String) -> String {
pub fn clear_clipboard_history_older_than(
duration_type: String,
older_then: String,
keep_pinned: Option<bool>,
keep_starred: Option<bool>,
) -> String {
// Convert older_then string to an integer.
let duration_value: i64 = older_then.parse().unwrap_or(0);
@ -148,24 +153,43 @@ pub fn clear_clipboard_history_older_than(duration_type: String, older_then: Str
duration_value, duration_type
);
let keep_pinned = keep_pinned.unwrap_or(false);
let keep_starred = keep_starred.unwrap_or(false);
match duration_type.as_str() {
"days" => {
if duration_value == 0 {
history_service::delete_all_clipboard_histories();
history_service::delete_all_clipboard_histories(keep_pinned, keep_starred);
} else {
history_service::delete_clipboard_history_older_than(Duration::days(duration_value));
history_service::delete_clipboard_history_older_than(
Duration::days(duration_value),
keep_pinned,
keep_starred,
);
}
}
"weeks" => {
history_service::delete_clipboard_history_older_than(Duration::weeks(duration_value));
history_service::delete_clipboard_history_older_than(
Duration::weeks(duration_value),
keep_pinned,
keep_starred,
);
}
"months" => {
// Roughly considering a month as 4 weeks.
history_service::delete_clipboard_history_older_than(Duration::days(30 * duration_value));
history_service::delete_clipboard_history_older_than(
Duration::days(30 * duration_value),
keep_pinned,
keep_starred,
);
}
"year" => {
// Roughly considering a year as 52 weeks.
history_service::delete_clipboard_history_older_than(Duration::days(356 * duration_value));
history_service::delete_clipboard_history_older_than(
Duration::days(356 * duration_value),
keep_pinned,
keep_starred,
);
}
_ => {
println!("Unsupported duration type: {}", duration_type);
@ -177,8 +201,15 @@ pub fn clear_clipboard_history_older_than(duration_type: String, older_then: Str
}
#[tauri::command]
pub fn clear_recent_clipboard_history(duration_type: String, duration: String) -> String {
pub fn clear_recent_clipboard_history(
duration_type: String,
duration: String,
keep_pinned: Option<bool>,
keep_starred: Option<bool>,
) -> String {
let duration_value: i64 = duration.parse().unwrap_or(0);
let keep_pinned = keep_pinned.unwrap_or(false);
let keep_starred = keep_starred.unwrap_or(false);
println!(
"Clearing recent clipboard history for last {} {}",
@ -187,19 +218,39 @@ pub fn clear_recent_clipboard_history(duration_type: String, duration: String) -
match duration_type.as_str() {
"hour" => {
history_service::delete_recent_clipboard_history(Duration::hours(duration_value));
history_service::delete_recent_clipboard_history(
Duration::hours(duration_value),
keep_pinned,
keep_starred,
);
}
"days" => {
history_service::delete_recent_clipboard_history(Duration::days(duration_value));
history_service::delete_recent_clipboard_history(
Duration::days(duration_value),
keep_pinned,
keep_starred,
);
}
"weeks" => {
history_service::delete_recent_clipboard_history(Duration::weeks(duration_value));
history_service::delete_recent_clipboard_history(
Duration::weeks(duration_value),
keep_pinned,
keep_starred,
);
}
"months" => {
history_service::delete_recent_clipboard_history(Duration::days(30 * duration_value));
history_service::delete_recent_clipboard_history(
Duration::days(30 * duration_value),
keep_pinned,
keep_starred,
);
}
"year" => {
history_service::delete_recent_clipboard_history(Duration::days(356 * duration_value));
history_service::delete_recent_clipboard_history(
Duration::days(356 * duration_value),
keep_pinned,
keep_starred,
);
}
_ => {
println!("Unsupported duration type: {}", duration_type);

View File

@ -34,8 +34,22 @@ fn run_history_cleanup_job() {
.and_then(|s| s.value_int)
.unwrap_or(1);
let deleted_count =
history_commands::clear_clipboard_history_older_than(duration_type, duration.to_string());
let keep_pinned = locked_settings
.get("isKeepPinnedOnClearEnabled")
.and_then(|s| s.value_bool)
.unwrap_or(false);
let keep_starred = locked_settings
.get("isKeepStarredOnClearEnabled")
.and_then(|s| s.value_bool)
.unwrap_or(false);
let deleted_count = history_commands::clear_clipboard_history_older_than(
duration_type,
duration.to_string(),
Some(keep_pinned),
Some(keep_starred)
);
debug_output(|| {
println!("Deleted {} items from clipboard history", deleted_count);

View File

@ -289,10 +289,11 @@ pub fn add_clipboard_history_from_image(
let _ = image.save(&image_file_name);
// Convert absolute path to relative path before storing
let relative_image_path = image_file_name.to_str()
let relative_image_path = image_file_name
.to_str()
.map(|path| db::to_relative_image_path(path))
.unwrap_or_default();
let new_history = create_new_history(
_history_id,
_image_data_low_res,
@ -640,19 +641,36 @@ pub fn get_clipboard_history_by_id(history_id_value: &String) -> Option<Clipboar
// Transform image path for frontend consumption
result.transform_image_path_for_frontend();
Some(result)
}
pub fn delete_clipboard_history_older_than(age: Duration) -> Result<String, diesel::result::Error> {
pub fn delete_clipboard_history_older_than(
age: Duration,
keep_pinned: bool,
keep_starred: bool,
) -> Result<String, diesel::result::Error> {
let connection = &mut establish_pool_db_connection();
let now = Utc::now().timestamp_millis();
let threshold_timestamp = now - age.num_milliseconds();
// Build filter conditions
let mut filter_conditions = clipboard_history::table
.filter(updated_at.lt(threshold_timestamp))
.into_boxed();
if keep_pinned {
filter_conditions = filter_conditions.filter(is_pinned.ne(true).or(is_pinned.is_null()));
}
if keep_starred {
filter_conditions = filter_conditions.filter(is_favorite.ne(true).or(is_favorite.is_null()));
}
// Handle image files
let image_items_to_delete = clipboard_history::table
.filter(updated_at.lt(threshold_timestamp).and(is_image.eq(true)))
let image_items_to_delete = filter_conditions
.filter(is_image.eq(true))
.load::<ClipboardHistory>(connection)?;
for item in image_items_to_delete.iter() {
@ -663,9 +681,23 @@ pub fn delete_clipboard_history_older_than(age: Duration) -> Result<String, dies
}
}
// Handle link items
let links_items_to_delete = clipboard_history::table
.filter(updated_at.lt(threshold_timestamp).and(is_link.eq(true)))
// Handle link items - rebuild filter conditions for links
let mut link_filter_conditions = clipboard_history::table
.filter(updated_at.lt(threshold_timestamp))
.into_boxed();
if keep_pinned {
link_filter_conditions =
link_filter_conditions.filter(is_pinned.ne(true).or(is_pinned.is_null()));
}
if keep_starred {
link_filter_conditions =
link_filter_conditions.filter(is_favorite.ne(true).or(is_favorite.is_null()));
}
let links_items_to_delete = link_filter_conditions
.filter(is_link.eq(true))
.load::<ClipboardHistory>(connection)?;
let history_ids_to_delete: Vec<String> = links_items_to_delete
@ -673,10 +705,29 @@ pub fn delete_clipboard_history_older_than(age: Duration) -> Result<String, dies
.map(|item| item.history_id.clone())
.collect();
// Perform the main delete operation
let deleted_count =
diesel::delete(clipboard_history::table.filter(updated_at.lt(threshold_timestamp)))
.execute(connection)?;
// Get the IDs to delete based on filters for the main deletion
let ids_to_delete: Vec<String> = {
let mut query = clipboard_history::table
.filter(updated_at.lt(threshold_timestamp))
.select(history_id)
.into_boxed();
if keep_pinned {
query = query.filter(is_pinned.ne(true).or(is_pinned.is_null()));
}
if keep_starred {
query = query.filter(is_favorite.ne(true).or(is_favorite.is_null()));
}
query.load::<String>(connection)?
};
let deleted_count = if !ids_to_delete.is_empty() {
diesel::delete(clipboard_history.filter(history_id.eq_any(&ids_to_delete))).execute(connection)?
} else {
0
};
// Delete associated link metadata
delete_link_metadata_by_history_ids(&history_ids_to_delete);
@ -686,16 +737,29 @@ pub fn delete_clipboard_history_older_than(age: Duration) -> Result<String, dies
pub fn delete_recent_clipboard_history(
delete_duration: Duration,
keep_pinned: bool,
keep_starred: bool,
) -> Result<String, diesel::result::Error> {
let connection = &mut establish_pool_db_connection();
let now = Utc::now().timestamp_millis();
let delete_threshold = now - delete_duration.num_milliseconds();
// Find records to delete (newer than delete_threshold)
let records_to_delete = clipboard_history::table
// Build filter conditions for recent records
let mut filter_conditions = clipboard_history::table
.filter(updated_at.gt(delete_threshold))
.load::<ClipboardHistory>(connection)?;
.into_boxed();
if keep_pinned {
filter_conditions = filter_conditions.filter(is_pinned.ne(true).or(is_pinned.is_null()));
}
if keep_starred {
filter_conditions = filter_conditions.filter(is_favorite.ne(true).or(is_favorite.is_null()));
}
// Find records to delete (newer than delete_threshold)
let records_to_delete = filter_conditions.load::<ClipboardHistory>(connection)?;
// Handle image files
let image_items: Vec<&ClipboardHistory> = records_to_delete
@ -722,10 +786,29 @@ pub fn delete_recent_clipboard_history(
.map(|item| item.history_id.clone())
.collect();
// Perform the main delete operation
let deleted_count =
diesel::delete(clipboard_history::table.filter(updated_at.gt(delete_threshold)))
.execute(connection)?;
// Get the IDs to delete based on filters for recent deletion
let ids_to_delete_recent: Vec<String> = {
let mut query = clipboard_history::table
.filter(updated_at.gt(delete_threshold))
.select(history_id)
.into_boxed();
if keep_pinned {
query = query.filter(is_pinned.ne(true).or(is_pinned.is_null()));
}
if keep_starred {
query = query.filter(is_favorite.ne(true).or(is_favorite.is_null()));
}
query.load::<String>(connection)?
};
let deleted_count = if !ids_to_delete_recent.is_empty() {
diesel::delete(clipboard_history.filter(history_id.eq_any(&ids_to_delete_recent))).execute(connection)?
} else {
0
};
// Delete associated link metadata
delete_link_metadata_by_history_ids(&history_ids_to_delete);
@ -736,18 +819,68 @@ pub fn delete_recent_clipboard_history(
))
}
pub fn delete_all_clipboard_histories() -> String {
pub fn delete_all_clipboard_histories(keep_pinned: bool, keep_starred: bool) -> String {
let connection = &mut establish_pool_db_connection();
let folder_path = db::get_clipboard_images_dir();
if !keep_pinned && !keep_starred {
// Delete everything - original behavior
let folder_path = db::get_clipboard_images_dir();
let _ = remove_dir_if_exists(&folder_path);
let _ = diesel::delete(clipboard_history)
.execute(connection)
.expect("Error deleting all clipboard histories");
delete_all_link_metadata_with_history_ids();
} else {
// Selective deletion - preserve pinned and/or starred items
// First, get all items that will be deleted
let mut items_query = clipboard_history.into_boxed();
if keep_pinned {
items_query = items_query.filter(is_pinned.ne(true).or(is_pinned.is_null()));
}
if keep_starred {
items_query = items_query.filter(is_favorite.ne(true).or(is_favorite.is_null()));
}
let _ = remove_dir_if_exists(&folder_path);
// Get items to delete for image and link cleanup
let items_to_delete = items_query
.load::<ClipboardHistory>(connection)
.expect("Error loading items to delete");
let _ = diesel::delete(clipboard_history)
.execute(connection)
.expect("Error deleting all clipboard histories");
// Delete image files for items being deleted
for item in items_to_delete.iter() {
if item.is_image == Some(true) {
if let Some(ref path) = item.image_path_full_res {
if let Err(e) = delete_file_and_maybe_parent(&Path::new(path)) {
eprintln!("Error deleting image file {}: {}", path, e);
}
}
}
}
delete_all_link_metadata_with_history_ids();
// Get history IDs for link metadata cleanup
let history_ids_to_delete: Vec<String> = items_to_delete
.iter()
.filter(|item| item.is_link == Some(true))
.map(|item| item.history_id.clone())
.collect();
// Delete the filtered records by ID
let item_ids_to_delete: Vec<String> = items_to_delete
.iter()
.map(|item| item.history_id.clone())
.collect();
if !item_ids_to_delete.is_empty() {
let _ = diesel::delete(clipboard_history.filter(history_id.eq_any(&item_ids_to_delete)))
.execute(connection)
.expect("Error deleting filtered clipboard histories");
}
// Delete associated link metadata
delete_link_metadata_by_history_ids(&history_ids_to_delete);
}
"ok".to_string()
}