hlassiege/darylpublic Fork
⑂ 223eea8
Commits
⬇ Clone ▾
git clone https://git.rickub.com/hlassiege/daryl.git
git clone ssh://git@rickub.com/hlassiege/daryl.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP

fix(media): refresh the media list when images are added from the search

Validated images were copied into the project but the list behind the popup only reloaded on close, so nothing seemed to happen. Reload it right away and show the Assets group.
hlassiege committed 2026-10-13T15:21:45+02:00 Browse files
223eea8 parent: c803802
modified web/src/project/ResourcesPage.vue +7 -1
@@ -56,6 +56,12 @@ function closeAdd() {
5656 else load();
5757 }
5858
59+// des images validées dans la popup apparaissent derrière, sans attendre sa fermeture
60+async function onAdded() {
61+ await load();
62+ tab.value = "Assets";
63+}
64+
5965 // un téléchargement YouTube qui se termine arrive dans la liste
6066 const downloaded = computed(() => store.project?.runtime.assets.downloads.filter((d) => d.finished).length ?? 0);
6167 watch(downloaded, (n, before) => { if (n > before) load(); });
@@ -146,7 +152,7 @@ async function toLibrary(item: Item, category: string) {
146152 </div>
147153 <span v-if="!items.length" class="nothing">{{ t("common.nothingYet") }}</span>
148154 </div>
149- <AddMediaModal v-if="adding && store.project?.id === pid" v-model:tab="addTab" :uploading="uploading" @files="uploadFiles" @close="closeAdd" />
155+ <AddMediaModal v-if="adding && store.project?.id === pid" v-model:tab="addTab" :uploading="uploading" @files="uploadFiles" @added="onAdded" @close="closeAdd" />
150156 <MediaLightbox v-model="zoom" :items="zoomable">
151157 <template #actions="{ item }"><button class="link-btn" @click="reveal(item.rel)">{{ t("common.showInExplorer") }}</button></template>
152158 </MediaLightbox>
@@ -56,6 +56,12 @@ function closeAdd() {
56 else load();56 else load();
57 }57 }
58 58
59+// des images validées dans la popup apparaissent derrière, sans attendre sa fermeture
60+async function onAdded() {
61+ await load();
62+ tab.value = "Assets";
63+}
64+
59 // un téléchargement YouTube qui se termine arrive dans la liste65 // un téléchargement YouTube qui se termine arrive dans la liste
60 const downloaded = computed(() => store.project?.runtime.assets.downloads.filter((d) => d.finished).length ?? 0);66 const downloaded = computed(() => store.project?.runtime.assets.downloads.filter((d) => d.finished).length ?? 0);
61 watch(downloaded, (n, before) => { if (n > before) load(); });67 watch(downloaded, (n, before) => { if (n > before) load(); });
@@ -146,7 +152,7 @@ async function toLibrary(item: Item, category: string) {
146 </div>152 </div>
147 <span v-if="!items.length" class="nothing">{{ t("common.nothingYet") }}</span>153 <span v-if="!items.length" class="nothing">{{ t("common.nothingYet") }}</span>
148 </div>154 </div>
149- <AddMediaModal v-if="adding && store.project?.id === pid" v-model:tab="addTab" :uploading="uploading" @files="uploadFiles" @close="closeAdd" />155+ <AddMediaModal v-if="adding && store.project?.id === pid" v-model:tab="addTab" :uploading="uploading" @files="uploadFiles" @added="onAdded" @close="closeAdd" />
150 <MediaLightbox v-model="zoom" :items="zoomable">156 <MediaLightbox v-model="zoom" :items="zoomable">
151 <template #actions="{ item }"><button class="link-btn" @click="reveal(item.rel)">{{ t("common.showInExplorer") }}</button></template>157 <template #actions="{ item }"><button class="link-btn" @click="reveal(item.rel)">{{ t("common.showInExplorer") }}</button></template>
152 </MediaLightbox>158 </MediaLightbox>
modified web/src/project/media/AddMediaModal.vue +2 -2
@@ -14,7 +14,7 @@ import YoutubeTab from "./YoutubeTab.vue";
1414
1515 const tab = defineModel<AddTab>("tab", { required: true });
1616 defineProps<{ uploading: number | null }>();
17-const emit = defineEmits<{ close: []; files: [files: File[]] }>();
17+const emit = defineEmits<{ close: []; files: [files: File[]]; added: [] }>();
1818 const { t } = useI18n();
1919
2020 const title = computed(() => t(`media.add.tabs.${tab.value}.label`));
@@ -60,7 +60,7 @@ function onPick(e: Event) {
6060 <input ref="input" type="file" multiple hidden @change="onPick">
6161 </template>
6262 <YoutubeTab v-else-if="tab === 'youtube'" />
63- <ImagesTab v-else-if="tab === 'images'" />
63+ <ImagesTab v-else-if="tab === 'images'" @added="emit('added')" />
6464 <DocTab v-else />
6565 </Modal>
6666 </template>
@@ -14,7 +14,7 @@ import YoutubeTab from "./YoutubeTab.vue";
14 14
15 const tab = defineModel<AddTab>("tab", { required: true });15 const tab = defineModel<AddTab>("tab", { required: true });
16 defineProps<{ uploading: number | null }>();16 defineProps<{ uploading: number | null }>();
17-const emit = defineEmits<{ close: []; files: [files: File[]] }>();17+const emit = defineEmits<{ close: []; files: [files: File[]]; added: [] }>();
18 const { t } = useI18n();18 const { t } = useI18n();
19 19
20 const title = computed(() => t(`media.add.tabs.${tab.value}.label`));20 const title = computed(() => t(`media.add.tabs.${tab.value}.label`));
@@ -60,7 +60,7 @@ function onPick(e: Event) {
60 <input ref="input" type="file" multiple hidden @change="onPick">60 <input ref="input" type="file" multiple hidden @change="onPick">
61 </template>61 </template>
62 <YoutubeTab v-else-if="tab === 'youtube'" />62 <YoutubeTab v-else-if="tab === 'youtube'" />
63- <ImagesTab v-else-if="tab === 'images'" />63+ <ImagesTab v-else-if="tab === 'images'" @added="emit('added')" />
64 <DocTab v-else />64 <DocTab v-else />
65 </Modal>65 </Modal>
66 </template>66 </template>
modified web/src/project/media/ImagesTab.vue +2 -0
@@ -14,6 +14,7 @@ import type { ImagesState } from "../types";
1414 import CheckBox from "./CheckBox.vue";
1515 import DestPicker from "./DestPicker.vue";
1616
17+const emit = defineEmits<{ added: [] }>();
1718 const { t } = useI18n();
1819 const base = `/api/projects/${store.project!.id}/assets`;
1920 const state = ref<ImagesState>({ messages: [], results: [], busy: false, error: null, activity: null });
@@ -81,6 +82,7 @@ async function validate() {
8182 receive(out);
8283 const dest = out.results.find((r) => r.added)?.added ?? "";
8384 toast(t("sourcing.images.added", { dest }, out.added));
85+ if (out.added) emit("added");
8486 } catch (e) {
8587 toast((e as Error).message, true);
8688 }
@@ -14,6 +14,7 @@ import type { ImagesState } from "../types";
14 import CheckBox from "./CheckBox.vue";14 import CheckBox from "./CheckBox.vue";
15 import DestPicker from "./DestPicker.vue";15 import DestPicker from "./DestPicker.vue";
16 16
17+const emit = defineEmits<{ added: [] }>();
17 const { t } = useI18n();18 const { t } = useI18n();
18 const base = `/api/projects/${store.project!.id}/assets`;19 const base = `/api/projects/${store.project!.id}/assets`;
19 const state = ref<ImagesState>({ messages: [], results: [], busy: false, error: null, activity: null });20 const state = ref<ImagesState>({ messages: [], results: [], busy: false, error: null, activity: null });
@@ -81,6 +82,7 @@ async function validate() {
81 receive(out);82 receive(out);
82 const dest = out.results.find((r) => r.added)?.added ?? "";83 const dest = out.results.find((r) => r.added)?.added ?? "";
83 toast(t("sourcing.images.added", { dest }, out.added));84 toast(t("sourcing.images.added", { dest }, out.added));
85+ if (out.added) emit("added");
84 } catch (e) {86 } catch (e) {
85 toast((e as Error).message, true);87 toast((e as Error).message, true);
86 }88 }