Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6ae44a8
chore: move legacy Flutter codebase to legacy/flutter
lucaslus Sep 3, 2026
1f624c3
feat: refactor floatick to tauri v2 + react/ts menu bar architecture
lucaslus Sep 3, 2026
8b3c614
fix(ui): restore exact Floatick design system, brandmark, action bar …
lucaslus Sep 3, 2026
2ad08af
fix(i18n, markdown, mui): comprehensive i18n, dedicated markdown rend…
lucaslus Sep 3, 2026
4ce7c06
fix(i18n): 100% comprehensive i18n coverage, reactive date grouping a…
lucaslus Sep 3, 2026
36222e3
feat(ui): top-tier raycast/linear luxury obsidian aesthetic, tactile …
lucaslus Sep 3, 2026
d3d1a8f
refactor(ui, i18n): streamline visual hierarchy and reduce copy verbo…
lucaslus Sep 3, 2026
0ae120b
feat(ui, fonts, shortcuts): bundle local Google Sans & Fira Code font…
lucaslus Sep 3, 2026
d396189
refactor(theme, ui): 100% faithful restoration of original Flutter de…
lucaslus Sep 3, 2026
c998dd5
perf(rendering): enable 120Hz ProMotion GPU layer compositing, touch …
lucaslus Sep 3, 2026
ee14260
refactor(editor): 100% faithful recreation of Flutter FloatickDocumen…
lucaslus Sep 3, 2026
9d5209d
refactor(tags): 100% authentic recreation of Flutter 292px Side Drawe…
lucaslus Sep 3, 2026
e6f7e37
fix(tags): complete forensic overhaul matching Flutter - multi-select…
lucaslus Sep 3, 2026
efebed7
fix(tags): add Flutter colorValue backward compatibility in Rust stor…
lucaslus Sep 3, 2026
16d9c94
fix(window): fix initial and tray window positioning by properly conv…
lucaslus Sep 3, 2026
0518f8b
feat(icons): migrate from lucide-react to @phosphor-icons/react with …
lucaslus Sep 3, 2026
307e0f7
fix(window): prevent immediate hide on focus loss with debounce and h…
lucaslus Sep 3, 2026
ec1147f
feat(tray): add macOS native template double-check icon and live acti…
lucaslus Sep 3, 2026
6a1de90
refactor(ui): streamline border-radii and remove unnecessary button b…
lucaslus Sep 3, 2026
214007d
fix(i18n): add missing settingsTitle and tag localization keys in zh …
lucaslus Sep 3, 2026
058b974
refactor(settings): streamline theme switcher to minimalist icon-only…
lucaslus Sep 3, 2026
9339cc9
feat: modernize website showcase, integrate TipTap editor, and polish…
lucaslus Sep 4, 2026
afa5479
feat(editor): introduce view mode & edit mode toggle and refresh edit…
lucaslus Sep 4, 2026
270262e
style(ui): use normal sentence case for date groups and time labels i…
lucaslus Sep 4, 2026
86ed9b2
fix: stabilize tray panel and refine product website
lucaslus Sep 7, 2026
7748c99
chore(release): prepare universal Tauri v0.4.0 release
lucaslus Sep 7, 2026
c3429a6
fix(ci): retain app bundle for release verification
lucaslus Sep 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/release-notes-header.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ Floatick 目前仍处于早期版本。第一次打开时,如果 macOS 需要
尝试打开一次 Floatick,然后前往“系统设置”→“隐私与安全”,在“安全性”区域
点击“仍要打开”。

完成一次确认后,后续即可正常启动。应用内更新会使用独立的 Sparkle EdDSA
签名验证下载内容,并在安装前征求确认。
完成一次确认后,后续即可正常启动。安装包同时支持 Apple 芯片和 Intel Mac。

Floatick is still at an early stage. If macOS asks for an additional confirmation
on first launch, try opening Floatick once, then go to System Settings → Privacy &
Security and choose Open Anyway in the Security section.

In-app updates verify downloads with an independent Sparkle EdDSA signature and
always ask before installation.
The same installer supports both Apple silicon and Intel Macs.
26 changes: 26 additions & 0 deletions .github/release-notes/0.4.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
## Floatick v0.4.0

### 中文

- 全新菜单栏应用:点击托盘图标打开待办和笔记,角标显示未完成任务数。
- 使用 Tauri、React 与 Rust 重构,继续使用 `~/.floatick` 保存本地数据。
- 新版富文本编辑器支持阅读与编辑切换、任务清单、标题、Markdown 快捷输入和复制。
- 待办和笔记共用彩色标签,支持搜索、组合筛选、归档和恢复。
- 修复托盘点击与失焦关闭之间的竞争,减少面板打开时闪关、重开的情况。
- 更新中英文官网、产品截图和手机布局,清理截图圆角白边。

升级说明:v0.4.0 会展示截止时间与逾期状态,但暂未迁移 v0.3.4 的到点弹出提醒和内置
“检查更新”。后续版本可从官网或 GitHub Releases 下载安装。建议升级前备份 `~/.floatick`。

### English

- A new menu bar app for todos and notes, with an active task count in the tray.
- Rebuilt with Tauri, React, and Rust; local data remains in `~/.floatick`.
- A new editor with reading and editing modes, checklists, headings, Markdown shortcuts, and copy.
- Shared colored tags, search, combined filters, archiving, and restore for todos and notes.
- Fixed competing tray and blur events that could make the panel briefly close and reopen.
- Refreshed the bilingual website, product screenshots, mobile layout, and screenshot corners.

Upgrade note: v0.4.0 displays due dates and overdue status, but the v0.3.4 reminder popups and built-in
update checker have not yet been migrated. Download subsequent versions from the website or GitHub
Releases. Back up `~/.floatick` before upgrading.
147 changes: 73 additions & 74 deletions .github/workflows/candidate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,17 @@ concurrency:
cancel-in-progress: true

env:
FLUTTER_VERSION: 3.44.7
PRODUCT_NAME: Floatick

jobs:
candidate:
name: Build draft release
runs-on: macos-15
runs-on: macos-latest
timeout-minutes: 45

steps:
- name: Check out repository
uses: actions/checkout@v7
uses: actions/checkout@v4
with:
fetch-depth: 0

Expand All @@ -40,21 +39,23 @@ jobs:
fi

branch_version="${BASH_REMATCH[1]}"
full_version=$(awk '/^version:/{print $2}' pubspec.yaml)
app_version=${full_version%%+*}
app_build_number=${full_version#*+}
pkg_version=$(jq -r .version package.json)
tauri_version=$(jq -r .version src-tauri/tauri.conf.json)

if [[ "$full_version" == "$app_version" ||
! "$app_build_number" =~ ^[1-9][0-9]*$ ]]; then
echo "pubspec version must include a positive build number." >&2
cargo_version=$(sed -n 's/^version = "\([^"]*\)"/\1/p' src-tauri/Cargo.toml | head -n 1)
app_build_number=$(jq -r .bundle.macOS.bundleVersion src-tauri/tauri.conf.json)
if [[ "$pkg_version" != "$branch_version" || "$tauri_version" != "$branch_version" || "$cargo_version" != "$branch_version" ]]; then
echo "Branch release/$branch_version does not match version in package.json ($pkg_version) or tauri.conf.json ($tauri_version)." >&2
exit 1
fi
if [[ "$app_version" != "$branch_version" ]]; then
echo "Branch release/$branch_version does not match pubspec version $app_version." >&2
if [[ ! "$app_build_number" =~ ^[1-9][0-9]*$ ]]; then
echo "Set a positive bundle.macOS.bundleVersion build number." >&2
exit 1
fi
if git ls-remote --exit-code --tags origin "refs/tags/v$app_version" \
>/dev/null 2>&1; then

app_version="$branch_version"

if git ls-remote --exit-code --tags origin "refs/tags/v$app_version" >/dev/null 2>&1; then
echo "Stable tag v$app_version already exists." >&2
exit 1
fi
Expand All @@ -63,91 +64,91 @@ jobs:
echo "app_build_number=$app_build_number" >> "$GITHUB_OUTPUT"
echo "candidate_tag=candidate/v$app_version" >> "$GITHUB_OUTPUT"

- name: Install Flutter
shell: bash
run: |
git clone \
--branch "$FLUTTER_VERSION" \
--depth 1 \
https://github.com/flutter/flutter.git \
"$RUNNER_TEMP/flutter"
echo "$RUNNER_TEMP/flutter/bin" >> "$GITHUB_PATH"
- name: Install pnpm
uses: pnpm/action-setup@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: 'pnpm'

- name: Set up Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-apple-darwin,x86_64-apple-darwin

- name: Cache cargo registry & target
uses: swatinem/rust-cache@v2
with:
workspaces: src-tauri -> target

- name: Install dependencies
run: flutter pub get
run: pnpm install --frozen-lockfile

- name: Verify source
- name: Verify frontend and backend tests
run: |
dart format --output=none --set-exit-if-changed lib test
flutter analyze
flutter test
pnpm build
cargo test --manifest-path src-tauri/Cargo.toml --locked

- name: Build release app
- name: Build macOS release bundles
run: pnpm tauri build --target universal-apple-darwin --bundles app,dmg

- name: Verify app version, architectures, and startup
env:
APP_VERSION: ${{ steps.version.outputs.app_version }}
APP_BUILD_NUMBER: ${{ steps.version.outputs.app_build_number }}
run: |
flutter build macos \
--release \
--build-name "$APP_VERSION" \
--build-number "$APP_BUILD_NUMBER"

- name: Prepare unsigned candidate app
run: |
tool/release/prepare_unsigned_app.sh \
"build/macos/Build/Products/Release/$PRODUCT_NAME.app"

- name: Verify update feed
shell: bash
run: |
repository_name=${GITHUB_REPOSITORY#*/}
expected_feed_url="https://$GITHUB_REPOSITORY_OWNER.github.io/$repository_name/appcast.xml"
tool/release/verify_update_feed.sh \
"build/macos/Build/Products/Release/$PRODUCT_NAME.app" \
"$expected_feed_url"

- name: Verify app architectures
shell: bash
run: |
app_path="build/macos/Build/Products/Release/$PRODUCT_NAME.app"
executable_name=$(/usr/libexec/PlistBuddy \
-c 'Print :CFBundleExecutable' \
"$app_path/Contents/Info.plist")
architectures=$(lipo -archs "$app_path/Contents/MacOS/$executable_name")

if [[ "$architectures" != *arm64* || "$architectures" != *x86_64* ]]; then
echo "Expected a universal app, found: $architectures" >&2
app_path="src-tauri/target/universal-apple-darwin/release/bundle/macos/$PRODUCT_NAME.app"
info_plist="$app_path/Contents/Info.plist"
installed_version=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' "$info_plist")
installed_build=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleVersion' "$info_plist")
executable_name=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleExecutable' "$info_plist")
executable="$app_path/Contents/MacOS/$executable_name"
[[ "$installed_version" == "$APP_VERSION" && "$installed_build" == "$APP_BUILD_NUMBER" ]]
lipo -verify_arch arm64 x86_64 "$executable"
"$executable" > "$RUNNER_TEMP/floatick-startup.log" 2>&1 &
app_pid=$!
trap 'kill "$app_pid" 2>/dev/null || true' EXIT
sleep 5
if ! kill -0 "$app_pid" 2>/dev/null; then
cat "$RUNNER_TEMP/floatick-startup.log"
echo "Floatick exited during the startup smoke test." >&2
exit 1
fi
kill "$app_pid"
wait "$app_pid" || true
trap - EXIT

- name: Smoke-test candidate app
run: |
tool/release/smoke_test_app.sh \
"build/macos/Build/Products/Release/$PRODUCT_NAME.app"

- name: Create candidate package
- name: Package candidate artifacts
id: package
env:
APP_VERSION: ${{ steps.version.outputs.app_version }}
APP_BUILD_NUMBER: ${{ steps.version.outputs.app_build_number }}
shell: bash
run: |
artifact_directory="$RUNNER_TEMP/artifacts"
mkdir -p "$artifact_directory"

dmg_source=$(find src-tauri/target/universal-apple-darwin/release/bundle/dmg -name "*.dmg" | head -n 1)
if [[ -z "$dmg_source" || ! -f "$dmg_source" ]]; then
echo "No DMG generated by Tauri build." >&2
exit 1
fi

dmg_name="$PRODUCT_NAME-$APP_VERSION-macos-universal.dmg"
dmg_path="$artifact_directory/$dmg_name"
manifest_name="$PRODUCT_NAME-$APP_VERSION-release-manifest.json"
manifest_path="$artifact_directory/$manifest_name"

tool/release/create_dmg.sh \
"build/macos/Build/Products/Release/$PRODUCT_NAME.app" \
"$dmg_path" \
"$PRODUCT_NAME"
cp "$dmg_source" "$dmg_path"

(
cd "$artifact_directory"
shasum -a 256 "$dmg_name" > "$dmg_name.sha256"
)
dmg_sha256=$(awk '{print $1}' "$dmg_path.sha256")

manifest_name="$PRODUCT_NAME-$APP_VERSION-release-manifest.json"
manifest_path="$artifact_directory/$manifest_name"
jq -n \
--arg product "$PRODUCT_NAME" \
--arg version "$APP_VERSION" \
Expand Down Expand Up @@ -199,8 +200,7 @@ jobs:
gh release edit "$CANDIDATE_TAG" \
--draft \
--target "$GITHUB_SHA" \
--title "$PRODUCT_NAME v$APP_VERSION — Candidate" \
--notes-file .github/release-notes-header.md
--title "$PRODUCT_NAME v$APP_VERSION — Candidate"
gh release upload "$CANDIDATE_TAG" \
"$DMG_PATH#$DMG_NAME" \
"$DMG_PATH.sha256#$DMG_NAME.sha256" \
Expand All @@ -214,8 +214,7 @@ jobs:
--verify-tag \
--draft \
--target "$GITHUB_SHA" \
--title "$PRODUCT_NAME v$APP_VERSION — Candidate" \
--notes-file .github/release-notes-header.md
--title "$PRODUCT_NAME v$APP_VERSION — Candidate"
fi

echo "Draft release updated for commit $GITHUB_SHA."
Loading
Loading