fix(derush): drag a small label instead of the whole thumbnail onto the timeline
The thumbnail hid the insertion marker under the cursor; the label sits below and to the right of it.
23a0a14 parent: f0eb0eb modified
web/src/i18n/locales/en/derush.ts +1 -0 | @@ -73,6 +73,7 @@ export default { | ||
| 73 | 73 | removeConfirm: "Remove?", |
| 74 | 74 | removeTitle: "Remove this clip from the project (and from every timeline)", |
| 75 | 75 | append: "Add this whole clip at the end of the open timeline", |
| 76 | + dragMany: "{n} clips", | |
| 76 | 77 | importing: "Importing {p}%", |
| 77 | 78 | }, |
| 78 | 79 | timelines: { |
| @@ -73,6 +73,7 @@ export default { | |||
| 73 | removeConfirm: "Remove?", | 73 | removeConfirm: "Remove?", |
| 74 | removeTitle: "Remove this clip from the project (and from every timeline)", | 74 | removeTitle: "Remove this clip from the project (and from every timeline)", |
| 75 | append: "Add this whole clip at the end of the open timeline", | 75 | append: "Add this whole clip at the end of the open timeline", |
| 76 | + dragMany: "{n} clips", | ||
| 76 | importing: "Importing {p}%", | 77 | importing: "Importing {p}%", |
| 77 | }, | 78 | }, |
| 78 | timelines: { | 79 | timelines: { |
modified
web/src/i18n/locales/fr/derush.ts +1 -0 | @@ -73,6 +73,7 @@ export default { | ||
| 73 | 73 | removeConfirm: "Retirer ?", |
| 74 | 74 | removeTitle: "Retirer ce rush du projet (et de toutes les timelines)", |
| 75 | 75 | append: "Ajouter ce rush entier à la fin de la timeline ouverte", |
| 76 | + dragMany: "{n} rushes", | |
| 76 | 77 | importing: "Import {p} %", |
| 77 | 78 | }, |
| 78 | 79 | timelines: { |
| @@ -73,6 +73,7 @@ export default { | |||
| 73 | removeConfirm: "Retirer ?", | 73 | removeConfirm: "Retirer ?", |
| 74 | removeTitle: "Retirer ce rush du projet (et de toutes les timelines)", | 74 | removeTitle: "Retirer ce rush du projet (et de toutes les timelines)", |
| 75 | append: "Ajouter ce rush entier à la fin de la timeline ouverte", | 75 | append: "Ajouter ce rush entier à la fin de la timeline ouverte", |
| 76 | + dragMany: "{n} rushes", | ||
| 76 | importing: "Import {p} %", | 77 | importing: "Import {p} %", |
| 77 | }, | 78 | }, |
| 78 | timelines: { | 79 | timelines: { |
modified
web/src/project/steps/derush/MediaPool.vue +24 -2 | @@ -86,8 +86,20 @@ function dragRush(e: DragEvent, id: string) { | ||
| 86 | 86 | setDrag(e, ids.map((rush) => ({ rush }))); |
| 87 | 87 | } |
| 88 | 88 | function setDrag(e: DragEvent, items: MediaItem[]) { |
| 89 | - e.dataTransfer?.setData(MEDIA_TYPE, JSON.stringify(items)); | |
| 90 | - if (e.dataTransfer) e.dataTransfer.effectAllowed = "copy"; | |
| 89 | + const dt = e.dataTransfer; | |
| 90 | + if (!dt) return; | |
| 91 | + dt.setData(MEDIA_TYPE, JSON.stringify(items)); | |
| 92 | + dt.effectAllowed = "copy"; | |
| 93 | + // une étiquette en bas à droite du curseur plutôt que la vignette entière : le point d'insertion reste visible | |
| 94 | + const first = items[0]; | |
| 95 | + const label = items.length > 1 ? t("derush.pool.dragMany", { n: items.length }) | |
| 96 | + : first.tl ? d.nameOf(first.tl) : project.value.rushes.find((r) => r.id === first.rush)?.name ?? ""; | |
| 97 | + const chip = document.createElement("div"); | |
| 98 | + chip.className = "drag-chip"; | |
| 99 | + chip.textContent = label; | |
| 100 | + document.body.appendChild(chip); | |
| 101 | + dt.setDragImage(chip, 0, 0); | |
| 102 | + setTimeout(() => chip.remove()); | |
| 91 | 103 | } |
| 92 | 104 | |
| 93 | 105 | // --- timelines --------------------------------------------------------------------------- |
| @@ -259,3 +271,13 @@ function onDrop(e: DragEvent) { | ||
| 259 | 271 | .name.mono { font-size: 11.5px; } |
| 260 | 272 | .time { font-size: 10.5px; color: var(--faint); margin-top: -3px; } |
| 261 | 273 | </style> |
| 274 | + | |
| 275 | +<style> | |
| 276 | +/* l'image du glisser vers la timeline : hors écran, avec une marge transparente qui la décale du curseur */ | |
| 277 | +.drag-chip { | |
| 278 | + position: fixed; top: -1000px; left: 0; max-width: 220px; padding: 3px 8px; | |
| 279 | + border-left: 16px solid transparent; border-top: 18px solid transparent; background-clip: padding-box; | |
| 280 | + background-color: var(--ink); color: #fff; font-family: var(--mono); font-size: 11px; border-radius: 3px; | |
| 281 | + white-space: nowrap; overflow: hidden; text-overflow: ellipsis; | |
| 282 | +} | |
| 283 | +</style> | |
| @@ -86,8 +86,20 @@ function dragRush(e: DragEvent, id: string) { | |||
| 86 | setDrag(e, ids.map((rush) => ({ rush }))); | 86 | setDrag(e, ids.map((rush) => ({ rush }))); |
| 87 | } | 87 | } |
| 88 | function setDrag(e: DragEvent, items: MediaItem[]) { | 88 | function setDrag(e: DragEvent, items: MediaItem[]) { |
| 89 | - e.dataTransfer?.setData(MEDIA_TYPE, JSON.stringify(items)); | 89 | + const dt = e.dataTransfer; |
| 90 | - if (e.dataTransfer) e.dataTransfer.effectAllowed = "copy"; | 90 | + if (!dt) return; |
| 91 | + dt.setData(MEDIA_TYPE, JSON.stringify(items)); | ||
| 92 | + dt.effectAllowed = "copy"; | ||
| 93 | + // une étiquette en bas à droite du curseur plutôt que la vignette entière : le point d'insertion reste visible | ||
| 94 | + const first = items[0]; | ||
| 95 | + const label = items.length > 1 ? t("derush.pool.dragMany", { n: items.length }) | ||
| 96 | + : first.tl ? d.nameOf(first.tl) : project.value.rushes.find((r) => r.id === first.rush)?.name ?? ""; | ||
| 97 | + const chip = document.createElement("div"); | ||
| 98 | + chip.className = "drag-chip"; | ||
| 99 | + chip.textContent = label; | ||
| 100 | + document.body.appendChild(chip); | ||
| 101 | + dt.setDragImage(chip, 0, 0); | ||
| 102 | + setTimeout(() => chip.remove()); | ||
| 91 | } | 103 | } |
| 92 | 104 | ||
| 93 | // --- timelines --------------------------------------------------------------------------- | 105 | // --- timelines --------------------------------------------------------------------------- |
| @@ -259,3 +271,13 @@ function onDrop(e: DragEvent) { | |||
| 259 | .name.mono { font-size: 11.5px; } | 271 | .name.mono { font-size: 11.5px; } |
| 260 | .time { font-size: 10.5px; color: var(--faint); margin-top: -3px; } | 272 | .time { font-size: 10.5px; color: var(--faint); margin-top: -3px; } |
| 261 | </style> | 273 | </style> |
| 274 | + | ||
| 275 | +<style> | ||
| 276 | +/* l'image du glisser vers la timeline : hors écran, avec une marge transparente qui la décale du curseur */ | ||
| 277 | +.drag-chip { | ||
| 278 | + position: fixed; top: -1000px; left: 0; max-width: 220px; padding: 3px 8px; | ||
| 279 | + border-left: 16px solid transparent; border-top: 18px solid transparent; background-clip: padding-box; | ||
| 280 | + background-color: var(--ink); color: #fff; font-family: var(--mono); font-size: 11px; border-radius: 3px; | ||
| 281 | + white-space: nowrap; overflow: hidden; text-overflow: ellipsis; | ||
| 282 | +} | ||
| 283 | +</style> | ||