Skip to content

Conversation

@buzsh
Copy link
Contributor

@buzsh buzsh commented Jun 2, 2024

TODO

Example Syntax

declare global {
  interface Window {
    webkit: {
      messageHandlers: {
        copilotMessageProcessed: {
          postMessage: (message: string) => void;
        };
        copilotSidebarHidden: {
          postMessage: (message: string) => void;
        };
        copilotPopupHidden: {
          postMessage: (message: string) => void;
        };
      };
    };
    sendMessageToCopilot: (message: string) => void;
    showCopilotSidebar: () => void;
    hideCopilotSidebar: () => void;
    showCopilotPopup: () => void;
    hideCopilotPopup: () => void;
  }
}
  • Parse webkit message handlers
  • Generate separate enum for typesafe ScriptMessageHandlers
  • Generate WebView extensions for typesafe ScriptMessageHandlers
  • Generate view modifiers for typesafe ScriptMessageHandlers

Additional Ideas

  • Pass types through postMessage functions
  • Swift extensions for verifying types

Testing

  • Ensure duplicate postMessage names cannot be created

More Examples

Boolean

declare global {
  interface Window {
    webkit: {
      messageHandlers: {
        copilotSidebarHidden: {
          postMessage: (isHidden: boolean) => void;
        };
      };
    };
  }
}

// Sending a boolean message
window.webkit.messageHandlers.copilotSidebarHidden.postMessage(true);

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
  if message.name == "copilotSidebarHidden" {
    if let isHidden = message.body as? Bool, isHidden {
      // Do something when the sidebar is hidden
    }
  }
}

Multiple Parameter Types

interface SidebarStatus {
  isHidden: boolean;
  timestamp: number;
}

declare global {
  interface Window {
    webkit: {
      messageHandlers: {
        copilotSidebarHidden: {
          postMessage: (status: SidebarStatus) => void;
        };
      };
    };
  }
}

// Sending an object message
window.webkit.messageHandlers.copilotSidebarHidden.postMessage({ isHidden: true, timestamp: Date.now() });

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
  if message.name == "copilotSidebarHidden" {
    if let status = message.body as? [String: Any],
       let isHidden = status["isHidden"] as? Bool,
       let timestamp = status["timestamp"] as? Double {
      // Do something with isHidden and timestamp
    }
  }
}

Different Method Name

declare global {
  interface Window {
    webkit: {
      messageHandlers: {
        handleSidebarStatus: {
          sendStatus: (status: string) => void;
        };
      };
    };
  }
}

// Sending a string message
window.webkit.messageHandlers.handleSidebarStatus.sendStatus("hidden");

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
  if message.name == "handleSidebarStatus" {
    if let status = message.body as? String, status == "hidden" {
      // Do something when the sidebar status is "hidden"
    }
  }
}

Generative: interface

interface SidebarStatus {
  isHidden: boolean;
  progress: number;
}

struct SidebarStatus: Codable {
  let isHidden: Bool
  let progress: Double
}

Usage

let status = SidebarStatus(isHidden: true, progress: 0.75)

Conversion

interface SidebarStatus {
  isHidden: boolean;
  progress: number;
}

declare global {
  interface Window {
    webkit: {
      messageHandlers: {
        copilotSidebarHidden: {
          postMessage: (status: SidebarStatus) => void;
        };
      };
    };
  }
}

// Sending an object message
window.webkit.messageHandlers.copilotSidebarHidden.postMessage({ isHidden: true, progress: 0.75 });

struct SidebarStatus: Codable {
  let isHidden: Bool
  let progress: Double
}

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
  if message.name == "copilotSidebarHidden" {
    if let data = message.body as? [String: Any] {
      do {
        let jsonData = try JSONSerialization.data(withJSONObject: data, options: [])
        let status = try JSONDecoder().decode(SidebarStatus.self, from: jsonData)
        // Use the status struct
        print("Sidebar is hidden: \(status.isHidden), progress: \(status.progress)")
      } catch {
        print("Failed to decode SidebarStatus: \(error)")
      }
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants