react-native-inapp-inspector 2.3.15 → 2.3.16

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.
Files changed (96) hide show
  1. package/README.md +1 -0
  2. package/dist/commonjs/components/Inspector/AnalyticsTab.js +0 -22
  3. package/dist/commonjs/components/Inspector/ConsoleTab.js +0 -22
  4. package/dist/commonjs/components/Inspector/CrashTab.js +0 -23
  5. package/dist/commonjs/components/Inspector/FeedbackModal.d.ts +7 -0
  6. package/dist/commonjs/components/Inspector/FeedbackModal.js +552 -0
  7. package/dist/commonjs/components/Inspector/InspectorHeader.js +56 -4
  8. package/dist/commonjs/components/Inspector/MainScreen.js +45 -3
  9. package/dist/commonjs/components/Inspector/NetworkTab.js +27 -38
  10. package/dist/commonjs/components/Inspector/NpmStarPrompt.d.ts +3 -0
  11. package/dist/commonjs/components/Inspector/NpmStarPrompt.js +494 -0
  12. package/dist/commonjs/components/Inspector/PerformanceTab.js +8 -1
  13. package/dist/commonjs/components/Inspector/ReduxTab.js +0 -22
  14. package/dist/commonjs/components/Inspector/SettingsPanel.js +1035 -173
  15. package/dist/commonjs/components/Inspector/StorageTab.js +0 -23
  16. package/dist/commonjs/components/Inspector/TabBar.js +50 -15
  17. package/dist/commonjs/components/NetworkIcons.d.ts +5 -0
  18. package/dist/commonjs/components/NetworkIcons.js +33 -2
  19. package/dist/commonjs/constants/version.d.ts +1 -1
  20. package/dist/commonjs/constants/version.js +1 -1
  21. package/dist/commonjs/helpers/index.d.ts +1 -0
  22. package/dist/commonjs/helpers/index.js +1 -0
  23. package/dist/commonjs/helpers/remoteConfig.d.ts +4 -0
  24. package/dist/commonjs/helpers/remoteConfig.js +165 -0
  25. package/dist/commonjs/helpers/searchQueryParser.js +2 -0
  26. package/dist/commonjs/helpers/telemetry.d.ts +5 -0
  27. package/dist/commonjs/helpers/telemetry.js +339 -8
  28. package/dist/commonjs/index.d.ts +1 -0
  29. package/dist/commonjs/index.js +32 -2
  30. package/dist/commonjs/styles/AppFonts.d.ts +2 -0
  31. package/dist/commonjs/styles/AppFonts.js +1 -0
  32. package/dist/commonjs/styles/index.d.ts +22 -0
  33. package/dist/commonjs/styles/index.js +19 -0
  34. package/dist/commonjs/types/enums.d.ts +1 -0
  35. package/dist/commonjs/types/enums.js +1 -0
  36. package/dist/commonjs/types/interfaces.d.ts +12 -0
  37. package/dist/esm/components/Inspector/AnalyticsTab.js +1 -23
  38. package/dist/esm/components/Inspector/ConsoleTab.js +1 -23
  39. package/dist/esm/components/Inspector/CrashTab.js +1 -24
  40. package/dist/esm/components/Inspector/FeedbackModal.d.ts +7 -0
  41. package/dist/esm/components/Inspector/FeedbackModal.js +515 -0
  42. package/dist/esm/components/Inspector/InspectorHeader.js +57 -5
  43. package/dist/esm/components/Inspector/MainScreen.js +46 -4
  44. package/dist/esm/components/Inspector/NetworkTab.js +28 -39
  45. package/dist/esm/components/Inspector/NpmStarPrompt.d.ts +3 -0
  46. package/dist/esm/components/Inspector/NpmStarPrompt.js +454 -0
  47. package/dist/esm/components/Inspector/PerformanceTab.js +8 -1
  48. package/dist/esm/components/Inspector/ReduxTab.js +1 -23
  49. package/dist/esm/components/Inspector/SettingsPanel.js +1038 -176
  50. package/dist/esm/components/Inspector/StorageTab.js +0 -23
  51. package/dist/esm/components/Inspector/TabBar.js +50 -15
  52. package/dist/esm/components/NetworkIcons.d.ts +5 -0
  53. package/dist/esm/components/NetworkIcons.js +26 -0
  54. package/dist/esm/constants/version.d.ts +1 -1
  55. package/dist/esm/constants/version.js +1 -1
  56. package/dist/esm/helpers/index.d.ts +1 -0
  57. package/dist/esm/helpers/index.js +1 -0
  58. package/dist/esm/helpers/remoteConfig.d.ts +4 -0
  59. package/dist/esm/helpers/remoteConfig.js +160 -0
  60. package/dist/esm/helpers/searchQueryParser.js +2 -0
  61. package/dist/esm/helpers/telemetry.d.ts +5 -0
  62. package/dist/esm/helpers/telemetry.js +332 -9
  63. package/dist/esm/index.d.ts +1 -0
  64. package/dist/esm/index.js +30 -2
  65. package/dist/esm/styles/AppFonts.d.ts +2 -0
  66. package/dist/esm/styles/AppFonts.js +1 -0
  67. package/dist/esm/styles/index.d.ts +22 -0
  68. package/dist/esm/styles/index.js +19 -0
  69. package/dist/esm/types/enums.d.ts +1 -0
  70. package/dist/esm/types/enums.js +1 -0
  71. package/dist/esm/types/interfaces.d.ts +12 -0
  72. package/package.json +1 -1
  73. package/src/components/Inspector/AnalyticsTab.tsx +0 -23
  74. package/src/components/Inspector/ConsoleTab.tsx +0 -23
  75. package/src/components/Inspector/CrashTab.tsx +0 -23
  76. package/src/components/Inspector/FeedbackModal.tsx +626 -0
  77. package/src/components/Inspector/InspectorHeader.tsx +78 -2
  78. package/src/components/Inspector/MainScreen.tsx +59 -3
  79. package/src/components/Inspector/NetworkTab.tsx +69 -78
  80. package/src/components/Inspector/NpmStarPrompt.tsx +532 -0
  81. package/src/components/Inspector/PerformanceTab.tsx +8 -1
  82. package/src/components/Inspector/ReduxTab.tsx +0 -23
  83. package/src/components/Inspector/SettingsPanel.tsx +1162 -197
  84. package/src/components/Inspector/StorageTab.tsx +0 -23
  85. package/src/components/Inspector/TabBar.tsx +57 -20
  86. package/src/components/NetworkIcons.tsx +92 -0
  87. package/src/constants/version.ts +1 -1
  88. package/src/helpers/index.ts +1 -0
  89. package/src/helpers/remoteConfig.ts +212 -0
  90. package/src/helpers/searchQueryParser.ts +3 -0
  91. package/src/helpers/telemetry.ts +381 -10
  92. package/src/index.tsx +42 -0
  93. package/src/styles/AppFonts.ts +2 -0
  94. package/src/styles/index.ts +20 -1
  95. package/src/types/enums.ts +1 -0
  96. package/src/types/interfaces.ts +12 -0
package/README.md CHANGED
@@ -11,6 +11,7 @@
11
11
  <p align="center">
12
12
  <a href="https://www.npmjs.com/package/react-native-inapp-inspector"><img src="https://img.shields.io/npm/v/react-native-inapp-inspector?color=6366f1&label=npm" alt="npm version" /></a>
13
13
  <a href="https://www.npmjs.com/package/react-native-inapp-inspector"><img src="https://img.shields.io/npm/dm/react-native-inapp-inspector?color=3b82f6&label=downloads" alt="npm downloads" /></a>
14
+ <a href="https://github.com/vengatmacuser/react-native-inapp-inspector"><img src="https://img.shields.io/github/stars/vengatmacuser/react-native-inapp-inspector?color=f59e0b&label=stars&logo=github" alt="GitHub stars" /></a>
14
15
  <a href="https://bundlephobia.com/package/react-native-inapp-inspector"><img src="https://img.shields.io/bundlephobia/minzip/react-native-inapp-inspector?color=10b981&label=minzipped" alt="bundle size" /></a>
15
16
  <a href="https://github.com/vengatmacuser/react-native-inapp-inspector/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="license" /></a>
16
17
  <a href="https://github.com/vengatmacuser/react-native-inapp-inspector"><img src="https://img.shields.io/badge/platform-iOS%20%7C%20Android%20%7C%20Expo-blue" alt="platform" /></a>
@@ -972,28 +972,6 @@ const AnalyticsTab = react_1.default.memo(() => {
972
972
  flexGrow: 1,
973
973
  },
974
974
  ]} keyboardShouldPersistTaps="handled"/>
975
-
976
- <TouchableScale_1.default onPress={() => {
977
- try {
978
- listRef.current?.scrollToOffset({
979
- offset: 0,
980
- animated: true,
981
- });
982
- }
983
- catch {
984
- try {
985
- listRef.current?.scrollToIndex({
986
- index: 0,
987
- animated: true,
988
- });
989
- }
990
- catch { }
991
- }
992
- }} hitSlop={12} style={styles_1.default.scrollTopBtn}>
993
- <react_native_1.View style={{ transform: [{ rotate: '180deg' }] }}>
994
- <NetworkIcons_1.ChevronIcon color={AppColors_1.AppColors.white} size={18}/>
995
- </react_native_1.View>
996
- </TouchableScale_1.default>
997
975
  </>) : null}
998
976
  </react_native_1.View>
999
977
  </>);
@@ -537,28 +537,6 @@ const ConsoleTab = react_1.default.memo(() => {
537
537
  styles_1.default.listContent,
538
538
  filteredConsoleLogs.length === 0 && { flexGrow: 1 },
539
539
  ]} keyboardShouldPersistTaps="handled"/>
540
-
541
- <TouchableScale_1.default onPress={() => {
542
- try {
543
- listRef.current?.scrollToOffset({
544
- offset: 0,
545
- animated: true,
546
- });
547
- }
548
- catch {
549
- try {
550
- listRef.current?.scrollToIndex({
551
- index: 0,
552
- animated: true,
553
- });
554
- }
555
- catch { }
556
- }
557
- }} hitSlop={12} style={styles_1.default.scrollTopBtn}>
558
- <react_native_1.View style={{ transform: [{ rotate: '180deg' }] }}>
559
- <NetworkIcons_1.ChevronIcon color={AppColors_1.AppColors.white} size={18}/>
560
- </react_native_1.View>
561
- </TouchableScale_1.default>
562
540
  </react_native_1.View>);
563
541
  });
564
542
  exports.default = ConsoleTab;
@@ -45,7 +45,6 @@ const AnimatedEntrance_1 = __importDefault(require("../AnimatedEntrance"));
45
45
  const EndOfListFooter_1 = __importDefault(require("../EndOfListFooter"));
46
46
  const FeatureUnderDevNotice_1 = __importDefault(require("./FeatureUnderDevNotice"));
47
47
  const HighlightText_1 = __importDefault(require("../HighlightText"));
48
- const styles_1 = __importDefault(require("../../styles"));
49
48
  const AppColors_1 = require("../../styles/AppColors");
50
49
  const AppFonts_1 = require("../../styles/AppFonts");
51
50
  const crashHandler_1 = require("../../customHooks/crashHandler");
@@ -462,28 +461,6 @@ const CrashTab = react_1.default.memo(() => {
462
461
  </TouchableScale_1.default>)}
463
462
  </react_native_1.ScrollView>) : (<>
464
463
  <react_native_1.FlatList ref={listRef} data={filteredList} keyExtractor={item => item.id} renderItem={renderCard} initialNumToRender={12} maxToRenderPerBatch={8} windowSize={5} removeClippedSubviews={true} renderToHardwareTextureAndroid={true} contentContainerStyle={localStyles.listContent} showsVerticalScrollIndicator={false} ListFooterComponent={<EndOfListFooter_1.default />}/>
465
-
466
- <TouchableScale_1.default onPress={() => {
467
- try {
468
- listRef.current?.scrollToOffset({
469
- offset: 0,
470
- animated: true,
471
- });
472
- }
473
- catch {
474
- try {
475
- listRef.current?.scrollToIndex({
476
- index: 0,
477
- animated: true,
478
- });
479
- }
480
- catch { }
481
- }
482
- }} hitSlop={12} style={styles_1.default.scrollTopBtn}>
483
- <react_native_1.View style={{ transform: [{ rotate: '180deg' }] }}>
484
- <NetworkIcons_1.ChevronIcon color={AppColors_1.AppColors.white} size={18}/>
485
- </react_native_1.View>
486
- </TouchableScale_1.default>
487
464
  </>)}
488
465
 
489
466
 
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ export interface FeedbackModalProps {
3
+ visible?: boolean;
4
+ onClose: () => void;
5
+ }
6
+ export declare const FeedbackModal: React.FC<FeedbackModalProps>;
7
+ export default FeedbackModal;
@@ -0,0 +1,552 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.FeedbackModal = void 0;
37
+ const react_1 = __importStar(require("react"));
38
+ const react_native_1 = require("react-native");
39
+ const AppColors_1 = require("../../styles/AppColors");
40
+ const AppFonts_1 = require("../../styles/AppFonts");
41
+ const version_1 = require("../../constants/version");
42
+ const helpers_1 = require("../../helpers");
43
+ const telemetry_1 = require("../../helpers/telemetry");
44
+ const NetworkIcons_1 = require("../NetworkIcons");
45
+ const DEVELOPER_EMAIL = 'vengatmacuser@gmail.com';
46
+ const CATEGORIES = [
47
+ { key: 'feedback', label: 'Feedback', icon: '💬' },
48
+ { key: 'bug', label: 'Bug Report', icon: '🐛' },
49
+ { key: 'feature', label: 'Feature Request', icon: '✨' },
50
+ { key: 'performance', label: 'Performance', icon: '⚡' },
51
+ { key: 'help', label: 'Support / Help', icon: '❓' },
52
+ ];
53
+ const RATING_LABELS = ['', 'Poor', 'Fair', 'Good', 'Very Good', 'Excellent!'];
54
+ const FeedbackModal = ({ onClose }) => {
55
+ const [category, setCategory] = (0, react_1.useState)('feedback');
56
+ const [rating, setRating] = (0, react_1.useState)(5);
57
+ const [subject, setSubject] = (0, react_1.useState)('');
58
+ const [message, setMessage] = (0, react_1.useState)('');
59
+ const [showDiagnostics, setShowDiagnostics] = (0, react_1.useState)(false);
60
+ const [isSending, setIsSending] = (0, react_1.useState)(false);
61
+ const [copiedDraft, setCopiedDraft] = (0, react_1.useState)(false);
62
+ (0, react_1.useEffect)(() => {
63
+ (0, telemetry_1.trackTelemetryEvent)('feedback_modal_opened', { category });
64
+ }, []);
65
+ const appName = (0, helpers_1.getAppName)() || 'React Native App';
66
+ const bundleId = (0, helpers_1.getBundleIdentifier)() || 'unknown';
67
+ const appVersion = (0, helpers_1.getAppVersionAndBuild)() || '1.0.0';
68
+ const { width, height } = react_native_1.Dimensions.get('window');
69
+ const getDiagnosticsText = () => {
70
+ return [
71
+ `• Package: react-native-inapp-inspector@${version_1.LIB_VERSION}`,
72
+ `• Platform: ${react_native_1.Platform.OS.toUpperCase()} (${react_native_1.Platform.Version})`,
73
+ `• App: ${appName} (${bundleId}) v${appVersion}`,
74
+ `• Screen: ${Math.round(width)} x ${Math.round(height)} (Scale ${react_native_1.PixelRatio.get()})`,
75
+ `• Timestamp: ${new Date().toISOString()}`,
76
+ ].join('\n');
77
+ };
78
+ const buildEmailDraft = () => {
79
+ const activeCat = CATEGORIES.find(c => c.key === category)?.label || category;
80
+ const emailSubject = `[In-App Inspector] [${activeCat}] ${subject.trim() || 'User Feedback'}`;
81
+ const bodyLines = [
82
+ `Category: ${activeCat}`,
83
+ `Rating: ${rating} / 5 (${RATING_LABELS[rating] || ''})`,
84
+ ...(subject.trim() ? [`Subject: ${subject.trim()}`] : []),
85
+ '',
86
+ 'Feedback / Message:',
87
+ message.trim() || '(No message provided)',
88
+ '',
89
+ '----------------------------------------',
90
+ 'System & Diagnostic Info:',
91
+ getDiagnosticsText(),
92
+ '----------------------------------------',
93
+ ];
94
+ return {
95
+ activeCat,
96
+ subject: emailSubject,
97
+ body: bodyLines.join('\n'),
98
+ };
99
+ };
100
+ const handleCopyDraft = () => {
101
+ const draft = buildEmailDraft();
102
+ const fullText = `To: ${DEVELOPER_EMAIL}\nSubject: ${draft.subject}\n\n${draft.body}`;
103
+ (0, helpers_1.copyToClipboard)(fullText, 'Email Draft & Diagnostics');
104
+ setCopiedDraft(true);
105
+ setTimeout(() => setCopiedDraft(false), 2000);
106
+ (0, helpers_1.showToast)('Feedback draft copied to clipboard');
107
+ };
108
+ const handleSendEmail = async () => {
109
+ if (isSending)
110
+ return;
111
+ setIsSending(true);
112
+ try {
113
+ const draft = buildEmailDraft();
114
+ const mailtoUrl = `mailto:${DEVELOPER_EMAIL}?subject=${encodeURIComponent(draft.subject)}&body=${encodeURIComponent(draft.body)}`;
115
+ (0, telemetry_1.trackTelemetryEvent)('feedback_submitted', {
116
+ category,
117
+ rating,
118
+ has_subject: Boolean(subject.trim()),
119
+ has_message: Boolean(message.trim()),
120
+ });
121
+ let opened = false;
122
+ try {
123
+ const canOpen = await react_native_1.Linking.canOpenURL(mailtoUrl);
124
+ if (canOpen) {
125
+ await react_native_1.Linking.openURL(mailtoUrl);
126
+ opened = true;
127
+ }
128
+ else {
129
+ await react_native_1.Linking.openURL(mailtoUrl);
130
+ opened = true;
131
+ }
132
+ }
133
+ catch (err) {
134
+ opened = false;
135
+ }
136
+ if (opened) {
137
+ (0, helpers_1.showToast)('Opening mail client...');
138
+ onClose();
139
+ }
140
+ else {
141
+ const fullDraft = `To: ${DEVELOPER_EMAIL}\nSubject: ${draft.subject}\n\n${draft.body}`;
142
+ (0, helpers_1.copyToClipboard)(fullDraft, 'Feedback Draft');
143
+ react_native_1.Alert.alert('Email Client Not Available', `Your feedback and diagnostics have been copied to the clipboard!\n\nYou can paste and send directly to:\n${DEVELOPER_EMAIL}`, [
144
+ {
145
+ text: 'Copy Email Address',
146
+ onPress: () => {
147
+ (0, helpers_1.copyToClipboard)(DEVELOPER_EMAIL, 'Email Address');
148
+ (0, helpers_1.showToast)('Email address copied!');
149
+ },
150
+ },
151
+ {
152
+ text: 'Done',
153
+ style: 'default',
154
+ onPress: onClose,
155
+ },
156
+ ]);
157
+ }
158
+ }
159
+ catch (err) {
160
+ console.warn('[FeedbackModal] Error sending email:', err);
161
+ }
162
+ finally {
163
+ setIsSending(false);
164
+ }
165
+ };
166
+ return (<react_native_1.View style={styles.container}>
167
+
168
+ <react_native_1.View style={styles.bannerBar}>
169
+ <react_native_1.View style={styles.bannerIconBox}>
170
+ <NetworkIcons_1.HeadphonesIcon size={18} color={AppColors_1.AppColors.purple}/>
171
+ </react_native_1.View>
172
+ <react_native_1.View style={{ flex: 1 }}>
173
+ <react_native_1.Text style={styles.bannerTitle}>Share your feedback or report an issue</react_native_1.Text>
174
+ <react_native_1.Text style={styles.bannerSub}>
175
+ Direct communication with the maintainers. Diagnostic info is auto-attached.
176
+ </react_native_1.Text>
177
+ </react_native_1.View>
178
+ </react_native_1.View>
179
+
180
+ <react_native_1.ScrollView style={styles.scrollContent} contentContainerStyle={styles.scrollInner} showsVerticalScrollIndicator={false} keyboardShouldPersistTaps="handled">
181
+
182
+ <react_native_1.Text style={styles.sectionLabel}>WHAT CAN WE HELP WITH?</react_native_1.Text>
183
+ <react_native_1.View style={styles.categoryGrid}>
184
+ {CATEGORIES.map(cat => {
185
+ const isSelected = category === cat.key;
186
+ return (<react_native_1.TouchableOpacity key={cat.key} activeOpacity={0.7} onPress={() => setCategory(cat.key)} style={[
187
+ styles.categoryChip,
188
+ isSelected && styles.categoryChipSelected,
189
+ ]}>
190
+ <react_native_1.Text style={styles.categoryIcon}>{cat.icon}</react_native_1.Text>
191
+ <react_native_1.Text style={[
192
+ styles.categoryText,
193
+ isSelected && styles.categoryTextSelected,
194
+ ]}>
195
+ {cat.label}
196
+ </react_native_1.Text>
197
+ </react_native_1.TouchableOpacity>);
198
+ })}
199
+ </react_native_1.View>
200
+
201
+
202
+ <react_native_1.View style={styles.ratingCard}>
203
+ <react_native_1.View style={styles.ratingHeader}>
204
+ <react_native_1.Text style={styles.ratingTitle}>Rate your experience</react_native_1.Text>
205
+ {rating > 0 && (<react_native_1.Text style={styles.ratingBadge}>
206
+ {RATING_LABELS[rating]}
207
+ </react_native_1.Text>)}
208
+ </react_native_1.View>
209
+ <react_native_1.View style={styles.starsRow}>
210
+ {[1, 2, 3, 4, 5].map(star => {
211
+ const filled = star <= rating;
212
+ return (<react_native_1.TouchableOpacity key={star} activeOpacity={0.7} onPress={() => setRating(star)} style={styles.starTouch}>
213
+ <NetworkIcons_1.StarIcon size={26} color={filled ? '#FFB800' : AppColors_1.AppColors.grayTextWeak}/>
214
+ </react_native_1.TouchableOpacity>);
215
+ })}
216
+ </react_native_1.View>
217
+ </react_native_1.View>
218
+
219
+
220
+ <react_native_1.Text style={styles.sectionLabel}>SUBJECT (OPTIONAL)</react_native_1.Text>
221
+ <react_native_1.View style={styles.inputWrapper}>
222
+ <react_native_1.TextInput style={styles.textInput} placeholder="Brief summary..." placeholderTextColor={AppColors_1.AppColors.grayTextWeak} value={subject} onChangeText={setSubject} maxLength={80}/>
223
+ </react_native_1.View>
224
+
225
+
226
+ <react_native_1.Text style={styles.sectionLabel}>YOUR MESSAGE / DETAILS</react_native_1.Text>
227
+ <react_native_1.View style={[styles.inputWrapper, styles.textareaWrapper]}>
228
+ <react_native_1.TextInput style={[styles.textInput, styles.textarea]} placeholder="Describe your issue, feature request, or suggestion in detail..." placeholderTextColor={AppColors_1.AppColors.grayTextWeak} value={message} onChangeText={setMessage} multiline numberOfLines={4} textAlignVertical="top"/>
229
+ </react_native_1.View>
230
+
231
+
232
+ <react_native_1.TouchableOpacity activeOpacity={0.8} onPress={() => setShowDiagnostics(!showDiagnostics)} style={styles.diagnosticsToggle}>
233
+ <react_native_1.View style={styles.diagnosticsHeader}>
234
+ <NetworkIcons_1.InfoCircleIcon size={14} color={AppColors_1.AppColors.purple}/>
235
+ <react_native_1.Text style={styles.diagnosticsTitle}>
236
+ Diagnostics & System Details (Auto-attached)
237
+ </react_native_1.Text>
238
+ </react_native_1.View>
239
+ <react_native_1.Text style={styles.diagnosticsArrow}>
240
+ {showDiagnostics ? '▲' : '▼'}
241
+ </react_native_1.Text>
242
+ </react_native_1.TouchableOpacity>
243
+
244
+ {showDiagnostics && (<react_native_1.View style={styles.diagnosticsBox}>
245
+ <react_native_1.Text style={styles.diagnosticsText}>
246
+ {getDiagnosticsText()}
247
+ </react_native_1.Text>
248
+ </react_native_1.View>)}
249
+
250
+
251
+ <react_native_1.View style={styles.recipientBadge}>
252
+ <react_native_1.Text style={styles.recipientText}>
253
+ 📧 Emails to: <react_native_1.Text style={styles.recipientHighlight}>{DEVELOPER_EMAIL}</react_native_1.Text>
254
+ </react_native_1.Text>
255
+ </react_native_1.View>
256
+ </react_native_1.ScrollView>
257
+
258
+
259
+ <react_native_1.View style={styles.footer}>
260
+ <react_native_1.TouchableOpacity activeOpacity={0.7} onPress={handleCopyDraft} style={styles.copyDraftBtn}>
261
+ {copiedDraft ? (<NetworkIcons_1.CheckIcon size={14} color={AppColors_1.AppColors.emerald500}/>) : (<NetworkIcons_1.CopyIcon size={14} color={AppColors_1.AppColors.grayText}/>)}
262
+ <react_native_1.Text style={[
263
+ styles.copyDraftBtnText,
264
+ copiedDraft && { color: AppColors_1.AppColors.emerald500 },
265
+ ]}>
266
+ {copiedDraft ? 'Copied!' : 'Copy Draft'}
267
+ </react_native_1.Text>
268
+ </react_native_1.TouchableOpacity>
269
+
270
+ <react_native_1.View style={styles.footerRight}>
271
+ <react_native_1.TouchableOpacity activeOpacity={0.7} onPress={onClose} style={styles.cancelBtn}>
272
+ <react_native_1.Text style={styles.cancelBtnText}>Cancel</react_native_1.Text>
273
+ </react_native_1.TouchableOpacity>
274
+
275
+ <react_native_1.TouchableOpacity activeOpacity={0.8} onPress={handleSendEmail} style={styles.submitBtn}>
276
+ <NetworkIcons_1.SendIcon size={16} color={AppColors_1.AppColors.white}/>
277
+ <react_native_1.Text style={styles.submitBtnText}>
278
+ {isSending ? 'Sending...' : 'Send via Email'}
279
+ </react_native_1.Text>
280
+ </react_native_1.TouchableOpacity>
281
+ </react_native_1.View>
282
+ </react_native_1.View>
283
+ </react_native_1.View>);
284
+ };
285
+ exports.FeedbackModal = FeedbackModal;
286
+ const styles = react_native_1.StyleSheet.create({
287
+ container: {
288
+ flex: 1,
289
+ backgroundColor: AppColors_1.AppColors.primaryLight,
290
+ },
291
+ bannerBar: {
292
+ flexDirection: 'row',
293
+ alignItems: 'center',
294
+ gap: 10,
295
+ backgroundColor: `${AppColors_1.AppColors.purple}12`,
296
+ paddingHorizontal: 14,
297
+ paddingVertical: 10,
298
+ borderBottomWidth: 1,
299
+ borderBottomColor: `${AppColors_1.AppColors.purple}20`,
300
+ },
301
+ bannerIconBox: {
302
+ width: 32,
303
+ height: 32,
304
+ borderRadius: 8,
305
+ backgroundColor: `${AppColors_1.AppColors.purple}20`,
306
+ alignItems: 'center',
307
+ justifyContent: 'center',
308
+ },
309
+ bannerTitle: {
310
+ fontFamily: AppFonts_1.AppFonts.interSemiBold,
311
+ fontSize: 12.5,
312
+ color: AppColors_1.AppColors.purple,
313
+ },
314
+ bannerSub: {
315
+ fontFamily: AppFonts_1.AppFonts.interRegular,
316
+ fontSize: 10.5,
317
+ color: AppColors_1.AppColors.grayText,
318
+ marginTop: 1,
319
+ },
320
+ scrollContent: {
321
+ flex: 1,
322
+ },
323
+ scrollInner: {
324
+ paddingHorizontal: 16,
325
+ paddingTop: 12,
326
+ paddingBottom: 20,
327
+ },
328
+ sectionLabel: {
329
+ fontFamily: AppFonts_1.AppFonts.interSemiBold,
330
+ fontSize: 10.5,
331
+ color: AppColors_1.AppColors.grayText,
332
+ letterSpacing: 0.8,
333
+ marginBottom: 8,
334
+ marginTop: 10,
335
+ },
336
+ categoryGrid: {
337
+ flexDirection: 'row',
338
+ flexWrap: 'wrap',
339
+ gap: 8,
340
+ paddingBottom: 4,
341
+ },
342
+ categoryChip: {
343
+ flexDirection: 'row',
344
+ alignItems: 'center',
345
+ gap: 6,
346
+ paddingVertical: 7,
347
+ paddingHorizontal: 12,
348
+ borderRadius: 8,
349
+ backgroundColor: AppColors_1.AppColors.grayBackground,
350
+ borderWidth: 1,
351
+ borderColor: AppColors_1.AppColors.dividerColor,
352
+ },
353
+ categoryChipSelected: {
354
+ backgroundColor: `${AppColors_1.AppColors.purple}15`,
355
+ borderColor: AppColors_1.AppColors.purple,
356
+ },
357
+ categoryIcon: {
358
+ fontSize: 13,
359
+ },
360
+ categoryText: {
361
+ fontFamily: AppFonts_1.AppFonts.interMedium,
362
+ fontSize: 12,
363
+ color: AppColors_1.AppColors.grayText,
364
+ },
365
+ categoryTextSelected: {
366
+ color: AppColors_1.AppColors.purple,
367
+ fontFamily: AppFonts_1.AppFonts.interSemiBold,
368
+ },
369
+ ratingCard: {
370
+ backgroundColor: AppColors_1.AppColors.grayBackground,
371
+ borderRadius: 12,
372
+ padding: 12,
373
+ marginTop: 12,
374
+ borderWidth: 1,
375
+ borderColor: AppColors_1.AppColors.dividerColor,
376
+ },
377
+ ratingHeader: {
378
+ flexDirection: 'row',
379
+ justifyContent: 'space-between',
380
+ alignItems: 'center',
381
+ marginBottom: 8,
382
+ },
383
+ ratingTitle: {
384
+ fontFamily: AppFonts_1.AppFonts.interSemiBold,
385
+ fontSize: 12.5,
386
+ color: AppColors_1.AppColors.primaryBlack,
387
+ },
388
+ ratingBadge: {
389
+ fontFamily: AppFonts_1.AppFonts.interSemiBold,
390
+ fontSize: 11,
391
+ color: '#D97706',
392
+ backgroundColor: '#FEF3C7',
393
+ paddingHorizontal: 8,
394
+ paddingVertical: 2,
395
+ borderRadius: 6,
396
+ },
397
+ starsRow: {
398
+ flexDirection: 'row',
399
+ alignItems: 'center',
400
+ gap: 12,
401
+ paddingVertical: 4,
402
+ },
403
+ starTouch: {
404
+ padding: 2,
405
+ },
406
+ inputWrapper: {
407
+ backgroundColor: AppColors_1.AppColors.grayBackground,
408
+ borderRadius: 10,
409
+ borderWidth: 1,
410
+ borderColor: AppColors_1.AppColors.dividerColor,
411
+ paddingHorizontal: 12,
412
+ paddingVertical: 8,
413
+ },
414
+ textareaWrapper: {
415
+ minHeight: 88,
416
+ paddingVertical: 10,
417
+ },
418
+ textInput: {
419
+ fontFamily: AppFonts_1.AppFonts.interRegular,
420
+ fontSize: 13,
421
+ color: AppColors_1.AppColors.primaryBlack,
422
+ padding: 0,
423
+ },
424
+ textarea: {
425
+ height: 72,
426
+ },
427
+ diagnosticsToggle: {
428
+ flexDirection: 'row',
429
+ alignItems: 'center',
430
+ justifyContent: 'space-between',
431
+ backgroundColor: `${AppColors_1.AppColors.purple}10`,
432
+ borderRadius: 8,
433
+ paddingHorizontal: 12,
434
+ paddingVertical: 9,
435
+ marginTop: 14,
436
+ borderWidth: 1,
437
+ borderColor: `${AppColors_1.AppColors.purple}25`,
438
+ },
439
+ diagnosticsHeader: {
440
+ flexDirection: 'row',
441
+ alignItems: 'center',
442
+ gap: 8,
443
+ flex: 1,
444
+ },
445
+ diagnosticsTitle: {
446
+ fontFamily: AppFonts_1.AppFonts.interMedium,
447
+ fontSize: 11.5,
448
+ color: AppColors_1.AppColors.purple,
449
+ },
450
+ diagnosticsArrow: {
451
+ fontSize: 10,
452
+ color: AppColors_1.AppColors.purple,
453
+ },
454
+ diagnosticsBox: {
455
+ backgroundColor: '#1E1B2E',
456
+ borderRadius: 8,
457
+ padding: 10,
458
+ marginTop: 6,
459
+ borderWidth: 1,
460
+ borderColor: AppColors_1.AppColors.dividerColor,
461
+ },
462
+ diagnosticsText: {
463
+ fontFamily: AppFonts_1.AppFonts.interRegular,
464
+ fontSize: 11,
465
+ color: '#E2DFEB',
466
+ lineHeight: 17,
467
+ },
468
+ recipientBadge: {
469
+ marginTop: 12,
470
+ paddingVertical: 6,
471
+ paddingHorizontal: 10,
472
+ borderRadius: 6,
473
+ backgroundColor: AppColors_1.AppColors.grayBackground,
474
+ borderWidth: 1,
475
+ borderColor: AppColors_1.AppColors.dividerColor,
476
+ alignSelf: 'flex-start',
477
+ },
478
+ recipientText: {
479
+ fontFamily: AppFonts_1.AppFonts.interRegular,
480
+ fontSize: 11,
481
+ color: AppColors_1.AppColors.grayText,
482
+ },
483
+ recipientHighlight: {
484
+ fontFamily: AppFonts_1.AppFonts.interSemiBold,
485
+ color: AppColors_1.AppColors.purple,
486
+ },
487
+ footer: {
488
+ flexDirection: 'row',
489
+ alignItems: 'center',
490
+ justifyContent: 'space-between',
491
+ paddingHorizontal: 14,
492
+ paddingTop: 10,
493
+ paddingBottom: 14,
494
+ borderTopWidth: 1,
495
+ borderTopColor: AppColors_1.AppColors.dividerColor,
496
+ backgroundColor: AppColors_1.AppColors.primaryLight,
497
+ },
498
+ copyDraftBtn: {
499
+ flexDirection: 'row',
500
+ alignItems: 'center',
501
+ gap: 5,
502
+ paddingVertical: 8,
503
+ paddingHorizontal: 10,
504
+ borderRadius: 8,
505
+ backgroundColor: AppColors_1.AppColors.grayBackground,
506
+ borderWidth: 1,
507
+ borderColor: AppColors_1.AppColors.dividerColor,
508
+ },
509
+ copyDraftBtnText: {
510
+ fontFamily: AppFonts_1.AppFonts.interMedium,
511
+ fontSize: 11.5,
512
+ color: AppColors_1.AppColors.grayText,
513
+ },
514
+ footerRight: {
515
+ flexDirection: 'row',
516
+ alignItems: 'center',
517
+ gap: 8,
518
+ },
519
+ cancelBtn: {
520
+ paddingVertical: 8,
521
+ paddingHorizontal: 14,
522
+ borderRadius: 8,
523
+ backgroundColor: AppColors_1.AppColors.grayBackground,
524
+ borderWidth: 1,
525
+ borderColor: AppColors_1.AppColors.dividerColor,
526
+ },
527
+ cancelBtnText: {
528
+ fontFamily: AppFonts_1.AppFonts.interMedium,
529
+ fontSize: 12.5,
530
+ color: AppColors_1.AppColors.grayText,
531
+ },
532
+ submitBtn: {
533
+ flexDirection: 'row',
534
+ alignItems: 'center',
535
+ gap: 6,
536
+ backgroundColor: AppColors_1.AppColors.purple,
537
+ paddingVertical: 8,
538
+ paddingHorizontal: 15,
539
+ borderRadius: 8,
540
+ shadowColor: AppColors_1.AppColors.purple,
541
+ shadowOffset: { width: 0, height: 2 },
542
+ shadowOpacity: 0.35,
543
+ shadowRadius: 6,
544
+ elevation: 4,
545
+ },
546
+ submitBtnText: {
547
+ fontFamily: AppFonts_1.AppFonts.interSemiBold,
548
+ fontSize: 12.5,
549
+ color: AppColors_1.AppColors.white,
550
+ },
551
+ });
552
+ exports.default = exports.FeedbackModal;