rn-backstage 1.2.1 → 1.4.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 +109 -2
- package/lib/commonjs/Backstage.js +19 -2
- package/lib/commonjs/Backstage.js.map +1 -1
- package/lib/commonjs/bug-report.js +173 -0
- package/lib/commonjs/bug-report.js.map +1 -0
- package/lib/commonjs/components/BackstagePanel.js +100 -17
- package/lib/commonjs/components/BackstagePanel.js.map +1 -1
- package/lib/commonjs/components/BugReportComposer.js +510 -0
- package/lib/commonjs/components/BugReportComposer.js.map +1 -0
- package/lib/commonjs/components/FlagsTab.js +21 -11
- package/lib/commonjs/components/FlagsTab.js.map +1 -1
- package/lib/commonjs/components/FloatingPill.js +82 -22
- package/lib/commonjs/components/FloatingPill.js.map +1 -1
- package/lib/commonjs/components/InfoTab.js +5 -1
- package/lib/commonjs/components/InfoTab.js.map +1 -1
- package/lib/commonjs/components/LogItem.js +6 -0
- package/lib/commonjs/components/LogItem.js.map +1 -1
- package/lib/commonjs/components/LogsTab.js +3 -3
- package/lib/commonjs/components/LogsTab.js.map +1 -1
- package/lib/commonjs/components/NetworkTab.js +3 -2
- package/lib/commonjs/components/NetworkTab.js.map +1 -1
- package/lib/commonjs/components/StorageTab.js +672 -0
- package/lib/commonjs/components/StorageTab.js.map +1 -0
- package/lib/commonjs/constants.js +88 -6
- package/lib/commonjs/constants.js.map +1 -1
- package/lib/commonjs/index.js +84 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/types.js +2 -0
- package/lib/commonjs/types.js.map +1 -1
- package/lib/module/Backstage.js +19 -2
- package/lib/module/Backstage.js.map +1 -1
- package/lib/module/bug-report.js +164 -0
- package/lib/module/bug-report.js.map +1 -0
- package/lib/module/components/BackstagePanel.js +101 -18
- package/lib/module/components/BackstagePanel.js.map +1 -1
- package/lib/module/components/BugReportComposer.js +505 -0
- package/lib/module/components/BugReportComposer.js.map +1 -0
- package/lib/module/components/FlagsTab.js +23 -13
- package/lib/module/components/FlagsTab.js.map +1 -1
- package/lib/module/components/FloatingPill.js +86 -26
- package/lib/module/components/FloatingPill.js.map +1 -1
- package/lib/module/components/InfoTab.js +6 -2
- package/lib/module/components/InfoTab.js.map +1 -1
- package/lib/module/components/LogItem.js +7 -1
- package/lib/module/components/LogItem.js.map +1 -1
- package/lib/module/components/LogsTab.js +3 -3
- package/lib/module/components/LogsTab.js.map +1 -1
- package/lib/module/components/NetworkTab.js +3 -2
- package/lib/module/components/NetworkTab.js.map +1 -1
- package/lib/module/components/StorageTab.js +667 -0
- package/lib/module/components/StorageTab.js.map +1 -0
- package/lib/module/constants.js +88 -6
- package/lib/module/constants.js.map +1 -1
- package/lib/module/index.js +14 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/types.js +4 -0
- package/lib/module/types.js.map +1 -1
- package/lib/typescript/Backstage.d.ts.map +1 -1
- package/lib/typescript/bug-report.d.ts +12 -0
- package/lib/typescript/bug-report.d.ts.map +1 -0
- package/lib/typescript/components/BackstagePanel.d.ts +4 -1
- package/lib/typescript/components/BackstagePanel.d.ts.map +1 -1
- package/lib/typescript/components/BugReportComposer.d.ts +17 -0
- package/lib/typescript/components/BugReportComposer.d.ts.map +1 -0
- package/lib/typescript/components/FlagsTab.d.ts.map +1 -1
- package/lib/typescript/components/FloatingPill.d.ts +2 -0
- package/lib/typescript/components/FloatingPill.d.ts.map +1 -1
- package/lib/typescript/components/InfoTab.d.ts.map +1 -1
- package/lib/typescript/components/LogItem.d.ts.map +1 -1
- package/lib/typescript/components/LogsTab.d.ts.map +1 -1
- package/lib/typescript/components/NetworkTab.d.ts.map +1 -1
- package/lib/typescript/components/StorageTab.d.ts +9 -0
- package/lib/typescript/components/StorageTab.d.ts.map +1 -0
- package/lib/typescript/constants.d.ts +74 -4
- package/lib/typescript/constants.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +13 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +55 -0
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +7 -6
- package/src/Backstage.tsx +0 -209
- package/src/ThemeContext.tsx +0 -38
- package/src/components/BackstagePanel.tsx +0 -258
- package/src/components/FlagsTab.tsx +0 -198
- package/src/components/FloatingPill.tsx +0 -153
- package/src/components/InfoTab.tsx +0 -230
- package/src/components/JsonTreeView.tsx +0 -239
- package/src/components/LogItem.tsx +0 -144
- package/src/components/LogsTab.tsx +0 -217
- package/src/components/NetworkItem.tsx +0 -425
- package/src/components/NetworkTab.tsx +0 -240
- package/src/components/TabBar.tsx +0 -154
- package/src/constants.ts +0 -114
- package/src/index.ts +0 -18
- package/src/log-interceptor.ts +0 -148
- package/src/network-interceptor.ts +0 -468
- package/src/types.ts +0 -213
- package/src/utils/formatTimestamp.ts +0 -22
- package/src/utils/stringify.ts +0 -90
package/README.md
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
# rn-backstage
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/rn-backstage)
|
|
4
|
+
[](https://www.npmjs.com/package/rn-backstage)
|
|
5
|
+
|
|
3
6
|
A zero-dependency developer/QA debug panel for React Native apps. Inspect device info, view state trees, monitor console logs, inspect network requests, and trigger custom actions — all from a sleek in-app panel.
|
|
4
7
|
|
|
5
8
|
## Features
|
|
6
9
|
|
|
7
|
-
- 🎯 **Draggable floating pill** — always accessible, repositionable trigger
|
|
10
|
+
- 🎯 **Draggable floating pill** — always accessible, repositionable trigger with safe area bounds
|
|
8
11
|
- 📱 **Device & build info** — OS version, app version, build number, and custom data
|
|
9
12
|
- 🌳 **State tree inspector** — visualize Redux, Zustand, or any store state
|
|
10
13
|
- 📋 **Console log viewer** — intercepts all console methods with search & filtering
|
|
11
14
|
- 🌐 **Network inspector** — intercepts fetch & XMLHttpRequest with request/response details, headers, body, timing, and copy-as-cURL
|
|
12
15
|
- 🎚 **Feature flag toggle** — render switches to toggle flags in real-time without restarting
|
|
16
|
+
- 🗄 **Storage viewer** — inspect, edit, and delete AsyncStorage/MMKV entries via a pluggable adapter
|
|
13
17
|
- ⚡ **Quick actions** — add custom buttons (logout, clear cache, etc.)
|
|
14
18
|
- 🔌 **Extensible tabs** — add custom tabs for app-specific debugging tools
|
|
15
|
-
- 🎨 **
|
|
19
|
+
- 🎨 **Light & dark theme** — auto-follows device setting, or override manually
|
|
16
20
|
- 📦 **Zero dependencies** — only peer deps are `react` and `react-native`
|
|
17
21
|
|
|
18
22
|
## Installation
|
|
@@ -55,6 +59,7 @@ export default function App() {
|
|
|
55
59
|
The Network tab automatically intercepts all `fetch()` and `XMLHttpRequest` traffic — including libraries built on top of them like **Axios**, **Apisauce**, **ky**, and **Apollo Client**.
|
|
56
60
|
|
|
57
61
|
Each request shows:
|
|
62
|
+
|
|
58
63
|
- Method, URL, status code, and duration
|
|
59
64
|
- Request & response headers
|
|
60
65
|
- Request & response body (auto-parsed JSON with tree view)
|
|
@@ -74,6 +79,7 @@ Each request shows:
|
|
|
74
79
|
autoFilterNetworkLogs={true}
|
|
75
80
|
/>
|
|
76
81
|
```
|
|
82
|
+
|
|
77
83
|
## Feature Flag Toggle
|
|
78
84
|
|
|
79
85
|
Pass feature flags to render a dedicated **Flags** tab with toggle switches. The tab only appears when at least one flag is provided. Toggling calls your callback in real-time — no app restart needed.
|
|
@@ -92,6 +98,59 @@ const [flags, setFlags] = useState([
|
|
|
92
98
|
/>
|
|
93
99
|
```
|
|
94
100
|
|
|
101
|
+
## Storage Viewer
|
|
102
|
+
|
|
103
|
+
Pass a `storageAdapter` to render a **Storage** tab that lets you browse, edit, add, and delete key-value entries. The tab only appears when an adapter is provided. Works with any storage backend — zero dependencies.
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
import AsyncStorage from '@react-native-async-storage/async-storage'
|
|
107
|
+
|
|
108
|
+
;<Backstage
|
|
109
|
+
storageAdapter={{
|
|
110
|
+
getAllKeys: () => AsyncStorage.getAllKeys(),
|
|
111
|
+
getItem: key => AsyncStorage.getItem(key),
|
|
112
|
+
setItem: (key, value) => AsyncStorage.setItem(key, value),
|
|
113
|
+
removeItem: key => AsyncStorage.removeItem(key),
|
|
114
|
+
}}
|
|
115
|
+
/>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
MMKV example:
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
import { storage } from './mmkv'
|
|
122
|
+
|
|
123
|
+
;<Backstage
|
|
124
|
+
storageAdapter={{
|
|
125
|
+
getAllKeys: () => Promise.resolve(storage.getAllKeys()),
|
|
126
|
+
getItem: key => Promise.resolve(storage.getString(key) ?? null),
|
|
127
|
+
setItem: (key, value) => Promise.resolve(storage.set(key, value)),
|
|
128
|
+
removeItem: key => Promise.resolve(storage.delete(key)),
|
|
129
|
+
}}
|
|
130
|
+
/>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Bug Report
|
|
134
|
+
|
|
135
|
+
Add a `bugReport` config to enable one-tap bug reporting. Tapping the 🐛 button in the panel header opens a composer that auto-attaches device info, logs, network activity, and state. Reports can be shared via the system share sheet or submitted to a webhook.
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
<Backstage
|
|
139
|
+
bugReport={{
|
|
140
|
+
onSubmit: report => {
|
|
141
|
+
// Full BugReport object with all context
|
|
142
|
+
console.log(report.title, report.severity, report.logs.length)
|
|
143
|
+
},
|
|
144
|
+
// Optional: POST to a webhook
|
|
145
|
+
webhookUrl: 'https://your-api.com/bugs',
|
|
146
|
+
// Optional: capture screenshot (requires a library like react-native-view-shot)
|
|
147
|
+
captureScreenshot: () => viewShotRef.current.capture(),
|
|
148
|
+
maxLogsInReport: 50,
|
|
149
|
+
maxNetworkEntriesInReport: 20,
|
|
150
|
+
}}
|
|
151
|
+
/>
|
|
152
|
+
```
|
|
153
|
+
|
|
95
154
|
## Props
|
|
96
155
|
|
|
97
156
|
| Prop | Type | Default | Description |
|
|
@@ -106,6 +165,7 @@ const [flags, setFlags] = useState([
|
|
|
106
165
|
| `quickActions` | `QuickAction[]` | `[]` | Custom action buttons |
|
|
107
166
|
| `featureFlags` | `FeatureFlag[]` | `[]` | Feature flags with toggle switches |
|
|
108
167
|
| `onToggleFeatureFlag` | `(key, val: boolean) => void` | `undefined` | Callback when a flag is toggled |
|
|
168
|
+
| `storageAdapter` | `StorageAdapter` | `undefined` | Storage adapter for the Storage Viewer tab |
|
|
109
169
|
| `maxLogs` | `number` | `500` | Maximum logs to retain |
|
|
110
170
|
| `logFilters` | `string[]` | `[]` | Messages to exclude from logs |
|
|
111
171
|
| `onCopyLogs` | `(logs: string) => void` | `undefined` | Callback when copying logs |
|
|
@@ -115,7 +175,14 @@ const [flags, setFlags] = useState([
|
|
|
115
175
|
| `networkFilters` | `string[]` | `[]` | URL substrings to exclude from capture |
|
|
116
176
|
| `autoFilterNetworkLogs` | `boolean` | `true` | Auto-filter network callback logs from Logs tab |
|
|
117
177
|
| `jsonMaxDepth` | `number` | `10` | Max nesting depth for all JSON tree views |
|
|
178
|
+
| `initialX` | `number` | `undefined` | Initial X position for the floating pill |
|
|
179
|
+
| `initialY` | `number` | `undefined` | Initial Y position for the floating pill |
|
|
180
|
+
| `pillText` | `string` | `undefined` | Text on the pill (defaults to version or "DEV") |
|
|
181
|
+
| `pillWidth` | `number` | `60` | Width of the floating pill |
|
|
182
|
+
| `pillHeight` | `number` | `32` | Height of the floating pill |
|
|
118
183
|
| `extraTabs` | `BackstageTab[]` | `[]` | Additional custom tabs |
|
|
184
|
+
| `bugReport` | `BugReportConfig` | `undefined` | Bug report config (shows 🐛 button in header) |
|
|
185
|
+
| `styles` | `BackstageStyleOverrides` | `undefined` | Custom style overrides |
|
|
119
186
|
| `children` | `ReactNode` | `undefined` | Extra content in InfoTab |
|
|
120
187
|
|
|
121
188
|
## Ref Methods
|
|
@@ -126,6 +193,46 @@ const ref = useRef<BackstageRef>(null)
|
|
|
126
193
|
ref.current?.open() // Open the panel
|
|
127
194
|
ref.current?.close() // Close the panel
|
|
128
195
|
ref.current?.clearLogs() // Clear all captured logs
|
|
196
|
+
ref.current?.submitBugReport() // Open bug report composer
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Individual Components
|
|
200
|
+
|
|
201
|
+
All internal components are exported for advanced use cases — compose your own custom debug UI:
|
|
202
|
+
|
|
203
|
+
```tsx
|
|
204
|
+
import {
|
|
205
|
+
BackstagePanel,
|
|
206
|
+
FloatingPill,
|
|
207
|
+
TabBar,
|
|
208
|
+
InfoTab,
|
|
209
|
+
LogsTab,
|
|
210
|
+
LogItem,
|
|
211
|
+
NetworkTab,
|
|
212
|
+
NetworkItem,
|
|
213
|
+
FlagsTab,
|
|
214
|
+
StorageTab,
|
|
215
|
+
BugReportComposer,
|
|
216
|
+
JsonTreeView, // useful standalone for any JSON data
|
|
217
|
+
} from 'rn-backstage'
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## TestIDs
|
|
221
|
+
|
|
222
|
+
All interactive elements have consistent `testID` attributes for E2E testing. Import the `TestIDs` object to reference them:
|
|
223
|
+
|
|
224
|
+
```tsx
|
|
225
|
+
import { TestIDs } from 'rn-backstage'
|
|
226
|
+
|
|
227
|
+
// Static IDs
|
|
228
|
+
TestIDs.floatingPill // 'backstage.floating-pill'
|
|
229
|
+
TestIDs.panel // 'backstage.panel'
|
|
230
|
+
TestIDs.header.closeButton // 'backstage.header.close'
|
|
231
|
+
|
|
232
|
+
// Dynamic IDs (for items in lists)
|
|
233
|
+
TestIDs.logItem.container(id) // 'backstage.log-item.{id}'
|
|
234
|
+
TestIDs.flagsTab.flagSwitch(key) // 'backstage.flag.{key}'
|
|
235
|
+
TestIDs.storageTab.entryRow(key) // 'backstage.storage.entry.{key}'
|
|
129
236
|
```
|
|
130
237
|
|
|
131
238
|
## License
|
|
@@ -27,6 +27,7 @@ const Backstage = exports.Backstage = /*#__PURE__*/(0, _react.forwardRef)(({
|
|
|
27
27
|
quickActions,
|
|
28
28
|
featureFlags,
|
|
29
29
|
onToggleFeatureFlag,
|
|
30
|
+
storageAdapter,
|
|
30
31
|
maxLogs = _constants.DEFAULT_MAX_LOGS,
|
|
31
32
|
logFilters,
|
|
32
33
|
onCopyLogs,
|
|
@@ -36,12 +37,15 @@ const Backstage = exports.Backstage = /*#__PURE__*/(0, _react.forwardRef)(({
|
|
|
36
37
|
initialX,
|
|
37
38
|
initialY,
|
|
38
39
|
pillText,
|
|
40
|
+
pillWidth,
|
|
41
|
+
pillHeight,
|
|
39
42
|
enableNetworkInspector = true,
|
|
40
43
|
maxNetworkEntries = _constants.DEFAULT_MAX_NETWORK_ENTRIES,
|
|
41
44
|
maxNetworkBodySize,
|
|
42
45
|
networkFilters,
|
|
43
46
|
autoFilterNetworkLogs = true,
|
|
44
|
-
jsonMaxDepth
|
|
47
|
+
jsonMaxDepth,
|
|
48
|
+
bugReport: bugReportConfig
|
|
45
49
|
}, ref) => {
|
|
46
50
|
const [panelVisible, setPanelVisible] = (0, _react.useState)(false);
|
|
47
51
|
const [hasError, setHasError] = (0, _react.useState)(false);
|
|
@@ -125,10 +129,18 @@ const Backstage = exports.Backstage = /*#__PURE__*/(0, _react.forwardRef)(({
|
|
|
125
129
|
|
|
126
130
|
// ── Expose ref methods ────────────────────────────────────
|
|
127
131
|
|
|
132
|
+
const openBugReportRef = (0, _react.useRef)(null);
|
|
128
133
|
(0, _react.useImperativeHandle)(ref, () => ({
|
|
129
134
|
open: openPanel,
|
|
130
135
|
close: closePanel,
|
|
131
|
-
clearLogs
|
|
136
|
+
clearLogs,
|
|
137
|
+
submitBugReport: () => {
|
|
138
|
+
if (bugReportConfig) {
|
|
139
|
+
openPanel();
|
|
140
|
+
// Small delay to let panel mount first
|
|
141
|
+
setTimeout(() => openBugReportRef.current?.(), 100);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
132
144
|
}));
|
|
133
145
|
|
|
134
146
|
// ── Render ────────────────────────────────────────────────
|
|
@@ -146,6 +158,8 @@ const Backstage = exports.Backstage = /*#__PURE__*/(0, _react.forwardRef)(({
|
|
|
146
158
|
onPress: openPanel,
|
|
147
159
|
initialX: initialX,
|
|
148
160
|
initialY: initialY,
|
|
161
|
+
pillWidth: pillWidth,
|
|
162
|
+
pillHeight: pillHeight,
|
|
149
163
|
styles: propStyles
|
|
150
164
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_BackstagePanel.BackstagePanel, {
|
|
151
165
|
visible: panelVisible,
|
|
@@ -167,6 +181,9 @@ const Backstage = exports.Backstage = /*#__PURE__*/(0, _react.forwardRef)(({
|
|
|
167
181
|
onCopyNetwork: onCopyLogs,
|
|
168
182
|
extraTabs: extraTabs,
|
|
169
183
|
jsonMaxDepth: jsonMaxDepth,
|
|
184
|
+
storageAdapter: storageAdapter,
|
|
185
|
+
bugReportConfig: bugReportConfig,
|
|
186
|
+
bugReportOpenerRef: openBugReportRef,
|
|
170
187
|
styles: propStyles,
|
|
171
188
|
children: children
|
|
172
189
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_constants","_logInterceptor","_networkInterceptor","_FloatingPill","_BackstagePanel","_ThemeContext","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","Backstage","exports","forwardRef","visible","theme","themePreference","appVersion","buildNumber","bundleId","deviceInfo","state","quickActions","featureFlags","onToggleFeatureFlag","maxLogs","DEFAULT_MAX_LOGS","logFilters","onCopyLogs","extraTabs","children","styles","propStyles","initialX","initialY","pillText","enableNetworkInspector","maxNetworkEntries","DEFAULT_MAX_NETWORK_ENTRIES","maxNetworkBodySize","networkFilters","autoFilterNetworkLogs","jsonMaxDepth","ref","panelVisible","setPanelVisible","useState","hasError","setHasError","logs","setLogs","networkEntries","setNetworkEntries","logBuffer","useRef","LogBuffer","networkBuffer","NetworkBuffer","openPanel","useCallback","current","getAll","closePanel","clearLogs","clear","refreshLogs","refreshNetwork","clearNetwork","useEffect","handleLogEntry","entry","push","level","installInterceptor","uninstallInterceptor","handleNetworkEntry","upsert","installNetworkInterceptor","filters","maxBodySize","uninstallNetworkInterceptor","useImperativeHandle","open","close","displayText","jsx","BackstageThemeProvider","preference","jsxs","View","style","container","pointerEvents","FloatingPill","text","onPress","BackstagePanel","onClose","onRefreshLogs","onRefreshNetwork","onClearNetwork","onCopyNetwork","displayName","StyleSheet","create","absoluteFillObject","zIndex","elevation"],"sourceRoot":"../../src","sources":["Backstage.tsx"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,uBAAA,CAAAC,OAAA;AAQA,IAAAC,YAAA,GAAAD,OAAA;AACA,IAAAE,UAAA,GAAAF,OAAA;AACA,IAAAG,eAAA,GAAAH,OAAA;AACA,IAAAI,mBAAA,GAAAJ,OAAA;AAKA,IAAAK,aAAA,GAAAL,OAAA;AACA,IAAAM,eAAA,GAAAN,OAAA;AACA,IAAAO,aAAA,GAAAP,OAAA;AAAuD,IAAAQ,WAAA,GAAAR,OAAA;AAAA,SAAAD,wBAAAU,CAAA,EAAAC,CAAA,6BAAAC,OAAA,MAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAZ,uBAAA,YAAAA,CAAAU,CAAA,EAAAC,CAAA,SAAAA,CAAA,IAAAD,CAAA,IAAAA,CAAA,CAAAK,UAAA,SAAAL,CAAA,MAAAM,CAAA,EAAAC,CAAA,EAAAC,CAAA,KAAAC,SAAA,QAAAC,OAAA,EAAAV,CAAA,iBAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,SAAAQ,CAAA,MAAAF,CAAA,GAAAL,CAAA,GAAAG,CAAA,GAAAD,CAAA,QAAAG,CAAA,CAAAK,GAAA,CAAAX,CAAA,UAAAM,CAAA,CAAAM,GAAA,CAAAZ,CAAA,GAAAM,CAAA,CAAAO,GAAA,CAAAb,CAAA,EAAAQ,CAAA,gBAAAP,CAAA,IAAAD,CAAA,gBAAAC,CAAA,OAAAa,cAAA,CAAAC,IAAA,CAAAf,CAAA,EAAAC,CAAA,OAAAM,CAAA,IAAAD,CAAA,GAAAU,MAAA,CAAAC,cAAA,KAAAD,MAAA,CAAAE,wBAAA,CAAAlB,CAAA,EAAAC,CAAA,OAAAM,CAAA,CAAAK,GAAA,IAAAL,CAAA,CAAAM,GAAA,IAAAP,CAAA,CAAAE,CAAA,EAAAP,CAAA,EAAAM,CAAA,IAAAC,CAAA,CAAAP,CAAA,IAAAD,CAAA,CAAAC,CAAA,WAAAO,CAAA,KAAAR,CAAA,EAAAC,CAAA;AAGvD;;AAEO,MAAMkB,SAAS,GAAAC,OAAA,CAAAD,SAAA,gBAAG,IAAAE,iBAAU,EACjC,CACE;EACEC,OAAO,GAAG,IAAI;EACdC,KAAK,EAAEC,eAAe,GAAG,MAAM;EAC/BC,UAAU;EACVC,WAAW;EACXC,QAAQ;EACRC,UAAU;EACVC,KAAK;EACLC,YAAY;EACZC,YAAY;EACZC,mBAAmB;EACnBC,OAAO,GAAGC,2BAAgB;EAC1BC,UAAU;EACVC,UAAU;EACVC,SAAS;EACTC,QAAQ;EACRC,MAAM,EAAEC,UAAU;EAClBC,QAAQ;EACRC,QAAQ;EACRC,QAAQ;EACRC,sBAAsB,GAAG,IAAI;EAC7BC,iBAAiB,GAAGC,sCAA2B;EAC/CC,kBAAkB;EAClBC,cAAc;EACdC,qBAAqB,GAAG,IAAI;EAC5BC;
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_constants","_logInterceptor","_networkInterceptor","_FloatingPill","_BackstagePanel","_ThemeContext","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","Backstage","exports","forwardRef","visible","theme","themePreference","appVersion","buildNumber","bundleId","deviceInfo","state","quickActions","featureFlags","onToggleFeatureFlag","storageAdapter","maxLogs","DEFAULT_MAX_LOGS","logFilters","onCopyLogs","extraTabs","children","styles","propStyles","initialX","initialY","pillText","pillWidth","pillHeight","enableNetworkInspector","maxNetworkEntries","DEFAULT_MAX_NETWORK_ENTRIES","maxNetworkBodySize","networkFilters","autoFilterNetworkLogs","jsonMaxDepth","bugReport","bugReportConfig","ref","panelVisible","setPanelVisible","useState","hasError","setHasError","logs","setLogs","networkEntries","setNetworkEntries","logBuffer","useRef","LogBuffer","networkBuffer","NetworkBuffer","openPanel","useCallback","current","getAll","closePanel","clearLogs","clear","refreshLogs","refreshNetwork","clearNetwork","useEffect","handleLogEntry","entry","push","level","installInterceptor","uninstallInterceptor","handleNetworkEntry","upsert","installNetworkInterceptor","filters","maxBodySize","uninstallNetworkInterceptor","openBugReportRef","useImperativeHandle","open","close","submitBugReport","setTimeout","displayText","jsx","BackstageThemeProvider","preference","jsxs","View","style","container","pointerEvents","FloatingPill","text","onPress","BackstagePanel","onClose","onRefreshLogs","onRefreshNetwork","onClearNetwork","onCopyNetwork","bugReportOpenerRef","displayName","StyleSheet","create","absoluteFillObject","zIndex","elevation"],"sourceRoot":"../../src","sources":["Backstage.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.buildDeviceInfo = buildDeviceInfo;
|
|
7
|
+
exports.composeBugReport = composeBugReport;
|
|
8
|
+
exports.formatDeviceInfoForReport = formatDeviceInfoForReport;
|
|
9
|
+
exports.formatLogsForReport = formatLogsForReport;
|
|
10
|
+
exports.formatNetworkForReport = formatNetworkForReport;
|
|
11
|
+
exports.formatStateForReport = formatStateForReport;
|
|
12
|
+
exports.submitToWebhook = submitToWebhook;
|
|
13
|
+
var _reactNative = require("react-native");
|
|
14
|
+
var _types = require("./types");
|
|
15
|
+
// ─── Report Composition ──────────────────────────────────────────────────────
|
|
16
|
+
|
|
17
|
+
const SEVERITY_LABELS = {
|
|
18
|
+
low: '🟢 Low',
|
|
19
|
+
medium: '🟡 Medium',
|
|
20
|
+
high: '🟠 High',
|
|
21
|
+
critical: '🔴 Critical'
|
|
22
|
+
};
|
|
23
|
+
function formatTimestamp(ts) {
|
|
24
|
+
const d = new Date(ts);
|
|
25
|
+
return d.toISOString().replace('T', ' ').substring(0, 19);
|
|
26
|
+
}
|
|
27
|
+
function formatLogLevel(level) {
|
|
28
|
+
switch (level) {
|
|
29
|
+
case _types.LogLevel.error:
|
|
30
|
+
return '❌ ERROR';
|
|
31
|
+
case _types.LogLevel.warn:
|
|
32
|
+
return '⚠️ WARN';
|
|
33
|
+
case _types.LogLevel.info:
|
|
34
|
+
return 'ℹ️ INFO';
|
|
35
|
+
case _types.LogLevel.debug:
|
|
36
|
+
return '🔍 DEBUG';
|
|
37
|
+
default:
|
|
38
|
+
return '📝 LOG';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function formatDeviceInfoForReport(items) {
|
|
42
|
+
if (items.length === 0) return '';
|
|
43
|
+
const lines = items.map(i => `- **${i.label}**: ${i.value}`);
|
|
44
|
+
return `## 📱 Device Info\n\n${lines.join('\n')}\n`;
|
|
45
|
+
}
|
|
46
|
+
function formatLogsForReport(logs) {
|
|
47
|
+
if (logs.length === 0) return '';
|
|
48
|
+
const lines = logs.map(l => `\`${formatTimestamp(l.timestamp)}\` ${formatLogLevel(l.level)} ${l.message}`);
|
|
49
|
+
return `## 📋 Console Logs (${logs.length})\n\n\`\`\`\n${lines.join('\n')}\n\`\`\`\n`;
|
|
50
|
+
}
|
|
51
|
+
function formatNetworkForReport(entries) {
|
|
52
|
+
if (entries.length === 0) return '';
|
|
53
|
+
const lines = entries.map(e => {
|
|
54
|
+
const status = e.status ?? '⏳';
|
|
55
|
+
const duration = e.duration ? `${e.duration}ms` : '...';
|
|
56
|
+
return `- \`${e.method}\` ${e.url} → ${status} (${duration})`;
|
|
57
|
+
});
|
|
58
|
+
return `## 🌐 Network Activity (${entries.length})\n\n${lines.join('\n')}\n`;
|
|
59
|
+
}
|
|
60
|
+
function formatStateForReport(state) {
|
|
61
|
+
try {
|
|
62
|
+
const json = JSON.stringify(state, null, 2);
|
|
63
|
+
// Truncate if too large
|
|
64
|
+
const truncated = json.length > 5000 ? json.substring(0, 5000) + '\n... (truncated)' : json;
|
|
65
|
+
return `## 🌳 State Snapshot\n\n\`\`\`json\n${truncated}\n\`\`\`\n`;
|
|
66
|
+
} catch {
|
|
67
|
+
return `## 🌳 State Snapshot\n\n\`[Could not serialize state]\`\n`;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function composeBugReport(report) {
|
|
71
|
+
const sections = [];
|
|
72
|
+
sections.push(`# 🐛 Bug Report: ${report.title}\n`);
|
|
73
|
+
sections.push(`**Severity**: ${SEVERITY_LABELS[report.severity]}`);
|
|
74
|
+
sections.push(`**Reported**: ${formatTimestamp(report.timestamp)}`);
|
|
75
|
+
sections.push(`**Platform**: ${_reactNative.Platform.OS} ${_reactNative.Platform.Version}\n`);
|
|
76
|
+
if (report.description) {
|
|
77
|
+
sections.push(`## Description\n\n${report.description}\n`);
|
|
78
|
+
}
|
|
79
|
+
if (report.deviceInfo.length > 0) {
|
|
80
|
+
sections.push(formatDeviceInfoForReport(report.deviceInfo));
|
|
81
|
+
}
|
|
82
|
+
if (report.logs.length > 0) {
|
|
83
|
+
sections.push(formatLogsForReport(report.logs));
|
|
84
|
+
}
|
|
85
|
+
if (report.networkEntries.length > 0) {
|
|
86
|
+
sections.push(formatNetworkForReport(report.networkEntries));
|
|
87
|
+
}
|
|
88
|
+
if (report.state && Object.keys(report.state).length > 0) {
|
|
89
|
+
sections.push(formatStateForReport(report.state));
|
|
90
|
+
}
|
|
91
|
+
if (report.screenshotUri) {
|
|
92
|
+
sections.push(`## 📸 Screenshot\n\nAttached: ${report.screenshotUri}\n`);
|
|
93
|
+
}
|
|
94
|
+
sections.push('---\n*Generated by rn-backstage*');
|
|
95
|
+
return sections.join('\n');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ─── Webhook Submission ──────────────────────────────────────────────────────
|
|
99
|
+
|
|
100
|
+
async function submitToWebhook(webhookUrl, report) {
|
|
101
|
+
try {
|
|
102
|
+
const body = {
|
|
103
|
+
title: report.title,
|
|
104
|
+
description: report.description,
|
|
105
|
+
severity: report.severity,
|
|
106
|
+
platform: _reactNative.Platform.OS,
|
|
107
|
+
platformVersion: String(_reactNative.Platform.Version),
|
|
108
|
+
timestamp: report.timestamp,
|
|
109
|
+
deviceInfo: report.deviceInfo,
|
|
110
|
+
logs: report.logs.map(l => ({
|
|
111
|
+
level: l.level,
|
|
112
|
+
message: l.message,
|
|
113
|
+
timestamp: l.timestamp
|
|
114
|
+
})),
|
|
115
|
+
networkEntries: report.networkEntries.map(e => ({
|
|
116
|
+
method: e.method,
|
|
117
|
+
url: e.url,
|
|
118
|
+
status: e.status,
|
|
119
|
+
duration: e.duration
|
|
120
|
+
}))
|
|
121
|
+
};
|
|
122
|
+
if (report.state) {
|
|
123
|
+
body.state = report.state;
|
|
124
|
+
}
|
|
125
|
+
if (report.screenshotUri) {
|
|
126
|
+
body.screenshotUri = report.screenshotUri;
|
|
127
|
+
}
|
|
128
|
+
const response = await fetch(webhookUrl, {
|
|
129
|
+
method: 'POST',
|
|
130
|
+
headers: {
|
|
131
|
+
'Content-Type': 'application/json'
|
|
132
|
+
},
|
|
133
|
+
body: JSON.stringify(body)
|
|
134
|
+
});
|
|
135
|
+
if (!response.ok) {
|
|
136
|
+
return {
|
|
137
|
+
success: false,
|
|
138
|
+
error: `HTTP ${response.status}`
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
success: true
|
|
143
|
+
};
|
|
144
|
+
} catch (err) {
|
|
145
|
+
return {
|
|
146
|
+
success: false,
|
|
147
|
+
error: err instanceof Error ? err.message : 'Unknown error'
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ─── Device Info Builder ─────────────────────────────────────────────────────
|
|
153
|
+
|
|
154
|
+
function buildDeviceInfo(appVersion, buildNumber, bundleId, extraInfo = []) {
|
|
155
|
+
const info = [{
|
|
156
|
+
label: 'Platform',
|
|
157
|
+
value: `${_reactNative.Platform.OS} ${_reactNative.Platform.Version}`
|
|
158
|
+
}];
|
|
159
|
+
if (appVersion) info.push({
|
|
160
|
+
label: 'App Version',
|
|
161
|
+
value: appVersion
|
|
162
|
+
});
|
|
163
|
+
if (buildNumber) info.push({
|
|
164
|
+
label: 'Build Number',
|
|
165
|
+
value: buildNumber
|
|
166
|
+
});
|
|
167
|
+
if (bundleId) info.push({
|
|
168
|
+
label: 'Bundle ID',
|
|
169
|
+
value: bundleId
|
|
170
|
+
});
|
|
171
|
+
return [...info, ...extraInfo];
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=bug-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_reactNative","require","_types","SEVERITY_LABELS","low","medium","high","critical","formatTimestamp","ts","d","Date","toISOString","replace","substring","formatLogLevel","level","LogLevel","error","warn","info","debug","formatDeviceInfoForReport","items","length","lines","map","i","label","value","join","formatLogsForReport","logs","l","timestamp","message","formatNetworkForReport","entries","e","status","duration","method","url","formatStateForReport","state","json","JSON","stringify","truncated","composeBugReport","report","sections","push","title","severity","Platform","OS","Version","description","deviceInfo","networkEntries","Object","keys","screenshotUri","submitToWebhook","webhookUrl","body","platform","platformVersion","String","response","fetch","headers","ok","success","err","Error","buildDeviceInfo","appVersion","buildNumber","bundleId","extraInfo"],"sourceRoot":"../../src","sources":["bug-report.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -13,6 +13,8 @@ var _InfoTab = require("./InfoTab");
|
|
|
13
13
|
var _LogsTab = require("./LogsTab");
|
|
14
14
|
var _NetworkTab = require("./NetworkTab");
|
|
15
15
|
var _FlagsTab = require("./FlagsTab");
|
|
16
|
+
var _StorageTab = require("./StorageTab");
|
|
17
|
+
var _BugReportComposer = require("./BugReportComposer");
|
|
16
18
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
17
19
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
18
20
|
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
@@ -33,6 +35,11 @@ const FLAGS_TAB = {
|
|
|
33
35
|
title: 'Flags',
|
|
34
36
|
icon: '🎚'
|
|
35
37
|
};
|
|
38
|
+
const STORAGE_TAB = {
|
|
39
|
+
key: 'storage',
|
|
40
|
+
title: 'Storage',
|
|
41
|
+
icon: '🗄'
|
|
42
|
+
};
|
|
36
43
|
const LOGS_TAB = {
|
|
37
44
|
key: 'logs',
|
|
38
45
|
title: 'Logs',
|
|
@@ -61,16 +68,37 @@ const BackstagePanel = ({
|
|
|
61
68
|
onCopyNetwork,
|
|
62
69
|
extraTabs = [],
|
|
63
70
|
jsonMaxDepth,
|
|
71
|
+
storageAdapter,
|
|
72
|
+
bugReportConfig,
|
|
73
|
+
bugReportOpenerRef,
|
|
64
74
|
styles: propStyles,
|
|
65
75
|
children
|
|
66
76
|
}) => {
|
|
67
77
|
const [activeTab, setActiveTab] = (0, _react.useState)('info');
|
|
78
|
+
const [bugReportVisible, setBugReportVisible] = (0, _react.useState)(false);
|
|
68
79
|
const theme = (0, _ThemeContext.useBackstageTheme)();
|
|
69
80
|
const styles = (0, _react.useMemo)(() => createStyles(theme), [theme]);
|
|
70
81
|
|
|
82
|
+
// Reset to Info tab when panel closes so indicator and content stay in sync
|
|
83
|
+
(0, _react.useEffect)(() => {
|
|
84
|
+
if (!visible) {
|
|
85
|
+
setActiveTab('info');
|
|
86
|
+
}
|
|
87
|
+
}, [visible]);
|
|
88
|
+
|
|
89
|
+
// Register opener callback for the parent ref
|
|
90
|
+
(0, _react.useEffect)(() => {
|
|
91
|
+
if (!bugReportOpenerRef) return;
|
|
92
|
+
bugReportOpenerRef.current = () => setBugReportVisible(true);
|
|
93
|
+
return () => {
|
|
94
|
+
bugReportOpenerRef.current = null;
|
|
95
|
+
};
|
|
96
|
+
}, [bugReportOpenerRef]);
|
|
97
|
+
|
|
71
98
|
// Compose all tabs: built-in (conditionally including Flags) + extra
|
|
72
99
|
const hasFlags = featureFlags && featureFlags.length > 0;
|
|
73
|
-
const
|
|
100
|
+
const hasStorage = !!storageAdapter;
|
|
101
|
+
const allTabs = [...ALWAYS_ON_TABS, ...(hasFlags ? [FLAGS_TAB] : []), ...(hasStorage ? [STORAGE_TAB] : []), LOGS_TAB, ...extraTabs.map(t => ({
|
|
74
102
|
key: t.key,
|
|
75
103
|
title: t.title,
|
|
76
104
|
icon: t.icon
|
|
@@ -97,6 +125,11 @@ const BackstagePanel = ({
|
|
|
97
125
|
flags: featureFlags ?? [],
|
|
98
126
|
onToggle: onToggleFeatureFlag
|
|
99
127
|
});
|
|
128
|
+
case 'storage':
|
|
129
|
+
return storageAdapter ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_StorageTab.StorageTab, {
|
|
130
|
+
adapter: storageAdapter,
|
|
131
|
+
jsonMaxDepth: jsonMaxDepth
|
|
132
|
+
}) : null;
|
|
100
133
|
case 'network':
|
|
101
134
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_NetworkTab.NetworkTab, {
|
|
102
135
|
entries: networkEntries,
|
|
@@ -127,7 +160,7 @@ const BackstagePanel = ({
|
|
|
127
160
|
}
|
|
128
161
|
};
|
|
129
162
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Modal, {
|
|
130
|
-
testID: _constants.TestIDs.
|
|
163
|
+
testID: _constants.TestIDs.panelModal,
|
|
131
164
|
animationType: "slide",
|
|
132
165
|
transparent: false,
|
|
133
166
|
visible: visible,
|
|
@@ -137,8 +170,10 @@ const BackstagePanel = ({
|
|
|
137
170
|
barStyle: theme.background < '#888' ? 'light-content' : 'dark-content',
|
|
138
171
|
backgroundColor: theme.background
|
|
139
172
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.SafeAreaView, {
|
|
173
|
+
testID: _constants.TestIDs.panel,
|
|
140
174
|
style: [styles.safeArea, propStyles?.panelStyle],
|
|
141
175
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
176
|
+
testID: _constants.TestIDs.header.container,
|
|
142
177
|
style: styles.header,
|
|
143
178
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
144
179
|
style: styles.headerLeft,
|
|
@@ -146,24 +181,43 @@ const BackstagePanel = ({
|
|
|
146
181
|
style: styles.headerBrand,
|
|
147
182
|
children: "\u2699"
|
|
148
183
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
184
|
+
testID: _constants.TestIDs.header.title,
|
|
149
185
|
style: [styles.headerTitle, propStyles?.headerTitleStyle],
|
|
150
186
|
children: "Backstage"
|
|
151
187
|
})]
|
|
152
|
-
}), /*#__PURE__*/(0, _jsxRuntime.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
children:
|
|
166
|
-
|
|
188
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
189
|
+
style: styles.headerRight,
|
|
190
|
+
children: [bugReportConfig && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
191
|
+
testID: _constants.TestIDs.bugReport.triggerButton,
|
|
192
|
+
style: styles.headerButton,
|
|
193
|
+
onPress: () => setBugReportVisible(true),
|
|
194
|
+
activeOpacity: 0.7,
|
|
195
|
+
hitSlop: {
|
|
196
|
+
top: 8,
|
|
197
|
+
bottom: 8,
|
|
198
|
+
left: 8,
|
|
199
|
+
right: 8
|
|
200
|
+
},
|
|
201
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
202
|
+
style: styles.headerButtonText,
|
|
203
|
+
children: "\uD83D\uDC1B"
|
|
204
|
+
})
|
|
205
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
206
|
+
testID: _constants.TestIDs.header.closeButton,
|
|
207
|
+
style: styles.closeButton,
|
|
208
|
+
onPress: onClose,
|
|
209
|
+
activeOpacity: 0.7,
|
|
210
|
+
hitSlop: {
|
|
211
|
+
top: 8,
|
|
212
|
+
bottom: 8,
|
|
213
|
+
left: 8,
|
|
214
|
+
right: 8
|
|
215
|
+
},
|
|
216
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
217
|
+
style: styles.closeButtonText,
|
|
218
|
+
children: "\u2715"
|
|
219
|
+
})
|
|
220
|
+
})]
|
|
167
221
|
})]
|
|
168
222
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_TabBar.TabBar, {
|
|
169
223
|
tabs: allTabs,
|
|
@@ -173,6 +227,17 @@ const BackstagePanel = ({
|
|
|
173
227
|
style: styles.content,
|
|
174
228
|
children: renderTabContent()
|
|
175
229
|
})]
|
|
230
|
+
}), bugReportConfig && /*#__PURE__*/(0, _jsxRuntime.jsx)(_BugReportComposer.BugReportComposer, {
|
|
231
|
+
visible: bugReportVisible,
|
|
232
|
+
onClose: () => setBugReportVisible(false),
|
|
233
|
+
config: bugReportConfig,
|
|
234
|
+
logs: logs,
|
|
235
|
+
networkEntries: networkEntries,
|
|
236
|
+
state: state,
|
|
237
|
+
appVersion: appVersion,
|
|
238
|
+
buildNumber: buildNumber,
|
|
239
|
+
bundleId: bundleId,
|
|
240
|
+
deviceInfo: deviceInfo
|
|
176
241
|
})]
|
|
177
242
|
});
|
|
178
243
|
};
|
|
@@ -223,6 +288,24 @@ const createStyles = t => _reactNative.StyleSheet.create({
|
|
|
223
288
|
color: t.textSecondary,
|
|
224
289
|
fontWeight: '700'
|
|
225
290
|
},
|
|
291
|
+
headerRight: {
|
|
292
|
+
flexDirection: 'row',
|
|
293
|
+
alignItems: 'center',
|
|
294
|
+
gap: 8
|
|
295
|
+
},
|
|
296
|
+
headerButton: {
|
|
297
|
+
width: 32,
|
|
298
|
+
height: 32,
|
|
299
|
+
borderRadius: 16,
|
|
300
|
+
backgroundColor: t.surfaceElevated,
|
|
301
|
+
borderWidth: 1,
|
|
302
|
+
borderColor: t.border,
|
|
303
|
+
alignItems: 'center',
|
|
304
|
+
justifyContent: 'center'
|
|
305
|
+
},
|
|
306
|
+
headerButtonText: {
|
|
307
|
+
fontSize: 16
|
|
308
|
+
},
|
|
226
309
|
content: {
|
|
227
310
|
flex: 1
|
|
228
311
|
}
|