Skip to content

Latest commit

 

History

592 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TypeSync

A cross-platform note-taking app with cloud sync, markdown support, and productivity features.

TypeSync Design

Features

Core Features

  • 📝 Rich Text Editing - Markdown-like text formatting with headers, lists, quotes, and code blocks
  • 📁 Folder Organization - Organize notes in a hierarchical folder structure
  • 🏷️ Tags - Add tags to notes for easy categorization and filtering
  • 🔍 Search - Full-text search across all notes
  • 📊 Statistics - Line and character count displayed in real-time

Sync & Storage

  • ☁️ Cloud Sync - Real-time synchronization via Firebase
  • 📴 Offline First - Works offline with background sync when connected
  • 💾 Storage Tiers:
    • Free: unlimited local notes with a small 5 MB cloud trial
    • TypeSync Lite: 1 GB (€2.99/month)

Productivity

  • 📅 Calendar - Test reminders and event scheduling
  • 📋 Timetable - Weekly class schedule management
  • Homework Todo - Task list with due dates and priorities

Customization

  • 🌙 Dark Mode - Toggle dark mode or sync with system
  • 🎨 Theme Colors - Customizable accent colors
  • 🖼️ Background Colors - Per-file/folder background colors

Other Features

  • 📄 PDF Insert - Insert and view PDFs in notes
  • 👤 User Profiles - Login/register with email
  • ⚠️ Smart Errors - Expandable error messages (simple by default)

Getting Started

Prerequisites

  • Nix (recommended for development)
  • Flutter SDK (3.22.0 or later)
  • Firebase CLI (for deployment)

Development Setup with Nix (Recommended)

  1. Install Nix if you haven't already:

    curl -L https://nixos.org/nix/install | sh
  2. Enable Flakes (if not already enabled):

    echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
  3. Enter development environment:

    cd TypeSync
    nix develop

    This automatically sets up:

    • Flutter SDK
    • Dart SDK
    • Android SDK with required components
    • Linux desktop build dependencies
    • Node.js (for firebase-tools)
  4. Install dependencies:

    flutter pub get
  5. Configure Firebase (see Firebase Setup section)

  6. Run the app:

    # Linux desktop
    flutter run -d linux
    
    # Android (connect device or start emulator first)
    flutter run -d android

Development Setup without Nix

  1. Install Flutter: Follow the official guide

  2. Install Android Studio (for Android development)

  3. Install Linux dependencies (for Linux desktop):

    sudo apt-get install clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev
  4. Clone and setup:

    git clone https://github.com/YOUR_USERNAME/TypeSync.git
    cd TypeSync
    flutter pub get

Firebase Setup

  1. Install Firebase CLI (if not already installed):

    npm install -g firebase-tools
  2. Create a Firebase project:

    • Go to Firebase Console
    • Create a new project
    • Enable Authentication (Email/Password)
    • Enable Cloud Firestore
    • Enable Cloud Storage
  3. Configure Firebase (recommended method):

    # Install FlutterFire CLI
    dart pub global activate flutterfire_cli
    
    # Configure Firebase
    flutterfire configure

    This will automatically update lib/firebase_options.dart with your project's configuration.

  4. Alternative manual setup:

    • Download configuration files from Firebase Console
    • For Android: Place google-services.json in android/app/
    • Update lib/firebase_options.dart with your values
  5. Set up Firestore Security Rules:

    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        match /users/{userId} {
          allow read, write: if request.auth != null && request.auth.uid == userId;
        }
        match /notes/{noteId} {
          allow read, write: if request.auth != null && 
            request.auth.uid == resource.data.userId;
        }
        match /folders/{folderId} {
          allow read, write: if request.auth != null && 
            request.auth.uid == resource.data.userId;
        }
      }
    }
  6. Set up Storage Security Rules:

    rules_version = '2';
    service firebase.storage {
      match /b/{bucket}/o {
        match /users/{userId}/{allPaths=**} {
          allow read, write: if request.auth != null && request.auth.uid == userId;
       }
     }
    }
  7. Configure transactional email with Resend:

    • Verify and enable typesync@khonager.de as a valid sender in Resend
    • Store the Resend API key in Firebase Functions secrets before deploying:
    firebase functions:secrets:set RESEND_API_KEY
    • Deploy Functions after configuration:
    firebase deploy --only functions
  8. Configure subscriptions with RevenueCat:

    • Create the three monthly products/packages: monthly, typesync_plus_monthly, and typesync_pro_monthly.
    • Create matching entitlements: TypeSync Lite, plus, and pro.
    • Use the default offering
    • The default web SDK key is scaffolded for testing, or override it with:
    flutter build web --dart-define=REVENUECAT_WEB_API_KEY=public_web_key
    • Native builds never fall back to the RevenueCat test key. Pass the platform production SDK key:
    flutter build apk --dart-define=REVENUECAT_ANDROID_API_KEY=public_android_key
    flutter build ios --dart-define=REVENUECAT_APPLE_API_KEY=public_apple_key
    • Add REVENUECAT_ANDROID_API_KEY as a GitHub Actions secret and REVENUECAT_APPLE_API_KEY as a Codemagic environment variable. Mobile release jobs fail before building if either key is missing or starts with test_, preventing another store build that RevenueCat will close.
    • Store the RevenueCat webhook token before deploying Functions:
    firebase functions:secrets:set REVENUECAT_WEBHOOK_AUTH_TOKEN
    • Configure the RevenueCat webhook to POST to revenuecat_webhook with the same token. The webhook, not the app, writes the effective plan and cloud quota. Do not grant billing fields from a client.
    • For web and Linux checkout, set each public RevenueCat paywall URL in both web/billing_config.json and assets/billing_config.json. Leave a plan's URL empty until its checkout is live; the app will keep that plan unavailable instead of showing a broken purchase button.
  9. Configure complimentary-access administrators:

    • Never add personal email addresses to Dart, Python, or JSON files.
    • Set the server-only allow-list interactively (comma-separated) and deploy:
    firebase functions:secrets:set ADMIN_EMAILS
    firebase deploy --only functions,firestore:rules
    • Alternatively give an account the Firebase Auth custom claim admin: true using a trusted server/Admin SDK. Both mechanisms are verified only by Cloud Functions.
    • An administrator will see an Admin: complimentary access card on the Storage Plans screen. It can grant TypeSync Lite, Plus, or Pro temporarily or until revoked. These grants are separate from RevenueCat purchases, so a webhook cannot erase them and a revoke cannot remove a paid plan.
    • The previous Gumroad and Patreon activation endpoints are deliberately disabled. Keep all self-service access on RevenueCat so there is one server-verified source of payment truth.

Building for Release

Android APK

flutter build apk --release

Output: build/app/outputs/flutter-apk/app-release.apk

Android App Bundle (for Play Store)

flutter build appbundle --release

Output: build/app/outputs/bundle/release/app-release.aab

Linux

flutter build linux --release

Output: build/linux/x64/release/bundle/

Project Structure

lib/
├── main.dart                 # App entry point
├── app/
│   └── app.dart              # MaterialApp configuration
├── core/
│   ├── models/               # Data models (Note, Folder, User, etc.)
│   ├── providers/            # State management (Provider)
│   ├── services/             # Business logic (Auth, Sync, Storage)
│   ├── theme/                # App theming
│   └── routes/               # Navigation routes
└── features/
    ├── home/                 # Home screen with folder/file browser
    ├── editor/               # Note editor with rich text
    ├── auth/                 # Login/Register screens
    ├── settings/             # App settings
    ├── calendar/             # Calendar & reminders
    ├── timetable/            # Weekly schedule
    ├── homework/             # Todo list
    ├── profile/              # User profile
    └── subscription/         # Storage plans

GitHub Workflows

The project includes automated CI/CD with GitHub Actions:

Branches

  • main: Development branch
  • stable: Stable channel branch
  • unstable: Dev builds - updates the dev tag

Automatic Releases

  • CI/CD: Runs analysis/tests on pushes and pull requests, plus unstable/dev build work.

  • Stable release workflow: After CI/CD succeeds on stable, a separate Release Stable workflow:

    • Validates that pubspec.yaml and the latest changelog entry match
    • Creates a new tagged release (v1.0.0, v1.0.1, etc.) only when the changelog introduces a version newer than the latest version tag
    • Otherwise refreshes the rolling stable-latest release/tag on the newest stable commit
    • Builds Android APK, AAB, Linux bundle, and Web bundle
  • Stable deploy workflow: After CI/CD succeeds on stable, a separate Deploy Web Stable workflow builds and deploys the web app

  • Dev releases: When pushed to unstable:

    • Publishes a new, versioned pre-release (for example, v1.1.18-dev.541)
    • Deletes the preceding dev release and tag, so only the current dev build is listed
    • Builds and uploads the Android and Linux development artifacts
    • The newest dev build appears first in GitHub Releases and has a monotonically increasing version for update clients such as Obtainium
    • In Obtainium, enable Include prereleases for the TypeSync dev installation

Manual Workflow

# Run tests
flutter test

# Check formatting
dart format lib test integration_test

# Analyze code
flutter analyze

# After building Android, verify the packaged native Firebase Auth version
flutter build apk --release
bash scripts/verify_android_firebase_auth_version.sh release

Android cold-restart authentication test

The repository includes a dedicated probe that signs in against the local Firebase Auth emulator, force-stops the Android process, relaunches it, and fails unless Firebase restores the same user:

bash scripts/test_android_auth_persistence.sh

Run it with one Android Studio emulator connected and the Firebase CLI installed. For safety, the script refuses physical devices because it clears the TypeSync app data before the probe.

Changelog Workflow

  • Canonical source: changelog/changelog.yaml
  • Release entry sections:
    • important (highlighted at top in-app)
    • new_features
    • fixes_improvements
    • notes (muted at bottom in-app)
  • Generate app and release artifacts:
python3 scripts/generate_changelog.py
  • Generated per-version release bodies for GitHub are written to:

    • changelog/generated/releases/<version>.md
    • changelog/generated/releases/<version>.txt
  • On stable, GitHub Actions compares the latest changelog version to the latest v* tag:

    • If the changelog version is newer, CI creates that immutable versioned release
    • If not, CI updates the rolling stable-latest release instead
  • Validate generated output is up to date (CI-friendly):

python3 scripts/generate_changelog.py --check

Configuration Files

File Purpose
flake.nix Nix development environment
pubspec.yaml Flutter dependencies
analysis_options.yaml Linter rules
lib/firebase_options.dart Firebase configuration
.github/workflows/ci.yml CI/CD pipeline

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/my-feature
  3. Make your changes
  4. Run tests: flutter test
  5. Format code: dart format lib test
  6. Commit: git commit -m 'Add my feature'
  7. Push: git push origin feature/my-feature
  8. Create a Pull Request

Code Style

  • Follow Effective Dart
  • Use trailing commas for better diffs
  • Document public APIs with /// comments
  • Keep functions focused and under 50 lines when possible

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages