Files
knock-gui/desktop-angular/CUSTOM_FILE_DIALOG.md

6.6 KiB

Custom File Dialogs Implementation

This document describes the custom file dialog implementations for the desktop-angular project. Both dialogs are native Electron BrowserWindows that provide file browsing and saving capabilities with customizable styling and filtering.

Overview

The custom file dialog replaces the system file dialog with a custom implementation that:

  • Opens in a specific directory (configs folder)
  • Supports file filtering by extension
  • Has customizable colors and styling
  • Provides a file browser interface
  • Returns the same data structure as the system dialog

Files Added

src/main/open-dialog.html

Purpose: HTML/CSS/JS interface for the file open dialog Features:

  • File browser with directory navigation
  • File filtering by extension
  • Customizable colors via CSS variables
  • Double-click to open files
  • Path input with browse functionality
  • File icons based on extension
  • File size display
  • File preview - Shows first 500 characters of selected files

src/main/save-dialog.html

Purpose: HTML/CSS/JS interface for the file save dialog Features:

  • File name input with validation
  • Directory path selection
  • Files list - Shows all files in current directory (no filtering)
  • File type filtering
  • Customizable colors via CSS variables
  • Filename validation (invalid characters, reserved names)
  • Browse button - Opens system directory picker

src/main/main.js (Updated)

New Function: openCustomFileDialog(config)

  • Creates a modal BrowserWindow (800x600)
  • Loads the open-dialog.html interface
  • Handles IPC communication with the dialog
  • Returns file selection results

New IPC Handler: dialog:customFile

  • Accepts configuration for the dialog
  • Returns file selection result

API Usage

From Angular Component

const result = await this.ipc.showCustomFileDialog({
  title: "Open Configuration File",
  defaultPath: "/path/to/configs",
  filters: [
    {
      name: "YAML Files",
      extensions: ["yaml", "yml", "txt"]
    },
    {
      name: "All Files",
      extensions: ["*"]
    }
  ],
  colors: {
    background: "#aa1c3a",
    text: "#ffffff",
    buttonBg: "#ffffff",
    buttonText: "#aa1c3a",
    border: "rgba(255,255,255,0.2)"
  }
});

if (!result.canceled) {
  console.log("Selected file:", result.filePath);
  console.log("File content:", result.content);
}

Configuration Schema

interface FileDialogConfig {
  title?: string;           // Dialog title
  defaultPath?: string;     // Initial directory path
  filters?: Array<{         // File type filters
    name: string;           // Filter name (e.g., "YAML Files")
    extensions: string[];   // File extensions (e.g., ["yaml", "yml"])
  }>;
  colors?: {               // Custom colors
    background?: string;    // Dialog background
    text?: string;         // Text color
    buttonBg?: string;     // Button background
    buttonText?: string;   // Button text color
    border?: string;       // Border color
  };
}

Result Schema

interface FileDialogResult {
  canceled: boolean;       // True if dialog was canceled
  filePath?: string;       // Selected file path (if not canceled)
  content?: string;        // File content (if not canceled)
}

Features

File Browser

  • Directory Navigation: Click folders to navigate
  • File Selection: Click files to select, double-click to open
  • Path Input: Type path manually and press Enter
  • Browse Button: Alternative way to navigate directories

File Filtering

  • Extension-based: Filters files by extension
  • Multiple Filters: Support for multiple filter groups
  • Wildcard Support: Use "*" for all files

Styling

  • CSS Variables: Customizable via CSS custom properties
  • Theme Matching: Default colors match app footer theme
  • Responsive: Adapts to window resizing

File Icons

  • Extension-based: Different icons for different file types
  • Fallback: Default document icon for unknown types

Integration

Current Usage

The custom file dialog is automatically used by the file:open IPC handler:

  • Opens in the configs directory
  • Filters for YAML/encrypted/text files
  • Uses app theme colors

Manual Usage

You can also use it directly:

// From any Angular component
const result = await this.ipc.showCustomFileDialog({
  title: "Select Image",
  defaultPath: os.homedir(),
  filters: [
    { name: "Images", extensions: ["png", "jpg", "gif"] }
  ]
});

Advantages Over System Dialog

  1. Guaranteed Path: Always opens in the correct directory
  2. Custom Styling: Matches application theme
  3. File Content: Returns file content automatically
  4. Cross-platform: Consistent behavior across platforms
  5. Customizable: Easy to modify appearance and behavior

File Structure

src/main/
├── open-dialog.html        # Custom file dialog interface
├── main.js                # Updated with dialog functions
└── preload.js             # Updated with API exposure

src/frontend/src/app/
└── ipc.service.ts         # Updated with dialog wrapper

Technical Details

Window Configuration

  • Size: 800x600 pixels (resizable)
  • Modal: Always on top of parent window
  • Frameless: Custom window chrome
  • Node Integration: Enabled for file system access

File System Access

  • Read Directory: Lists files and folders
  • Read Files: Loads file content as UTF-8
  • Path Validation: Checks if paths exist and are accessible
  • Error Handling: Graceful handling of permission errors

IPC Communication

  • Config Channel: file-dialog:config - sends dialog configuration
  • Result Channel: file-dialog:result - returns selection result
  • Directory Picker: dialog:showDirectoryPicker - system directory selection
  • Async/Await: Promise-based API for easy integration

Recent Updates

File Open Dialog

  • File Preview: Added preview section showing first 500 characters of selected files
  • Smart Preview: Only shows preview for text files under 1MB
  • Preview Styling: Monospace font with scrollable content area

File Save Dialog

  • Files List: Replaced content preview with list of files in current directory
  • All Files Shown: Shows all files without filtering by extension
  • Browse Button: Now opens system directory picker dialog
  • Directory Navigation: Click directories in file list to navigate
  • File Information: Shows file size and type icons

This implementation provides a reliable, customizable file dialog that integrates seamlessly with the application's design and functionality.