webdrop-bridge/docs/DRAG_DROP_PROBLEM_ANALYSIS.md
claudi f0bab2afa5
Some checks are pending
Tests & Quality Checks / Test on Python 3.11 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.11-1 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12-1 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.10 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.11-2 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12-2 (push) Waiting to run
Tests & Quality Checks / Build Artifacts (push) Blocked by required conditions
Tests & Quality Checks / Build Artifacts-1 (push) Blocked by required conditions
update documentation
2026-03-03 08:41:28 +01:00

9.3 KiB

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

Status: Phase 1 (File Drop) Implemented | Phase 2 (Popup Trigger) ⏸️ Planned
Last Updated: March 3, 2026

Overview

Current Implementation Status

Phase 1 - File Drop (IMPLEMENTED)

  • JavaScript in bridge_script_intercept.js intercepts drag events
  • Calls window.bridge.start_file_drag(url) via QWebChannel to Qt
  • Validates path against whitelist via PathValidator
  • Converts Azure Storage URLs to local paths via URLConverter
  • Creates and executes native Qt file drag operation
  • Target application (InDesign, Word, etc.) successfully receives file

⏸️ Phase 2 - Programmatic Popup Trigger (PLANNED)

  • Would require reverse-engineering the web app's popup trigger mechanism
  • Could be implemented by calling JavaScript function after successful drop
  • Currently: Applications handle popups manually or separately from file drops

Das Kernproblem

  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

Current Status (as of March 2026)

Phase 1 Complete:

  • File-drop via native Qt drag operations is fully functional
  • JavaScript bridge (bridge_script_intercept.js) successfully intercepts and converts drags
  • Path validation and Azure URL mapping working
  • Tested with real applications (InDesign, Word, etc.)

For Future Enhancement (Phase 2 - Popup Trigger)

If popup trigger integration is needed:

  1. 🔍 Reverse-Engineering the Target Web App:

    • Identify how popups are triggered (API call, component method, event, etc.)
    • Use browser DevTools:
      • Network tab → Monitor API calls
      • Console → Check for JavaScript errors/logs
      • Elements → Inspect component structure
      • Angular/Vue DevTools if applicable
  2. 🛠️ Implement Popup Trigger:

    • Create JavaScript hook function (e.g., window.trigger_popup(assetId))
    • Connect to drop success signal from Qt
    • Call popup trigger after successful file drop
  3. 🧪 Test Integration:

    • Verify file drops successfully
    • Verify popup appears after drop
    • Test with real assets/files

Alternative Approaches:

  • Lösung B (Manual): Keep file drop and popup as separate user actions
  • Lösung C (Complex): Use overlay window approach (more involved)

Current implementation uses Phase 1 of Lösung A and is production-ready.