streamflow/desktop-app/DEVELOPER_GUIDE.md
2025-12-17 00:42:43 +00:00

12 KiB

StreamFlow Desktop App - Developer Guide

Project Structure

desktop-app/
├── src/
│   ├── main/
│   │   └── main.js              # Main Electron process
│   ├── preload/
│   │   └── preload.js           # Preload script (IPC bridge)
│   └── renderer/
│       ├── connection.html      # Connection setup UI
│       └── connection.js        # Connection logic
├── build/
│   ├── icon.png                 # Application icon (512x512)
│   └── streamflow.desktop       # Linux desktop entry
├── resources/                   # Additional resources
├── dist/                        # Build output (git-ignored)
├── package.json                 # Dependencies and build config
├── build.sh                     # Build script
├── README.md                    # User documentation
├── INSTALLATION.md              # Installation guide
├── SECURITY_AUDIT.md            # Security documentation
└── LICENSE                      # MIT License

Development Setup

Prerequisites

  1. Node.js 18+ and npm

    node --version  # Should be v18.0.0 or higher
    npm --version
    
  2. Development tools (for native modules)

    # Ubuntu/Debian
    sudo apt install build-essential
    
    # Fedora
    sudo dnf groupinstall "Development Tools"
    
    # Arch
    sudo pacman -S base-devel
    
  3. Optional: ImageMagick (for icon generation)

    sudo apt install imagemagick  # Ubuntu/Debian
    

Installation

  1. Clone the repository:

    cd /path/to/tv/desktop-app
    
  2. Install dependencies:

    npm install
    
  3. Create an icon (optional):

    # See build/ICON_README.md for instructions
    # Or let build.sh create a placeholder
    

Running the Application

Development Mode

Run with developer tools enabled:

npm run dev

This enables:

  • DevTools (Ctrl+Shift+I)
  • Hot reload (when you change files, restart the app)
  • Verbose logging

Production Mode

Run as end-users would:

npm start

Building the AppImage

Quick Build

# Build for current architecture
npm run build:appimage

# Or use the build script
./build.sh

The AppImage will be created in dist/:

dist/StreamFlow-1.0.0-x86_64.AppImage

Build for Specific Architecture

# x64 (64-bit Intel/AMD)
npm run build:linux -- --x64

# ARM64 (64-bit ARM, e.g., Raspberry Pi 4)
npm run build:linux -- --arm64

# Build both
npm run build:linux

Build Options

Edit package.json to customize:

{
  "build": {
    "appId": "com.streamflow.desktop",
    "productName": "StreamFlow",
    "linux": {
      "target": ["AppImage"],
      "category": "AudioVideo",
      "icon": "build/icon.png"
    }
  }
}

Project Architecture

Electron Architecture

┌─────────────────────────────────────────┐
│         Main Process (Node.js)          │
│  - Window management                    │
│  - Server configuration                 │
│  - Credential storage                   │
│  - IPC handlers                         │
└─────────────┬───────────────────────────┘
              │ IPC (secure)
              │
┌─────────────▼───────────────────────────┐
│      Preload Script (Bridge)            │
│  - Exposes safe APIs via contextBridge  │
│  - No direct Node.js access             │
└─────────────┬───────────────────────────┘
              │
┌─────────────▼───────────────────────────┐
│    Renderer Process (Chromium)          │
│  - Connection window (local HTML)       │
│  - Main window (loads web app)          │
│  - Isolated from Node.js                │
└─────────────────────────────────────────┘

Security Model

  1. Context Isolation: Renderer process is sandboxed
  2. IPC Communication: Only whitelisted methods exposed
  3. Credential Storage: Encrypted with electron-store
  4. CSP: Strict Content Security Policy
  5. External Links: Blocked by default

Configuration

Environment Variables

Create .env file (optional):

# Development mode
NODE_ENV=development

# Custom encryption key (production)
ENCRYPTION_KEY=your-random-32-byte-hex-string

Electron Store

Configuration stored in:

~/.config/streamflow-config/config.json

Structure:

{
  "serverUrl": "https://your-server.com",
  "rememberCredentials": true,
  "username": "user@example.com",
  "password": "encrypted-password-here"
}

Code Style

JavaScript Style

Follow these conventions:

// Use const for immutable values
const SERVER_URL = 'https://example.com';

// Use let for mutable values
let connectionStatus = 'disconnected';

// Use async/await over promises
async function fetchData() {
  try {
    const response = await axios.get(url);
    return response.data;
  } catch (error) {
    logger.error('Fetch failed:', error);
    throw error;
  }
}

// Proper error handling
ipcMain.handle('my-handler', async (event, args) => {
  try {
    // Logic here
    return { success: true, data };
  } catch (error) {
    logger.error('Handler error:', error);
    return { success: false, error: error.message };
  }
});

Comments

// Good: Explain WHY, not WHAT
// Check server health before storing config to prevent
// users from saving unreachable servers
const health = await testConnection(serverUrl);

// Bad: Comments that restate code
// Get the server URL
const serverUrl = config.get('serverUrl');

Testing

Manual Testing Checklist

  • Connection window appears on first launch
  • Server URL validation works
  • Test connection succeeds for valid URLs
  • Test connection fails gracefully for invalid URLs
  • Credentials are saved when "Remember" is checked
  • Credentials are NOT saved when unchecked
  • 2FA flow works (if enabled on server)
  • Main window loads web app correctly
  • Video playback works
  • Audio playback works
  • Settings persist between sessions
  • "Change Server" menu item works
  • App closes cleanly
  • Restart preserves configuration

Testing with Different Server Configurations

  1. HTTPS Server:

    https://streamflow.example.com
    
  2. HTTP Server (local):

    http://localhost:3000
    
  3. LAN Server:

    http://192.168.1.100:3000
    
  4. With 2FA Enabled:

    • Test TOTP code entry
    • Test backup code usage
    • Test invalid code handling

Automated Testing

Currently, tests are manual. To add automated tests:

npm install --save-dev spectron mocha chai

Example test:

const { Application } = require('spectron');
const assert = require('assert');

describe('Application launch', function() {
  this.timeout(10000);

  beforeEach(function() {
    this.app = new Application({
      path: electronPath,
      args: [path.join(__dirname, '..')]
    });
    return this.app.start();
  });

  afterEach(function() {
    if (this.app && this.app.isRunning()) {
      return this.app.stop();
    }
  });

  it('shows connection window', async function() {
    const count = await this.app.client.getWindowCount();
    assert.equal(count, 1);
  });
});

Debugging

Enable Logging

# Verbose logs
npm run dev -- --enable-logging --v=1

# Save logs to file
npm run dev 2>&1 | tee app.log

DevTools

In development mode, press:

  • Ctrl+Shift+I - Open DevTools
  • Ctrl+R - Reload window
  • Ctrl+Shift+R - Hard reload

Remote Debugging

# Enable remote debugging
npm run dev -- --remote-debugging-port=9222

# Then open in Chrome:
# chrome://inspect

Check Electron Version

// In DevTools console
console.log(process.versions);
// Shows Node, Chromium, V8, Electron versions

Common Issues

Issue: Cannot find module 'electron'

Solution:

rm -rf node_modules package-lock.json
npm install

Issue: AppImage won't build

Solution:

# Install dependencies
npm run postinstall

# Clean and rebuild
rm -rf dist
npm run build:appimage

Issue: Connection window doesn't show

Solution: Check if config exists:

cat ~/.config/streamflow-config/config.json

# To reset:
rm ~/.config/streamflow-config/config.json

Issue: CSP errors in console

Solution: Verify the serverUrl in CSP matches your server. Edit src/main/main.js:

"connect-src 'self' " + serverUrl + " https: http: ws: wss:; "

Performance Optimization

Reduce Bundle Size

# Analyze bundle
npm install --save-dev webpack-bundle-analyzer

# Build with analysis
npm run build -- --analyze

Hardware Acceleration

Ensure GPU acceleration is enabled:

// In main.js
app.commandLine.appendSwitch('enable-features', 'VaapiVideoDecoder');

Check in DevTools:

chrome://gpu

Deployment

Release Checklist

  • Update version in package.json
  • Update CHANGELOG.md
  • Test on clean system
  • Build for all architectures
  • Test AppImage on multiple distributions
  • Generate checksums
  • Create GitHub release
  • Update documentation

Creating a Release

# 1. Update version
npm version patch  # or minor, or major

# 2. Build
./build.sh

# 3. Generate checksums
cd dist
sha256sum StreamFlow-*.AppImage > SHA256SUMS

# 4. Create release on GitHub
# Upload AppImage files and SHA256SUMS

Versioning

Follow Semantic Versioning (SemVer):

  • MAJOR: Breaking changes
  • MINOR: New features, backwards compatible
  • PATCH: Bug fixes, backwards compatible

Example: 1.2.3

  • 1 = Major version
  • 2 = Minor version
  • 3 = Patch version

Contributing

Adding a New Feature

  1. Create a feature branch
  2. Implement the feature
  3. Test thoroughly
  4. Update documentation
  5. Submit pull request

Code Review Checklist

  • Code follows style guidelines
  • All functions have error handling
  • Security implications considered
  • Performance impact assessed
  • Documentation updated
  • Manual testing completed
  • No sensitive data in logs

Resources

Electron Documentation

electron-builder

Tools

Support

For issues or questions:

  1. Check existing documentation
  2. Search GitHub issues
  3. Create a new issue with:
    • OS and version
    • Electron version
    • Steps to reproduce
    • Error messages
    • Logs

License

MIT License - See LICENSE file for details.


Happy coding! 🚀