more work

This commit is contained in:
Cipher Vance
2026-02-18 09:56:14 -06:00
parent 8634a76a44
commit dfc81b4485
4 changed files with 133 additions and 4 deletions

108
BUILD.md Normal file
View File

@@ -0,0 +1,108 @@
# Building RideAware Trainer
## Quick Start
### Local Development Build
```bash
npm run electron:dev
```
### Production Builds
#### Linux (from Linux)
```bash
npm run electron:build:linux
```
Builds: AppImage, deb, rpm (requires Ubuntu/Debian for deb/rpm)
#### Windows (from Windows)
```bash
npm run electron:build:win
```
Builds: NSIS installer (.exe)
#### macOS (from macOS)
```bash
npm run electron:build:mac
```
Builds: DMG, ZIP
## Cross-Platform Builds with GitHub Actions
The easiest way to build for all platforms is using GitHub Actions:
### Automatic Release Build
```bash
git tag v1.0.1
git push origin v1.0.1
```
This triggers the workflow which:
1. Builds on Windows, macOS, and Linux runners
2. Creates a GitHub Release
3. Uploads all installers (exe, dmg, AppImage, deb, rpm)
### Manual Build
Go to: GitHub → Actions → Build and Release → Run workflow
## Build Artifacts
After building, files are in the `release/` directory:
- **Windows**: `RideAware Trainer Setup 1.0.0.exe`
- **macOS**: `RideAware Trainer-1.0.0-arm64.dmg`, `RideAware Trainer-1.0.0-arm64-mac.zip`
- **Linux**:
- `RideAware Trainer-1.0.0.AppImage` (universal)
- `rideaware-trainer_1.0.0_amd64.deb` (Debian/Ubuntu)
- `rideaware-trainer-1.0.0.x86_64.rpm` (Fedora/RHEL)
## Platform Limitations
### Building from Linux
- ✅ Linux packages (AppImage always works, deb/rpm need Ubuntu)
- ❌ macOS DMG (requires macOS-specific dependencies)
- ❌ Windows EXE (requires Windows or Wine)
### Building from macOS
- ✅ macOS packages (DMG, ZIP)
- ✅ Linux packages (with Docker)
- ❌ Windows EXE (requires Windows or Wine)
### Building from Windows
- ✅ Windows packages (EXE)
- ✅ Linux packages (with WSL/Docker)
- ❌ macOS DMG (requires macOS)
**Recommendation**: Use GitHub Actions for cross-platform builds.
## Icon Requirements
Place app icons in the `build/` directory:
- `build/icon.ico` - Windows (256x256)
- `build/icon.icns` - macOS (1024x1024)
- `build/icon.png` - Linux (512x512)
## Troubleshooting
### "dmg-license not found" on Linux
This is expected. Build macOS packages on macOS or use GitHub Actions.
### "libcrypt.so.1 not found" on Fedora
Install compatibility package or use GitHub Actions (runs on Ubuntu).
### Build hangs on "packaging"
Check available disk space. Electron builds can use 500MB+ per platform.
## GitHub Actions Workflow
The workflow file is at `.github/workflows/build.yml`.
**Triggers:**
- Push to `main` branch (builds but doesn't release)
- Push tag starting with `v` (builds and creates release)
- Manual workflow dispatch
- Pull requests (builds but doesn't release)
**Permissions needed:**
- Repository Settings → Actions → General → Workflow permissions
- Enable "Read and write permissions"

View File

@@ -3,7 +3,7 @@ import {
getWorkoutsByMonth, getWorkoutsByMonth,
getTodaysWorkouts, getTodaysWorkouts,
getWeeksWorkouts, getWeeksWorkouts,
markWorkoutComplete, completeWorkout as apiCompleteWorkout,
} from '../services/api'; } from '../services/api';
import type { ApiWorkout } from '../types/api'; import type { ApiWorkout } from '../types/api';
import type { Workout, WorkoutInterval } from '../types/workout'; import type { Workout, WorkoutInterval } from '../types/workout';
@@ -166,17 +166,19 @@ export function useCalendarWorkouts(): UseCalendarWorkoutsReturn {
maxPower?: number; maxPower?: number;
maxHr?: number; maxHr?: number;
caloriesBurned?: number; caloriesBurned?: number;
syncToStrava?: boolean;
} }
) => { ) => {
try { try {
await markWorkoutComplete(workoutId, { await apiCompleteWorkout(workoutId, {
duration: Math.round(metrics.duration / 60), duration: Math.round(metrics.duration),
distance: metrics.distance, distance: metrics.distance,
avg_power: metrics.avgPower, avg_power: metrics.avgPower,
avg_hr: metrics.avgHr, avg_hr: metrics.avgHr,
max_power: metrics.maxPower, max_power: metrics.maxPower,
max_hr: metrics.maxHr, max_hr: metrics.maxHr,
calories_burned: metrics.caloriesBurned, calories_burned: metrics.caloriesBurned,
sync_to_strava: metrics.syncToStrava ?? true,
}); });
await refresh(); await refresh();
} catch (err) { } catch (err) {

View File

@@ -1,5 +1,5 @@
import { api } from './client'; import { api } from './client';
import type { ApiWorkout, WorkoutTemplate, WorkoutUpdatePayload } from '../../types/api'; import type { ApiWorkout, WorkoutTemplate, WorkoutUpdatePayload, WorkoutCompletionPayload } from '../../types/api';
export async function getWorkouts(): Promise<ApiWorkout[]> { export async function getWorkouts(): Promise<ApiWorkout[]> {
return api.get<ApiWorkout[]>('/protected/workouts'); return api.get<ApiWorkout[]>('/protected/workouts');
@@ -35,6 +35,13 @@ export async function markWorkoutComplete(
}); });
} }
export async function completeWorkout(
id: number,
completionData: WorkoutCompletionPayload
): Promise<ApiWorkout> {
return api.post<ApiWorkout>(`/protected/workouts/complete?id=${id}`, completionData);
}
export async function skipWorkout(id: number, notes?: string): Promise<ApiWorkout> { export async function skipWorkout(id: number, notes?: string): Promise<ApiWorkout> {
return api.put<ApiWorkout>(`/protected/workouts?id=${id}`, { return api.put<ApiWorkout>(`/protected/workouts?id=${id}`, {
status: 'skipped', status: 'skipped',

View File

@@ -151,3 +151,15 @@ export interface WorkoutUpdatePayload {
calories_burned?: number; calories_burned?: number;
notes?: string; notes?: string;
} }
export interface WorkoutCompletionPayload {
duration: number;
distance?: number;
avg_power?: number;
avg_hr?: number;
max_power?: number;
max_hr?: number;
calories_burned?: number;
notes?: string;
sync_to_strava?: boolean;
}