### Handle File Sharing with handleFile Source: https://context7.com/kbrgl/wayfer/llms.txt Orchestrates the file sharing process by validating the file, starting a temporary server, and triggering QR code generation. Implements automatic server cleanup timeouts. ```javascript // Internal function used by the renderer process function handleFile(filepath) { // Validate file exists and is not a directory ensureFile(filepath, () => { const minute = 60 * 1000; const hour = 60 * minute; let timeout = null; // Create server with request/completion handlers const server = createFileServer( filepath, () => { // Reset timeout on each request - closes 30 min after last request clearTimeout(timeout); timeout = setTimeout(() => { server.close(); }, 30 * minute); }, () => { // Notify user when transfer completes new Notification("Sent.", { body: "File transferred." }); } ); // Listen on random available port server.listen(0); // Set initial 2-hour timeout if QR is never scanned timeout = setTimeout(() => { server.close(); }, 2 * hour); // Generate QR code with properly encoded filename const encodedFileName = encodeURIComponent(path.basename(filepath)); const fullURL = url.resolve(server.networkAddress(), encodedFileName); // URL format: http://192.168.1.100:54321/myfile.pdf showCode(fullURL); }); } ``` -------------------------------- ### Configure Electron Menubar Application Source: https://context7.com/kbrgl/wayfer/llms.txt Sets up the Electron menubar with system tray, window configuration, and platform-specific icons. Handles app ready events, context menus, and file drops on the tray. ```javascript const { TouchBar, Menu } = require("electron"); const menubar = require("menubar"); const path = require("path"); // Initialize menubar with configuration const mb = menubar({ title: "Wayfer", width: 250, minWidth: 250, height: 220, minHeight: 220, preloadWindow: true, // Create window at startup for faster display icon: path.join(__dirname, "assets", "blank.png"), backgroundColor: "#e4fefd", }); // Handle app ready event mb.on("ready", () => { // Create right-click context menu const contextMenu = Menu.buildFromTemplate([ { label: "Quit", click: () => mb.app.quit(), }, ]); // Set platform-specific tray icon let iconFile; switch (process.platform) { case "darwin": iconFile = "trayTemplate.png"; // macOS template icon (adapts to dark/light) break; case "win32": iconFile = "tray.ico"; // Windows ICO format break; default: iconFile = "tray.png"; // Linux PNG } mb.tray.setImage(path.join(__dirname, "assets", iconFile)); // Right-click shows quit menu mb.tray.on("right-click", () => { mb.tray.popUpContextMenu(contextMenu); }); // Handle files dropped directly on tray icon mb.tray.on("drop-files", (e, filepaths) => { e.preventDefault(); mb.window.webContents.send("open-files", filepaths); }); }); ``` -------------------------------- ### Create a File Server with createFileServer Source: https://context7.com/kbrgl/wayfer/llms.txt Initializes a Koa-based HTTP server for serving a single file with support for range requests and compression. Use the networkAddress method to retrieve the accessible URL. ```javascript const createFileServer = require("./lib/createFileServer"); // Create a file server with lifecycle callbacks const server = createFileServer( "/path/to/myfile.pdf", // Called on each request (useful for resetting timeouts) () => { console.log("File requested"); }, // Called when file is fully sent (not for range requests) () => { console.log("File transfer complete"); } ); // Start server on random available port server.listen(0, () => { // Get the full network URL (e.g., "http://192.168.1.100:54321") const address = server.networkAddress(); console.log(`File available at: ${address}`); }); // Server configuration includes: // - gzip compression (level 9) // - Range request support for resume capability // - Automatic content-type detection ``` -------------------------------- ### Generate QR Codes with showCode Source: https://context7.com/kbrgl/wayfer/llms.txt Creates a temporary QR code image from a URL and opens it using the system's default image viewer. Requires the qr-image, temp-write, and opn packages. ```javascript const qr = require("qr-image"); const tempWrite = require("temp-write"); const opn = require("opn"); function showCode(address) { // Generate QR code as PNG stream const qrImage = qr.image(address, { parse_url: true, // Parse URL for optimal encoding size: 20, // Module size in pixels }); // Write to temp file and open in default viewer tempWrite(qrImage).then((tempFilePath) => { opn(tempFilePath); // Opens in Preview (macOS), Photos (Windows), etc. }); } // Usage example showCode("http://192.168.1.100:54321/document.pdf"); // Opens a QR code image that mobile devices can scan ``` -------------------------------- ### Create File Server API Source: https://context7.com/kbrgl/wayfer/llms.txt This API creates a Koa-based HTTP server to serve a single file. It supports compression, range requests for resume functionality, and provides callbacks for request lifecycle events. The server instance includes a `networkAddress()` method to retrieve the local network URL. ```APIDOC ## POST /api/files/server ### Description Creates a local HTTP server to serve a specified file, enabling downloads via a generated QR code. Supports resume functionality and provides lifecycle event callbacks. ### Method POST ### Endpoint /api/files/server ### Parameters #### Request Body - **filepath** (string) - Required - The absolute path to the file to be shared. - **onrequest** (function) - Optional - Callback function executed on each request to the server (e.g., for resetting timeouts). - **onsent** (function) - Optional - Callback function executed when the file has been fully sent (not applicable for range requests). ### Request Example ```json { "filepath": "/path/to/your/document.pdf", "onrequest": "() => { console.log('File requested'); }", "onsent": "() => { console.log('File transfer complete'); }" } ``` ### Response #### Success Response (200) - **serverInstance** (object) - An HTTP server instance with an added `networkAddress()` method. #### Response Example ```json { "message": "Server created successfully", "address": "http://192.168.1.100:54321" } ``` ``` -------------------------------- ### Handle File Sharing API Source: https://context7.com/kbrgl/wayfer/llms.txt This API processes a single file for sharing. It validates the file, creates a temporary HTTP server using `createFileServer`, generates a QR code containing the download URL, and manages the server's lifecycle with automatic timeout cleanup. ```APIDOC ## POST /api/files/share ### Description Initiates the file sharing process by creating a temporary HTTP server, generating a QR code with the file's download URL, and setting up automatic server cleanup. ### Method POST ### Endpoint /api/files/share ### Parameters #### Request Body - **filepath** (string) - Required - The path to the file to be shared. ### Request Example ```json { "filepath": "/Users/username/Documents/report.docx" } ``` ### Response #### Success Response (200) - **qrCodeUrl** (string) - The URL that will be encoded into the QR code. - **message** (string) - Confirmation message. #### Response Example ```json { "qrCodeUrl": "http://192.168.1.100:54321/report.docx", "message": "File processing initiated. QR code generated." } ``` ``` -------------------------------- ### Show QR Code API Source: https://context7.com/kbrgl/wayfer/llms.txt This API generates a QR code image from a given URL string and opens it using the system's default image viewer. It utilizes the `qr-image` library for QR code generation and `temp-write` for temporary file storage. ```APIDOC ## POST /api/qr/show ### Description Generates a QR code from a provided URL and displays it in the default system image viewer. ### Method POST ### Endpoint /api/qr/show ### Parameters #### Request Body - **address** (string) - Required - The URL to be encoded in the QR code. ### Request Example ```json { "address": "http://192.168.1.100:54321/image.png" } ``` ### Response #### Success Response (200) - **message** (string) - Confirmation that the QR code has been generated and displayed. #### Response Example ```json { "message": "QR code generated and opened in default viewer." } ``` ``` -------------------------------- ### Implement Drag-and-Drop File Handling in Renderer Source: https://context7.com/kbrgl/wayfer/llms.txt Handles drag-and-drop events for files in the renderer process, providing visual feedback and falling back to a file dialog. Listens for files from the main process. ```javascript const { remote, ipcRenderer } = require("electron"); const { dialog } = remote; // Get drop zone element const dropZone = document.getElementById("drop-zone"); // Double-click opens file picker dialog dropZone.ondblclick = () => { dialog.showOpenDialog( remote.getCurrentWindow(), { properties: ["openFile", "multiSelections"], }, (filepaths) => { if (filepaths) { filepaths.forEach(handleFile); } } ); }; // Visual feedback during drag dropZone.ondragenter = () => { dropZone.classList.add("active"); return false; }; dropZone.ondragleave = () => { dropZone.classList.remove("active"); return false; }; dropZone.ondragover = () => false; dropZone.ondragend = () => false; // Handle dropped files dropZone.ondrop = (e) => { e.preventDefault(); dropZone.classList.remove("active"); // Extract file paths from DataTransfer const filepaths = Array.from(e.dataTransfer.files).map(({ path }) => path); filepaths.forEach(handleFile); return false; }; // Listen for files from main process (tray drop, TouchBar) ipcRenderer.on("open-files", (e, filepaths) => { if (!filepaths) { // Show file dialog if no paths provided showOpenDialog(); } else { filepaths.forEach(handleFile); } }); ``` -------------------------------- ### Validate File Path Source: https://context7.com/kbrgl/wayfer/llms.txt Ensures a given path points to a file, not a directory, before processing. Displays an error message if the path is invalid or inaccessible. ```javascript const fs = require("fs"); const { dialog } = require("electron").remote; function ensureFile(filepath, onSure) { fs.lstat(filepath, (err, stats) => { if (err) { // File doesn't exist or permission error dialog.showMessageBox(remote.getCurrentWindow(), { type: "error", message: "An unexpected error occurred", }); } else if (stats.isFile()) { // Valid file - proceed with callback onSure(); } else { // Directory or other non-file type dialog.showMessageBox(remote.getCurrentWindow(), { type: "error", message: "Folders are currently unsupported.", }); } }); } // Usage ensureFile("/path/to/file.pdf", () => { console.log("File validated, proceed with sharing"); }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.