Skip to content

tharindu899/Inkwell

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

42 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Inkwell Logo

Inkwell

Beautiful, private note-taking โ€” on the web and as an Android app

Download APK
Build Release Downloads Vite React Capacitor Google Drive Sync

Write beautifully, anywhere. Notes live locally on your device and sync privately to your own Google Drive.


๐Ÿ“‹ Table of Contents

๐Ÿ“ฅ Download โœจ Features ๐Ÿ› ๏ธ Tech Stack
โšก Quick Start ๐ŸŒ Deploy to Vercel ๐Ÿ“ฑ Build Android APK
๐Ÿ”‘ GitHub Secrets โ˜๏ธ Google Drive Sync โš™๏ธ Environment Variables
๐Ÿš€ CI/CD Pipeline ๐Ÿ—„๏ธ Data Model ๐Ÿ”ง Troubleshooting
โœ… Release Check ๐Ÿ“š Docs ๐Ÿ“ฒ App Updates
๐ŸŽจ Android Icon ๐Ÿ“„ License

๐Ÿ“ฅ Download

Get latest release

Install from GitHub Releases. The app also includes an in-app updater from Settings โ†’ Check for updates.

๐ŸŽจ App Icon & Branding

Inkwell app icon preview

Inkwell uses the v27 dark/orange icon style to match the app UI.

Asset Purpose
public/icon.svg Scalable icon for browser, README, and app branding
public/logo.svg Wide README/header logo
public/logo.png PNG logo fallback
public/icon-512.png Master PNG used for Android/PWA icon generation
public/icon-*.png PWA and launcher sizes
public/favicon-* Browser tab icons
public/apple-touch-icon.png iOS home-screen icon
docs/app-icon-preview.png README preview image

GitHub Actions regenerates Android launcher/adaptive icons from public/icon-512.png during every APK build.

See docs/ANDROID_ICON.md.


โœจ Features

๐Ÿ“ Rich Text Editor

  • Bold ยท Italic ยท Underline ยท Strike ยท Highlight
  • H1 / H2 / H3 headings
  • Bullet ยท Ordered ยท โœ… Checklist
  • Blockquote ยท Code blocks ยท Tables ยท HR
  • Left / Center / Right align
  • Inline links & URL popover
  • ๐Ÿ“… Date / time insert
  • โ†ฉ๏ธ Undo / Redo
  • โŒจ๏ธ Markdown shortcuts (#, -, ```)
  • ๐Ÿ”ง Customisable toolbar (show/hide buttons)
  • ๐Ÿ’พ Auto-save (2 s debounce) + Ctrl+S
  • ๐Ÿ“– Reading mode (distraction-free)
  • ๐Ÿ”ข Live word & character count
  • ๐Ÿ›ก๏ธ Safer auto-save/background-save behavior
  • ๐Ÿท๏ธ Saved tag chips for quick tag selection in the editor

๐Ÿ—‚๏ธ Organise & Manage

  • ๐Ÿ“Œ Pin / unpin notes (long-press)
  • ๐Ÿ—‘๏ธ Delete with haptic feedback
  • ๐Ÿท๏ธ Tags โ€” add with Enter or comma
  • ๐Ÿ“’ Assign to a notebook from the editor
  • ๐Ÿ“ค Export as .txt ยท .md ยท .xls ยท .pdf
  • ๐Ÿ“š Notebooks with custom colour & icon
  • ๐Ÿ” Full-text search with match highlighting
  • ๐Ÿ”Ž Filter by: All ยท Title ยท Content ยท Tags
  • ๐Ÿ• Recent search history (max 8)
  • โ˜๏ธ Filter search by notebook
  • โ˜๏ธ Google Drive auto-backup
  • ๐Ÿ”„ Cross-tab sync via storage events
  • ๐Ÿ“ถ Offline banner on network loss

๐Ÿ† Profile & Stats

  • ๐Ÿ–ผ๏ธ Google account avatar + name
  • ๐Ÿ“Š Notes ยท Notebooks ยท Word count stats
  • ๐Ÿ”ฅ Writing streak (current + longest)
  • ๐Ÿ“… 14-week activity heatmap grid
  • โš™๏ธ Quick links to Settings & Notebooks

โš™๏ธ Settings & Preferences

  • ๐ŸŒ™ Dark / โ˜€๏ธ Light theme toggle
  • ๐Ÿ”ก Font size: Small ยท Medium ยท Large
  • โ˜๏ธ Manual Drive backup & restore
  • ๐Ÿ“ฅ Import / ๐Ÿ“ค Export all notes as JSON
  • ๐Ÿงน Clear all data (with confirmation)
  • ๐Ÿ”” Check for APK updates
  • ๐Ÿ“ฆ Storage usage display (KB)

๐Ÿค– Android Native

  • โฌ…๏ธ Hardware back button (exits app from Home)
  • ๐Ÿ“‹ Copy/select blocked outside editor
  • ๐Ÿ“ณ Haptic feedback (light ยท medium ยท heavy)
  • ๐ŸŽจ App icon auto-generated from icon-512.png
  • ๐Ÿ“ค Share sheet after file export

๐Ÿ”” Auto-Update Checker

  • ๐Ÿš€ Checks GitHub Releases on open + resume
  • ๐Ÿ“ฌ Bottom-sheet prompt when newer version found
  • ๐Ÿ“ฅ In-app APK download with MB/percent progress
  • ๐Ÿ”• Per-version dismissal (won't re-show same ver)
  • ๐Ÿ“ฆ Opens Android Package Installer directly
  • ๐Ÿงน Deletes temporary downloaded APK from cache

๐Ÿ› ๏ธ Tech Stack

Layer Tool Badge
โšก Bundler Vite 5 Vite
โš›๏ธ UI React 18 JSX React
๐Ÿ—บ๏ธ Routing React Router v6 (HashRouter) Router
๐Ÿ”„ State Context + useReducer React
๐Ÿ’พ Storage localStorage JS
๐ŸŽจ Styling Plain CSS CSS
๐ŸŽฏ Icons Font Awesome 6.5 CDN FA
๐Ÿ” Auth Google Identity Services (OAuth 2.0) Google
โ˜๏ธ Sync Google Drive REST API v3 Drive
๐Ÿ“ฑ Android Capacitor 6 Capacitor
๐ŸŒ Deploy Vercel Vercel
๐Ÿค– APK CI GitHub Actions Actions
๐ŸŸข Runtime Node.js 20.x Node
๐Ÿ“ฆ Capacitor plugins used
Plugin Purpose
@capacitor/app โฌ…๏ธ Back button + app resume event
@capacitor/filesystem ๐Ÿ’พ Native file save for exports
@capacitor/haptics ๐Ÿ“ณ Vibration feedback
@capacitor/share ๐Ÿ“ค Share sheet after export
@capacitor/browser ๐ŸŒ Open URLs in system browser
@codetrix-studio/capacitor-google-auth ๐Ÿ” Native Google Sign-In (Android)

๐Ÿ—‚๏ธ Project Structure

๐Ÿ“ฆ inkwell/
โ”œโ”€โ”€ ๐ŸŒ public/
โ”‚   โ”œโ”€โ”€ ๐Ÿ–ผ๏ธ icon.svg                    # Main scalable app icon
โ”‚   โ”œโ”€โ”€ ๐Ÿ–ผ๏ธ logo.svg / logo.png          # README/header brand logo
โ”‚   โ”œโ”€โ”€ ๐Ÿ“ฑ icon-*.png                   # PWA + launcher icon sizes
โ”‚   โ”œโ”€โ”€ ๐ŸŒŸ favicon-16.png / favicon-32.png
โ”‚   โ”œโ”€โ”€ ๐ŸŽ apple-touch-icon.png
โ”‚   โ”œโ”€โ”€ ๐Ÿ“„ manifest.json                # PWA web app manifest
โ”‚   โ””โ”€โ”€ โš™๏ธ sw.js                        # Service Worker
โ”‚
โ”œโ”€โ”€ ๐Ÿ“š docs/
โ”‚   โ”œโ”€โ”€ ๐Ÿ“ฒ APP_UPDATE_INSTALL.md        # In-app APK updater/install flow
โ”‚   โ”œโ”€โ”€ ๐ŸŽจ ANDROID_ICON.md              # Android adaptive icon sizing
โ”‚   โ”œโ”€โ”€ โœ… RELEASE_CHECK.md             # Release safety checklist
โ”‚   โ”œโ”€โ”€ ๐Ÿ“ CHANGELOG.md                  # App update history
โ”‚   โ”œโ”€โ”€ ๐Ÿ‘‹ WELCOME_NOTE.md                # Welcome note toolbar examples
โ”‚   โ”œโ”€โ”€ ๐ŸŒ“ THEME.md                     # Theme persistence notes
โ”‚   โ”œโ”€โ”€ โœ๏ธ EDITOR.md                    # Editor stability checklist
โ”‚   โ””โ”€โ”€ ๐Ÿ–ผ๏ธ app-icon-preview.png         # Icon preview for README
โ”‚
โ”œโ”€โ”€ ๐Ÿงฐ scripts/
โ”‚   โ””โ”€โ”€ โœ… release-check.mjs            # Local release validation script
โ”‚
โ”œโ”€โ”€ โš›๏ธ src/
โ”‚   โ”œโ”€โ”€ ๐Ÿš€ main.jsx                     # Entry: HashRouter + providers
โ”‚   โ”œโ”€โ”€ ๐Ÿ—บ๏ธ App.jsx                      # Routes + back button + offline banner
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ ๐Ÿ” auth/
โ”‚   โ”‚   โ”œโ”€โ”€ ๐Ÿ”‘ AuthContext.jsx          # Google OAuth web/native
โ”‚   โ”‚   โ””โ”€โ”€ โ˜๏ธ googleDrive.js           # Google Drive backup/restore
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ ๐Ÿ—„๏ธ store/
โ”‚   โ”‚   โ”œโ”€โ”€ ๐Ÿ”„ AppContext.jsx           # Global notes/notebooks state
โ”‚   โ”‚   โ””โ”€โ”€ ๐Ÿ’พ storage.js               # localStorage CRUD helpers
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ ๐Ÿ“„ pages/
โ”‚   โ”‚   โ”œโ”€โ”€ ๐Ÿ”‘ Login.jsx                # Google sign-in
โ”‚   โ”‚   โ”œโ”€โ”€ ๐Ÿ  Home.jsx                 # Dashboard + pinned/recent notes
โ”‚   โ”‚   โ”œโ”€โ”€ โœ๏ธ Editor.jsx               # Rich editor + markdown + reading mode
โ”‚   โ”‚   โ”œโ”€โ”€ ๐Ÿ“š Notebooks.jsx            # Notebook list / CRUD
โ”‚   โ”‚   โ”œโ”€โ”€ ๐Ÿ“– NotebookDetail.jsx       # One notebook's notes
โ”‚   โ”‚   โ”œโ”€โ”€ ๐Ÿ” Search.jsx               # Full-text search
โ”‚   โ”‚   โ”œโ”€โ”€ ๐Ÿท๏ธ Tags.jsx                 # Tag list + tag notes
โ”‚   โ”‚   โ”œโ”€โ”€ ๐Ÿ‘ค Profile.jsx              # User stats
โ”‚   โ”‚   โ””โ”€โ”€ โš™๏ธ Settings.jsx             # Theme, sync, update, import/export
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ ๐Ÿงฉ components/
โ”‚   โ”‚   โ”œโ”€โ”€ ๐Ÿ” TopBar.jsx
โ”‚   โ”‚   โ”œโ”€โ”€ ๐Ÿ”ป BottomNav.jsx
โ”‚   โ”‚   โ”œโ”€โ”€ โž• Fab.jsx
โ”‚   โ”‚   โ”œโ”€โ”€ ๐Ÿ“ NoteCard.jsx
โ”‚   โ”‚   โ”œโ”€โ”€ ๐Ÿ“ญ EmptyState.jsx
โ”‚   โ”‚   โ”œโ”€โ”€ ๐Ÿ”” Toast.jsx
โ”‚   โ”‚   โ””โ”€โ”€ ๐Ÿ“ฒ UpdateChecker.jsx        # GitHub Release APK updater
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ ๐Ÿช hooks/
โ”‚   โ”‚   โ”œโ”€โ”€ ๐ŸŒ“ useTheme.js              # Persistent dark/light theme
โ”‚   โ”‚   โ””โ”€โ”€ ๐Ÿ‘‹ useGreeting.js
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ ๐Ÿ› ๏ธ utils/
โ”‚   โ”‚   โ”œโ”€โ”€ ๐Ÿ“ค exportNote.js            # TXT / MD / XLS / PDF export
โ”‚   โ”‚   โ”œโ”€โ”€ ๐Ÿ“ณ haptics.js
โ”‚   โ”‚   โ”œโ”€โ”€ ๐Ÿงฎ helpers.js
โ”‚   โ”‚   โ””โ”€โ”€ ๐ŸŒฑ seed.js
โ”‚   โ”‚
โ”‚   โ””โ”€โ”€ ๐ŸŽจ styles/
โ”‚       โ””โ”€โ”€ ๐ŸŽจ styles.css               # Full app styling
โ”‚
โ”œโ”€โ”€ ๐Ÿค– .github/workflows/
โ”‚   โ””โ”€โ”€ ๐Ÿ“ฆ build-apk.yml                # Build signed APK + GitHub Release
โ”‚
โ”œโ”€โ”€ ๐Ÿ” .env.example
โ”œโ”€โ”€ ๐Ÿšซ .gitignore
โ”œโ”€โ”€ ๐Ÿ“ฑ capacitor.config.json
โ”œโ”€โ”€ ๐ŸŒ index.html
โ”œโ”€โ”€ ๐Ÿ“ฆ package.json
โ”œโ”€โ”€ ๐Ÿ”’ package-lock.json
โ”œโ”€โ”€ ๐Ÿš€ push.sh
โ”œโ”€โ”€ โ–ฒ vercel.json
โ””โ”€โ”€ โšก vite.config.js

๐Ÿšซ Do not commit generated/sensitive files

node_modules/
dist/
android/
.env
*.jks
keystore.txt

โšก Quick Start

# 1๏ธโƒฃ  Clone the repo
git clone https://github.com/tharindu899/Inkwell.git
cd Inkwell

# 2๏ธโƒฃ  Set up environment
cp .env.example .env
# โ†’ Edit .env and set VITE_GOOGLE_CLIENT_ID

# 3๏ธโƒฃ  Install & run
npm install
npm run dev

๐ŸŒ Opens at http://localhost:5173


๐ŸŒ Deploy to Vercel

1. Push your repo to GitHub
2. vercel.com/new  โ†’  import repo
3. Framework: Vite  |  Build: npm run build  |  Output: dist
4. Add env var: VITE_GOOGLE_CLIENT_ID = <your client id>
5. Deploy ๐Ÿš€

vercel.json handles SPA rewrites + correct cache headers automatically.


๐Ÿ“ฑ Build Android APK

๐Ÿ’ก No PC needed โ€” works fully from Termux on your phone.

Step 1 โ€” Create a signing keystore

pkg install openjdk-17

keytool -genkeypair -v \
  -keystore inkwell-release.jks \
  -alias inkwell \
  -keyalg RSA -keysize 2048 -validity 10000 \
  -storepass YOUR_STORE_PASSWORD \
  -keypass  YOUR_KEY_PASSWORD \
  -dname "CN=Inkwell, OU=App, O=Personal, L=City, S=State, C=US"

base64 inkwell-release.jks > keystore.txt
cat keystore.txt   # โ† copy ALL of this output

โš ๏ธ Keep inkwell-release.jks safe. Losing it means you can't update the app later.


Step 2 โ€” Push to GitHub

pkg install git
git config --global user.name  "Your Name"
git config --global user.email "you@email.com"

git init && git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/YOUR_USERNAME/YOUR_REPO.git
git push -u origin main

Step 3 โ€” Add GitHub Secrets

Your repo โ†’ Settings โ†’ Secrets and variables โ†’ Actions โ†’ New repository secret


๐Ÿ”‘ GitHub Secrets

Secret Value Required
KEYSTORE_BASE64 Full base64 from cat keystore.txt โœ…
KEY_ALIAS inkwell (your chosen alias) โœ…
KEY_PASSWORD Your keypass value โœ…
STORE_PASSWORD Your storepass value โœ…
VITE_GOOGLE_CLIENT_ID Google OAuth 2.0 Client ID โœ…
VITE_GITHUB_REPO Optional local override; workflow uses github.repository โž–
VITE_GITHUB_TOKEN Not recommended for public APK builds โŒ

Step 4 โ€” Fix Google OAuth for Android

In Google Cloud Console โ†’ Credentials โ†’ your OAuth Client โ†’ Authorised JavaScript origins, add:

https://localhost

Required because Capacitor serves the app from https://localhost inside Android WebView.

Also create a separate Android OAuth credential (type: Android) with:

  • Package name: com.inkwell.notes
  • SHA-1: found in the GitHub Actions job summary after your first build

Step 5 โ€” Get your APK

GitHub โ†’ Actions โ†’ your workflow run โ†’ wait ~5 min โ†’ Artifacts โ†’ download APK

Or grab it from the Releases tab โ€” the CI creates one automatically. โœ…

To install: open APK on phone โ†’ Install (Enable: Settings โ†’ Security โ†’ Install unknown apps)


Step 6 โ€” Release new versions

Every git push to main auto-creates a GitHub Release. The CI derives the version from the run number:

Run #45  โ†’  v1.4.5      Run #106  โ†’  v2.0.6

MAJOR = floor(run / 100) + 1
MINOR = floor((run % 100) / 10)
PATCH = run % 10

The in-app update checker compares this version against the latest GitHub Release and prompts users to download if newer.


โš™๏ธ Environment Variables

Variable Required Description
VITE_GOOGLE_CLIENT_ID โœ… Google OAuth 2.0 Client ID โ€” get one here
VITE_GITHUB_REPO Optional local override; workflow uses github.repository โž–
VITE_GITHUB_TOKEN Not recommended for public APK builds โŒ
๐Ÿ” How to get a Google Client ID
  1. Google Cloud Console โ†’ create/select a project
  2. APIs & Services โ†’ Library โ†’ enable Google Drive API
  3. APIs & Services โ†’ OAuth consent screen โ†’ External โ†’ add scope .../auth/drive.appdata
  4. Credentials โ†’ Create โ†’ OAuth 2.0 Client ID โ†’ Web application
  5. Authorised JavaScript origins:
    • http://localhost:5173 (local dev)
    • https://your-app.vercel.app (production)
    • https://localhost (Android WebView โ€” required)
  6. Copy the Client ID

๐Ÿš€ CI/CD Pipeline

๐Ÿ“ค git push main
        โ”‚
        โ–ผ
โ‘  ๐Ÿ”  Checkout + Node 20 + npm install
โ‘ก ๐Ÿฉน  Patch GoogleAuth plugin (add Drive scope to native token)
โ‘ข ๐Ÿ”ข  Derive version from run number  โ†’  TAG, VERSION, APK_NAME
โ‘ฃ ๐Ÿ“  Write version into package.json  (so VITE_APP_VERSION matches tag)
โ‘ค ๐Ÿ—๏ธ   npm run build  โ†’  dist/ (Vite)
โ‘ฅ ๐Ÿ“ฑ  npx cap add android  โ†’  android/ (Capacitor project)
โ‘ฆ ๐ŸŽจ  Generate Android launcher/adaptive icons from icon-512.png
โ‘ง โ˜•  Set up JDK 21 + Android SDK (API 35)
โ‘จ ๐Ÿ”—  Patch native APK installer + npx cap sync android
โ‘ฉ ๐Ÿ”“  Decode KEYSTORE_BASE64  โ†’  inkwell-release.jks
โ‘ช ๐Ÿ”‘  Print SHA-1 to job summary (for Google Cloud Console setup)
โ‘ซ ๐Ÿ”จ  ./gradlew assembleRelease  โ†’  signed APK
โ‘ฌ ๐Ÿ“ฆ  Rename APK  โ†’  Inkwell-v{VERSION}.apk
โ‘ญ โฌ†๏ธ   Upload as workflow artifact (retained 30 days)
โ‘ฎ ๐ŸŽ‰  Create GitHub Release with APK attached
โ‘ฏ ๐Ÿ“ฒ  Native updater downloads APK inside app from Releases

โ˜๏ธ Google Drive Sync

๐Ÿ”’ Backup file lives in appDataFolder โ€” never visible in your My Drive.

Backup (inkwell-sync.json):

Step What happens
โœ๏ธ You edit a note 1.2 s debounce timer starts
โฑ๏ธ Timer fires Cached token used (no popup)
๐Ÿ“ค Drive call PATCH if file exists ยท POST multipart if new
โœ… Done iw_last_auto_backup updated in localStorage

Restore on login:

Condition Behaviour
๐Ÿ†• Fresh install / only welcome note Cloud data replaces local entirely
๐Ÿ“ฑ Existing notes present Merge by ID โ€” newer updatedAt wins
โœ… After merge Merged result pushed back to Drive

Manual backup / restore also available in Settings.


๐Ÿ—„๏ธ Data Model

๐Ÿ“‹ localStorage keys
Key Content
iw_notes JSON array of note objects
iw_notebooks JSON array of notebook objects
iw_profile { name, email, joinDate }
iw_theme "dark" or "light"
iw_fontSize "small" ยท "medium" ยท "large"
iw_sort "modified" ยท "created" ยท "title" ยท "tags"
iw_searches Up to 8 recent search strings
iw_gauth Cached Google user + access token + expiry
iw_prefs Miscellaneous UI preferences
iw_last_auto_backup ISO timestamp of last Drive backup
iw_last_cloud_sync Drive file modifiedTime
๐Ÿ“ Note object shape
{
  "id": "lp3abc12x",
  "title": "My Note",
  "content": "<p>HTML from editor</p>",
  "tags": ["work", "ideas"],
  "notebookId": "lp1xyz99a",
  "pinned": false,
  "wordCount": 42,
  "createdAt": "2025-01-01T10:00:00.000Z",
  "updatedAt": "2025-01-15T14:30:00.000Z"
}
๐Ÿ“š Notebook object shape
{
  "id": "lp1xyz99a",
  "name": "Work",
  "color": "#6090e0",
  "icon": "fa-briefcase",
  "createdAt": "2025-01-01T09:00:00.000Z"
}

๐Ÿ“ What to Commit

โœ…  DO commit                  โŒ  NEVER commit
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
src/                           dist/          โ† Vite output
public/                        android/       โ† Capacitor output
docs/
index.html                     node_modules/
package.json                   inkwell-release.jks  โ† signing key!
capacitor.config.json          keystore.txt         โ† base64 key!
vite.config.js                 .env                 โ† has your secrets
vercel.json
.env.example
.gitignore
.github/workflows/build-apk.yml

โœ… Release Check

Before publishing or creating a new release, run the release check from the project root:

npm ci
npm run release:check

The full checklist is in docs/RELEASE_CHECK.md. It covers required GitHub secrets, files that must not be committed, and the expected clean build checks.


๐Ÿ”ง Troubleshooting

๐Ÿšจ Symptom ๐Ÿ’ก Cause โœ… Fix
Sign-in button stuck "loading" VITE_GOOGLE_CLIENT_ID missing Add to .env or Vercel env vars
Sign-in failed on Android Missing Android OAuth credential Add Android credential in GCloud Console (SHA-1 + package com.inkwell.notes)
Drive backup/restore does nothing Token expired or Drive scope missing Sign out โ†’ sign in again; re-run CI
APK build: SDK location not found setup-android step failed Re-run the workflow
APK build: KEYSTORE_BASE64 error Secret missing or bad base64 Re-encode keystore, update secret
Update checker: "Repo not found" VITE_GITHUB_REPO secret missing or wrong Set it to your-username/your-repo in GitHub Secrets โ†’ Actions
Update checker: "rate limited" Too many API calls (60/hr limit) Set VITE_GITHUB_TOKEN with contents:read
Notes not syncing across tabs Browser blocking storage events Check browser privacy/storage settings
White screen on Android Absolute URL paths failing in WebView Confirm base: './' in vite.config.js + HashRouter is used

๐Ÿง  Key Design Decisions

๐Ÿ” Why HashRouter instead of BrowserRouter?

Android WebView serves assets from the filesystem โ€” there's no server to fall back to /index.html for deep links. HashRouter keeps navigation in the URL hash (https://localhost/#/editor), which works perfectly on-device.

๐Ÿ“‚ Why `base: './'` in vite.config.js?

Capacitor copies the built dist/ folder into the Android project. Absolute asset paths (/assets/...) fail when loading from the filesystem. Relative paths (./assets/...) work correctly in both WebView and browser.

๐Ÿฉน Why does the CI patch the GoogleAuth plugin?

@codetrix-studio/capacitor-google-auth only requests profile email by default. The CI patches the plugin's Java source to add https://www.googleapis.com/auth/drive.appdata before Capacitor generates the Android project, because native Google Sign-In must request all scopes upfront โ€” they can't be added silently later.

๐Ÿ“‹ Why is copy/select blocked outside the editor?

Android WebView lets users long-press and copy UI labels. CopySelectGuard intercepts copy, cut, and selectstart events globally, allowing them only when the event target (or selection nodes) are inside .editor-body, .editor-title, or [data-inkwell-copy-ok="1"].



Light mode code block fix

Code blocks now use a readable light surface in light theme, with dark text and visible copy/action buttons.


๐Ÿ“š Docs

The docs/ folder keeps release/setup notes separate from the main README.

Doc Purpose
docs/APP_UPDATE_INSTALL.md In-app APK update, installer, and cleanup flow
docs/ANDROID_ICON.md Android adaptive icon size and safe-zone notes
docs/THEME.md Light/dark theme persistence details
docs/EDITOR.md Editor save, markdown, paste, tag chips, and mobile stability notes
docs/RELEASE_CHECK.md Final checks before publishing a public release
docs/CHANGELOG.md Full app update history and release notes template
docs/WELCOME_NOTE.md App welcome note and editor toolbar examples

Recommended reading order:

  1. RELEASE_CHECK.md
  2. ANDROID_ICON.md
  3. APP_UPDATE_INSTALL.md
  4. THEME.md
  5. EDITOR.md

๐Ÿ“ Changelog

Full update history is available in docs/CHANGELOG.md.

For the in-app update popup, write the newest changes in the GitHub Release description/body. Inkwell reads that release body and shows the short changelog in the update sheet.

Recommended release body format:

## Inkwell v1.0.9

### Fixed
- Added selected delete confirmation
- Added 5-second Undo after delete
- Fixed Tags page selected/unselected colors

### Install
Tap Install in the app update popup or download the APK below.

๐Ÿ“ฒ App Updates

Inkwell checks GitHub Releases for a newer Android APK. The app uses the GitHub Release description/body as changelog text for the update popup.

What the update popup shows

State Result
Current APK is older New APK update available + Install
Current APK matches latest release You are already updated
Release has no APK asset Opens the GitHub Release page
In-app install is blocked Falls back to the release page

Download & install flow

  1. Open Settings โ†’ Check for updates.
  2. Inkwell checks the latest GitHub Release for tharindu899/Inkwell.
  3. If a newer APK exists, the popup shows:
    • latest version
    • installed version
    • APK size
    • download count
    • repo name
    • MB / percent progress bar
  4. Tap Install.
  5. The APK downloads inside the app.
  6. Android Package Installer opens directly.
  7. Tap Install / Update manually.
  8. The temporary downloaded APK is deleted from app cache after a short delay.

Android does not allow silent APK updates for normal apps, so the final Install/Update tap is required.

See docs/APP_UPDATE_INSTALL.md.


๐ŸŽจ Android Icon

The APK build uses correct Android launcher/adaptive icon sizes and safe-zone padding so MIUI/Android launchers do not crop the icon badly.

See docs/ANDROID_ICON.md.


๐ŸŒ“ Theme Persistence

Theme selection is saved in iw_theme and applied before React renders, so light mode stays active after closing and reopening the Android app.

See docs/THEME.md.

๐Ÿ“„ License

Personal project โ€” see the repository for any licence details.


Made with ๐Ÿ–Š๏ธ by tharindu899

โญ Star the repo if you find it useful!

  • Tag selector updated: the editor footer now stays compact, and full tag management opens in a modal.

  • Manage Tags modal is now compact, smaller, and uses a 2-column action layout.

  • Manage Tags modal now uses horizontal scrolling compact tag chips and removes duplicate Add controls.

  • Editor tag selector now matches the notebook selector style, and the Tags page uses compact note-like tag pills.

  • Tags page uses independent note-size tag pills, and notebook badges use the matching notebook icon.

  • Added selected delete confirmation modal with 5-second Undo toast.

  • App welcome note demonstrates all main editor toolbar options for first-time users.

  • App welcome note refreshes only the built-in welcome-note; it does not overwrite user notes.

  • Added full toolbar examples inside the actual app welcome note.

  • Added GitHub theme as the third app appearance option.

  • Welcome note no longer shows a fixed version tag; it can refresh through internal seed updates.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages