chunky based retrieve and search through entire db

This commit is contained in:
pandadev 2024-08-10 00:25:59 +02:00
parent 1e756f8e48
commit 654fec0fa8
No known key found for this signature in database
GPG key ID: C39629DACB8E762F
2 changed files with 89 additions and 43 deletions

114
app.vue
View file

@ -66,10 +66,13 @@ import { listen } from '@tauri-apps/api/event';
const db = ref(null); const db = ref(null);
const history = ref([]); const history = ref([]);
const chunkSize = 50;
let offset = 0;
let isLoading = false;
const resultsContainer = ref(null);
const searchQuery = ref(''); const searchQuery = ref('');
const selectedGroupIndex = ref(0); const selectedGroupIndex = ref(0);
const selectedItemIndex = ref(0); const selectedItemIndex = ref(0);
const resultsContainer = ref(null);
const selectedElement = ref(null); const selectedElement = ref(null);
const searchInput = ref(null); const searchInput = ref(null);
const os = platform(); const os = platform();
@ -133,9 +136,25 @@ const isSelected = (groupIndex, itemIndex) => {
return selectedGroupIndex.value === groupIndex && selectedItemIndex.value === itemIndex; return selectedGroupIndex.value === groupIndex && selectedItemIndex.value === itemIndex;
}; };
const searchHistory = () => { const searchHistory = async () => {
selectedGroupIndex.value = 0; if (!db.value) return;
selectedItemIndex.value = 0;
history.value = [];
offset = 0;
const query = `%${searchQuery.value}%`;
const results = await db.value.select(
'SELECT * FROM history WHERE content LIKE ? ORDER BY timestamp DESC LIMIT ?',
[query, chunkSize]
);
history.value = await Promise.all(results.map(async item => {
if (item.content_type === 'image') {
const dimensions = await getImageDimensions(item.content);
return { ...item, dimensions };
}
return item;
}));
}; };
const selectNext = () => { const selectNext = () => {
@ -260,42 +279,53 @@ const getImageUrl = async (path) => {
} }
}; };
const loadAllHistory = async () => { const loadHistoryChunk = async () => {
if (!db.value) return; if (!db.value || isLoading) return;
const rawHistory = await db.value.select( isLoading = true;
'SELECT * FROM history ORDER BY timestamp DESC' let results;
);
history.value = await Promise.all(rawHistory.map(async item => { if (searchQuery.value) {
const query = `%${searchQuery.value}%`;
results = await db.value.select(
'SELECT * FROM history WHERE content LIKE ? ORDER BY timestamp DESC LIMIT ? OFFSET ?',
[query, chunkSize, offset]
);
} else {
results = await db.value.select(
'SELECT * FROM history ORDER BY timestamp DESC LIMIT ? OFFSET ?',
[chunkSize, offset]
);
}
if (results.length === 0) {
isLoading = false;
return;
}
const processedChunk = await Promise.all(results.map(async item => {
if (item.content_type === 'image') { if (item.content_type === 'image') {
const dimensions = await getImageDimensions(item.content); const dimensions = await getImageDimensions(item.content);
return { ...item, dimensions }; return { ...item, dimensions };
} }
return item; return item;
})); }));
history.value = [...history.value, ...processedChunk];
offset += chunkSize;
isLoading = false;
}; };
onMounted(async () => { const handleScroll = () => {
db.value = await Database.load('sqlite:data.db'); if (!resultsContainer.value) return;
await loadAllHistory();
await listen('tauri://focus', async () => { const { viewport } = resultsContainer.value.osInstance().elements();
await loadAllHistory(); const { scrollTop, scrollHeight, clientHeight } = viewport;
focusSearchInput();
});
await listen('tauri://blur', () => { if (scrollHeight - scrollTop - clientHeight < 100) {
if (searchInput.value) { loadHistoryChunk();
searchInput.value.blur();
}
});
// autostart
if (!await isEnabled()) {
await enable()
} }
}); };
const hideApp = async () => { const hideApp = async () => {
await app.hide(); await app.hide();
@ -343,6 +373,36 @@ const scrollToSelectedItem = () => {
watch([selectedGroupIndex, selectedItemIndex], scrollToSelectedItem); watch([selectedGroupIndex, selectedItemIndex], scrollToSelectedItem);
watch(searchQuery, () => {
searchHistory();
});
onMounted(async () => {
db.value = await Database.load('sqlite:data.db');
await loadHistoryChunk();
if (resultsContainer.value) {
resultsContainer.value.osInstance().elements().viewport.addEventListener('scroll', handleScroll);
}
await listen('tauri://focus', async () => {
history.value = [];
offset = 0;
await loadHistoryChunk();
focusSearchInput();
});
await listen('tauri://blur', () => {
if (searchInput.value) {
searchInput.value.blur();
}
});
if (!await isEnabled()) {
await enable()
}
});
</script> </script>
<style lang="scss"> <style lang="scss">

View file

@ -219,17 +219,3 @@ pub fn start_monitor(app_handle: AppHandle) -> Result<(), String> {
app_handle.emit("plugin:clipboard://clipboard-monitor/status", true).map_err(|e| e.to_string())?; app_handle.emit("plugin:clipboard://clipboard-monitor/status", true).map_err(|e| e.to_string())?;
Ok(()) Ok(())
} }
#[tauri::command]
pub fn stop_monitor(app_handle: AppHandle) -> Result<(), String> {
let clipboard = app_handle.state::<Clipboard>();
clipboard.stop_monitor(app_handle.clone()).map_err(|e| e.to_string())?;
app_handle.emit("plugin:clipboard://clipboard-monitor/status", false).map_err(|e| e.to_string())?;
Ok(())
}
#[tauri::command]
pub fn is_monitor_running(app_handle: AppHandle) -> bool {
let clipboard = app_handle.state::<Clipboard>();
clipboard.is_monitor_running()
}