* feat: add conversations, desktop (Tauri), and offline sync Major new features: - conversations module: Slack-like channels, threads, reactions, pins - Tauri desktop app with local SQLite for offline-first operation - Hybrid logical clock sync engine with conflict resolution - DB provider abstraction (D1/Tauri/memory) with React context Conversations: - Text/voice/announcement channels with categories - Message threads, reactions, attachments, pinning - Real-time presence and typing indicators - Full-text search across messages Desktop (Tauri): - Local SQLite database with sync to cloud D1 - Offline mutation queue with automatic replay - Window management and keyboard shortcuts - Desktop shell with offline banner Sync infrastructure: - Vector clock implementation for causality tracking - Last-write-wins with semantic conflict resolution - Delta sync via checkpoints for bandwidth efficiency - Comprehensive test coverage Also adds e2e test setup with Playwright and CI workflows for desktop releases. * fix(tests): sync engine test schema and checkpoint logic - Add missing process_after column and sync_tombstone table to test schemas - Fix checkpoint update to save cursor even when records array is empty - Revert claude-code-review.yml workflow changes to match main --------- Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
33 lines
832 B
TypeScript
Executable File
33 lines
832 B
TypeScript
Executable File
"use client"
|
|
|
|
import { useSyncExternalStore } from "react"
|
|
import { isNative, isIOS, isAndroid, getMobilePlatform } from "@/lib/native/platform"
|
|
|
|
// Snapshot never changes after initial load (Capacitor injects before hydration)
|
|
function subscribe(_onStoreChange: () => void): () => void {
|
|
return () => {}
|
|
}
|
|
|
|
function getSnapshot(): boolean {
|
|
return isNative()
|
|
}
|
|
|
|
function getServerSnapshot(): boolean {
|
|
return false
|
|
}
|
|
|
|
export function useNative(): boolean {
|
|
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)
|
|
}
|
|
|
|
// Returns mobile platform only (ios, android, web) - for desktop use useDesktopPlatform
|
|
export function useNativePlatform(): "ios" | "android" | "web" {
|
|
return useSyncExternalStore(
|
|
subscribe,
|
|
() => getMobilePlatform(),
|
|
() => "web" as const,
|
|
)
|
|
}
|
|
|
|
export { isIOS, isAndroid }
|