webdrop-bridge/docs/DRAG_DROP_PROBLEM_ANALYSIS.md
claudi dee02ad600 Add drag & drop script variants and enhanced debugging tools
- Introduced multiple JavaScript scripts for handling drag & drop functionality:
  - `bridge_script.js`: Original implementation with popup prevention.
  - `bridge_script_debug.js`: Debug version with extensive logging for troubleshooting.
  - `bridge_script_v2.js`: Enhanced version extending DataTransfer for better integration.
  - `bridge_script_hybrid.js`: Hybrid approach allowing parallel native file drag.
  - `bridge_script_drop_intercept.js`: Intercepts drop events for custom handling.
  - `bridge_script_intercept.js`: Prevents browser drag for ALT+drag, using Qt for file drag.

- Added detailed documentation in `SCRIPT_VARIANTS.md` outlining usage, status, and recommended workflows for each script.
- Implemented logging features to capture drag events, DataTransfer modifications, and network requests for better debugging.
- Enhanced DataTransfer handling to support Windows-specific file formats and improve user experience during drag & drop operations.
2026-02-17 19:19:14 +01:00

7.9 KiB

Drag & Drop Problem Analysis - File Drop + Web App Popup

Das Kernproblem

Ziel: Bei ALT-Drag soll:

  1. File gedroppt werden (Z:\ Laufwerk) → Native File-Drop
  2. Web-App Popup erscheinen (Auschecken-Dialog) → Web-App Drop-Event

Problem: Diese beiden schließen sich gegenseitig aus:

  • Native File-Drag (von Qt) → Web-App bekommt kein Drop-Event → Kein Popup
  • Browser Text-Drag (von Web-App) → Kein File-Drop → Kein File

Browser-Sicherheitsbeschränkungen

  1. DataTransfer.files ist read-only
    Wir können keine Files zu einem DataTransfer hinzufügen

  2. Nur EIN Drag zur Zeit möglich
    Wir können keinen parallelen Drag starten

  3. DataTransfer kann nicht erstellt werden
    Wir können kein synthetisches Drop-Event mit Files erzeugen

  4. Cross-Domain Sicherheit
    File-Zugriff ist stark eingeschränkt

Getestete Ansätze

Ansatz 1: DataTransfer erweitern

Idee: Web-App setzt URL, wir fügen Files hinzu
Problem: DataTransfer.files ist read-only

Ansatz 2: Parallele Drags

Idee: Browser-Drag + Qt-Drag gleichzeitig
Problem: Nur ein Drag zur Zeit möglich

Ansatz 3: Synthetisches Drop-Event

Idee: Original Drop abfangen, neues Event mit Files erzeugen
Problem: DataTransfer.files kann nicht gesetzt werden

⚠️ Ansatz 4: Native Drag + Event-Simulation

Idee: Qt Native Drag, dann Web-App Event manuell auslösen
Problem: Erfordert Kenntnis der exakten Web-App Event-Struktur (Angular CDK)

🎯 Praktikable Lösungen

Lösung A: Zwei-Phasen Ansatz (EMPFOHLEN für Testing)

Phase 1: File-Drop

  1. ALT-Drag startet
  2. JavaScript erkennt convertible URL
  3. Ruft Qt's start_file_drag(url) auf
  4. preventDefault() verhindert Browser-Drag
  5. Qt Native Drag läuft
  6. File wird gedroppt

Phase 2: Popup manuell triggern 7. Nach erfolgreichem Drop (via Qt Signal) 8. JavaScript simuliert den Event/API-Call der das Popup auslöst 9. Popup erscheint

Vorteile:

  • Funktioniert garantiert für File-Drop
  • Kontrolle über beide Phasen
  • Kann debugged werden

Nachteile:

  • ⚠️ Erfordert Reverse-Engineering des Popup-Triggers
  • ⚠️ Könnte bei Web-App Updates brechen

Implementierung:

// Phase 1: Standard - File Drag
document.addEventListener('dragstart', function(e) {
  if (!e.altKey) return;
  
  // Extract URL from DataTransfer
  var url = e.dataTransfer.getData('text/plain');
  if (isConvertible(url)) {
    e.preventDefault();
    window.bridge.start_file_drag(url);
  }
}, true);

// Phase 2: Popup Trigger (nach Drop-Erfolg)
// Qt ruft auf: window.trigger_checkout_popup(assetId)
window.trigger_checkout_popup = function(assetId) {
  // Option 1: Klick auf Checkout-Button simulieren
  // Option 2: API-Call direkt aufrufen
  // Option 3: Angular-Event dispatchen
  
  // Beispiel: Suche nach Angular-Component und rufe Methode auf
  var angularComponent = findAngularComponent('ay-asset-card');
  if (angularComponent) {
    angularComponent.onCheckout(assetId);
  }
};

TODO für diese Lösung:

  1. File-Drag funktioniert bereits
  2. ⏸️ Herausfinden wie Popup ausgelöst wird:
    • Browser DevTools öffnen
    • Network-Tab beobachten (API-Call?)
    • Elements-Tab nutzen (Angular Component?)
    • Event-Listeners ansehen

Lösung B: Gar nichts ändern beim Drag (FALLBACK)

Ansatz:

  1. ALT-Drag läuft normal durch (URL-Text wird gedroppt)
  2. Popup erscheint
  3. Nach Popup-Bestätigung (Auschecken)
  4. DANN konvertieren wir die URL und kopieren das File

Vorteile:

  • Web-App funktioniert normal
  • Kein Popup-Problem
  • Einfach zu implementieren

Nachteile:

  • ⚠️ Kein echter Drag & Drop (nur Copy)
  • ⚠️ User muss zweimal handeln

Lösung C: File-Drop via Qt Window Overlay (EXPERIMENTELL)

Ansatz:

  1. Beim ALT-Drag: Start Normal Web-App Drag
  2. Qt erstellt ein transparentes Overlay-Window über dem Browser
  3. Overlay fängt das Drop-Event ab
  4. Qt macht File-Drop
  5. Qt leitet Drop-Koordinaten an Browser weiter
  6. Browser bekommt synthetisches Event (ohne Files, nur Koordinaten)
  7. Popup erscheint

Vorteile:

  • Beide Funktionen potentiell möglich
  • Keine DataTransfer-Manipulation nötig

Nachteile:

  • ⚠️ Sehr komplex
  • ⚠️ Plattform-spezifisch (Windows)
  • ⚠️ Performance-Overhead

🔬 Nächste Schritte - Reverse Engineering

Um Lösung A zu implementieren, müssen wir herausfinden:

1. Wie wird das Popup ausgelöst?

Debug-Schritte:

// In Browser Console ausführen während ALT-Drag+Drop

// Methode 1: Event-Listener finden
getEventListeners(document)

// Methode 2: Angular Component finden
var cards = document.querySelectorAll('ay-asset-card');
var component = ng.getComponent(cards[0]); // Angular DevTools
console.log(component);

// Methode 3: Network-Tab
// Schauen ob API-Call gemacht wird nach Drop

Erwartete Möglichkeiten:

  • API-Call zu /api/assets/{id}/checkout
  • Angular Event: cdkDropListDropped
  • Component-Methode: onAssetDropped() oder ähnlich
  • Modal-Service: ModalService.show('checkout-dialog')

2. Asset-ID extrahieren

Die Asset-ID wird benötigt für den Popup-Trigger:

// Asset-ID ist wahrscheinlich in:
// - Element-ID: "anPGZszKzgKaSz1SIx2HFgduy"
// - Image-URL: "./GlobalDAM JRI_files/anPGZszKzgKaSz1SIx2HFgduy"
// - Data-Attribut: data-asset-id

function extractAssetId(element) {
  // Aus Element-ID
  if (element.id && element.id.match(/^a[A-Za-z0-9_-]+$/)) {
    return element.id;
  }
  
  // Aus Bild-URL
  var img = element.querySelector('img');
  if (img && img.src) {
    var match = img.src.match(/([A-Za-z0-9_-]{20,})/);
    if (match) return match[1];
  }
  
  return null;
}

3. Popup programmatisch öffnen

Sobald wir wissen wie, implementieren wir:

# Python (Qt)
class DragBridge(QObject):
    @Slot(str)
    def on_file_dropped_success(self, local_path: str):
        """Called after successful file drop."""
        # Extrahiere Asset-ID aus Pfad oder URL-Mapping
        asset_id = self.extract_asset_id(local_path)
        
        # Trigger Popup via JavaScript
        js_code = f"window.trigger_checkout_popup('{asset_id}')"
        self.web_view.page().runJavaScript(js_code)

Quick Win: Debugging aktivieren

Fügen Sie zu allen JavaScript-Varianten umfangreiches Logging hinzu:

// In bridge_script.js

// Log ALLE Events
['dragstart', 'drag', 'dragenter', 'dragover', 'drop', 'dragend'].forEach(function(eventName) {
  document.addEventListener(eventName, function(e) {
    console.log('[DEBUG]', eventName, {
      target: e.target.tagName,
      dataTransfer: {
        types: e.dataTransfer.types,
        effectAllowed: e.dataTransfer.effectAllowed,
        dropEffect: e.dataTransfer.dropEffect
      },
      altKey: e.altKey,
      coordinates: {x: e.clientX, y: e.clientY}
    });
  }, true);
});

// Log DataTransfer Zugriffe
Object.defineProperty(DataTransfer.prototype, 'types', {
  get: function() {
    var types = this._types || [];
    console.log('[DEBUG] DataTransfer.types accessed:', types);
    return types;
  }
});

📝 Empfehlung

Sofortige Maßnahmen:

  1. Lösung A Phase 1 ist bereits implementiert (File-Drop funktioniert)

  2. 🔍 Reverse-Engineering durchführen:

    • GlobalDAM JRI im Browser öffnen
    • DevTools öffnen (F12)
    • ALT-Drag+Drop durchführen
    • Beobachten:
      • Network-Tab → API-Calls?
      • Console → Fehler/Logs?
      • Angular DevTools → Component-Events?
  3. 🛠️ Popup-Trigger implementieren:

    • Sobald bekannt WIE Popup ausgelöst wird
    • JavaScript-Funktion trigger_checkout_popup() erstellen
    • Von Qt aus nach erfolgreichem Drop aufrufen
  4. 🧪 Testen:

    • ALT-Drag eines Assets
    • File-Drop sollte funktionieren
    • Popup sollte erscheinen

Fallback: Falls Reverse-Engineering zu komplex ist → Lösung B verwenden (Kein Drag, nur Copy nach Popup-Bestätigung)