@mushi-mushi/react-native 0.22.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -2
- package/dist/index.cjs +1269 -479
- package/dist/index.d.cts +170 -7
- package/dist/index.d.ts +170 -7
- package/dist/index.js +1118 -323
- package/package.json +3 -9
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, FC, ReactElement } from 'react';
|
|
3
|
-
import { MushiAnalyticsConfig, MushiRewardsConfig, MushiPageContext, MushiBreadcrumb, MushiReporterReport, MushiReporterComment, MushiHallOfFameEntry, MushiPropertyValue, MushiTierResult, MushiReputationResult, MushiAssistantReply } from '@mushi-mushi/core';
|
|
3
|
+
import { MushiAnalyticsConfig, MushiRewardsConfig, MushiPageContext, MushiBreadcrumb, MushiReporterReport, MushiReporterComment, MushiApiResponse, MushiHallOfFameEntry, MushiPropertyValue, MushiTierResult, MushiReputationResult, MushiAssistantReply } from '@mushi-mushi/core';
|
|
4
4
|
export { MushiHallOfFameEntry, MushiReporterComment, MushiReporterReport } from '@mushi-mushi/core';
|
|
5
|
+
import { MushiReporterUpdates, MushiReporterNotificationPrefs, MushiReporterPrefsUpdate, MushiReporterReportDetail } from '@mushi-mushi/core/reporter-channels';
|
|
5
6
|
|
|
6
7
|
interface ConsoleEntry {
|
|
7
8
|
level: 'log' | 'warn' | 'error';
|
|
@@ -74,6 +75,42 @@ declare function getDeviceInfo(): DeviceInfo;
|
|
|
74
75
|
/** The subset of the web `analytics` block that applies on native. */
|
|
75
76
|
type RNAnalyticsConfig = Pick<MushiAnalyticsConfig, 'enabled' | 'consent' | 'flushIntervalMs' | 'propertyAllowlist'>;
|
|
76
77
|
|
|
78
|
+
/**
|
|
79
|
+
* FILE: theme.ts
|
|
80
|
+
* PURPOSE: Host-adaptive theme for the RN report sheet (`widget.theme`).
|
|
81
|
+
*
|
|
82
|
+
* OVERVIEW:
|
|
83
|
+
* - Defaults are neutral: the shared washi/sumi surfaces with an INK accent,
|
|
84
|
+
* so the sheet reads as part of the host app rather than a neon Mushi
|
|
85
|
+
* product. The neon palette is only used by `<MushiBanner variant="neon">`.
|
|
86
|
+
* - Hosts override any token. When a host sets `accent` but not `accentFg`,
|
|
87
|
+
* the text colour on the accent is picked for contrast (black or white).
|
|
88
|
+
*
|
|
89
|
+
* Plan 018 (docs/execplans/reporter-loop-v2.md §1.4).
|
|
90
|
+
*/
|
|
91
|
+
interface MushiRNTheme {
|
|
92
|
+
/** Sheet background. */
|
|
93
|
+
bg: string;
|
|
94
|
+
/** Primary text. */
|
|
95
|
+
fg: string;
|
|
96
|
+
/** Secondary text. */
|
|
97
|
+
muted: string;
|
|
98
|
+
/** Cards, inputs, chips. */
|
|
99
|
+
surface: string;
|
|
100
|
+
/** Borders and separators. */
|
|
101
|
+
border: string;
|
|
102
|
+
/** Selected chip, primary button, links. */
|
|
103
|
+
accent: string;
|
|
104
|
+
/** Text on `accent`. */
|
|
105
|
+
accentFg: string;
|
|
106
|
+
success: string;
|
|
107
|
+
error: string;
|
|
108
|
+
/** Host font family; undefined keeps the platform font. */
|
|
109
|
+
fontFamily?: string;
|
|
110
|
+
/** Corner radius for cards, inputs and buttons. */
|
|
111
|
+
radius: number;
|
|
112
|
+
}
|
|
113
|
+
|
|
77
114
|
interface MushiRNConfig {
|
|
78
115
|
projectId: string;
|
|
79
116
|
apiKey: string;
|
|
@@ -115,6 +152,39 @@ interface MushiRNConfig {
|
|
|
115
152
|
};
|
|
116
153
|
/** Poll interval (ms) for My Reports while the inbox tab is open. 0 = off (default). */
|
|
117
154
|
inboxPollIntervalMs?: number;
|
|
155
|
+
/**
|
|
156
|
+
* Theme tokens for the report sheet (bg, fg, muted, surface, border,
|
|
157
|
+
* accent, accentFg, success, error, fontFamily, radius). Unset tokens
|
|
158
|
+
* use neutral system-style defaults with an ink accent; when only
|
|
159
|
+
* `accent` is set, the text on it is chosen for contrast.
|
|
160
|
+
*/
|
|
161
|
+
theme?: Partial<MushiRNTheme>;
|
|
162
|
+
/**
|
|
163
|
+
* Characters needed before Send enables. Default 8 (Plan 018 §1.1); an
|
|
164
|
+
* attached screenshot lowers it to 0.
|
|
165
|
+
*/
|
|
166
|
+
minDescriptionLength?: number;
|
|
167
|
+
};
|
|
168
|
+
/**
|
|
169
|
+
* Optional native modules, passed in instead of loaded. When set, the SDK
|
|
170
|
+
* uses them and never loads that package itself — the safest option for
|
|
171
|
+
* Metro configs that disallow optional requires. Each one is also picked up
|
|
172
|
+
* automatically when installed.
|
|
173
|
+
* - `netInfo`: `@react-native-community/netinfo` — resend queued reports when the network returns.
|
|
174
|
+
* - `viewShot`: `react-native-view-shot` — attach a screenshot.
|
|
175
|
+
* - `expoSensors`: `expo-sensors` — shake to report.
|
|
176
|
+
*/
|
|
177
|
+
netInfo?: unknown;
|
|
178
|
+
viewShot?: unknown;
|
|
179
|
+
expoSensors?: unknown;
|
|
180
|
+
/** How reporters hear back outside the sheet (Plan 018 §4). No native push. */
|
|
181
|
+
notifications?: {
|
|
182
|
+
/** One "the developer replied" / "your bug is fixed" toast when the app returns to the foreground. Default true. */
|
|
183
|
+
toast?: boolean;
|
|
184
|
+
/** Offer "Get updates by email" after sending, when the project offers email. Default true. */
|
|
185
|
+
email?: boolean;
|
|
186
|
+
/** Prefill that email box from `setUser({ email })`. Default false; the box is never pre-ticked. */
|
|
187
|
+
emailFromIdentity?: boolean;
|
|
118
188
|
};
|
|
119
189
|
assistant?: {
|
|
120
190
|
enabled?: boolean;
|
|
@@ -175,6 +245,8 @@ interface MushiRNInstance {
|
|
|
175
245
|
submitReport(data: {
|
|
176
246
|
description: string;
|
|
177
247
|
category: string;
|
|
248
|
+
/** Host / chip sub-label, e.g. 'feature' for the Idea chip. */
|
|
249
|
+
userCategory?: string;
|
|
178
250
|
screenshotDataUrl?: string;
|
|
179
251
|
}): Promise<{
|
|
180
252
|
ok: boolean;
|
|
@@ -226,8 +298,39 @@ interface MushiRNInstance {
|
|
|
226
298
|
}): void;
|
|
227
299
|
/** List this device's reports ordered by most recent. Returns [] on failure. */
|
|
228
300
|
listMyReports(): Promise<MushiReporterReport[]>;
|
|
229
|
-
/** List admin + reporter comments on a specific report. */
|
|
301
|
+
/** List admin + reporter comments on a specific report. Returns [] on failure. */
|
|
230
302
|
listMyComments(reportId: string): Promise<MushiReporterComment[]>;
|
|
303
|
+
/** Like `listMyComments`, but resolves `null` when the thread could not be loaded, so a UI can offer Retry. */
|
|
304
|
+
loadMyThread(reportId: string): Promise<MushiReporterComment[] | null>;
|
|
305
|
+
/** Mark this device's unread notifications for a report as read. Resolves the number marked (0 on failure). */
|
|
306
|
+
markReportRead(reportId: string): Promise<number>;
|
|
307
|
+
/** Unread count and the newest unread updates on this device's reports (null on failure). */
|
|
308
|
+
getReporterUpdates(): Promise<MushiReporterUpdates | null>;
|
|
309
|
+
/**
|
|
310
|
+
* Fires with the unread count and newest updates when you subscribe and
|
|
311
|
+
* each time the app comes back to the foreground, so the host can draw its
|
|
312
|
+
* own badge (a feedback band, a tab dot). Returns an unsubscribe function.
|
|
313
|
+
*/
|
|
314
|
+
onReporterUpdate(cb: (updates: MushiReporterUpdates) => void): () => void;
|
|
315
|
+
/** This reporter's email choices; the address comes back masked (null on failure). */
|
|
316
|
+
getNotificationPrefs(): Promise<MushiReporterNotificationPrefs | null>;
|
|
317
|
+
/**
|
|
318
|
+
* Ask for email updates (`{ email }` sends a confirmation email first) or
|
|
319
|
+
* change channels. Only when the reporter asked — never pre-tick an opt-in.
|
|
320
|
+
* Resolves the server's answer, including `EMAIL_NOT_AVAILABLE` when this
|
|
321
|
+
* app does not offer email. (No native push on React Native.)
|
|
322
|
+
*/
|
|
323
|
+
setNotificationPrefs(update: MushiReporterPrefsUpdate): Promise<MushiApiResponse<MushiReporterNotificationPrefs>>;
|
|
324
|
+
/**
|
|
325
|
+
* One report with its timeline (GET /v1/reporter/reports/:id). Resolves
|
|
326
|
+
* null when it could not be loaded (show Retry) and 'unsupported' when the
|
|
327
|
+
* server predates the route (fall back to `loadMyThread`).
|
|
328
|
+
*/
|
|
329
|
+
loadMyReportDetail(reportId: string): Promise<MushiReporterReportDetail | null | 'unsupported'>;
|
|
330
|
+
/** The address to prefill in the email opt-in box, only with `notifications.emailFromIdentity`. */
|
|
331
|
+
emailPrefill(): string | null;
|
|
332
|
+
/** Open the sheet on "Your reports". */
|
|
333
|
+
openMyReports(): void;
|
|
231
334
|
/** Post a reporter reply on a report thread. Returns the new comment or null on failure. */
|
|
232
335
|
replyToReport(reportId: string, body: string): Promise<MushiReporterComment | null>;
|
|
233
336
|
/** Record a reporter feedback signal (e.g. `confirms`, `not_fixed`) on a report. Returns the outcome or null. */
|
|
@@ -281,9 +384,13 @@ declare function useMushiWidget(): {
|
|
|
281
384
|
*
|
|
282
385
|
* OVERVIEW:
|
|
283
386
|
* - Slide-up modal built entirely on RN built-ins (Modal, Animated, PanResponder)
|
|
284
|
-
* -
|
|
387
|
+
* - One screen, free text first: optional type chips, Send once there are a
|
|
388
|
+
* few words (8 by default) or a screenshot, then a receipt in place with
|
|
389
|
+
* Track it / Done and an optional, never pre-ticked email opt-in
|
|
285
390
|
* - Drag-to-dismiss via PanResponder on the handle area
|
|
286
|
-
* -
|
|
391
|
+
* - Host-adaptive theme (`widget.theme`, see ../theme.ts) over light/dark
|
|
392
|
+
* - "Your reports": statuses come from the shared core table
|
|
393
|
+
* (`@mushi-mushi/core/reporter-ui`), so web and RN say the same thing
|
|
287
394
|
*
|
|
288
395
|
* DEPENDENCIES:
|
|
289
396
|
* - React Native built-in APIs only (no third-party libs)
|
|
@@ -296,11 +403,19 @@ declare function useMushiWidget(): {
|
|
|
296
403
|
* TECHNICAL DETAILS:
|
|
297
404
|
* - PanResponder threshold: 80 px downward drag dismisses
|
|
298
405
|
* - Animated.spring for slide-up, Animated.timing for backdrop
|
|
299
|
-
* -
|
|
406
|
+
* - Reduce Motion (AccessibilityInfo) makes open / close instant
|
|
407
|
+
* - The thread is the report's v2 timeline (GET /v1/reporter/reports/:id):
|
|
408
|
+
* pipeline events render from the shared core templates in the reporter's
|
|
409
|
+
* locale, replies as bubbles. Loads show a skeleton, then Retry on failure;
|
|
410
|
+
* a failed reply keeps its text and offers Retry. Opening a thread marks it
|
|
411
|
+
* read. An older server without the route falls back to the comment list.
|
|
300
412
|
*
|
|
301
413
|
* NOTES:
|
|
302
414
|
* - KeyboardAvoidingView wraps the sheet so the text input stays visible
|
|
303
|
-
* -
|
|
415
|
+
* - Chips come from core's REPORTER_CATEGORIES (bug, slow, visual, confusing,
|
|
416
|
+
* idea); "Idea" files a feature request
|
|
417
|
+
* - accessibilityViewIsModal is iOS-only; RN's Modal is its own window on
|
|
418
|
+
* Android, which keeps TalkBack focus inside the sheet there.
|
|
304
419
|
*/
|
|
305
420
|
|
|
306
421
|
interface MushiBottomSheetProps {
|
|
@@ -324,6 +439,12 @@ interface MushiBottomSheetProps {
|
|
|
324
439
|
assistantSuggestions?: string[];
|
|
325
440
|
/** Poll My Reports while inbox tab is open. 0 disables polling. */
|
|
326
441
|
inboxPollIntervalMs?: number;
|
|
442
|
+
/** Theme tokens (`widget.theme`); unset tokens use the neutral defaults. */
|
|
443
|
+
theme?: Partial<MushiRNTheme>;
|
|
444
|
+
/** Characters needed before Send enables (`widget.minDescriptionLength`, default 8). */
|
|
445
|
+
minDescriptionLength?: number;
|
|
446
|
+
/** Offer "Get updates by email" on the receipt when the project offers email (`notifications.email`). */
|
|
447
|
+
emailOptIn?: boolean;
|
|
327
448
|
}
|
|
328
449
|
declare const MushiBottomSheet: FC<MushiBottomSheetProps>;
|
|
329
450
|
|
|
@@ -447,4 +568,46 @@ declare class AsyncStorageQueue {
|
|
|
447
568
|
private getAsyncStorage;
|
|
448
569
|
}
|
|
449
570
|
|
|
450
|
-
|
|
571
|
+
/**
|
|
572
|
+
* FILE: optional-modules.ts
|
|
573
|
+
* PURPOSE: The SDK's three optional native peers (network-aware delivery,
|
|
574
|
+
* screenshots, shake-to-report), loaded without crashing the app.
|
|
575
|
+
*
|
|
576
|
+
* Order for each one:
|
|
577
|
+
* 1. A module the host passed in config (`netInfo`, `viewShot`, `expoSensors`).
|
|
578
|
+
* No dynamic loading at all — the safest path.
|
|
579
|
+
* 2. A literal `require('<module>')` inside try/catch. Metro resolves a literal
|
|
580
|
+
* require at bundle time and treats one inside try/catch as optional
|
|
581
|
+
* (`transformer.allowOptionalDependencies`, on in Expo and React Native's
|
|
582
|
+
* default Metro config).
|
|
583
|
+
*
|
|
584
|
+
* Why the build matters: esbuild's ESM output rewrites `require('x')` to its
|
|
585
|
+
* `__require('x')` interop shim. Metro can't resolve a module name handed to
|
|
586
|
+
* the shim, so it called its own require with a string at runtime and crashed
|
|
587
|
+
* the app (reportFatalError) — the try/catch never saw it (0.21–0.23).
|
|
588
|
+
* tsup.config.ts restores literal `require(...)` in dist and fails the build
|
|
589
|
+
* if any `__require(` is left (src/bundling/preserve-optional-requires.ts).
|
|
590
|
+
*/
|
|
591
|
+
interface MushiNetInfoModule {
|
|
592
|
+
addEventListener(listener: (state: {
|
|
593
|
+
isConnected: boolean | null;
|
|
594
|
+
isInternetReachable: boolean | null;
|
|
595
|
+
}) => void): () => void;
|
|
596
|
+
}
|
|
597
|
+
interface MushiViewShotModule {
|
|
598
|
+
captureScreen(options: Record<string, unknown>): Promise<string>;
|
|
599
|
+
}
|
|
600
|
+
interface MushiExpoSensorsModule {
|
|
601
|
+
Accelerometer: {
|
|
602
|
+
setUpdateInterval(ms: number): void;
|
|
603
|
+
addListener(listener: (event: {
|
|
604
|
+
x: number;
|
|
605
|
+
y: number;
|
|
606
|
+
z: number;
|
|
607
|
+
}) => void): {
|
|
608
|
+
remove(): void;
|
|
609
|
+
};
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
export { AsyncStorageQueue, type ConsoleEntry, type DeviceInfo, MUSHI_BANNER_DEFAULT_HEIGHT, MushiBanner, type MushiBannerProps, MushiBottomSheet, type MushiBottomSheetProps, type MushiExpoSensorsModule, MushiFloatingButton, type MushiFloatingButtonProps, type MushiNetInfoModule, MushiProvider, type MushiRNConfig, type MushiRNInstance, MushiTrigger, type MushiTriggerProps, type MushiViewShotModule, type NavigationEntry, type NetworkEntry, type RNAnalyticsConfig, getDeviceInfo, setupConsoleCapture, setupNetworkCapture, useMushi, useMushiReport, useMushiWidget, useNavigationCapture };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, FC, ReactElement } from 'react';
|
|
3
|
-
import { MushiAnalyticsConfig, MushiRewardsConfig, MushiPageContext, MushiBreadcrumb, MushiReporterReport, MushiReporterComment, MushiHallOfFameEntry, MushiPropertyValue, MushiTierResult, MushiReputationResult, MushiAssistantReply } from '@mushi-mushi/core';
|
|
3
|
+
import { MushiAnalyticsConfig, MushiRewardsConfig, MushiPageContext, MushiBreadcrumb, MushiReporterReport, MushiReporterComment, MushiApiResponse, MushiHallOfFameEntry, MushiPropertyValue, MushiTierResult, MushiReputationResult, MushiAssistantReply } from '@mushi-mushi/core';
|
|
4
4
|
export { MushiHallOfFameEntry, MushiReporterComment, MushiReporterReport } from '@mushi-mushi/core';
|
|
5
|
+
import { MushiReporterUpdates, MushiReporterNotificationPrefs, MushiReporterPrefsUpdate, MushiReporterReportDetail } from '@mushi-mushi/core/reporter-channels';
|
|
5
6
|
|
|
6
7
|
interface ConsoleEntry {
|
|
7
8
|
level: 'log' | 'warn' | 'error';
|
|
@@ -74,6 +75,42 @@ declare function getDeviceInfo(): DeviceInfo;
|
|
|
74
75
|
/** The subset of the web `analytics` block that applies on native. */
|
|
75
76
|
type RNAnalyticsConfig = Pick<MushiAnalyticsConfig, 'enabled' | 'consent' | 'flushIntervalMs' | 'propertyAllowlist'>;
|
|
76
77
|
|
|
78
|
+
/**
|
|
79
|
+
* FILE: theme.ts
|
|
80
|
+
* PURPOSE: Host-adaptive theme for the RN report sheet (`widget.theme`).
|
|
81
|
+
*
|
|
82
|
+
* OVERVIEW:
|
|
83
|
+
* - Defaults are neutral: the shared washi/sumi surfaces with an INK accent,
|
|
84
|
+
* so the sheet reads as part of the host app rather than a neon Mushi
|
|
85
|
+
* product. The neon palette is only used by `<MushiBanner variant="neon">`.
|
|
86
|
+
* - Hosts override any token. When a host sets `accent` but not `accentFg`,
|
|
87
|
+
* the text colour on the accent is picked for contrast (black or white).
|
|
88
|
+
*
|
|
89
|
+
* Plan 018 (docs/execplans/reporter-loop-v2.md §1.4).
|
|
90
|
+
*/
|
|
91
|
+
interface MushiRNTheme {
|
|
92
|
+
/** Sheet background. */
|
|
93
|
+
bg: string;
|
|
94
|
+
/** Primary text. */
|
|
95
|
+
fg: string;
|
|
96
|
+
/** Secondary text. */
|
|
97
|
+
muted: string;
|
|
98
|
+
/** Cards, inputs, chips. */
|
|
99
|
+
surface: string;
|
|
100
|
+
/** Borders and separators. */
|
|
101
|
+
border: string;
|
|
102
|
+
/** Selected chip, primary button, links. */
|
|
103
|
+
accent: string;
|
|
104
|
+
/** Text on `accent`. */
|
|
105
|
+
accentFg: string;
|
|
106
|
+
success: string;
|
|
107
|
+
error: string;
|
|
108
|
+
/** Host font family; undefined keeps the platform font. */
|
|
109
|
+
fontFamily?: string;
|
|
110
|
+
/** Corner radius for cards, inputs and buttons. */
|
|
111
|
+
radius: number;
|
|
112
|
+
}
|
|
113
|
+
|
|
77
114
|
interface MushiRNConfig {
|
|
78
115
|
projectId: string;
|
|
79
116
|
apiKey: string;
|
|
@@ -115,6 +152,39 @@ interface MushiRNConfig {
|
|
|
115
152
|
};
|
|
116
153
|
/** Poll interval (ms) for My Reports while the inbox tab is open. 0 = off (default). */
|
|
117
154
|
inboxPollIntervalMs?: number;
|
|
155
|
+
/**
|
|
156
|
+
* Theme tokens for the report sheet (bg, fg, muted, surface, border,
|
|
157
|
+
* accent, accentFg, success, error, fontFamily, radius). Unset tokens
|
|
158
|
+
* use neutral system-style defaults with an ink accent; when only
|
|
159
|
+
* `accent` is set, the text on it is chosen for contrast.
|
|
160
|
+
*/
|
|
161
|
+
theme?: Partial<MushiRNTheme>;
|
|
162
|
+
/**
|
|
163
|
+
* Characters needed before Send enables. Default 8 (Plan 018 §1.1); an
|
|
164
|
+
* attached screenshot lowers it to 0.
|
|
165
|
+
*/
|
|
166
|
+
minDescriptionLength?: number;
|
|
167
|
+
};
|
|
168
|
+
/**
|
|
169
|
+
* Optional native modules, passed in instead of loaded. When set, the SDK
|
|
170
|
+
* uses them and never loads that package itself — the safest option for
|
|
171
|
+
* Metro configs that disallow optional requires. Each one is also picked up
|
|
172
|
+
* automatically when installed.
|
|
173
|
+
* - `netInfo`: `@react-native-community/netinfo` — resend queued reports when the network returns.
|
|
174
|
+
* - `viewShot`: `react-native-view-shot` — attach a screenshot.
|
|
175
|
+
* - `expoSensors`: `expo-sensors` — shake to report.
|
|
176
|
+
*/
|
|
177
|
+
netInfo?: unknown;
|
|
178
|
+
viewShot?: unknown;
|
|
179
|
+
expoSensors?: unknown;
|
|
180
|
+
/** How reporters hear back outside the sheet (Plan 018 §4). No native push. */
|
|
181
|
+
notifications?: {
|
|
182
|
+
/** One "the developer replied" / "your bug is fixed" toast when the app returns to the foreground. Default true. */
|
|
183
|
+
toast?: boolean;
|
|
184
|
+
/** Offer "Get updates by email" after sending, when the project offers email. Default true. */
|
|
185
|
+
email?: boolean;
|
|
186
|
+
/** Prefill that email box from `setUser({ email })`. Default false; the box is never pre-ticked. */
|
|
187
|
+
emailFromIdentity?: boolean;
|
|
118
188
|
};
|
|
119
189
|
assistant?: {
|
|
120
190
|
enabled?: boolean;
|
|
@@ -175,6 +245,8 @@ interface MushiRNInstance {
|
|
|
175
245
|
submitReport(data: {
|
|
176
246
|
description: string;
|
|
177
247
|
category: string;
|
|
248
|
+
/** Host / chip sub-label, e.g. 'feature' for the Idea chip. */
|
|
249
|
+
userCategory?: string;
|
|
178
250
|
screenshotDataUrl?: string;
|
|
179
251
|
}): Promise<{
|
|
180
252
|
ok: boolean;
|
|
@@ -226,8 +298,39 @@ interface MushiRNInstance {
|
|
|
226
298
|
}): void;
|
|
227
299
|
/** List this device's reports ordered by most recent. Returns [] on failure. */
|
|
228
300
|
listMyReports(): Promise<MushiReporterReport[]>;
|
|
229
|
-
/** List admin + reporter comments on a specific report. */
|
|
301
|
+
/** List admin + reporter comments on a specific report. Returns [] on failure. */
|
|
230
302
|
listMyComments(reportId: string): Promise<MushiReporterComment[]>;
|
|
303
|
+
/** Like `listMyComments`, but resolves `null` when the thread could not be loaded, so a UI can offer Retry. */
|
|
304
|
+
loadMyThread(reportId: string): Promise<MushiReporterComment[] | null>;
|
|
305
|
+
/** Mark this device's unread notifications for a report as read. Resolves the number marked (0 on failure). */
|
|
306
|
+
markReportRead(reportId: string): Promise<number>;
|
|
307
|
+
/** Unread count and the newest unread updates on this device's reports (null on failure). */
|
|
308
|
+
getReporterUpdates(): Promise<MushiReporterUpdates | null>;
|
|
309
|
+
/**
|
|
310
|
+
* Fires with the unread count and newest updates when you subscribe and
|
|
311
|
+
* each time the app comes back to the foreground, so the host can draw its
|
|
312
|
+
* own badge (a feedback band, a tab dot). Returns an unsubscribe function.
|
|
313
|
+
*/
|
|
314
|
+
onReporterUpdate(cb: (updates: MushiReporterUpdates) => void): () => void;
|
|
315
|
+
/** This reporter's email choices; the address comes back masked (null on failure). */
|
|
316
|
+
getNotificationPrefs(): Promise<MushiReporterNotificationPrefs | null>;
|
|
317
|
+
/**
|
|
318
|
+
* Ask for email updates (`{ email }` sends a confirmation email first) or
|
|
319
|
+
* change channels. Only when the reporter asked — never pre-tick an opt-in.
|
|
320
|
+
* Resolves the server's answer, including `EMAIL_NOT_AVAILABLE` when this
|
|
321
|
+
* app does not offer email. (No native push on React Native.)
|
|
322
|
+
*/
|
|
323
|
+
setNotificationPrefs(update: MushiReporterPrefsUpdate): Promise<MushiApiResponse<MushiReporterNotificationPrefs>>;
|
|
324
|
+
/**
|
|
325
|
+
* One report with its timeline (GET /v1/reporter/reports/:id). Resolves
|
|
326
|
+
* null when it could not be loaded (show Retry) and 'unsupported' when the
|
|
327
|
+
* server predates the route (fall back to `loadMyThread`).
|
|
328
|
+
*/
|
|
329
|
+
loadMyReportDetail(reportId: string): Promise<MushiReporterReportDetail | null | 'unsupported'>;
|
|
330
|
+
/** The address to prefill in the email opt-in box, only with `notifications.emailFromIdentity`. */
|
|
331
|
+
emailPrefill(): string | null;
|
|
332
|
+
/** Open the sheet on "Your reports". */
|
|
333
|
+
openMyReports(): void;
|
|
231
334
|
/** Post a reporter reply on a report thread. Returns the new comment or null on failure. */
|
|
232
335
|
replyToReport(reportId: string, body: string): Promise<MushiReporterComment | null>;
|
|
233
336
|
/** Record a reporter feedback signal (e.g. `confirms`, `not_fixed`) on a report. Returns the outcome or null. */
|
|
@@ -281,9 +384,13 @@ declare function useMushiWidget(): {
|
|
|
281
384
|
*
|
|
282
385
|
* OVERVIEW:
|
|
283
386
|
* - Slide-up modal built entirely on RN built-ins (Modal, Animated, PanResponder)
|
|
284
|
-
* -
|
|
387
|
+
* - One screen, free text first: optional type chips, Send once there are a
|
|
388
|
+
* few words (8 by default) or a screenshot, then a receipt in place with
|
|
389
|
+
* Track it / Done and an optional, never pre-ticked email opt-in
|
|
285
390
|
* - Drag-to-dismiss via PanResponder on the handle area
|
|
286
|
-
* -
|
|
391
|
+
* - Host-adaptive theme (`widget.theme`, see ../theme.ts) over light/dark
|
|
392
|
+
* - "Your reports": statuses come from the shared core table
|
|
393
|
+
* (`@mushi-mushi/core/reporter-ui`), so web and RN say the same thing
|
|
287
394
|
*
|
|
288
395
|
* DEPENDENCIES:
|
|
289
396
|
* - React Native built-in APIs only (no third-party libs)
|
|
@@ -296,11 +403,19 @@ declare function useMushiWidget(): {
|
|
|
296
403
|
* TECHNICAL DETAILS:
|
|
297
404
|
* - PanResponder threshold: 80 px downward drag dismisses
|
|
298
405
|
* - Animated.spring for slide-up, Animated.timing for backdrop
|
|
299
|
-
* -
|
|
406
|
+
* - Reduce Motion (AccessibilityInfo) makes open / close instant
|
|
407
|
+
* - The thread is the report's v2 timeline (GET /v1/reporter/reports/:id):
|
|
408
|
+
* pipeline events render from the shared core templates in the reporter's
|
|
409
|
+
* locale, replies as bubbles. Loads show a skeleton, then Retry on failure;
|
|
410
|
+
* a failed reply keeps its text and offers Retry. Opening a thread marks it
|
|
411
|
+
* read. An older server without the route falls back to the comment list.
|
|
300
412
|
*
|
|
301
413
|
* NOTES:
|
|
302
414
|
* - KeyboardAvoidingView wraps the sheet so the text input stays visible
|
|
303
|
-
* -
|
|
415
|
+
* - Chips come from core's REPORTER_CATEGORIES (bug, slow, visual, confusing,
|
|
416
|
+
* idea); "Idea" files a feature request
|
|
417
|
+
* - accessibilityViewIsModal is iOS-only; RN's Modal is its own window on
|
|
418
|
+
* Android, which keeps TalkBack focus inside the sheet there.
|
|
304
419
|
*/
|
|
305
420
|
|
|
306
421
|
interface MushiBottomSheetProps {
|
|
@@ -324,6 +439,12 @@ interface MushiBottomSheetProps {
|
|
|
324
439
|
assistantSuggestions?: string[];
|
|
325
440
|
/** Poll My Reports while inbox tab is open. 0 disables polling. */
|
|
326
441
|
inboxPollIntervalMs?: number;
|
|
442
|
+
/** Theme tokens (`widget.theme`); unset tokens use the neutral defaults. */
|
|
443
|
+
theme?: Partial<MushiRNTheme>;
|
|
444
|
+
/** Characters needed before Send enables (`widget.minDescriptionLength`, default 8). */
|
|
445
|
+
minDescriptionLength?: number;
|
|
446
|
+
/** Offer "Get updates by email" on the receipt when the project offers email (`notifications.email`). */
|
|
447
|
+
emailOptIn?: boolean;
|
|
327
448
|
}
|
|
328
449
|
declare const MushiBottomSheet: FC<MushiBottomSheetProps>;
|
|
329
450
|
|
|
@@ -447,4 +568,46 @@ declare class AsyncStorageQueue {
|
|
|
447
568
|
private getAsyncStorage;
|
|
448
569
|
}
|
|
449
570
|
|
|
450
|
-
|
|
571
|
+
/**
|
|
572
|
+
* FILE: optional-modules.ts
|
|
573
|
+
* PURPOSE: The SDK's three optional native peers (network-aware delivery,
|
|
574
|
+
* screenshots, shake-to-report), loaded without crashing the app.
|
|
575
|
+
*
|
|
576
|
+
* Order for each one:
|
|
577
|
+
* 1. A module the host passed in config (`netInfo`, `viewShot`, `expoSensors`).
|
|
578
|
+
* No dynamic loading at all — the safest path.
|
|
579
|
+
* 2. A literal `require('<module>')` inside try/catch. Metro resolves a literal
|
|
580
|
+
* require at bundle time and treats one inside try/catch as optional
|
|
581
|
+
* (`transformer.allowOptionalDependencies`, on in Expo and React Native's
|
|
582
|
+
* default Metro config).
|
|
583
|
+
*
|
|
584
|
+
* Why the build matters: esbuild's ESM output rewrites `require('x')` to its
|
|
585
|
+
* `__require('x')` interop shim. Metro can't resolve a module name handed to
|
|
586
|
+
* the shim, so it called its own require with a string at runtime and crashed
|
|
587
|
+
* the app (reportFatalError) — the try/catch never saw it (0.21–0.23).
|
|
588
|
+
* tsup.config.ts restores literal `require(...)` in dist and fails the build
|
|
589
|
+
* if any `__require(` is left (src/bundling/preserve-optional-requires.ts).
|
|
590
|
+
*/
|
|
591
|
+
interface MushiNetInfoModule {
|
|
592
|
+
addEventListener(listener: (state: {
|
|
593
|
+
isConnected: boolean | null;
|
|
594
|
+
isInternetReachable: boolean | null;
|
|
595
|
+
}) => void): () => void;
|
|
596
|
+
}
|
|
597
|
+
interface MushiViewShotModule {
|
|
598
|
+
captureScreen(options: Record<string, unknown>): Promise<string>;
|
|
599
|
+
}
|
|
600
|
+
interface MushiExpoSensorsModule {
|
|
601
|
+
Accelerometer: {
|
|
602
|
+
setUpdateInterval(ms: number): void;
|
|
603
|
+
addListener(listener: (event: {
|
|
604
|
+
x: number;
|
|
605
|
+
y: number;
|
|
606
|
+
z: number;
|
|
607
|
+
}) => void): {
|
|
608
|
+
remove(): void;
|
|
609
|
+
};
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
export { AsyncStorageQueue, type ConsoleEntry, type DeviceInfo, MUSHI_BANNER_DEFAULT_HEIGHT, MushiBanner, type MushiBannerProps, MushiBottomSheet, type MushiBottomSheetProps, type MushiExpoSensorsModule, MushiFloatingButton, type MushiFloatingButtonProps, type MushiNetInfoModule, MushiProvider, type MushiRNConfig, type MushiRNInstance, MushiTrigger, type MushiTriggerProps, type MushiViewShotModule, type NavigationEntry, type NetworkEntry, type RNAnalyticsConfig, getDeviceInfo, setupConsoleCapture, setupNetworkCapture, useMushi, useMushiReport, useMushiWidget, useNavigationCapture };
|