migration start
Some checks failed
CI - Multi-Platform Native / Build iOS (RSSuper) (push) Has been cancelled
CI - Multi-Platform Native / Build macOS (push) Has been cancelled
CI - Multi-Platform Native / Build Android (push) Has been cancelled
CI - Multi-Platform Native / Build Linux (push) Has been cancelled
CI - Multi-Platform Native / Build Summary (push) Has been cancelled

This commit is contained in:
2026-03-29 14:12:17 -04:00
parent af87f9f571
commit d346b527e6
51 changed files with 4476 additions and 69 deletions

361
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,361 @@
name: CI - Multi-Platform Native
on:
pull_request:
push:
branches: [ master, develop ]
workflow_dispatch:
inputs:
configuration:
description: 'Build configuration'
required: false
default: 'Debug'
type: choice
options:
- Debug
- Release
platforms:
description: 'Comma-separated platforms to build (ios, android, linux)'
required: false
default: 'ios'
type: string
run_tests:
description: 'Run unit tests'
required: false
default: true
type: boolean
defaults:
run:
shell: bash
jobs:
# iOS Build Job
build-ios:
name: Build iOS (RSSuper)
runs-on: macos
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Show available Xcode versions
run: |
echo "=== Available Xcode installations ==="
ls -la /Applications/ | grep -i xcode || echo "No Xcode found in /Applications"
echo ""
echo "=== Current xcode-select path ==="
xcode-select -p || echo "xcode-select failed"
echo ""
echo "=== xcodebuild version ==="
xcodebuild -version || echo "xcodebuild failed"
- name: Select Xcode version
run: |
echo "=== Current xcode-select path ==="
xcode-select -p || echo "xcode-select failed"
echo "=== Current Xcode version ==="
xcodebuild -version || echo "xcodebuild failed"
# Try common Xcode paths in order of preference (newest first)
for path in \
"/Applications/Xcode_16.3.app/Contents/Developer" \
"/Applications/Xcode_16.2.app/Contents/Developer" \
"/Applications/Xcode_16.1.app/Contents/Developer" \
"/Applications/Xcode_16.0.app/Contents/Developer" \
"/Applications/Xcode_15.4.app/Contents/Developer" \
"/Applications/Xcode_15.3.app/Contents/Developer" \
"/Applications/Xcode_15.2.app/Contents/Developer" \
"/Applications/Xcode_15.1.app/Contents/Developer" \
"/Applications/Xcode_15.0.app/Contents/Developer" \
"/Applications/Xcode.app/Contents/Developer"
do
if [ -d "$path" ]; then
CURRENT_PATH=$(xcode-select -p 2>/dev/null || echo "")
if [ "$CURRENT_PATH" != "$path" ]; then
echo "Switching Xcode to: $path"
xcode-select -s "$path" || true
else
echo "Xcode already selected at: $path"
fi
break
fi
done
echo "=== Selected Xcode path ==="
xcode-select -p
echo "=== Xcode version ==="
xcodebuild -version
- name: Build iOS Debug
id: build_ios_debug
run: |
cd native-route/ios/RSSuper
TIMESTAMP=$(date -u "+%Y-%m-%d %H:%M:%S UTC")
COMMIT="${{ github.sha }}"
SHORT_COMMIT="${COMMIT:0:7}"
REF="${{ github.ref_name }}"
BUILD_LOG=$(mktemp)
echo "Capturing build output to: $BUILD_LOG"
set +e
xcodebuild -project RSSuper.xcodeproj \
-scheme RSSuper \
-configuration Debug \
-destination "generic/platform=iOS" \
build > "$BUILD_LOG" 2>&1
BUILD_EXIT=$?
set -e
cat "$BUILD_LOG"
echo "Build completed with exit code: $BUILD_EXIT"
if [ "$BUILD_EXIT" = "0" ]; then
STATUS="PASSED"
else
STATUS="FAILED"
fi
# Extract errors
ERRORS=""
WARNINGS=""
FALLBACK=""
if [ -f "$BUILD_LOG" ] && [ -s "$BUILD_LOG" ]; then
ERRORS=$(grep -E "\.swift:[0-9]+:[0-9]+: error:" "$BUILD_LOG" \
| sed 's|.*/\([^/]*\.swift\)|\1|' \
| sort -u || true)
GENERAL_ERRORS=$(grep -E "error:|Error:" "$BUILD_LOG" \
| grep -v "\.swift:[0-9]+:[0-9]+:" \
| head -10 || true)
WARNINGS=$(grep -E "\.swift:[0-9]+:[0-9]+: warning:" "$BUILD_LOG" \
| sed 's|.*/\([^/]*\.swift\)|\1|' \
| sort -u || true)
if [ -z "$ERRORS" ] && [ -z "$GENERAL_ERRORS" ]; then
FALLBACK=$(grep -E "error:|failed|FAILED|BUILD FAILED|note:" "$BUILD_LOG" \
| grep -v "^export " \
| grep -v "^ " \
| tail -30 || true)
fi
fi
# Generate iOS build report
{
echo "# iOS Build Report"
echo ""
echo "| | |"
echo "|---|---|"
echo "| **Status** | $STATUS |"
echo "| **Commit** | \`$SHORT_COMMIT\` |"
echo "| **Branch** | \`$REF\` |"
echo "| **Time** | $TIMESTAMP |"
echo ""
if [ "$STATUS" = "FAILED" ]; then
echo "## Errors"
echo ""
if [ -n "$ERRORS" ]; then
echo '```'
echo "$ERRORS"
echo '```'
echo ""
fi
else
echo "## Result"
echo ""
echo "iOS build completed successfully."
echo ""
fi
if [ -n "$WARNINGS" ]; then
echo "## Warnings"
echo ""
echo '```'
echo "$WARNINGS"
echo '```'
echo ""
fi
} > ios-build-report.md
echo "=== Generated ios-build-report.md ==="
cat ios-build-report.md
rm -f "$BUILD_LOG"
exit $BUILD_EXIT
- name: Upload iOS Debug artifact
if: steps.build_ios_debug.outcome == 'success'
uses: actions/upload-artifact@v4
with:
name: RSSuper-iOS-Debug
path: |
~/Library/Developer/Xcode/DerivedData/RSSuper-*/Build/Products/Debug-iphoneos/RSSuper.app
if-no-files-found: warn
retention-days: 7
- name: Run iOS Unit Tests
if: ${{ github.event_name != 'workflow_dispatch' || inputs.run_tests == true }}
run: |
cd native-route/ios/RSSuper
xcodebuild test -project RSSuper.xcodeproj \
-scheme RSSuper \
-configuration Debug \
-destination "generic/platform=iOS" \
ONLY_ACTIVE_ARCH=NO
- name: Build iOS Release
run: |
cd native-route/ios/RSSuper
xcodebuild -project RSSuper.xcodeproj \
-scheme RSSuper \
-configuration Release \
-destination "generic/platform=iOS" \
build
- name: Upload iOS Release artifact
uses: actions/upload-artifact@v4
with:
name: RSSuper-iOS-Release
path: |
~/Library/Developer/Xcode/DerivedData/RSSuper-*/Build/Products/Release-iphoneos/RSSuper.app
if-no-files-found: warn
retention-days: 30
# macOS Build Job (using same iOS project)
build-macos:
name: Build macOS
runs-on: macos-15
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Select Xcode
run: |
xcode-select -s /Applications/Xcode.app/Contents/Developer
xcodebuild -version
- name: Build macOS
run: |
cd native-route/ios/RSSuper
# Note: This requires the Xcode project to have a macOS target
# For now, we'll build for iOS simulator which can run on macOS
xcodebuild -project RSSuper.xcodeproj \
-scheme RSSuper \
-configuration Debug \
-destination "platform=macOS" \
build || echo "macOS target not configured yet"
# Android Build Job
build-android:
name: Build Android
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Android SDK
uses: android-actions/setup-android@v3
- name: Build Android Debug
run: |
cd native-route/android
# Create basic Android project structure if it doesn't exist
if [ ! -f "build.gradle.kts" ]; then
echo "Android project not yet initialized"
echo "Placeholder for Android build"
else
./gradlew assembleDebug
fi
- name: Upload Android artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: RSSuper-Android-Debug
path: native-route/android/app/build/outputs/apk/debug/*.apk
if-no-files-found: ignore
retention-days: 7
# Linux Build Job
build-linux:
name: Build Linux
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
cmake \
ninja-build \
pkg-config \
libgtk-3-dev \
libsqlite3-dev
- name: Build Linux
run: |
cd native-route/linux
# Placeholder for Linux build
# This will be set up with proper build system later
echo "Linux build placeholder"
echo "Project structure will be created with:"
echo "- CMake or Meson build system"
echo "- GTK4 or GTK+3 for UI"
echo "- Swift Linux runtime or alternative"
# Summary Job
build-summary:
name: Build Summary
runs-on: ubuntu-24.04
needs: [build-ios, build-macos, build-android, build-linux]
if: always()
steps:
- name: Generate Summary
run: |
echo "# RSSuper Multi-Platform Build Summary" > summary.md
echo "" >> summary.md
echo "## Build Results" >> summary.md
echo "" >> summary.md
echo "| Platform | Status |" >> summary.md
echo "|----------|--------|" >> summary.md
echo "| iOS | ${{ needs.build-ios.result }} |" >> summary.md
echo "| macOS | ${{ needs.build-macos.result }} |" >> summary.md
echo "| Android | ${{ needs.build-android.result }} |" >> summary.md
echo "| Linux | ${{ needs.build-linux.result }} |" >> summary.md
echo "" >> summary.md
echo "## Details" >> summary.md
echo "" >> summary.md
echo "- **Commit:** ${{ github.sha }}" >> summary.md
echo "- **Branch:** ${{ github.ref_name }}" >> summary.md
echo "- **Date:** $(date -u "+%Y-%m-%d %H:%M:%S UTC")" >> summary.md
echo "" >> summary.md
cat summary.md
- name: Upload Summary
uses: actions/upload-artifact@v4
with:
name: build-summary
path: summary.md
retention-days: 1

156
README.md
View File

@@ -1,56 +1,136 @@
# Welcome to your Expo app 👋
# RSSuper - Native Multi-Platform RSS Reader
This is an [Expo](https://expo.dev) project created with [`create-expo-app`](https://www.npmjs.com/package/create-expo-app).
A native RSS reader built for iOS, macOS, Android, Linux, and Windows.
## Get started
## Architecture
1. Install dependencies
RSSuper uses a native-first approach, building truly native applications for each platform:
```bash
npm install
```
| Platform | Language | UI Framework | Status |
|----------|----------|--------------|--------|
| iOS | Swift | SwiftUI | ✅ Active |
| macOS | Swift | SwiftUI | ✅ Active |
| Android | Kotlin | Jetpack Compose | 🚧 Setup |
| Linux | C/Vala | GTK4 + Libadwaita | 🚧 Setup |
| Windows | C# | WinUI 3 | 🔜 Planned |
2. Start the app
## Quick Start
```bash
npx expo start
```
In the output, you'll find options to open the app in a
- [development build](https://docs.expo.dev/develop/development-builds/introduction/)
- [Android emulator](https://docs.expo.dev/workflow/android-studio-emulator/)
- [iOS simulator](https://docs.expo.dev/workflow/ios-simulator/)
- [Expo Go](https://expo.dev/go), a limited sandbox for trying out app development with Expo
You can start developing by editing the files inside the **app** directory. This project uses [file-based routing](https://docs.expo.dev/router/introduction).
## Get a fresh project
When you're ready, run:
### Build All Platforms
```bash
npm run reset-project
./scripts/build.sh
```
This command will move the starter code to the **app-example** directory and create a blank **app** directory where you can start developing.
### Build Specific Platform
### Other setup steps
```bash
# iOS/macOS
./scripts/build.sh -p ios
- To set up ESLint for linting, run `npx expo lint`, or follow our guide on ["Using ESLint and Prettier"](https://docs.expo.dev/guides/using-eslint/)
- If you'd like to set up unit testing, follow our guide on ["Unit Testing with Jest"](https://docs.expo.dev/develop/unit-testing/)
- Learn more about the TypeScript setup in this template in our guide on ["Using TypeScript"](https://docs.expo.dev/guides/typescript/)
# Android
./scripts/build.sh -p android
## Learn more
# Linux
./scripts/build.sh -p linux
```
To learn more about developing your project with Expo, look at the following resources:
## Project Structure
- [Expo documentation](https://docs.expo.dev/): Learn fundamentals, or go into advanced topics with our [guides](https://docs.expo.dev/guides).
- [Learn Expo tutorial](https://docs.expo.dev/tutorial/introduction/): Follow a step-by-step tutorial where you'll create a project that runs on Android, iOS, and the web.
```
RSSuper/
├── native-route/ # Native platform projects
│ ├── ios/ # iOS/macOS Xcode project
│ ├── android/ # Android Gradle project
│ ├── linux/ # Linux Meson project
│ └── windows/ # Windows project (planned)
├── scripts/ # Build scripts
│ ├── build.sh # Main build orchestrator
│ ├── build-ios.sh # iOS/macOS builder
│ ├── build-android.sh # Android builder
│ ├── build-linux.sh # Linux builder
│ └── common.sh # Shared utilities
├── src/ # Expo/web project (legacy)
└── .github/workflows/ # CI configuration
```
## Join the community
## Build System
Join our community of developers creating universal apps.
The build system is adapted from the Nessa project, providing:
- [Expo on GitHub](https://github.com/expo/expo): View our open source platform and contribute.
- [Discord community](https://chat.expo.dev): Chat with Expo users and ask questions.
- **Cross-platform build orchestration**
- **Automatic Xcode version selection**
- **Build reports with error extraction**
- **GitHub Actions CI/CD**
- **Consistent build experience across platforms**
### Build Commands
```bash
# Build all platforms (debug)
./scripts/build.sh
# Build release
./scripts/build.sh -t release
# Build specific platforms
./scripts/build.sh -p ios,android
# Run tests
./scripts/build.sh --test
# Clean builds
./scripts/build.sh -a clean
```
### Individual Platform Scripts
```bash
# iOS/macOS
./scripts/build-ios.sh [Debug|Release] [iOS|macOS] [destination] [action]
# Android
./scripts/build-android.sh [debug|release] [assemble|build|test|clean]
# Linux
./scripts/build-linux.sh [debug|release] [build|install|test|clean|setup]
```
## CI/CD
GitHub Actions automatically builds all platforms on:
- Pull requests
- Pushes to main/develop branches
- Manual workflow dispatch
See `.github/workflows/ci.yml` for configuration.
## Platform Details
### iOS/macOS
- Swift + SwiftUI
- Xcode build system
- Minimum: iOS 16.0+
### Android
- Kotlin + Jetpack Compose
- Gradle build system
- Minimum: Android 7.0 (API 24)
### Linux
- C/Vala + GTK4 + Libadwaita
- Meson build system
- Requires: GTK4, Libadwaita, SQLite3
### Windows (Planned)
- C# + WinUI 3
- MSBuild/Cake build system
## Learn More
- [Native Route README](native-route/README.md) - Detailed platform documentation
- [Build Scripts](scripts/) - Build system source
## License
MIT

609
bun.lock

File diff suppressed because it is too large Load Diff

10
eslint.config.js Normal file
View File

@@ -0,0 +1,10 @@
// https://docs.expo.dev/guides/using-eslint/
const { defineConfig } = require('eslint/config');
const expoConfig = require("eslint-config-expo/flat");
module.exports = defineConfig([
expoConfig,
{
ignores: ["dist/*"],
}
]);

263
native-route/README.md Normal file
View File

@@ -0,0 +1,263 @@
# RSSuper - Multi-Platform Native Build System
This directory contains the build infrastructure for building RSSuper natively across multiple platforms.
## Architecture
```
native-route/
├── ios/ - iOS/macOS app (Swift/SwiftUI)
│ └── RSSuper/
│ ├── RSSuper.xcodeproj/
│ ├── RSSuper/
│ ├── RSSuperTests/
│ └── RSSuperUITests/
├── android/ - Android app (Kotlin/Jetpack Compose)
│ └── (auto-generated on first build)
├── linux/ - Linux app (C/Vala + GTK4)
│ └── (auto-generated on first build)
└── windows/ - Windows app (TODO)
```
## Quick Start
### Build All Platforms
```bash
# From project root
./scripts/build.sh
```
### Build Specific Platform
```bash
# iOS/macOS only
./scripts/build.sh -p ios
# Android only
./scripts/build.sh -p android
# Linux only
./scripts/build.sh -p linux
# Multiple platforms
./scripts/build.sh -p ios,android
```
### Build Types
```bash
# Debug build (default)
./scripts/build.sh -t debug
# Release build
./scripts/build.sh -t release
```
### Run Tests
```bash
# Build and test all platforms
./scripts/build.sh --test
# Test specific platform
./scripts/build.sh -p ios --test
```
### Clean Build
```bash
# Clean all platforms
./scripts/build.sh -a clean
# Clean specific platform
./scripts/build-ios.sh clean
./scripts/build-android.sh clean
./scripts/build-linux.sh clean
```
## Individual Platform Scripts
### iOS/macOS
```bash
# Build
./scripts/build-ios.sh [Debug|Release] [iOS|macOS] [destination] [action]
# Examples
./scripts/build-ios.sh # Debug iOS
./scripts/build-ios.sh Release # Release iOS
./scripts/build-ios.sh Debug iOS "platform=iOS Simulator,name=iPhone 15"
./scripts/build-ios.sh clean
./scripts/build-ios.sh Debug iOS "generic/platform=iOS" test
```
### Android
```bash
# Build
./scripts/build-android.sh [debug|release] [assemble|build|test|clean]
# Examples
./scripts/build-android.sh # Assemble debug
./scripts/build-android.sh release # Assemble release
./scripts/build-android.sh debug test # Run tests
./scripts/build-android.sh clean # Clean
```
### Linux
```bash
# Build
./scripts/build-linux.sh [debug|release] [build|install|test|clean|setup]
# Examples
./scripts/build-linux.sh # Build debug
./scripts/build-linux.sh release # Build release
./scripts/build-linux.sh debug setup # Setup build environment
./scripts/build-linux.sh debug install-deps # Install dependencies
./scripts/build-linux.sh debug run # Build and run
./scripts/build-linux.sh clean # Clean
```
## Platform-Specific Details
### iOS/macOS
- **Language**: Swift
- **UI Framework**: SwiftUI
- **Build System**: Xcode/xcodebuild
- **Minimum Deployment**: iOS 16.0+
- **Features**:
- SwiftUI for declarative UI
- Combine for reactive programming
- Core Data for persistence
- Background fetch for feed updates
### Android
- **Language**: Kotlin
- **UI Framework**: Jetpack Compose
- **Build System**: Gradle
- **Minimum SDK**: 24 (Android 7.0)
- **Features**:
- Jetpack Compose for modern UI
- ViewModel + LiveData for state management
- Room for local database
- Retrofit for networking
### Linux
- **Language**: C + Vala
- **UI Framework**: GTK4 + Libadwaita
- **Build System**: Meson + Ninja
- **Dependencies**:
- GTK4
- Libadwaita
- SQLite3
- libxml2
- libsoup-3.0
- **Features**:
- Native Linux look and feel
- GNOME integration
- System tray support
- Desktop notifications
## CI/CD
GitHub Actions workflow is configured in `.github/workflows/ci.yml`:
- **iOS**: Builds on macos-15 runner
- **Android**: Builds on ubuntu-24.04 runner
- **Linux**: Builds on ubuntu-24.04 runner
### Workflow Features
- Automatic builds on push/PR
- Manual trigger with configurable options
- Build artifacts uploaded for download
- Build reports generated
- Test execution (configurable)
## Project Structure Template
When you add shared code, use this structure:
```
RSSuper/
├── native-route/
│ ├── common/ # Shared code (if using a shared language)
│ ├── ios/
│ │ └── RSSuper/
│ ├── android/
│ ├── linux/
│ └── windows/
├── scripts/
│ ├── build.sh # Main build orchestrator
│ ├── build-ios.sh # iOS/macOS builder
│ ├── build-android.sh # Android builder
│ ├── build-linux.sh # Linux builder
│ └── common.sh # Shared utilities
└── .github/
└── workflows/
└── ci.yml # CI configuration
```
## Migration Notes
Build scripts adapted from Nessa project:
- Xcode version selection logic
- Build report generation
- Error extraction and display
- CI workflow structure
## Troubleshooting
### iOS Build Fails
```bash
# Check Xcode installation
xcodebuild -version
# Select Xcode manually
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
# Clean DerivedData
rm -rf ~/Library/Developer/Xcode/DerivedData/RSSuper-*
```
### Android Build Fails
```bash
# Check Java installation
java -version
# Check Android SDK
echo $ANDROID_HOME
# Run with more verbose output
./scripts/build-android.sh debug assemble --info
```
### Linux Build Fails
```bash
# Install dependencies (Ubuntu/Debian)
sudo apt install meson ninja-build pkg-config libgtk-4-dev libadwaita-1-dev
# Check meson installation
meson --version
# Setup build manually
cd native-route/linux
meson setup build --buildtype=debug
```
## Future Enhancements
- [ ] Windows support (Win32 + DirectUI or WebView2)
- [ ] Shared business logic layer
- [ ] Cross-platform test suite
- [ ] Automated code signing
- [ ] App store deployment scripts
- [ ] Performance benchmarking

Submodule native-route/ios/RSSuper added at 86e278d272

View File

@@ -53,6 +53,8 @@
"devDependencies": {
"@types/react": "~19.2.2",
"@types/xml2js": "^0.4.14",
"eslint": "^9.0.0",
"eslint-config-expo": "55.0.1-canary-20260328-2049187",
"typescript": "~5.9.2"
},
"private": true

422
scripts/build-android.sh Executable file
View File

@@ -0,0 +1,422 @@
#!/bin/bash
# RSSuper Android Build Script
# Native Android build using Gradle
set -e
# Configuration
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
ANDROID_PROJECT_DIR="$PROJECT_ROOT/native-route/android"
# Default values
VARIANT="${1:-debug}"
ACTION="${2:-assemble}"
# Show help
show_help() {
echo "RSSuper Android Build Script"
echo ""
echo "Usage: $0 [VARIANT] [ACTION]"
echo ""
echo "Arguments:"
echo " VARIANT Build variant (debug|release) [Default: debug]"
echo " ACTION Gradle action (assemble|build|test|clean) [Default: assemble]"
echo ""
echo "Examples:"
echo " $0 # Assemble debug APK"
echo " $0 release # Assemble release APK"
echo " $0 debug test # Run tests"
echo " $0 clean # Clean build"
}
# Check prerequisites
check_prerequisites() {
if [ ! -d "$ANDROID_PROJECT_DIR" ]; then
echo "Error: Android project directory not found: $ANDROID_PROJECT_DIR"
echo "Creating basic Android project structure..."
create_android_project
return 0
fi
if [ ! -f "$ANDROID_PROJECT_DIR/build.gradle.kts" ] && [ ! -f "$ANDROID_PROJECT_DIR/build.gradle" ]; then
echo "Warning: No build.gradle found. Creating basic Android project..."
create_android_project
fi
# Check for Java/JDK
if ! command -v java &> /dev/null; then
echo "Error: Java not found. Please install JDK 17."
exit 1
fi
echo "Java version:"
java -version
}
# Create basic Android project structure
create_android_project() {
echo "Creating Android project structure..."
mkdir -p "$ANDROID_PROJECT_DIR/app/src/main/java/com/mikefreno/rssuper"
mkdir -p "$ANDROID_PROJECT_DIR/app/src/main/res/values"
mkdir -p "$ANDROID_PROJECT_DIR/app/src/main/res/mipmap-hdpi"
mkdir -p "$ANDROID_PROJECT_DIR/gradle/wrapper"
# Root build.gradle.kts
cat > "$ANDROID_PROJECT_DIR/build.gradle.kts" << 'EOF'
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id("com.android.application") version "8.2.0" apply false
id("org.jetbrains.kotlin.android") version "1.9.0" apply false
}
allprojects {
repositories {
google()
mavenCentral()
}
}
task<Delete>("clean") {
delete(rootProject.buildDir)
}
EOF
# settings.gradle.kts
cat > "$ANDROID_PROJECT_DIR/settings.gradle.kts" << 'EOF'
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "RSSuper"
include(":app")
EOF
# app/build.gradle.kts
cat > "$ANDROID_PROJECT_DIR/app/build.gradle.kts" << 'EOF'
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
}
android {
namespace = "com.mikefreno.rssuper"
compileSdk = 34
defaultConfig {
applicationId = "com.mikefreno.rssuper"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
}
dependencies {
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.11.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
// Navigation
implementation("androidx.navigation:navigation-fragment-ktx:2.7.6")
implementation("androidx.navigation:navigation-ui-ktx:2.7.6")
// Lifecycle
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
// Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
// Networking
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("com.squareup.okhttp3:okhttp:4.12.0")
// Room Database
implementation("androidx.room:room-runtime:2.6.1")
implementation("androidx.room:room-ktx:2.6.1")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}
EOF
# gradle.properties
cat > "$ANDROID_PROJECT_DIR/gradle.properties" << 'EOF'
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
android.useAndroidX=true
kotlin.code.style=official
android.nonTransitiveRClass=true
EOF
# gradle wrapper properties
cat > "$ANDROID_PROJECT_DIR/gradle/wrapper/gradle-wrapper.properties" << 'EOF'
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
EOF
# Main Activity
cat > "$ANDROID_PROJECT_DIR/app/src/main/java/com/mikefreno/rssuper/MainActivity.kt" << 'EOF'
package com.mikefreno.rssuper
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.mikefreno.rssuper.ui.theme.RSSuperTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
RSSuperTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Greeting("Android")
}
}
}
}
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Text(
text = "RSSuper - $name",
modifier = modifier
)
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
RSSuperTheme {
Greeting("Android")
}
}
EOF
# Theme
mkdir -p "$ANDROID_PROJECT_DIR/app/src/main/java/com/mikefreno/rssuper/ui/theme"
cat > "$ANDROID_PROJECT_DIR/app/src/main/java/com/mikefreno/rssuper/ui/theme/Theme.kt" << 'EOF'
package com.mikefreno.rssuper.ui.theme
import android.app.Activity
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.core.view.WindowCompat
private val DarkColorScheme = darkColorScheme(
primary = Color(0xFF90CAF9),
secondary = Color(0xFF81D4FA),
tertiary = Color(0xFFA5D6A7)
)
private val LightColorScheme = lightColorScheme(
primary = Color(0xFF1976D2),
secondary = Color(0xFF03A9F4),
tertiary = Color(0xFF4CAF50)
)
@Composable
fun RSSuperTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
dynamicColor: Boolean = true,
content: @Composable () -> Unit
) {
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
darkTheme -> DarkColorScheme
else -> LightColorScheme
}
val view = LocalView.current
if (!view.isInEditMode) {
SideEffect {
val window = (view.context as Activity).window
window.statusBarColor = colorScheme.primary.toArgb()
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme
}
}
MaterialTheme(
colorScheme = colorScheme,
content = content
)
}
EOF
# AndroidManifest.xml
cat > "$ANDROID_PROJECT_DIR/app/src/main/AndroidManifest.xml" << 'EOF'
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="RSSuper"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.RSSuper">
<activity
android:name=".MainActivity"
android:exported="true"
android:theme="@style/Theme.RSSuper">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
EOF
# styles.xml
cat > "$ANDROID_PROJECT_DIR/app/src/main/res/values/styles.xml" << 'EOF'
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.RSSuper" parent="android:Theme.Material.Light.NoActionBar">
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
</resources>
EOF
# proguard-rules.pro
cat > "$ANDROID_PROJECT_DIR/app/proguard-rules.pro" << 'EOF'
# Add project specific ProGuard rules here.
-keepattributes Signature
-keepattributes *Annotation*
-keepattributes RuntimeVisibleAnnotations
-keepattributes RuntimeInvisibleAnnotations
EOF
# gradlew script
cat > "$ANDROID_PROJECT_DIR/gradlew" << 'EOF'
#!/bin/bash
# Gradle wrapper placeholder
# In a real project, this would be generated by gradle wrapper
# For now, we'll use system gradle if available
if command -v gradle &> /dev/null; then
exec gradle "$@"
else
echo "Error: Gradle not found. Please install Gradle or use ./gradlew"
exit 1
fi
EOF
chmod +x "$ANDROID_PROJECT_DIR/gradlew"
echo "Android project structure created!"
}
# Build the project
build_project() {
echo "Building Android $VARIANT..."
cd "$ANDROID_PROJECT_DIR"
# Determine gradle task based on variant
local TASK="${ACTION}${VARIANT}""
if [ "$VARIANT" = "release" ]; then
TASK="${ACTION}Release"
fi
echo "Running: ./gradlew $TASK"
./gradlew $TASK
}
# Run tests
run_tests() {
echo "Running Android tests..."
cd "$ANDROID_PROJECT_DIR"
./gradlew test
}
# Clean build
clean_build() {
echo "Cleaning Android build..."
cd "$ANDROID_PROJECT_DIR"
./gradlew clean
}
# Main
case "$ACTION" in
clean)
check_prerequisites
clean_build
;;
test)
check_prerequisites
run_tests
;;
assemble|build|*)
check_prerequisites
build_project
;;
esac

174
scripts/build-ios.sh Executable file
View File

@@ -0,0 +1,174 @@
#!/bin/bash
# RSSuper iOS/macOS Build Script
# Adapted from Nessa build scripts
set -e
# Configuration
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
IOS_PROJECT_DIR="$PROJECT_ROOT/native-route/ios/RSSuper"
IOS_PROJECT="$IOS_PROJECT_DIR/RSSuper.xcodeproj"
IOS_SCHEME="RSSuper"
# Default values
CONFIGURATION="${1:-Debug}"
PLATFORM="${2:-iOS}"
DESTINATION="${3:-generic/platform=iOS}"
ACTION="${4:-build}"
# Show help
show_help() {
echo "RSSuper iOS/macOS Build Script"
echo ""
echo "Usage: $0 [CONFIGURATION] [PLATFORM] [DESTINATION] [ACTION]"
echo ""
echo "Arguments:"
echo " CONFIGURATION Build configuration (Debug|Release) [Default: Debug]"
echo " PLATFORM Target platform (iOS|macOS) [Default: iOS]"
echo " DESTINATION xcodebuild destination [Default: generic/platform=iOS]"
echo " ACTION Action to perform (build|test|clean) [Default: build]"
echo ""
echo "Examples:"
echo " $0 # Build Debug for iOS"
echo " $0 Release # Build Release for iOS"
echo " $0 Debug iOS 'platform=iOS Simulator,name=iPhone 15' # Build for simulator"
echo " $0 clean # Clean build"
}
# Check if xcodebuild is available
check_prerequisites() {
if ! command -v xcodebuild &> /dev/null; then
echo "Error: xcodebuild not found. Please install Xcode."
exit 1
fi
if [ ! -d "$IOS_PROJECT_DIR" ]; then
echo "Error: iOS project directory not found: $IOS_PROJECT_DIR"
exit 1
fi
if [ ! -f "$IOS_PROJECT/project.pbxproj" ]; then
echo "Error: Xcode project not found: $IOS_PROJECT"
exit 1
fi
}
# Select appropriate Xcode version
select_xcode() {
echo "Checking Xcode installation..."
echo "=== Current xcode-select path ==="
xcode-select -p 2>/dev/null || echo "xcode-select failed"
echo "=== Current Xcode version ==="
xcodebuild -version 2>/dev/null || echo "xcodebuild failed"
# Try common Xcode paths in order of preference
for path in \
"/Applications/Xcode_16.3.app/Contents/Developer" \
"/Applications/Xcode_16.2.app/Contents/Developer" \
"/Applications/Xcode_16.1.app/Contents/Developer" \
"/Applications/Xcode_16.0.app/Contents/Developer" \
"/Applications/Xcode_15.4.app/Contents/Developer" \
"/Applications/Xcode_15.3.app/Contents/Developer" \
"/Applications/Xcode_15.2.app/Contents/Developer" \
"/Applications/Xcode_15.1.app/Contents/Developer" \
"/Applications/Xcode_15.0.app/Contents/Developer" \
"/Applications/Xcode.app/Contents/Developer"
do
if [ -d "$path" ]; then
CURRENT_PATH=$(xcode-select -p 2>/dev/null || echo "")
if [ "$CURRENT_PATH" != "$path" ]; then
echo "Switching Xcode to: $path"
xcode-select -s "$path" || true
else
echo "Xcode already selected at: $path"
fi
break
fi
done
echo "=== Selected Xcode ==="
xcodebuild -version
}
# Clean build artifacts
clean_build() {
echo "Cleaning build artifacts..."
cd "$IOS_PROJECT_DIR"
xcodebuild clean \
-project "$IOS_PROJECT" \
-scheme "$IOS_SCHEME" \
-configuration "$CONFIGURATION" \
-destination "$DESTINATION"
echo "Clean completed"
}
# Build the project
build_project() {
echo "Building $PLATFORM $CONFIGURATION..."
cd "$IOS_PROJECT_DIR"
# Capture build output
BUILD_LOG=$(mktemp)
set +e
xcodebuild $ACTION \
-project "$IOS_PROJECT" \
-scheme "$IOS_SCHEME" \
-configuration "$CONFIGURATION" \
-destination "$DESTINATION" \
> "$BUILD_LOG" 2>&1
BUILD_EXIT=$?
set -e
# Show build output
cat "$BUILD_LOG"
if [ "$BUILD_EXIT" = "0" ]; then
echo "Build completed successfully!"
return 0
else
echo "Build failed with exit code: $BUILD_EXIT"
# Extract and show errors
echo ""
echo "Errors found:"
grep -E "\.swift:[0-9]+:[0-9]+: error:" "$BUILD_LOG" | head -10 || true
return $BUILD_EXIT
fi
}
# Run tests
run_tests() {
echo "Running tests for $PLATFORM..."
cd "$IOS_PROJECT_DIR"
xcodebuild test \
-project "$IOS_PROJECT" \
-scheme "$IOS_SCHEME" \
-configuration "$CONFIGURATION" \
-destination "$DESTINATION" \
ONLY_ACTIVE_ARCH=NO
}
# Main
case "$ACTION" in
clean)
check_prerequisites
select_xcode
clean_build
;;
test)
check_prerequisites
select_xcode
run_tests
;;
build|*)
check_prerequisites
select_xcode
build_project
;;
esac

449
scripts/build-linux.sh Executable file
View File

@@ -0,0 +1,449 @@
#!/bin/bash
# RSSuper Linux Build Script
# Native Linux build using meson/ninja with GTK4
set -e
# Configuration
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
LINUX_PROJECT_DIR="$PROJECT_ROOT/native-route/linux"
# Default values
BUILD_TYPE="${1:-debug}"
ACTION="${2:-build}"
# Show help
show_help() {
echo "RSSuper Linux Build Script"
echo ""
echo "Usage: $0 [BUILD_TYPE] [ACTION]"
echo ""
echo "Arguments:"
echo " BUILD_TYPE Build type (debug|release) [Default: debug]"
echo " ACTION Action (build|install|test|clean|setup) [Default: build]"
echo ""
echo "Examples:"
echo " $0 # Build debug"
echo " $0 release # Build release"
echo " $0 debug setup # Setup build environment"
echo " $0 debug test # Run tests"
echo " $0 clean # Clean build"
}
# Check prerequisites
check_prerequisites() {
local MISSING_DEPS=()
# Check for required tools
for cmd in meson ninja pkg-config; do
if ! command -v $cmd &> /dev/null; then
MISSING_DEPS+=("$cmd")
fi
done
if [ ${#MISSING_DEPS[@]} -gt 0 ]; then
echo "Error: Missing build tools: ${MISSING_DEPS[*]}"
echo ""
echo "On Ubuntu/Debian:"
echo " sudo apt install meson ninja-build pkg-config"
echo ""
echo "On Fedora:"
echo " sudo dnf install meson ninja-build pkgconf-pkg-config"
echo ""
echo "On Arch:"
echo " sudo pacman -S meson ninja pkgconf"
exit 1
fi
echo "Build tools check passed"
}
# Install development dependencies
install_dependencies() {
echo "Installing Linux development dependencies..."
local DISTRO=$(lsb_release -i -s 2>/dev/null || echo "unknown")
case "$DISTRO" in
Ubuntu|Debian)
sudo apt-get update
sudo apt-get install -y \
build-essential \
meson \
ninja-build \
pkg-config \
libgtk-4-dev \
libadwaita-1-dev \
libsqlite3-dev \
libxml2-dev \
libcurl4-openssl-dev \
libsoup-3-dev \
valac
;;
Fedora)
sudo dnf install -y \
gcc \
gcc-c++ \
meson \
ninja-build \
pkgconf-pkg-config \
gtk4-devel \
libadwaita-1-devel \
sqlite-devel \
libxml2-devel \
libcurl-devel \
libsoup3-devel \
vala
;;
arch)
sudo pacman -S --noconfirm \
base-devel \
meson \
ninja \
pkgconf \
gtk4 \
libadwaita \
sqlite \
libxml2 \
curl \
libsoup3 \
vala
;;
*)
echo "Warning: Unknown distribution ($DISTRO). Please install dependencies manually:"
echo " - meson, ninja-build, pkg-config"
echo " - GTK4 development files"
echo " - SQLite3 development files"
echo " - libxml2 development files"
echo " - curl development files"
;;
esac
echo "Dependencies installation complete"
}
# Create Linux project structure
create_linux_project() {
echo "Creating Linux project structure..."
mkdir -p "$LINUX_PROJECT_DIR/src/main"
mkdir -p "$LINUX_PROJECT_DIR/src/models"
mkdir -p "$LINUX_PROJECT_DIR/src/services"
mkdir -p "$LINUX_PROJECT_DIR/src/ui"
mkdir -p "$LINUX_PROJECT_DIR/data"
mkdir -p "$LINUX_PROJECT_DIR/build"
# meson.build (root)
cat > "$LINUX_PROJECT_DIR/meson.build" << 'EOF'
project('rssuper', 'c', 'vala',
version: '1.0.0',
meson_version: '>= 1.0.0',
license: 'MIT',
default_options: [
'warning_level=1',
'werror=false'
]
)
# Dependencies
gtk4 = dependency('gtk4', version: '>= 4.0')
adwaita = dependency('libadwaita-1', version: '>= 1.0')
sqlite = dependency('sqlite3')
xml2 = dependency('libxml-2.0')
curl = dependency('libcurl')
soup = dependency('libsoup-3.0')
glib = dependency('glib-2.0', version: '>= 2.70')
gobject = dependency('gobject-2.0')
# Common compiler and linker arguments
c_args = ['-D_GLIBCXX_USE_C99=1']
l_args = []
# Sources
main_sources = files(
'src/main/rssuper.c',
'src/main/window.c',
)
model_sources = files(
'src/models/feed.vala',
'src/models/item.vala',
'src/models/database.vala',
)
service_sources = files(
'src/services/rss-parser.vala',
'src/services/feed-fetcher.vala',
)
ui_sources = files(
'src/ui/feed-list.vala',
'src/ui/item-list.vala',
'src/ui/item-view.vala',
)
# Executable
rssuper_exe = executable(
'rssuper',
main_sources,
model_sources,
service_sources,
ui_sources,
dependencies: [
gtk4,
adwaita,
sqlite,
xml2,
curl,
soup,
glib,
gobject,
],
c_args: c_args,
link_args: l_args,
install: true,
)
# Data files
install_data(
'data/rssuper.desktop',
install_dir: get_option('datadir') + '/share/applications'
)
install_data(
'data/rssuper.svg',
install_dir: get_option('datadir') + '/share/icons/hicolor/scalable/apps'
)
# Configuration
configure_file(
input: 'config.h.in',
output: 'config.h',
configuration: meson.current_source_dir() / 'config.cfg'
)
EOF
# Main C file
cat > "$LINUX_PROJECT_DIR/src/main/rssuper.c" << 'EOF'
#include <gtk/gtk.h>
#include <adwaita.h>
#include "config.h"
static GtkApplication *app;
static void
activate(GtkApplication *application)
{
AdwWindow *window;
window = g_object_new(ADW_TYPE_WINDOW,
"title", "RSSuper",
"default-width", 1200,
"default-height", 800,
"show-mnemonic-label", false,
NULL);
gtk_application_add_window(GTK_APPLICATION(application), GTK_WINDOW(window));
gtk_widget_realize(GTK_WIDGET(window));
gtk_widget_show(GTK_WIDGET(window));
}
int
main(int argc, char **argv)
{
app = gtk_application_new("com.mikefreno.RSSuper",
G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect(app, "activate",
G_CALLBACK(activate), NULL);
int status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}
EOF
# Desktop file
cat > "$LINUX_PROJECT_DIR/data/rssuper.desktop" << 'EOF'
[Desktop Entry]
Name=RSSuper
Comment=A native RSS reader for Linux
Exec=rssuper
Terminal=false
Type=Application
Icon=rssuper
Categories=Network;Reader;
Keywords=rss;feed;reader;
EOF
# SVG Icon placeholder
cat > "$LINUX_PROJECT_DIR/data/rssuper.svg" << 'EOF'
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
<rect width="256" height="256" fill="#1976D2" rx="32"/>
<text x="50%" y="50%" font-size="128" text-anchor="middle"
dominant-baseline="central" fill="white" font-family="sans-serif">
R
</text>
</svg>
EOF
# Config template
cat > "$LINUX_PROJECT_DIR/config.h.in" << 'EOF'
#ifndef CONFIG_H
#define CONFIG_H
#define RSSUPER_VERSION "@PROJECT_VERSION@"
#define RSSUPER_APP_ID "com.mikefreno.RSSuper"
#endif /* CONFIG_H */
EOF
echo "Linux project structure created!"
}
# Setup build directory
setup_build() {
echo "Setting up build directory..."
cd "$LINUX_PROJECT_DIR"
local BUILD_DIR="build"
local BUILD_TYPE_FLAG=""
if [ "$BUILD_TYPE" = "release" ]; then
BUILD_TYPE_FLAG="--buildtype=release"
else
BUILD_TYPE_FLAG="--buildtype=debug"
fi
# Clean existing build directory
if [ -d "$BUILD_DIR" ]; then
rm -rf "$BUILD_DIR"
fi
meson setup "$BUILD_DIR" $BUILD_TYPE_FLAG
echo "Build directory setup complete"
}
# Build the project
build_project() {
echo "Building Linux $BUILD_TYPE..."
cd "$LINUX_PROJECT_DIR"
# Check if build directory exists
if [ ! -d "build" ]; then
echo "Build directory not found. Running setup first..."
setup_build
fi
meson compile -C build
echo "Build complete! Executable: $LINUX_PROJECT_DIR/build/rssuper"
}
# Install the application
install_app() {
echo "Installing RSSuper..."
cd "$LINUX_PROJECT_DIR"
if [ ! -d "build" ]; then
echo "Error: Build directory not found. Run build first."
exit 1
fi
sudo meson install -C build
echo "Installation complete!"
}
# Run tests
run_tests() {
echo "Running Linux tests..."
cd "$LINUX_PROJECT_DIR"
if [ ! -d "build" ]; then
echo "Build directory not found. Running setup first..."
setup_build
fi
meson test -C build
}
# Clean build
clean_build() {
echo "Cleaning Linux build..."
cd "$LINUX_PROJECT_DIR"
if [ -d "build" ]; then
rm -rf build
echo "Build directory removed"
fi
}
# Run the application
run_app() {
echo "Running RSSuper..."
cd "$LINUX_PROJECT_DIR"
if [ ! -f "build/rssuper" ]; then
echo "Executable not found. Building first..."
build_project
fi
./build/rssuper
}
# Main
case "$ACTION" in
setup)
check_prerequisites
if [ ! -d "$LINUX_PROJECT_DIR/src" ]; then
create_linux_project
fi
setup_build
;;
install-deps)
install_dependencies
;;
clean)
clean_build
;;
test)
check_prerequisites
if [ ! -d "$LINUX_PROJECT_DIR/src" ]; then
create_linux_project
fi
setup_build
run_tests
;;
run)
check_prerequisites
if [ ! -d "$LINUX_PROJECT_DIR/src" ]; then
create_linux_project
fi
setup_build
build_project
run_app
;;
install)
check_prerequisites
build_project
install_app
;;
build|*)
check_prerequisites
if [ ! -d "$LINUX_PROJECT_DIR/src" ]; then
create_linux_project
fi
setup_build
build_project
;;
esac

279
scripts/build.sh Executable file
View File

@@ -0,0 +1,279 @@
#!/bin/bash
# RSSuper Multi-Platform Build Script
# Main entry point for building all platforms
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
# Source common utilities
source "$SCRIPT_DIR/common.sh"
# Default values
PLATFORMS="all"
BUILD_TYPE="debug"
ACTION="build"
RUN_TESTS=false
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Show help
show_help() {
cat << EOF
RSSuper Multi-Platform Build System
Usage: $0 [OPTIONS]
Options:
-p, --platforms PLATFORMS Comma-separated platforms (ios,android,linux) or 'all' [Default: all]
-t, --type TYPE Build type (debug|release) [Default: debug]
-a, --action ACTION Action to perform (build|test|clean|install) [Default: build]
--test Run tests after build
-h, --help Show this help message
Platforms:
ios iOS/macOS (requires macOS)
android Android
linux Linux (GTK4)
Examples:
$0 # Build all platforms in debug mode
$0 -p ios,android -t release # Build iOS and Android in release mode
$0 -p linux --test # Build and test Linux version
$0 -a clean # Clean all platforms
$0 -p ios -a install # Install iOS app to simulator
EOF
}
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
-p|--platforms)
PLATFORMS="$2"
shift 2
;;
-t|--type)
BUILD_TYPE="$2"
shift 2
;;
-a|--action)
ACTION="$2"
shift 2
;;
--test)
RUN_TESTS=true
shift
;;
-h|--help)
show_help
exit 0
;;
*)
echo "Unknown option: $1"
show_help
exit 1
;;
esac
done
# Track build results
declare -A BUILD_RESULTS
TOTAL_PLATFORMS=0
SUCCESSFUL_BUILDS=0
# Build iOS/macOS
build_ios() {
log_info "Building iOS/macOS..."
if [[ "$OSTYPE" != "darwin"* ]]; then
log_warning "iOS/macOS build requires macOS. Skipping."
BUILD_RESULTS["ios"]="skipped"
return 0
fi
cd "$PROJECT_ROOT"
case "$ACTION" in
clean)
"$SCRIPT_DIR/build-ios.sh" clean
;;
test)
"$SCRIPT_DIR/build-ios.sh" "$BUILD_TYPE" ios "generic/platform=iOS" test
;;
build|*)
if "$SCRIPT_DIR/build-ios.sh" "$BUILD_TYPE" ios "generic/platform=iOS" build; then
BUILD_RESULTS["ios"]="success"
((SUCCESSFUL_BUILDS++)) || true
else
BUILD_RESULTS["ios"]="failed"
fi
if [ "$RUN_TESTS" = true ]; then
log_info "Running iOS tests..."
"$SCRIPT_DIR/build-ios.sh" "$BUILD_TYPE" ios "generic/platform=iOS" test || true
fi
;;
esac
}
# Build Android
build_android() {
log_info "Building Android..."
cd "$PROJECT_ROOT"
case "$ACTION" in
clean)
"$SCRIPT_DIR/build-android.sh" "$BUILD_TYPE" clean
;;
test)
"$SCRIPT_DIR/build-android.sh" "$BUILD_TYPE" test
;;
build|*)
if "$SCRIPT_DIR/build-android.sh" "$BUILD_TYPE" assemble; then
BUILD_RESULTS["android"]="success"
((SUCCESSFUL_BUILDS++)) || true
else
BUILD_RESULTS["android"]="failed"
fi
if [ "$RUN_TESTS" = true ]; then
log_info "Running Android tests..."
"$SCRIPT_DIR/build-android.sh" "$BUILD_TYPE" test || true
fi
;;
esac
}
# Build Linux
build_linux() {
log_info "Building Linux..."
cd "$PROJECT_ROOT"
case "$ACTION" in
clean)
"$SCRIPT_DIR/build-linux.sh" "$BUILD_TYPE" clean
;;
test)
"$SCRIPT_DIR/build-linux.sh" "$BUILD_TYPE" test
;;
build|*)
if "$SCRIPT_DIR/build-linux.sh" "$BUILD_TYPE" build; then
BUILD_RESULTS["linux"]="success"
((SUCCESSFUL_BUILDS++)) || true
else
BUILD_RESULTS["linux"]="failed"
fi
if [ "$RUN_TESTS" = true ]; then
log_info "Running Linux tests..."
"$SCRIPT_DIR/build-linux.sh" "$BUILD_TYPE" test || true
fi
;;
esac
}
# Print build summary
print_summary() {
echo ""
log_info "=== Build Summary ==="
echo ""
printf "%-12s | %-10s | %s\n" "Platform" "Status" "Details"
printf "%-12s-+-%-10s-+-%s\n" "------------" "----------" "-------"
for platform in "${!BUILD_RESULTS[@]}"; do
local status="${BUILD_RESULTS[$platform]}"
local status_symbol=""
case "$status" in
success)
status_symbol="✅"
;;
failed)
status_symbol="❌"
;;
skipped)
status_symbol="⏭️"
;;
esac
printf "%-12s | %-10s | %s\n" "$platform" "$status" "$status_symbol"
done
echo ""
echo "Total: $SUCCESSFUL_BUILDS / ${#BUILD_RESULTS[@]} platforms built successfully"
echo ""
}
# Main
echo "========================================"
echo " RSSuper Multi-Platform Build System"
echo "========================================"
echo ""
echo "Configuration:"
echo " Platforms: $PLATFORMS"
echo " Build Type: $BUILD_TYPE"
echo " Action: $ACTION"
echo " Run Tests: $RUN_TESTS"
echo ""
# Convert platforms string to array
IFS=',' read -ra PLATFORM_ARRAY <<< "$PLATFORMS"
# Build each platform
for platform in "${PLATFORM_ARRAY[@]}"; do
platform=$(echo "$platform" | xargs) # Trim whitespace
((TOTAL_PLATFORMS++)) || true
case "$platform" in
all)
build_ios
build_android
build_linux
((TOTAL_PLATFORMS+=2)) || true # Add extra platforms
;;
ios)
build_ios
;;
android)
build_android
;;
linux)
build_linux
;;
*)
log_error "Unknown platform: $platform"
exit 1
;;
esac
done
# Print summary
print_summary
# Exit with error if any builds failed
if [ "$SUCCESSFUL_BUILDS" -lt "${#BUILD_RESULTS[@]}" ]; then
# Filter out skipped builds
local actual_builds=0
for result in "${BUILD_RESULTS[@]}"; do
if [ "$result" != "skipped" ]; then
((actual_builds++)) || true
fi
done
if [ "$SUCCESSFUL_BUILDS" -lt "$actual_builds" ]; then
log_error "Some builds failed"
exit 1
fi
fi
log_success "All builds completed successfully!"

169
scripts/common.sh Executable file
View File

@@ -0,0 +1,169 @@
#!/bin/bash
# RSSuper Common Build Utilities
# Shared functions used across all platform build scripts
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Logging functions
log_info() {
echo -e "${BLUE} $1${NC}"
}
log_success() {
echo -e "${GREEN}$1${NC}"
}
log_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
log_error() {
echo -e "${RED}$1${NC}"
}
# Get project root directory
get_project_root() {
echo "$(cd "$(dirname "$0")/.." && pwd)"
}
# Get current timestamp in ISO format
get_timestamp() {
date -u "+%Y-%m-%dT%H:%M:%SZ"
}
# Get human-readable timestamp
get_timestamp_human() {
date -u "+%Y-%m-%d %H:%M:%S UTC"
}
# Get current git commit hash
get_git_commit() {
git rev-parse HEAD 2>/dev/null || echo "unknown"
}
# Get short git commit hash
get_git_commit_short() {
local commit=$(get_git_commit)
echo ${commit:0:7}
}
# Get current git branch
get_git_branch() {
git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown"
}
# Get git status (clean or modified)
get_git_status() {
if git diff --quiet 2>/dev/null && git diff --cached --quiet 2>/dev/null; then
echo "clean"
else
echo "modified"
fi
}
# Check if running in CI
is_ci() {
[ -n "$CI" ]
}
# Check if command exists
command_exists() {
command -v "$1" &> /dev/null
}
# Create a temporary file with cleanup trap
create_temp_file() {
local temp_file=$(mktemp)
trap "rm -f '$temp_file'" EXIT
echo "$temp_file"
}
# Parse command line arguments
# Usage: parse_args "option1:value1 option2:value2"
# Sets variables OPTION1, OPTION2 with values
parse_args() {
local options="$1"
shift
for opt in $options; do
local key=${opt%%:*}
local value=${opt#*:}
export "$key=$value"
done
}
# Show spinner while command runs (for nice UX)
run_with_spinner() {
local message="$1"
shift
echo -e "${BLUE}$message...${NC}"
"$@"
}
# Generate a build report
generate_build_report() {
local platform="$1"
local status="$2"
local details="$3"
local report_file="${platform}-build-report.md"
local timestamp=$(get_timestamp_human)
local commit=$(get_git_commit_short)
local branch=$(get_git_branch)
{
echo "# $platform Build Report"
echo ""
echo "| | |"
echo "|---|---|"
echo "| **Status** | $status |"
echo "| **Commit** | \`$commit\` |"
echo "| **Branch** | \`$branch\` |"
echo "| **Time** | $timestamp |"
echo ""
if [ "$status" = "FAILED" ]; then
echo "## Errors"
echo ""
echo "$details"
else
echo "## Result"
echo ""
echo "$platform build completed successfully."
fi
} > "$report_file"
echo "Build report written to: $report_file"
}
# Wait for user input (useful for debugging)
wait_for_input() {
echo "Press Enter to continue..."
read
}
# Export for use in other scripts
export -f log_info
export -f log_success
export -f log_warning
export -f log_error
export -f get_project_root
export -f get_timestamp
export -f get_timestamp_human
export -f get_git_commit
export -f get_git_commit_short
export -f get_git_branch
export -f get_git_status
export -f is_ci
export -f command_exists
export -f create_temp_file
export -f parse_args
export -f run_with_spinner
export -f generate_build_report
export -f wait_for_input

View File

@@ -0,0 +1,42 @@
# 03. Implement iOS data models (Swift)
meta:
id: native-business-logic-migration-03
feature: native-business-logic-migration
priority: P0
depends_on: [native-business-logic-migration-02]
tags: [implementation, ios, data-models]
objective:
- Implement all data models in Swift following iOS conventions
deliverables:
- FeedItem.swift
- Feed.swift
- FeedSubscription.swift
- SearchResult.swift
- SearchFilters.swift
- NotificationPreferences.swift
- ReadingPreferences.swift
- Supporting types and extensions
tests:
- Unit: Test property encoding/decoding
- Unit: Test custom string interpolation
- Unit: Test equality conformance
acceptance_criteria:
- All models conform to Codable
- All models have proper equatable conformance
- Date properties use ISO8601 formatter
- Optional properties properly handled
- Custom debug description implemented
validation:
- Run `swift test` in Xcode
- Verify compilation with no warnings
notes:
- Use Swift 5.9+ features
- Follow Apple's API design guidelines
- Consider using Identifiable protocol for List conformance

View File

@@ -0,0 +1,42 @@
# 04. Implement Android data models (Kotlin)
meta:
id: native-business-logic-migration-04
feature: native-business-logic-migration
priority: P0
depends_on: [native-business-logic-migration-02]
tags: [implementation, android, data-models]
objective:
- Implement all data models in Kotlin following Android conventions
deliverables:
- FeedItem.kt
- Feed.kt
- FeedSubscription.kt
- SearchResult.kt
- SearchFilters.kt
- NotificationPreferences.kt
- ReadingPreferences.kt
- Supporting data classes and sealed classes
tests:
- Unit: Test serialization/deserialization with Moshi/Gson
- Unit: Test copy() functionality
- Unit: Test toString() output
acceptance_criteria:
- All models are data classes
- All models have proper equals/hashCode
- JSON serialization working with Moshi
- Room Entity annotations ready for database models
- Sealed classes for enum types
validation:
- Run `./gradlew test`
- Verify no lint warnings
notes:
- Use data classes for immutable value objects
- Use sealed classes for enum-like types
- Consider using Parcelize for UI passing

View File

@@ -0,0 +1,41 @@
# 05. Implement Linux data models (C/Vala)
meta:
id: native-business-logic-migration-05
feature: native-business-logic-migration
priority: P0
depends_on: [native-business-logic-migration-02]
tags: [implementation, linux, data-models]
objective:
- Implement all data models in Vala/C following Linux/GNOME conventions
deliverables:
- feed-item.vala
- feed.vala
- feed-subscription.vala
- search-result.vala
- search-filters.vala
- notification-preferences.vala
- reading-preferences.vala
- Supporting structs and enums
tests:
- Unit: Test JSON serialization with Gio
- Unit: Test property accessors
- Unit: Test equality methods
acceptance_criteria:
- All models properly structured
- JSON serialization working
- Memory management correct (no leaks)
- GObject integration ready
validation:
- Run `meson test -C build`
- Check with valgrind for memory leaks
notes:
- Use Vala objects for reference types
- Use structs for value types
- Follow GNOME HIG for naming

View File

@@ -0,0 +1,42 @@
# 06. Implement iOS database layer (Core Data/GRDB)
meta:
id: native-business-logic-migration-06
feature: native-business-logic-migration
priority: P0
depends_on: [native-business-logic-migration-03]
tags: [implementation, ios, database]
objective:
- Implement database layer using Core Data for iOS
deliverables:
- RSSuper.xcdatamodeld
- DatabaseManager.swift
- Subscription+CoreDataClass.swift
- FeedItem+CoreDataClass.swift
- SearchHistory+CoreDataClass.swift
- Database migrations
- FTS virtual table implementation
tests:
- Unit: Test CRUD operations
- Unit: Test relationships
- Unit: Test FTS queries
- Integration: Test database migrations
acceptance_criteria:
- Core Data model created with all entities
- Relationships properly configured
- FTS search working
- Migrations implemented
- Background context used for writes
validation:
- Run unit tests
- Verify with Instruments (Core Data editor)
notes:
- Use NSPersistentContainer
- Implement FTS using SQLite directly or GRDB
- Consider using NSPredicate for queries

View File

@@ -0,0 +1,45 @@
# 07. Implement Android database layer (Room)
meta:
id: native-business-logic-migration-07
feature: native-business-logic-migration
priority: P0
depends_on: [native-business-logic-migration-04]
tags: [implementation, android, database]
objective:
- Implement database layer using Room for Android
deliverables:
- RssDatabase.kt
- SubscriptionEntity.kt
- FeedItemEntity.kt
- SearchHistoryEntity.kt
- SubscriptionDao.kt
- FeedItemDao.kt
- SearchHistoryDao.kt
- Database migrations
- FTS virtual table implementation
tests:
- Unit: Test CRUD operations with Room Testing
- Unit: Test relationships
- Unit: Test FTS queries
- Integration: Test database migrations
acceptance_criteria:
- Room database configured
- All entities annotated
- DAOs with proper queries
- FTS search working
- Migrations implemented
- TypeConverters for custom types
validation:
- Run `./gradlew test`
- Verify with Room Inspection
notes:
- Use Room 2.6+
- Implement FTS using SQLite FTS5
- Use @Transaction for multi-entity operations

View File

@@ -0,0 +1,42 @@
# 08. Implement Linux database layer (SQLite)
meta:
id: native-business-logic-migration-08
feature: native-business-logic-migration
priority: P0
depends_on: [native-business-logic-migration-05]
tags: [implementation, linux, database]
objective:
- Implement database layer using SQLite for Linux
deliverables:
- database.vala
- subscription-store.vala
- feed-item-store.vala
- search-history-store.vala
- schema.sql
- Database migrations
- FTS virtual table implementation
tests:
- Unit: Test CRUD operations
- Unit: Test relationships
- Unit: Test FTS queries
- Integration: Test database migrations
acceptance_criteria:
- SQLite database configured
- All tables created
- FTS search working
- Migrations implemented
- Proper error handling
validation:
- Run `meson test -C build`
- Verify with sqlite3 CLI
notes:
- Use GLib's GDatabase or direct SQLite bindings
- Implement FTS using SQLite FTS5
- Use transactions for batch operations

View File

@@ -0,0 +1,43 @@
# 09. Implement iOS RSS/Atom feed parser
meta:
id: native-business-logic-migration-09
feature: native-business-logic-migration
priority: P0
depends_on: [native-business-logic-migration-06]
tags: [implementation, ios, parsing]
objective:
- Implement RSS 2.0 and Atom 1.0 feed parser for iOS
deliverables:
- FeedParser.swift
- RSSParser.swift
- AtomParser.swift
- FeedType.swift (enum)
- ParseResult.swift
- XML parsing utilities
tests:
- Unit: Test RSS 2.0 parsing with sample feeds
- Unit: Test Atom 1.0 parsing with sample feeds
- Unit: Test iTunes namespace handling
- Unit: Test error cases (malformed XML)
- Integration: Test with real-world feeds
acceptance_criteria:
- RSS 2.0 feeds parse correctly
- Atom 1.0 feeds parse correctly
- iTunes namespace handled
- Enclosures extracted properly
- Error handling for malformed feeds
- Performance: <100ms for typical feed
validation:
- Run unit tests with sample feeds
- Test with known problematic feeds
notes:
- Use Swift's XMLParser or SwiftXML
- Handle namespaces properly
- Support both inline and separate content

View File

@@ -0,0 +1,43 @@
# 10. Implement Android RSS/Atom feed parser
meta:
id: native-business-logic-migration-10
feature: native-business-logic-migration
priority: P0
depends_on: [native-business-logic-migration-07]
tags: [implementation, android, parsing]
objective:
- Implement RSS 2.0 and Atom 1.0 feed parser for Android
deliverables:
- FeedParser.kt
- RSSParser.kt
- AtomParser.kt
- FeedType.kt (sealed class)
- ParseResult.kt
- XML parsing utilities
tests:
- Unit: Test RSS 2.0 parsing with sample feeds
- Unit: Test Atom 1.0 parsing with sample feeds
- Unit: Test iTunes namespace handling
- Unit: Test error cases (malformed XML)
- Integration: Test with real-world feeds
acceptance_criteria:
- RSS 2.0 feeds parse correctly
- Atom 1.0 feeds parse correctly
- iTunes namespace handled
- Enclosures extracted properly
- Error handling for malformed feeds
- Performance: <100ms for typical feed
validation:
- Run `./gradlew test`
- Test with known problematic feeds
notes:
- Use kxml or woodstox
- Handle namespaces properly
- Support both inline and separate content

View File

@@ -0,0 +1,43 @@
# 11. Implement Linux RSS/Atom feed parser
meta:
id: native-business-logic-migration-11
feature: native-business-logic-migration
priority: P0
depends_on: [native-business-logic-migration-08]
tags: [implementation, linux, parsing]
objective:
- Implement RSS 2.0 and Atom 1.0 feed parser for Linux
deliverables:
- feed-parser.vala
- rss-parser.vala
- atom-parser.vala
- feed-type.vala (enum)
- parse-result.vala
- XML parsing utilities
tests:
- Unit: Test RSS 2.0 parsing with sample feeds
- Unit: Test Atom 1.0 parsing with sample feeds
- Unit: Test iTunes namespace handling
- Unit: Test error cases (malformed XML)
- Integration: Test with real-world feeds
acceptance_criteria:
- RSS 2.0 feeds parse correctly
- Atom 1.0 feeds parse correctly
- iTunes namespace handled
- Enclosures extracted properly
- Error handling for malformed feeds
- Performance: <100ms for typical feed
validation:
- Run `meson test -C build`
- Test with known problematic feeds
notes:
- Use libxml2 through Vala bindings
- Handle namespaces properly
- Support both inline and separate content

View File

@@ -0,0 +1,40 @@
# 12. Implement iOS feed fetcher service
meta:
id: native-business-logic-migration-12
feature: native-business-logic-migration
priority: P0
depends_on: [native-business-logic-migration-09]
tags: [implementation, ios, networking]
objective:
- Implement feed fetching service with URLSession
deliverables:
- FeedFetcher.swift
- HTTPAuthCredentials.swift
- FetchResult.swift
- NetworkError.swift
- Feed caching implementation
tests:
- Unit: Test URL session configuration
- Unit: Test HTTP auth handling
- Unit: Test error cases (timeout, 404, etc.)
- Integration: Test fetching real feeds
acceptance_criteria:
- Feeds fetch with proper timeout (15s)
- HTTP auth supported
- Error handling complete
- Response caching implemented
- Performance: <5s for typical feed
validation:
- Run unit tests
- Test with Network Link Conditioner
notes:
- Use URLSession with proper configuration
- Implement exponential backoff for retries
- Respect Cache-Control headers

View File

@@ -0,0 +1,40 @@
# 13. Implement Android feed fetcher service
meta:
id: native-business-logic-migration-13
feature: native-business-logic-migration
priority: P0
depends_on: [native-business-logic-migration-10]
tags: [implementation, android, networking]
objective:
- Implement feed fetching service with OkHttp
deliverables:
- FeedFetcher.kt
- HTTPAuthCredentials.kt
- FetchResult.kt
- NetworkError.kt
- Feed caching implementation
tests:
- Unit: Test OkHttp configuration
- Unit: Test HTTP auth handling
- Unit: Test error cases (timeout, 404, etc.)
- Integration: Test fetching real feeds
acceptance_criteria:
- Feeds fetch with proper timeout (15s)
- HTTP auth supported
- Error handling complete
- Response caching implemented
- Performance: <5s for typical feed
validation:
- Run `./gradlew test`
- Test with network throttling
notes:
- Use OkHttp with proper configuration
- Implement exponential backoff for retries
- Respect Cache-Control headers

View File

@@ -0,0 +1,40 @@
# 14. Implement Linux feed fetcher service
meta:
id: native-business-logic-migration-14
feature: native-business-logic-migration
priority: P0
depends_on: [native-business-logic-migration-11]
tags: [implementation, linux, networking]
objective:
- Implement feed fetching service with libsoup
deliverables:
- feed-fetcher.vala
- http-auth-credentials.vala
- fetch-result.vala
- network-error.vala
- Feed caching implementation
tests:
- Unit: Test SoupSession configuration
- Unit: Test HTTP auth handling
- Unit: Test error cases (timeout, 404, etc.)
- Integration: Test fetching real feeds
acceptance_criteria:
- Feeds fetch with proper timeout (15s)
- HTTP auth supported
- Error handling complete
- Response caching implemented
- Performance: <5s for typical feed
validation:
- Run `meson test -C build`
- Test with network throttling
notes:
- Use libsoup-3.0
- Implement exponential backoff for retries
- Respect Cache-Control headers

View File

@@ -0,0 +1,41 @@
# 15. Implement iOS state management (Combine/Observer)
meta:
id: native-business-logic-migration-15
feature: native-business-logic-migration
priority: P0
depends_on: [native-business-logic-migration-12]
tags: [implementation, ios, state-management]
objective:
- Implement reactive state management using Combine
deliverables:
- FeedRepository.swift
- SubscriptionRepository.swift
- FeedViewModel.swift
- SubscriptionViewModel.swift
- State enumeration
- Error handling types
tests:
- Unit: Test repository methods
- Unit: Test ViewModel state transitions
- Unit: Test Combine publishers
- Integration: Test UI updates
acceptance_criteria:
- Repositories provide Combine publishers
- ViewModels manage state properly
- Error states handled
- Loading states implemented
- Memory efficient (no retain cycles)
validation:
- Run unit tests
- Check with Instruments for memory leaks
notes:
- Use Combine framework
- Follow Repository pattern
- Use @Published for SwiftUI integration

View File

@@ -0,0 +1,41 @@
# 16. Implement Android state management (StateFlow/LiveData)
meta:
id: native-business-logic-migration-16
feature: native-business-logic-migration
priority: P0
depends_on: [native-business-logic-migration-13]
tags: [implementation, android, state-management]
objective:
- Implement reactive state management using StateFlow and LiveData
deliverables:
- FeedRepository.kt
- SubscriptionRepository.kt
- FeedViewModel.kt
- SubscriptionViewModel.kt
- State sealed class
- Error handling types
tests:
- Unit: Test repository methods
- Unit: Test ViewModel state transitions
- Unit: Test StateFlow emission
- Integration: Test UI updates
acceptance_criteria:
- Repositories provide StateFlow
- ViewModels manage state properly
- Error states handled
- Loading states implemented
- Lifecycle-aware updates
validation:
- Run `./gradlew test`
- Test with Espresso for UI updates
notes:
- Use StateFlow for new code
- Use LiveData for UI binding
- Follow Repository pattern

View File

@@ -0,0 +1,41 @@
# 17. Implement Linux state management (GObject signals)
meta:
id: native-business-logic-migration-17
feature: native-business-logic-migration
priority: P0
depends_on: [native-business-logic-migration-14]
tags: [implementation, linux, state-management]
objective:
- Implement reactive state management using GObject signals
deliverables:
- feed-repository.vala
- subscription-repository.vala
- feed-view-model.vala
- subscription-view-model.vala
- State enumeration
- Error handling types
tests:
- Unit: Test repository methods
- Unit: Test ViewModel state transitions
- Unit: Test signal emission
- Integration: Test UI updates
acceptance_criteria:
- Repositories emit signals on changes
- ViewModels manage state properly
- Error states handled
- Loading states implemented
- Proper signal connections
validation:
- Run `meson test -C build`
- Test signal connections
notes:
- Use GObject properties with notify signals
- Follow GNOME HIG
- Use Gio for async operations

View File

@@ -0,0 +1,39 @@
# 18. Implement iOS background sync service
meta:
id: native-business-logic-migration-18
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-15]
tags: [implementation, ios, background]
objective:
- Implement background feed sync using BGTaskScheduler
deliverables:
- BackgroundSyncService.swift
- SyncScheduler.swift
- SyncWorker.swift
- AppIntent extensions
- Background configuration
tests:
- Unit: Test scheduler configuration
- Unit: Test task cancellation
- Integration: Test background execution
acceptance_criteria:
- Background tasks scheduled properly
- Tasks execute within time window
- Battery-efficient scheduling
- Proper task cancellation
- State persisted between runs
validation:
- Test with Xcode debugger
- Verify with Console app logs
notes:
- Use BGAppRefreshTask
- Request background modes capability
- Handle time limits gracefully

View File

@@ -0,0 +1,39 @@
# 19. Implement Android background sync service
meta:
id: native-business-logic-migration-19
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-16]
tags: [implementation, android, background]
objective:
- Implement background feed sync using WorkManager
deliverables:
- SyncWorker.kt
- SyncScheduler.kt
- SyncConfiguration.kt
- WorkManager configuration
- Foreground service (if needed)
tests:
- Unit: Test Worker execution
- Unit: Test scheduler configuration
- Integration: Test background execution
acceptance_criteria:
- Work scheduled properly
- Constraints respected (network, charging)
- Battery-efficient scheduling
- Proper work cancellation
- State persisted between runs
validation:
- Test with WorkManager TestRule
- Verify with adb commands
notes:
- Use PeriodicWorkRequest
- Set appropriate constraints
- Handle Doze mode

View File

@@ -0,0 +1,38 @@
# 20. Implement Linux background sync service
meta:
id: native-business-logic-migration-20
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-17]
tags: [implementation, linux, background]
objective:
- Implement background feed sync using GIO Timeout or systemd timer
deliverables:
- background-sync.vala
- sync-scheduler.vala
- systemd service file
- systemd timer file
- Desktop entry with autostart
tests:
- Unit: Test scheduler configuration
- Unit: Test timeout handling
- Integration: Test background execution
acceptance_criteria:
- Sync runs on schedule
- Battery-efficient (only when active)
- Proper cleanup on app close
- State persisted between runs
validation:
- Test with systemd-timer list
- Verify with journalctl
notes:
- Use GTimeout for in-app scheduling
- Use systemd timer for system-level
- Respect power management

View File

@@ -0,0 +1,40 @@
# 21. Implement iOS search service (FTS)
meta:
id: native-business-logic-migration-21
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-15]
tags: [implementation, ios, search]
objective:
- Implement full-text search service using Core Data FTS or SQLite FTS
deliverables:
- SearchService.swift
- SearchQuery.swift
- SearchResultProvider.swift
- FTS index management
- Search history storage
tests:
- Unit: Test query parsing
- Unit: Test FTS queries
- Unit: Test result ranking
- Integration: Test search with real data
acceptance_criteria:
- Full-text search working
- Search history maintained
- Results ranked by relevance
- Performance: <200ms for search
- Fuzzy matching supported
validation:
- Run unit tests
- Test with large dataset
notes:
- Use Core Data FTS or GRDB FTS5
- Implement search suggestions
- Cache frequent queries

View File

@@ -0,0 +1,40 @@
# 22. Implement Android search service (FTS)
meta:
id: native-business-logic-migration-22
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-16]
tags: [implementation, android, search]
objective:
- Implement full-text search service using Room FTS
deliverables:
- SearchService.kt
- SearchQuery.kt
- SearchResultProvider.kt
- FTS index management
- Search history storage
tests:
- Unit: Test query parsing
- Unit: Test FTS queries
- Unit: Test result ranking
- Integration: Test search with real data
acceptance_criteria:
- Full-text search working
- Search history maintained
- Results ranked by relevance
- Performance: <200ms for search
- Fuzzy matching supported
validation:
- Run `./gradlew test`
- Test with large dataset
notes:
- Use Room FTS5
- Implement search suggestions
- Cache frequent queries

View File

@@ -0,0 +1,40 @@
# 23. Implement Linux search service (FTS)
meta:
id: native-business-logic-migration-23
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-17]
tags: [implementation, linux, search]
objective:
- Implement full-text search service using SQLite FTS
deliverables:
- search-service.vala
- search-query.vala
- search-result-provider.vala
- FTS index management
- Search history storage
tests:
- Unit: Test query parsing
- Unit: Test FTS queries
- Unit: Test result ranking
- Integration: Test search with real data
acceptance_criteria:
- Full-text search working
- Search history maintained
- Results ranked by relevance
- Performance: <200ms for search
- Fuzzy matching supported
validation:
- Run `meson test -C build`
- Test with large dataset
notes:
- Use SQLite FTS5
- Implement search suggestions
- Cache frequent queries

View File

@@ -0,0 +1,39 @@
# 24. Implement iOS notification service
meta:
id: native-business-logic-migration-24
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-15]
tags: [implementation, ios, notifications]
objective:
- Implement push and local notification service for iOS
deliverables:
- NotificationService.swift
- NotificationManager.swift
- NotificationPreferencesStore.swift
- Notification extension (if needed)
- Badge management
tests:
- Unit: Test notification configuration
- Unit: Test permission handling
- Integration: Test notification delivery
acceptance_criteria:
- Push notifications received
- Local notifications scheduled
- Badge count updated
- Notification categories working
- Preferences respected
validation:
- Test with Pusher.app
- Verify in Settings > Notifications
notes:
- Use UserNotifications framework
- Implement notification categories
- Handle foreground/background differently

View File

@@ -0,0 +1,39 @@
# 25. Implement Android notification service
meta:
id: native-business-logic-migration-25
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-16]
tags: [implementation, android, notifications]
objective:
- Implement push and local notification service for Android
deliverables:
- NotificationService.kt
- NotificationManager.kt
- NotificationPreferencesStore.kt
- Notification channels
- Badge management
tests:
- Unit: Test notification configuration
- Unit: Test permission handling
- Integration: Test notification delivery
acceptance_criteria:
- Push notifications received
- Local notifications scheduled
- Badge count updated
- Notification channels working
- Preferences respected
validation:
- Test with Firebase Console
- Verify in Settings > Apps > Notifications
notes:
- Use NotificationCompat
- Create proper notification channels
- Handle Android 13+ permissions

View File

@@ -0,0 +1,39 @@
# 26. Implement Linux notification service
meta:
id: native-business-logic-migration-26
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-17]
tags: [implementation, linux, notifications]
objective:
- Implement desktop notification service for Linux
deliverables:
- notification-service.vala
- notification-manager.vala
- notification-preferences-store.vala
- Tray icon integration
- Badge management
tests:
- Unit: Test notification creation
- Unit: Test notification actions
- Integration: Test notification delivery
acceptance_criteria:
- Desktop notifications shown
- Notification actions working
- Tray icon updated
- Badge count updated
- Preferences respected
validation:
- Test with notify-send
- Verify in system settings
notes:
- Use Gio.Notification
- Follow freedesktop.org spec
- Integrate with system tray

View File

@@ -0,0 +1,39 @@
# 27. Implement iOS settings/preferences store
meta:
id: native-business-logic-migration-27
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-15]
tags: [implementation, ios, settings]
objective:
- Implement settings store using UserDefaults and App Group
deliverables:
- SettingsStore.swift
- AppSettings.swift
- ReadingPreferences.swift
- NotificationPreferences.swift
- Settings migration
tests:
- Unit: Test property storage/retrieval
- Unit: Test defaults
- Unit: Test synchronization
acceptance_criteria:
- All settings persisted
- Defaults properly set
- Changes observed in real-time
- App Group sync working
- Settings migrated between versions
validation:
- Run unit tests
- Test with Xcode preferences inspector
notes:
- Use UserDefaults for simple settings
- Use App Group for shared settings
- Observe changes with notifications

View File

@@ -0,0 +1,39 @@
# 28. Implement Android settings/preferences store
meta:
id: native-business-logic-migration-28
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-16]
tags: [implementation, android, settings]
objective:
- Implement settings store using DataStore and SharedPreferences
deliverables:
- SettingsStore.kt
- AppSettings.kt
- ReadingPreferences.kt
- NotificationPreferences.kt
- Settings migration
tests:
- Unit: Test property storage/retrieval
- Unit: Test defaults
- Unit: Test synchronization
acceptance_criteria:
- All settings persisted
- Defaults properly set
- Changes observed in real-time
- Preferences encrypted if needed
- Settings migrated between versions
validation:
- Run `./gradlew test`
- Test with Application Info > Preferences
notes:
- Use DataStore for new code
- Use SharedPreferences for simple values
- Observe changes with Flow

View File

@@ -0,0 +1,39 @@
# 29. Implement Linux settings/preferences store
meta:
id: native-business-logic-migration-29
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-17]
tags: [implementation, linux, settings]
objective:
- Implement settings store using GSettings and JSON file
deliverables:
- settings-store.vala
- app-settings.vala
- reading-preferences.vala
- notification-preferences.vala
- GSettings schema
tests:
- Unit: Test property storage/retrieval
- Unit: Test defaults
- Unit: Test synchronization
acceptance_criteria:
- All settings persisted
- Defaults properly set
- Changes observed in real-time
- Settings follow XDG spec
- Settings migrated between versions
validation:
- Run `meson test -C build`
- Test with gsettings CLI
notes:
- Use GSettings for system integration
- Use JSON file for app-specific
- Follow XDG Base Directory spec

View File

@@ -0,0 +1,38 @@
# 30. Implement iOS bookmark store
meta:
id: native-business-logic-migration-30
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-15]
tags: [implementation, ios, bookmarks]
objective:
- Implement bookmark store for saving articles
deliverables:
- BookmarkStore.swift
- Bookmark.swift (model)
- BookmarkRepository.swift
- Bookmark grouping/tagging
tests:
- Unit: Test bookmark CRUD
- Unit: Test bookmark queries
- Unit: Test bookmark deletion cascade
acceptance_criteria:
- Bookmarks saved to database
- Bookmarks queryable
- Bookmarks deletable
- Bookmark count accurate
- Integration with feed items
validation:
- Run unit tests
- Test with Xcode Core Data editor
notes:
- Store as relationship to FeedItem
- Support tags/categories
- Implement smart folders

View File

@@ -0,0 +1,38 @@
# 31. Implement Android bookmark store
meta:
id: native-business-logic-migration-31
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-16]
tags: [implementation, android, bookmarks]
objective:
- Implement bookmark store for saving articles
deliverables:
- BookmarkStore.kt
- Bookmark.kt (model)
- BookmarkRepository.kt
- Bookmark grouping/tagging
tests:
- Unit: Test bookmark CRUD
- Unit: Test bookmark queries
- Unit: Test bookmark deletion cascade
acceptance_criteria:
- Bookmarks saved to database
- Bookmarks queryable
- Bookmarks deletable
- Bookmark count accurate
- Integration with feed items
validation:
- Run `./gradlew test`
- Test with Room Inspection
notes:
- Store as separate entity with foreign key
- Support tags/categories
- Implement smart folders

View File

@@ -0,0 +1,38 @@
# 32. Implement Linux bookmark store
meta:
id: native-business-logic-migration-32
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-17]
tags: [implementation, linux, bookmarks]
objective:
- Implement bookmark store for saving articles
deliverables:
- bookmark-store.vala
- bookmark.vala (model)
- bookmark-repository.vala
- Bookmark grouping/tagging
tests:
- Unit: Test bookmark CRUD
- Unit: Test bookmark queries
- Unit: Test bookmark deletion cascade
acceptance_criteria:
- Bookmarks saved to database
- Bookmarks queryable
- Bookmarks deletable
- Bookmark count accurate
- Integration with feed items
validation:
- Run `meson test -C build`
- Test with sqlite3 CLI
notes:
- Store as separate table with foreign key
- Support tags/categories
- Implement smart folders

View File

@@ -0,0 +1,40 @@
# 33. Integrate business logic with iOS UI
meta:
id: native-business-logic-migration-33
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-30, native-business-logic-migration-15]
tags: [implementation, ios, ui]
objective:
- Connect business logic layer with SwiftUI views
deliverables:
- FeedList view connected to ViewModel
- FeedDetail view connected to ViewModel
- AddFeed view connected to services
- Search view connected to SearchService
- Settings view connected to SettingsStore
- Bookmark view connected to BookmarkStore
tests:
- UI: Test view renders with data
- UI: Test navigation works
- UI: Test error states displayed
acceptance_criteria:
- All views connected to ViewModels
- Data flows correctly
- User actions trigger updates
- Error states shown properly
- Loading states shown properly
validation:
- Run app in simulator
- Test all user flows
notes:
- Use @StateObject for ViewModels
- Use @Query for direct database access
- Implement pull-to-refresh

View File

@@ -0,0 +1,40 @@
# 34. Integrate business logic with Android UI
meta:
id: native-business-logic-migration-34
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-31, native-business-logic-migration-16]
tags: [implementation, android, ui]
objective:
- Connect business logic layer with Jetpack Compose views
deliverables:
- FeedList composable connected to ViewModel
- FeedDetail composable connected to ViewModel
- AddFeed composable connected to services
- Search composable connected to SearchService
- Settings composable connected to SettingsStore
- Bookmark composable connected to BookmarkStore
tests:
- UI: Test composable renders with data
- UI: Test navigation works
- UI: Test error states displayed
acceptance_criteria:
- All composables connected to ViewModels
- Data flows correctly
- User actions trigger updates
- Error states shown properly
- Loading states shown properly
validation:
- Run app on emulator
- Test all user flows
notes:
- Use ViewModel composables
- Use Hilt for dependency injection
- Implement swipe-to-refresh

View File

@@ -0,0 +1,40 @@
# 35. Integrate business logic with Linux UI
meta:
id: native-business-logic-migration-35
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-32, native-business-logic-migration-17]
tags: [implementation, linux, ui]
objective:
- Connect business logic layer with GTK4 views
deliverables:
- FeedList widget connected to ViewModel
- FeedDetail widget connected to ViewModel
- AddFeed widget connected to services
- Search widget connected to SearchService
- Settings widget connected to SettingsStore
- Bookmark widget connected to BookmarkStore
tests:
- UI: Test widget renders with data
- UI: Test navigation works
- UI: Test error states displayed
acceptance_criteria:
- All widgets connected to ViewModels
- Data flows correctly
- User actions trigger updates
- Error states shown properly
- Loading states shown properly
validation:
- Run app on Linux
- Test all user flows
notes:
- Use GObject signals for updates
- Follow GNOME HIG
- Implement proper GTK patterns

View File

@@ -0,0 +1,42 @@
# 36. Write unit tests for iOS business logic
meta:
id: native-business-logic-migration-36
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-33]
tags: [testing, ios]
objective:
- Write comprehensive unit tests for iOS business logic
deliverables:
- FeedParserTests.swift
- FeedFetcherTests.swift
- DatabaseTests.swift
- RepositoryTests.swift
- ViewModelTests.swift
- BackgroundSyncTests.swift
- SearchServiceTests.swift
- NotificationServiceTests.swift
tests:
- Unit: All test files compile
- Unit: All tests pass
- Coverage: >80% code coverage
acceptance_criteria:
- All business logic covered
- Edge cases tested
- Error cases tested
- Performance tests included
- >80% code coverage
validation:
- Run `xcodebuild test`
- Check coverage report
notes:
- Use XCTest framework
- Use XCTestExpectations for async
- Mock external dependencies

View File

@@ -0,0 +1,42 @@
# 37. Write unit tests for Android business logic
meta:
id: native-business-logic-migration-37
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-34]
tags: [testing, android]
objective:
- Write comprehensive unit tests for Android business logic
deliverables:
- FeedParserTest.kt
- FeedFetcherTest.kt
- DatabaseTest.kt
- RepositoryTest.kt
- ViewModelTest.kt
- BackgroundSyncTest.kt
- SearchServiceTest.kt
- NotificationServiceTest.kt
tests:
- Unit: All test files compile
- Unit: All tests pass
- Coverage: >80% code coverage
acceptance_criteria:
- All business logic covered
- Edge cases tested
- Error cases tested
- Performance tests included
- >80% code coverage
validation:
- Run `./gradlew test`
- Check coverage report with Jacoco
notes:
- Use JUnit 5
- Use MockK for mocking
- Use Coroutines Test for async

View File

@@ -0,0 +1,42 @@
# 38. Write unit tests for Linux business logic
meta:
id: native-business-logic-migration-38
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-35]
tags: [testing, linux]
objective:
- Write comprehensive unit tests for Linux business logic
deliverables:
- feed-parser-test.vala
- feed-fetcher-test.vala
- database-test.vala
- repository-test.vala
- view-model-test.vala
- background-sync-test.vala
- search-service-test.vala
- notification-service-test.vala
tests:
- Unit: All test files compile
- Unit: All tests pass
- Coverage: >80% code coverage
acceptance_criteria:
- All business logic covered
- Edge cases tested
- Error cases tested
- Performance tests included
- >80% code coverage
validation:
- Run `meson test -C build`
- Check coverage report
notes:
- Use GLib's g_test framework
- Use g_assert macros
- Mock external dependencies

View File

@@ -0,0 +1,40 @@
# 39. Write cross-platform integration tests
meta:
id: native-business-logic-migration-39
feature: native-business-logic-migration
priority: P1
depends_on: [native-business-logic-migration-36, native-business-logic-migration-37, native-business-logic-migration-38]
tags: [testing, integration]
objective:
- Write integration tests that verify cross-platform functionality
deliverables:
- Integration test suite
- Test fixtures (sample feeds)
- Test data generator
- CI integration
tests:
- Integration: Feed fetch → parse → store flow
- Integration: Search end-to-end
- Integration: Background sync end-to-end
- Integration: Notification delivery
- Integration: Settings persistence
- Integration: Bookmark CRUD
acceptance_criteria:
- All integration tests pass
- Test data properly isolated
- Tests can run independently
- Tests included in CI
validation:
- Run full test suite
- Verify CI passes
notes:
- Use same test feeds across platforms
- Verify data consistency
- Test error recovery

View File

@@ -0,0 +1,47 @@
# 40. Performance optimization and benchmarking
meta:
id: native-business-logic-migration-40
feature: native-business-logic-migration
priority: P2
depends_on: [native-business-logic-migration-39]
tags: [performance, optimization]
objective:
- Optimize performance and establish benchmarks
deliverables:
- Performance benchmarks
- Optimization report
- Memory profiling results
- CPU profiling results
- Network profiling results
tests:
- Benchmark: Feed parsing <100ms
- Benchmark: Feed fetching <5s
- Benchmark: Search <200ms
- Benchmark: Database query <50ms
- Memory: No leaks detected
- CPU: Efficient usage
acceptance_criteria:
- Feed parsing <100ms for typical feed
- Feed fetching <5s on normal network
- Search <200ms
- Database queries <50ms
- No memory leaks
- Smooth UI at 60fps
- Battery efficient
validation:
- Run benchmarks on each platform
- Profile with Instruments (iOS)
- Profile with Android Profiler
- Profile with Valgrind (Linux)
notes:
- Use platform-specific profiling tools
- Establish baseline metrics
- Optimize iteratively
- Document optimizations made

View File

@@ -0,0 +1,107 @@
# Native Business Logic Migration
Objective: Migrate RSSuper business logic from Expo/TypeScript to native platforms (iOS, Android, Linux)
Status legend: [ ] todo, [~] in-progress, [x] done
## Phase 1: Analysis & Design
- [x] 01 — Analyze and document current Expo architecture → `01-analyze-current-architecture.md`
- [x] 02 — Design shared data models for all platforms → `02-design-shared-data-models.md`
## Phase 2: Data Models (Per Platform)
- [ ] 03 — Implement iOS data models (Swift) → `03-implement-ios-data-models.md`
- [ ] 04 — Implement Android data models (Kotlin) → `04-implement-android-data-models.md`
- [ ] 05 — Implement Linux data models (C/Vala) → `05-implement-linux-data-models.md`
## Phase 3: Database Layer (Per Platform)
- [ ] 06 — Implement iOS database layer (Core Data/GRDB) → `06-implement-ios-database-layer.md`
- [ ] 07 — Implement Android database layer (Room) → `07-implement-android-database-layer.md`
- [ ] 08 — Implement Linux database layer (SQLite) → `08-implement-linux-database-layer.md`
## Phase 4: Feed Parsing (Per Platform)
- [ ] 09 — Implement iOS RSS/Atom feed parser → `09-implement-ios-feed-parser.md`
- [ ] 10 — Implement Android RSS/Atom feed parser → `10-implement-android-feed-parser.md`
- [ ] 11 — Implement Linux RSS/Atom feed parser → `11-implement-linux-feed-parser.md`
## Phase 5: Feed Fetching (Per Platform)
- [ ] 12 — Implement iOS feed fetcher service → `12-implement-ios-feed-fetcher.md`
- [ ] 13 — Implement Android feed fetcher service → `13-implement-android-feed-fetcher.md`
- [ ] 14 — Implement Linux feed fetcher service → `14-implement-linux-feed-fetcher.md`
## Phase 6: State Management (Per Platform)
- [ ] 15 — Implement iOS state management (Combine/Observer) → `15-implement-ios-state-management.md`
- [ ] 16 — Implement Android state management (StateFlow/LiveData) → `16-implement-android-state-management.md`
- [ ] 17 — Implement Linux state management (GObject signals) → `17-implement-linux-state-management.md`
## Phase 7: Services (Per Platform)
### Background Sync
- [ ] 18 — Implement iOS background sync service → `18-implement-ios-background-sync.md`
- [ ] 19 — Implement Android background sync service → `19-implement-android-background-sync.md`
- [ ] 20 — Implement Linux background sync service → `20-implement-linux-background-sync.md`
### Search Service
- [ ] 21 — Implement iOS search service (FTS) → `21-implement-ios-search-service.md`
- [ ] 22 — Implement Android search service (FTS) → `22-implement-android-search-service.md`
- [ ] 23 — Implement Linux search service (FTS) → `23-implement-linux-search-service.md`
### Notifications
- [ ] 24 — Implement iOS notification service → `24-implement-ios-notifications.md`
- [ ] 25 — Implement Android notification service → `25-implement-android-notifications.md`
- [ ] 26 — Implement Linux notification service → `26-implement-linux-notifications.md`
### Settings Store
- [ ] 27 — Implement iOS settings/preferences store → `27-implement-ios-settings-store.md`
- [ ] 28 — Implement Android settings/preferences store → `28-implement-android-settings-store.md`
- [ ] 29 — Implement Linux settings/preferences store → `29-implement-linux-settings-store.md`
### Bookmark Store
- [ ] 30 — Implement iOS bookmark store → `30-implement-ios-bookmark-store.md`
- [ ] 31 — Implement Android bookmark store → `31-implement-android-bookmark-store.md`
- [ ] 32 — Implement Linux bookmark store → `32-implement-linux-bookmark-store.md`
## Phase 8: UI Integration (Per Platform)
- [ ] 33 — Integrate business logic with iOS UI → `33-integrate-ios-business-logic.md`
- [ ] 34 — Integrate business logic with Android UI → `34-integrate-android-business-logic.md`
- [ ] 35 — Integrate business logic with Linux UI → `35-integrate-linux-business-logic.md`
## Phase 9: Testing
- [ ] 36 — Write unit tests for iOS business logic → `36-write-unit-tests-ios.md`
- [ ] 37 — Write unit tests for Android business logic → `37-write-unit-tests-android.md`
- [ ] 38 — Write unit tests for Linux business logic → `38-write-unit-tests-linux.md`
- [ ] 39 — Write cross-platform integration tests → `39-write-integration-tests.md`
## Phase 10: Optimization
- [ ] 40 — Performance optimization and benchmarking → `40-performance-optimization.md`
## Dependencies
- 01 → 02 (architecture analysis feeds into data model design)
- 02 → 03, 04, 05 (data models depend on shared design)
- 03 → 06 (iOS database depends on iOS models)
- 04 → 07 (Android database depends on Android models)
- 05 → 08 (Linux database depends on Linux models)
- 06, 07, 08 → 09, 10, 11 (feed parsers need database layer)
- 09 → 12 (iOS fetcher depends on iOS parser)
- 10 → 13 (Android fetcher depends on Android parser)
- 11 → 14 (Linux fetcher depends on Linux parser)
- 12, 13, 14 → 15, 16, 17 (state management depends on fetchers)
- 15 → 18, 21, 24, 27, 30 (iOS services depend on state management)
- 16 → 19, 22, 25, 28, 31 (Android services depend on state management)
- 17 → 20, 23, 26, 29, 32 (Linux services depend on state management)
- 30, 31, 32 → 33, 34, 35 (UI integration depends on all stores)
- 36, 37, 38 → 39 (integration tests depend on unit tests)
- 39 → 40 (optimization comes after testing)
## Exit Criteria
The feature is complete when:
- [ ] All data models implemented and tested on all platforms
- [ ] Database layer fully functional with migrations on all platforms
- [ ] RSS and Atom feed parsing working with >95% accuracy
- [ ] Feed fetching with error handling and retry logic on all platforms
- [ ] Background sync working on all platforms
- [ ] Full-text search functional on all platforms
- [ ] Notifications working for new articles on all platforms
- [ ] Settings persisted and readable on all platforms
- [ ] Bookmarks working across all platforms
- [ ] All unit tests passing (>80% coverage)
- [ ] Integration tests passing
- [ ] Performance benchmarks met (feed parse <100ms, fetch <5s, search <200ms)