feat(ui): adaptive 3-panel layout, chat panel switching, audio metering fix
- Add responsive breakpoints (compact <600, medium 600-1023, expanded >=1024) - Add ViewportInfo InheritedWidget for layout-aware descendants - Add inline ChatPanel (380dp right column) for expanded desktop layout - Add channel right-click context menu with Chat option for in-place switching - Add per-target draft persistence via restoredDraft/onDraftChanged callbacks - Fix header chat button to switch to current voice channel when panel open - Fix close = dismiss (preserves last target and draft for reopen) - Add unread dot indicator on channel tiles when chat is closed - Fix audio regression: decimate dBFS computation to every 3rd callback (~31 Hz) to avoid buffer underruns on macOS CoreAudio real-time thread - Add tools/build-macos.sh release build script (7-step process) - Add chat panel switching implementation plan and 3-panel design spec Tests: 183 passed, 2 skipped. Flutter analyze clean.
This commit is contained in:
Executable
+206
@@ -0,0 +1,206 @@
|
||||
#!/usr/bin/env bash
|
||||
# Chanora macOS build helper.
|
||||
#
|
||||
# Run this on a macOS host that has already completed §4 of
|
||||
# docs/release/macos-build.md:
|
||||
# - Xcode 26+ with Command Line Tools
|
||||
# - Rust stable with aarch64-apple-darwin and/or x86_64-apple-darwin targets
|
||||
# - Flutter 3.41.9+ stable on PATH
|
||||
# - flutter_rust_bridge_codegen 2.12.0 (only if regenerating bindings)
|
||||
#
|
||||
# Usage (from the repo root ~/chanora):
|
||||
# ./tools/build-macos.sh
|
||||
# ./tools/build-macos.sh --no-rust # skip Rust rebuild (cached)
|
||||
# ./tools/build-macos.sh --regenerate-bindings # rerun FRB codegen first
|
||||
# ./tools/build-macos.sh --version v0.2.0-beta.1
|
||||
# ./tools/build-macos.sh --target aarch64-apple-darwin
|
||||
#
|
||||
# Produces:
|
||||
# target/<triple>/release/libchanora_bridge.dylib
|
||||
# apps/chanora_flutter/build/macos/Build/Products/Release/chanora_flutter.app
|
||||
# chanora-<version>-macos-<arch>.zip (release bundle)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
VERSION="v0.2.0-beta.1"
|
||||
SKIP_RUST=0
|
||||
REGEN=0
|
||||
TARGET="$(rustc -vV | grep '^host:' | cut -d' ' -f2)"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--version) VERSION="$2"; shift 2;;
|
||||
--no-rust) SKIP_RUST=1; shift;;
|
||||
--regenerate-bindings) REGEN=1; shift;;
|
||||
--target) TARGET="$2"; shift 2;;
|
||||
*) echo "unknown arg: $1" >&2; exit 2;;
|
||||
esac
|
||||
done
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
REPO_ROOT="$(pwd)"
|
||||
|
||||
bar() { printf '%s\n' '========================================================================'; }
|
||||
|
||||
ARCH="${TARGET%%-*}"
|
||||
bar
|
||||
echo "Chanora macOS build"
|
||||
echo "Repo root : $REPO_ROOT"
|
||||
echo "Version : $VERSION"
|
||||
echo "Target : $TARGET"
|
||||
echo "Arch : $ARCH"
|
||||
echo "Build Rust: $([ "$SKIP_RUST" = 1 ] && echo skip || echo yes)"
|
||||
bar
|
||||
|
||||
# ---------- 1. Verify toolchain ----------
|
||||
echo "[1/7] Verify toolchain"
|
||||
for cmd in cargo rustc flutter xcodebuild xcrun codesign install_name_tool; do
|
||||
if ! command -v "$cmd" >/dev/null; then
|
||||
echo " ERROR: '$cmd' not on PATH. See docs/release/macos-build.md." >&2
|
||||
exit 1
|
||||
fi
|
||||
printf " %-20s : %s\n" "$cmd" "$($cmd --version 2>&1 | head -1)"
|
||||
done
|
||||
|
||||
# ---------- 2. Verify Rust target ----------
|
||||
if [[ "$TARGET" != "$(rustc -vV | grep '^host:' | cut -d' ' -f2)" ]]; then
|
||||
if ! rustup target list --installed | grep -q "^$TARGET$"; then
|
||||
echo " Adding rustup target $TARGET..."
|
||||
rustup target add "$TARGET"
|
||||
fi
|
||||
else
|
||||
echo "[2/7] Rust target $TARGET is the host triple (already available)"
|
||||
fi
|
||||
|
||||
# ---------- 3. Add macOS platform if missing ----------
|
||||
FLUTTER_APP="$REPO_ROOT/apps/chanora_flutter"
|
||||
if [[ ! -d "$FLUTTER_APP/macos" ]]; then
|
||||
echo "[3/7] Add macOS platform to apps/chanora_flutter"
|
||||
(cd "$FLUTTER_APP" && flutter create --platforms=macos .)
|
||||
else
|
||||
echo "[3/7] macOS platform already present in apps/chanora_flutter"
|
||||
fi
|
||||
|
||||
# ---------- 4. (Optional) regenerate FRB bindings ----------
|
||||
if [[ $REGEN -eq 1 ]]; then
|
||||
echo "[4/7] Regenerate flutter_rust_bridge bindings"
|
||||
if ! command -v flutter_rust_bridge_codegen >/dev/null; then
|
||||
echo " flutter_rust_bridge_codegen not on PATH; install it first." >&2
|
||||
exit 1
|
||||
fi
|
||||
flutter_rust_bridge_codegen generate
|
||||
else
|
||||
echo "[4/7] Skipping FRB codegen (use --regenerate-bindings if api.rs changed)"
|
||||
fi
|
||||
|
||||
# ---------- 5. Build the Rust cdylib ----------
|
||||
DYLIB="$REPO_ROOT/target/$TARGET/release/libchanora_bridge.dylib"
|
||||
|
||||
if [[ $SKIP_RUST -eq 1 ]]; then
|
||||
echo "[5/7] Skipping Rust build (cached)"
|
||||
if [[ ! -f "$DYLIB" ]]; then
|
||||
echo " ERROR: --no-rust but $DYLIB not found. Run without --no-rust first." >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "[5/7] cargo build --release -p chanora_bridge --target $TARGET"
|
||||
export CMAKE_POLICY_VERSION_MINIMUM=3.5
|
||||
cargo build --release --target "$TARGET" -p chanora_bridge
|
||||
fi
|
||||
|
||||
echo " Bridge dylib: $DYLIB"
|
||||
if [[ ! -f "$DYLIB" ]]; then
|
||||
echo " ERROR: $DYLIB not found after build." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ---------- 6. flutter build macos --release ----------
|
||||
echo "[6/7] flutter build macos --release"
|
||||
cd "$FLUTTER_APP"
|
||||
flutter pub get
|
||||
flutter build macos --release
|
||||
|
||||
APP="$FLUTTER_APP/build/macos/Build/Products/Release/chanora_flutter.app"
|
||||
if [[ ! -d "$APP" ]]; then
|
||||
echo " ERROR: $APP not found after flutter build." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Wrap the bridge dylib into a proper .framework bundle, rewrite its
|
||||
# LC_ID_DYLIB, and ad-hoc codesign — same steps as macos-postbuild.sh.
|
||||
FW="$APP/Contents/Frameworks/chanora_bridge.framework"
|
||||
|
||||
echo " Wrapping bridge into chanora_bridge.framework"
|
||||
rm -rf "$FW"
|
||||
mkdir -p "$FW/Versions/A/Resources"
|
||||
cp "$DYLIB" "$FW/Versions/A/chanora_bridge"
|
||||
|
||||
cat > "$FW/Versions/A/Resources/Info.plist" << 'PLIST'
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>chanora_bridge</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>app.chanora.bridge</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>chanora_bridge</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
PLIST
|
||||
|
||||
ln -sf A "$FW/Versions/Current"
|
||||
ln -sf Versions/Current/chanora_bridge "$FW/chanora_bridge"
|
||||
ln -sf Versions/Current/Resources "$FW/Resources"
|
||||
|
||||
echo " install_name_tool -id @rpath/chanora_bridge.framework/chanora_bridge"
|
||||
install_name_tool \
|
||||
-id "@rpath/chanora_bridge.framework/chanora_bridge" \
|
||||
"$FW/Versions/A/chanora_bridge"
|
||||
|
||||
# Drop a stale plain dylib if a previous build left one alongside the framework.
|
||||
rm -f "$APP/Contents/Frameworks/libchanora_bridge.dylib"
|
||||
|
||||
echo " codesigning framework + app (ad-hoc)"
|
||||
codesign --force -s - --timestamp=none "$FW/Versions/A/chanora_bridge"
|
||||
codesign --force -s - --timestamp=none "$FW"
|
||||
codesign --force --deep -s - --timestamp=none "$APP"
|
||||
|
||||
codesign --verify --deep --strict "$APP"
|
||||
|
||||
echo " App bundle : $APP"
|
||||
|
||||
# ---------- 7. Package the bundle ----------
|
||||
echo "[7/7] Package release zip"
|
||||
cd "$REPO_ROOT"
|
||||
ZIP_NAME="chanora-$VERSION-macos-$ARCH.zip"
|
||||
ZIP_PATH="$REPO_ROOT/$ZIP_NAME"
|
||||
rm -f "$ZIP_PATH"
|
||||
|
||||
# zip the .app bundle from inside the Products directory so the archive
|
||||
# contains chanora_flutter.app/ at the top level.
|
||||
(cd "$FLUTTER_APP/build/macos/Build/Products/Release" && \
|
||||
zip -r -q "$ZIP_PATH" chanora_flutter.app)
|
||||
|
||||
echo " Zip : $ZIP_PATH"
|
||||
echo " Size : $(du -h "$ZIP_PATH" | cut -f1)"
|
||||
|
||||
shasum -a 256 "$ZIP_PATH"
|
||||
|
||||
bar
|
||||
echo "macOS build complete."
|
||||
bar
|
||||
echo "Artefacts:"
|
||||
echo " Rust lib:"
|
||||
echo " target/$TARGET/release/libchanora_bridge.dylib"
|
||||
echo " App bundle:"
|
||||
echo " $APP"
|
||||
echo " Zip:"
|
||||
echo " $ZIP_PATH"
|
||||
Reference in New Issue
Block a user