Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions client/platform/desktop/frontend/components/Settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,9 @@ export default defineComponent({
<v-card-title>Synchronize Recents</v-card-title>
<v-card-subtitle v-if="settings">
Scan project directory (<b><u>{{ settings.dataPath }}</u></b>) to rediscover
datasets and update Recents page. This is useful if you've manually deleted or moved
dataset folders around. DIVE Desktop stores annotation files, metadata, and possibly
datasets and update Recents. Missing or invalid project folders are removed from
Recents; existing access times are preserved. Useful if you've manually deleted or
moved dataset folders. DIVE Desktop stores annotation files, metadata, and possibly
trancoded copies of your source media here.
<browser-link
display="inline"
Expand Down
29 changes: 21 additions & 8 deletions client/platform/desktop/frontend/store/dataset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,29 @@ function clearRecents() {
window.localStorage.setItem(RecentsKey, JSON.stringify([]));
}

/**
* Sync Recents with project folders on disk.
*
* Removes cache entries whose project dirs are missing or invalid, adds newly
* discovered datasets, and refreshes metadata for existing ones while
* preserving each entry's accessedAt timestamp.
*/
async function autoDiscover() {
clearRecents();
/* Make sure settings are ready on backend */
await initializedSettings;
/* Nothing came from localStorage, try to populate from autodiscovery */
const discovered: JsonConfig[] = await window.diveDesktop.invoke('autodiscover-data');
discovered.forEach((d) => setRecents(d));
const discoveredIds = new Set(discovered.map((d) => d.id));

Object.keys(datasets.value).forEach((id) => {
if (!discoveredIds.has(id)) {
removeRecents(id);
}
});

discovered.forEach((d) => {
const existing = datasets.value[d.id];
setRecents(d, existing?.accessedAt);
});
}

/**
Expand All @@ -91,7 +107,6 @@ async function autoDiscover() {
* loadConfig() backend method.
*/
async function load() {
let loaded = [];
try {
const arr = window.localStorage.getItem(RecentsKey);
if (arr) {
Expand All @@ -100,15 +115,13 @@ async function load() {
maybeArr.forEach((meta: JsonConfigCache) => (
Vue.set(datasets.value, meta.id, hydrateJsonConfigCacheValue(meta))
));
loaded = maybeArr;
}
}
} catch (err) {
throw new Error(`could not load meta from localstorage: ${err}`);
}
if (loaded.length === 0) {
autoDiscover();
}
/* Prune missing/dead projects and pick up new ones without wiping access times */
await autoDiscover();
}

function locateDuplicates(meta: JsonConfig) {
Expand Down
Loading