mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-13 05:16:29 +02:00
Bundles the markdown rendering overhaul plus in-flight mobile feature
work as a single WIP for review.
Markdown work (the new direction):
- Swap internal Markdown component from hand-rolled marked walker to
react-native-enriched-markdown (Software Mansion, native md4c).
Public API <Markdown content={...} /> unchanged; consumers untouched.
Mention links degrade to colored links + onLinkPress routing.
- Pre-swap fixes that landed first: 3-layer inline code (later corrected),
Shiki via react-native-shiki-engine wired (now bypassed; code retained
for selective re-enable on code blocks), code block copy button with
expo-clipboard + expo-haptics, inline SVG copy/check icons, header
scale calibrated to Apple HIG, paragraph leading-6 for CJK, list
bullet column 24->16, lineBreakStrategyIOS="hangul-word" on outer
paragraph Text.
- Preprocess: <br> -> " \n" (CommonMark HardBreak) so md4c respects
intentional breaks without misreading bare \n.
- Drop the Expo Go compatibility constraint from CLAUDE.md and
markdown-renderer-research.md (project runs on dev client).
- New apps/mobile/docs/markdown-renderer-research.md captures the
RN nested-Text rendering constraints (#10775 / #45925 / #6728), the
CJK amplification mechanism, the typography scale calibration, and
every decision-log entry from the engine evolution.
Other in-flight mobile features included:
- Issue detail timeline polish, comment composer + action sheet,
mention suggestion bar, emoji picker sheet, reaction bar.
- Status / priority / assignee / label / due date picker sheets.
- My Issues filter sheet + view store.
- Realtime layer (ws-client, realtime-provider, use-inbox-realtime).
- Data layer additions (queries, mutations, schemas, attribute chips).
Cross-package:
- packages/core/api/schemas.ts: export IssueSchema for mobile use.
Build: native rebuild required after pulling (enriched-markdown is
a native Fabric module).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
55 lines
2.3 KiB
TypeScript
55 lines
2.3 KiB
TypeScript
/**
|
|
* Mobile-owned QueryClient.
|
|
*
|
|
* Bridges TanStack Query's two cross-cutting managers to native signals:
|
|
* - focusManager ← AppState ('active' = focused)
|
|
* - onlineManager ← NetInfo (isConnected)
|
|
*
|
|
* After this wiring is in place, queries with `refetchOnWindowFocus: true`
|
|
* (the default) refetch on foreground, and queries are automatically paused
|
|
* while offline + replayed when the network returns. The realtime
|
|
* WebSocket layer (data/realtime/) reads the same signals to drive socket
|
|
* connect/disconnect, so the two stay in sync.
|
|
*
|
|
* Web/desktop use a different QueryClient (packages/core/query-client.ts).
|
|
* Mobile maintains its own to keep React Native deps out of shared code.
|
|
*/
|
|
import { focusManager, onlineManager, QueryClient } from "@tanstack/react-query";
|
|
import { AppState, type AppStateStatus } from "react-native";
|
|
import NetInfo from "@react-native-community/netinfo";
|
|
|
|
export const queryClient = new QueryClient({
|
|
defaultOptions: {
|
|
queries: {
|
|
staleTime: 60 * 1000, // 1 minute
|
|
gcTime: 10 * 60 * 1000, // 10 minutes
|
|
retry: 1,
|
|
refetchOnWindowFocus: true, // honored via focusManager bridge below
|
|
},
|
|
mutations: {
|
|
retry: false,
|
|
},
|
|
},
|
|
});
|
|
|
|
// ── focusManager ← AppState ──────────────────────────────────────────
|
|
// Foregrounding the app counts as "focus" → triggers refetchOnWindowFocus
|
|
// for any stale queries the user is currently looking at.
|
|
focusManager.setEventListener((handleFocus) => {
|
|
const sub = AppState.addEventListener("change", (status: AppStateStatus) => {
|
|
handleFocus(status === "active");
|
|
});
|
|
return () => sub.remove();
|
|
});
|
|
|
|
// ── onlineManager ← NetInfo ──────────────────────────────────────────
|
|
// While offline, TanStack Query pauses queries; when isConnected flips
|
|
// back to true it replays paused fetches. RealtimeProvider also listens
|
|
// to NetInfo to force-reconnect the WS — both flows are driven by the
|
|
// same signal so client state and server state catch up together.
|
|
onlineManager.setEventListener((setOnline) => {
|
|
return NetInfo.addEventListener((state) => {
|
|
setOnline(state.isConnected === true);
|
|
});
|
|
});
|