react-native-inapp-inspector 2.4.0 → 2.4.2

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 (231) hide show
  1. package/README.ar.md +163 -0
  2. package/README.de.md +163 -0
  3. package/README.es.md +164 -0
  4. package/README.fr.md +163 -0
  5. package/README.hi.md +163 -0
  6. package/README.ja.md +180 -0
  7. package/README.ko.md +163 -0
  8. package/README.md +340 -243
  9. package/README.pt-BR.md +163 -0
  10. package/README.ru.md +163 -0
  11. package/README.zh-CN.md +387 -0
  12. package/android/src/main/java/com/inappinspector/NetworkInspectorModule.kt +82 -21
  13. package/assets/banner_dark.svg +186 -0
  14. package/assets/banner_light.svg +186 -0
  15. package/assets/icon_circle.svg +148 -0
  16. package/assets/icon_square.svg +369 -0
  17. package/assets/inapp_inspector_icon.gif +0 -0
  18. package/assets/inapp_inspector_icon_original.gif +0 -0
  19. package/assets/social_preview.png +0 -0
  20. package/assets/walkthrough.gif +0 -0
  21. package/dist/commonjs/components/AnimatedBrandOwl.d.ts +7 -0
  22. package/dist/commonjs/components/AnimatedBrandOwl.js +175 -0
  23. package/dist/commonjs/components/AppHeaderLogo.d.ts +1 -0
  24. package/dist/commonjs/components/AppHeaderLogo.js +7 -5
  25. package/dist/commonjs/components/BrandSquareIcon.d.ts +5 -0
  26. package/dist/commonjs/components/BrandSquareIcon.js +139 -0
  27. package/dist/commonjs/components/ConsoleLogCard.d.ts +2 -1
  28. package/dist/commonjs/components/ConsoleLogCard.js +23 -39
  29. package/dist/commonjs/components/Inspector/AboutModal.js +44 -54
  30. package/dist/commonjs/components/Inspector/AnalyticsTab.js +16 -16
  31. package/dist/commonjs/components/Inspector/ConfirmationModal.d.ts +13 -0
  32. package/dist/commonjs/components/Inspector/ConfirmationModal.js +32 -0
  33. package/dist/commonjs/components/Inspector/ConsoleTab.js +15 -15
  34. package/dist/commonjs/components/Inspector/CrashTab.js +25 -23
  35. package/dist/commonjs/components/Inspector/DebuggingTab.js +17 -17
  36. package/dist/commonjs/components/Inspector/FabLauncher.js +22 -30
  37. package/dist/commonjs/components/Inspector/FeatureUnderDevNotice.js +2 -2
  38. package/dist/commonjs/components/Inspector/LanguageSelectorModal.d.ts +15 -0
  39. package/dist/commonjs/components/Inspector/LanguageSelectorModal.js +90 -0
  40. package/dist/commonjs/components/Inspector/MainScreen.js +46 -33
  41. package/dist/commonjs/components/Inspector/MediaGalleryTab.js +21 -19
  42. package/dist/commonjs/components/Inspector/MediaPreviewModal.js +85 -101
  43. package/dist/commonjs/components/Inspector/NetworkTab.js +50 -50
  44. package/dist/commonjs/components/Inspector/NpmUpdateToast.js +1 -1
  45. package/dist/commonjs/components/Inspector/PushCard.d.ts +3 -2
  46. package/dist/commonjs/components/Inspector/PushCard.js +5 -4
  47. package/dist/commonjs/components/Inspector/PushDetail.js +32 -23
  48. package/dist/commonjs/components/Inspector/PushTab.js +13 -13
  49. package/dist/commonjs/components/Inspector/ReduxDetail.js +32 -32
  50. package/dist/commonjs/components/Inspector/ReduxTab.js +14 -14
  51. package/dist/commonjs/components/Inspector/SettingsPanel.js +258 -139
  52. package/dist/commonjs/components/Inspector/SocketCard.d.ts +5 -0
  53. package/dist/commonjs/components/Inspector/SocketCard.js +116 -0
  54. package/dist/commonjs/components/Inspector/SocketDetail.d.ts +4 -0
  55. package/dist/commonjs/components/Inspector/SocketDetail.js +317 -0
  56. package/dist/commonjs/components/Inspector/SocketFilterModal.d.ts +13 -0
  57. package/dist/commonjs/components/Inspector/SocketFilterModal.js +69 -0
  58. package/dist/commonjs/components/Inspector/SocketTab.d.ts +3 -0
  59. package/dist/commonjs/components/Inspector/SocketTab.js +112 -0
  60. package/dist/commonjs/components/Inspector/StorageTab.js +34 -32
  61. package/dist/commonjs/components/Inspector/SupportModal.d.ts +7 -0
  62. package/dist/commonjs/components/Inspector/SupportModal.js +125 -0
  63. package/dist/commonjs/components/Inspector/SupportPage.d.ts +5 -0
  64. package/dist/commonjs/components/Inspector/SupportPage.js +227 -0
  65. package/dist/commonjs/components/Inspector/TabBar.js +24 -23
  66. package/dist/commonjs/components/Inspector/UpdateAvailableModal.js +24 -24
  67. package/dist/commonjs/components/JsonViewer.js +7 -7
  68. package/dist/commonjs/components/LogCard.d.ts +3 -2
  69. package/dist/commonjs/components/LogCard.js +17 -14
  70. package/dist/commonjs/components/LogSyntaxHighlighter.js +5 -5
  71. package/dist/commonjs/components/ModuleErrorBoundary.js +2 -2
  72. package/dist/commonjs/components/NetworkIcons.d.ts +15 -0
  73. package/dist/commonjs/components/NetworkIcons.js +38 -3
  74. package/dist/commonjs/components/SegmentedTabs.js +1 -1
  75. package/dist/commonjs/constants/version.d.ts +1 -1
  76. package/dist/commonjs/constants/version.js +1 -1
  77. package/dist/commonjs/customHooks/socketLogger.d.ts +26 -0
  78. package/dist/commonjs/customHooks/socketLogger.js +2 -0
  79. package/dist/commonjs/helpers/index.js +3 -3
  80. package/dist/commonjs/helpers/memoryManager.d.ts +1 -0
  81. package/dist/commonjs/helpers/memoryManager.js +1 -1
  82. package/dist/commonjs/helpers/searchQueryParser.d.ts +1 -1
  83. package/dist/commonjs/helpers/searchQueryParser.js +5 -1
  84. package/dist/commonjs/helpers/settingsStore.d.ts +1 -0
  85. package/dist/commonjs/helpers/settingsStore.js +1 -1
  86. package/dist/commonjs/helpers/shareFormatter.d.ts +3 -1
  87. package/dist/commonjs/helpers/shareFormatter.js +8 -7
  88. package/dist/commonjs/i18n/index.d.ts +99 -1
  89. package/dist/commonjs/i18n/index.js +1 -1
  90. package/dist/commonjs/i18n/locales/ar.json +1 -1
  91. package/dist/commonjs/i18n/locales/bn.json +1 -0
  92. package/dist/commonjs/i18n/locales/de.json +1 -1
  93. package/dist/commonjs/i18n/locales/en.json +1 -1
  94. package/dist/commonjs/i18n/locales/es.json +1 -1
  95. package/dist/commonjs/i18n/locales/fr.json +1 -1
  96. package/dist/commonjs/i18n/locales/gu.json +1 -0
  97. package/dist/commonjs/i18n/locales/hi.json +1 -1
  98. package/dist/commonjs/i18n/locales/id.json +1 -0
  99. package/dist/commonjs/i18n/locales/it.json +1 -0
  100. package/dist/commonjs/i18n/locales/ja.json +1 -1
  101. package/dist/commonjs/i18n/locales/kn.json +1 -0
  102. package/dist/commonjs/i18n/locales/ko.json +1 -1
  103. package/dist/commonjs/i18n/locales/ml.json +1 -0
  104. package/dist/commonjs/i18n/locales/mr.json +1 -0
  105. package/dist/commonjs/i18n/locales/nl.json +1 -0
  106. package/dist/commonjs/i18n/locales/pa.json +1 -0
  107. package/dist/commonjs/i18n/locales/pl.json +1 -0
  108. package/dist/commonjs/i18n/locales/pt.json +1 -1
  109. package/dist/commonjs/i18n/locales/ru.json +1 -1
  110. package/dist/commonjs/i18n/locales/ta.json +1 -0
  111. package/dist/commonjs/i18n/locales/te.json +1 -0
  112. package/dist/commonjs/i18n/locales/tr.json +1 -0
  113. package/dist/commonjs/i18n/locales/vi.json +1 -0
  114. package/dist/commonjs/i18n/locales/zh.json +1 -1
  115. package/dist/commonjs/index.d.ts +13 -13
  116. package/dist/commonjs/index.js +5 -4
  117. package/dist/commonjs/native/NativeInspector.d.ts +1 -0
  118. package/dist/commonjs/socket.d.ts +4 -0
  119. package/dist/commonjs/socket.js +1 -0
  120. package/dist/commonjs/styles/index.d.ts +23 -0
  121. package/dist/commonjs/styles/index.js +1 -1
  122. package/dist/commonjs/types/enums.d.ts +40 -0
  123. package/dist/commonjs/types/enums.js +1 -1
  124. package/dist/commonjs/types/interfaces.d.ts +122 -1
  125. package/dist/esm/components/AnimatedBrandOwl.d.ts +7 -0
  126. package/dist/esm/components/AnimatedBrandOwl.js +175 -0
  127. package/dist/esm/components/AppHeaderLogo.d.ts +1 -0
  128. package/dist/esm/components/AppHeaderLogo.js +7 -5
  129. package/dist/esm/components/BrandSquareIcon.d.ts +5 -0
  130. package/dist/esm/components/BrandSquareIcon.js +139 -0
  131. package/dist/esm/components/ConsoleLogCard.d.ts +2 -1
  132. package/dist/esm/components/ConsoleLogCard.js +61 -77
  133. package/dist/esm/components/Inspector/AboutModal.js +85 -95
  134. package/dist/esm/components/Inspector/AnalyticsTab.js +31 -31
  135. package/dist/esm/components/Inspector/ConfirmationModal.d.ts +13 -0
  136. package/dist/esm/components/Inspector/ConfirmationModal.js +32 -0
  137. package/dist/esm/components/Inspector/ConsoleTab.js +49 -49
  138. package/dist/esm/components/Inspector/CrashTab.js +40 -38
  139. package/dist/esm/components/Inspector/DebuggingTab.js +29 -29
  140. package/dist/esm/components/Inspector/FabLauncher.js +50 -58
  141. package/dist/esm/components/Inspector/FeatureUnderDevNotice.js +7 -7
  142. package/dist/esm/components/Inspector/LanguageSelectorModal.d.ts +15 -0
  143. package/dist/esm/components/Inspector/LanguageSelectorModal.js +90 -0
  144. package/dist/esm/components/Inspector/MainScreen.js +123 -110
  145. package/dist/esm/components/Inspector/MediaGalleryTab.js +64 -62
  146. package/dist/esm/components/Inspector/MediaPreviewModal.js +107 -123
  147. package/dist/esm/components/Inspector/NetworkTab.js +90 -90
  148. package/dist/esm/components/Inspector/NpmUpdateToast.js +1 -1
  149. package/dist/esm/components/Inspector/PushCard.d.ts +3 -2
  150. package/dist/esm/components/Inspector/PushCard.js +23 -22
  151. package/dist/esm/components/Inspector/PushDetail.js +34 -25
  152. package/dist/esm/components/Inspector/PushTab.js +25 -25
  153. package/dist/esm/components/Inspector/ReduxDetail.js +42 -42
  154. package/dist/esm/components/Inspector/ReduxTab.js +35 -35
  155. package/dist/esm/components/Inspector/SettingsPanel.js +495 -376
  156. package/dist/esm/components/Inspector/SocketCard.d.ts +5 -0
  157. package/dist/esm/components/Inspector/SocketCard.js +116 -0
  158. package/dist/esm/components/Inspector/SocketDetail.d.ts +4 -0
  159. package/dist/esm/components/Inspector/SocketDetail.js +317 -0
  160. package/dist/esm/components/Inspector/SocketFilterModal.d.ts +13 -0
  161. package/dist/esm/components/Inspector/SocketFilterModal.js +69 -0
  162. package/dist/esm/components/Inspector/SocketTab.d.ts +3 -0
  163. package/dist/esm/components/Inspector/SocketTab.js +112 -0
  164. package/dist/esm/components/Inspector/StorageTab.js +136 -134
  165. package/dist/esm/components/Inspector/SupportModal.d.ts +7 -0
  166. package/dist/esm/components/Inspector/SupportModal.js +125 -0
  167. package/dist/esm/components/Inspector/SupportPage.d.ts +5 -0
  168. package/dist/esm/components/Inspector/SupportPage.js +227 -0
  169. package/dist/esm/components/Inspector/TabBar.js +36 -35
  170. package/dist/esm/components/Inspector/UpdateAvailableModal.js +22 -22
  171. package/dist/esm/components/JsonViewer.js +55 -55
  172. package/dist/esm/components/LogCard.d.ts +3 -2
  173. package/dist/esm/components/LogCard.js +61 -58
  174. package/dist/esm/components/LogSyntaxHighlighter.js +5 -5
  175. package/dist/esm/components/ModuleErrorBoundary.js +23 -23
  176. package/dist/esm/components/NetworkIcons.d.ts +15 -0
  177. package/dist/esm/components/NetworkIcons.js +38 -3
  178. package/dist/esm/components/SegmentedTabs.js +7 -7
  179. package/dist/esm/constants/version.d.ts +1 -1
  180. package/dist/esm/constants/version.js +1 -1
  181. package/dist/esm/customHooks/socketLogger.d.ts +26 -0
  182. package/dist/esm/customHooks/socketLogger.js +2 -0
  183. package/dist/esm/helpers/index.js +3 -3
  184. package/dist/esm/helpers/memoryManager.d.ts +1 -0
  185. package/dist/esm/helpers/memoryManager.js +1 -1
  186. package/dist/esm/helpers/searchQueryParser.d.ts +1 -1
  187. package/dist/esm/helpers/searchQueryParser.js +5 -1
  188. package/dist/esm/helpers/settingsStore.d.ts +1 -0
  189. package/dist/esm/helpers/settingsStore.js +1 -1
  190. package/dist/esm/helpers/shareFormatter.d.ts +3 -1
  191. package/dist/esm/helpers/shareFormatter.js +8 -7
  192. package/dist/esm/i18n/index.d.ts +99 -1
  193. package/dist/esm/i18n/index.js +1 -1
  194. package/dist/esm/i18n/locales/ar.json +1 -1
  195. package/dist/esm/i18n/locales/bn.json +1 -0
  196. package/dist/esm/i18n/locales/de.json +1 -1
  197. package/dist/esm/i18n/locales/en.json +1 -1
  198. package/dist/esm/i18n/locales/es.json +1 -1
  199. package/dist/esm/i18n/locales/fr.json +1 -1
  200. package/dist/esm/i18n/locales/gu.json +1 -0
  201. package/dist/esm/i18n/locales/hi.json +1 -1
  202. package/dist/esm/i18n/locales/id.json +1 -0
  203. package/dist/esm/i18n/locales/it.json +1 -0
  204. package/dist/esm/i18n/locales/ja.json +1 -1
  205. package/dist/esm/i18n/locales/kn.json +1 -0
  206. package/dist/esm/i18n/locales/ko.json +1 -1
  207. package/dist/esm/i18n/locales/ml.json +1 -0
  208. package/dist/esm/i18n/locales/mr.json +1 -0
  209. package/dist/esm/i18n/locales/nl.json +1 -0
  210. package/dist/esm/i18n/locales/pa.json +1 -0
  211. package/dist/esm/i18n/locales/pl.json +1 -0
  212. package/dist/esm/i18n/locales/pt.json +1 -1
  213. package/dist/esm/i18n/locales/ru.json +1 -1
  214. package/dist/esm/i18n/locales/ta.json +1 -0
  215. package/dist/esm/i18n/locales/te.json +1 -0
  216. package/dist/esm/i18n/locales/tr.json +1 -0
  217. package/dist/esm/i18n/locales/vi.json +1 -0
  218. package/dist/esm/i18n/locales/zh.json +1 -1
  219. package/dist/esm/index.d.ts +13 -13
  220. package/dist/esm/index.js +8 -7
  221. package/dist/esm/native/NativeInspector.d.ts +1 -0
  222. package/dist/esm/socket.d.ts +4 -0
  223. package/dist/esm/socket.js +1 -0
  224. package/dist/esm/styles/index.d.ts +23 -0
  225. package/dist/esm/styles/index.js +1 -1
  226. package/dist/esm/types/enums.d.ts +40 -0
  227. package/dist/esm/types/enums.js +1 -1
  228. package/dist/esm/types/interfaces.d.ts +122 -1
  229. package/ios/NetworkInspectorModule.mm +102 -12
  230. package/package.json +204 -2
  231. package/src/native/NativeInspector.ts +8 -0
@@ -0,0 +1,112 @@
1
+ import ce,{useCallback as b,useMemo as P,useRef as Ve,useState as B}from"react";import{FlatList as Ae,Platform as Le,Pressable as De,ScrollView as Pe,Share as ve,StyleSheet as Ee,Text as T,TextInput as Oe,TouchableOpacity as E,View as S}from"react-native";import{useInspector as Me}from"./InspectorContext";import $e from"./SocketCard";import He,{DEFAULT_SOCKET_FILTERS as _e,isSocketFiltersDefault as O}from"./SocketFilterModal";import{ConfirmationModal as Ue}from"./ConfirmationModal";import A from"../TouchableScale";import Ne from"../AnimatedEntrance";import Qe from"../EmptyState";import Ke from"../EndOfListFooter";import k from"../../styles";import{AppColors as t}from"../../styles/AppColors";import{AppFonts as x}from"../../styles/AppFonts";import{useTranslation as qe}from"../../i18n";import{copyToClipboard as Ge}from"../../helpers";import{showToast as M}from"../../helpers/toast";import{ClearIcon as Je,SearchIcon as Xe,TrashIcon as Se,WebsocketIcon as Ye,BoltIcon as U,FilterIcon as Ze,GlobeIcon as St,LockIcon as Ct,ClockIcon as Tt,FailIcon as Bt,CopyIcon as It,ShareIcon as Rt}from"../NetworkIcons";const Wt=10,Ft=ce.memo(()=>{const{t:s}=qe(),{socketRecords:R,filteredSocketRecords:j,socketSearch:C,setSocketSearch:$,socketQuickFilter:z,setSocketQuickFilter:N,setSelectedSocket:Q,clearAllSocketLogs:K,deleteMultipleSocketRecords:q,simulateSocket:G,maxSocketLogs:H}=Me(),ye=H||50,J=Ve(null),[X,be]=B(0),[L,Y]=B(ye),[Ce,Z]=B(!1),[y,ke]=B(_e),[n,W]=B(new Set),[ee,te]=B(!1),[I,F]=B({visible:!1,title:"",message:"",onConfirm:()=>{}});ce.useEffect(()=>{Y(H||50),J.current?.scrollToOffset({offset:0,animated:!1})},[C,z,H]);const oe=["chat","crypto","socketio","echo"],le=b(()=>{const e=oe[X%oe.length];G(e),be(o=>o+1),M(`Simulated ${e.toUpperCase()} WebSocket`)},[X,G]),w=P(()=>{let e=0,o=0,l=0,ie=0,ne=0,ae=0;return R.forEach(D=>{const _=(D.status||"open").toLowerCase();_==="open"?e++:_==="closed"?o++:_==="error"&&l++,D.client==="socket.io"||D.url.includes("/socket.io")?ae++:D.url.startsWith("wss://")?ie++:ne++}),{all:R.length,open:e,closed:o,error:l,wss:ie,ws:ne,sio:ae}},[R]),i=P(()=>{let e=j;return O(y)||(y.status.has("all")||(e=e.filter(o=>y.status.has(o.status||"open"))),y.types.has("all")||(e=e.filter(o=>!!(y.types.has("sio")&&(o.client==="socket.io"||o.url.includes("/socket.io"))||y.types.has("wss")&&o.url.startsWith("wss://")||y.types.has("ws")&&o.url.startsWith("ws://")))),y.sortBy==="time_asc"?e=[...e].sort((o,l)=>o.startTime-l.startTime):y.sortBy==="frames_desc"?e=[...e].sort((o,l)=>(l.frames?.length||0)-(o.frames?.length||0)):y.sortBy==="duration_desc"&&(e=[...e].sort((o,l)=>(l.duration||0)-(o.duration||0)))),e},[j,y]),V=P(()=>i.slice(0,L),[i,L]),re=b(e=>{W(o=>{const l=new Set(o);return l.has(e)?l.delete(e):l.add(e),l})},[]),Te=b(()=>{n.size===i.length?W(new Set):W(new Set(i.map(e=>e.id)))},[n.size,i]),we=b(()=>{const e=i.filter(l=>n.has(l.id));if(e.length===0)return;const o=e.map(l=>l.url).join(`
2
+ `);Ge(o,`${e.length} WebSocket URLs`),M(`${e.length} URLs copied to clipboard`)},[i,n]),xe=b(async()=>{const e=i.filter(o=>n.has(o.id));if(e.length!==0)try{const o=JSON.stringify(e.map(l=>({url:l.url,status:l.status,startTime:new Date(l.startTime).toISOString(),duration:l.duration,framesCount:l.frames?.length||0,totalBytesSent:l.totalBytesSent,totalBytesReceived:l.totalBytesReceived})),null,2);await ve.share({message:o,title:`WebSocket Traffic (${e.length} connections)`})}catch{}},[i,n]),Be=b(()=>{n.size!==0&&F({visible:!0,title:s("socket.deleteSelectedTitle","Delete Selected WebSockets"),message:s("socket.deleteSelectedMsg",{count:n.size,defaultValue:`Are you sure you want to delete ${n.size} selected WebSocket logs?`}),confirmText:s("common.delete","Delete"),cancelText:s("common.cancel","Cancel"),onConfirm:()=>{F(o=>({...o,visible:!1}));const e=Array.from(n);q?.(e),W(new Set),M(`Deleted ${e.length} WebSocket logs`)}})},[n,q,s]),ze=b(()=>{F({visible:!0,title:s("socket.clearTitle","Clear All WebSocket Logs"),message:s("socket.clearMessage","Are you sure you want to delete all recorded WebSocket sessions?"),confirmText:s("common.clear","Clear All"),cancelText:s("common.cancel","Cancel"),onConfirm:()=>{F(e=>({...e,visible:!1})),K(),W(new Set),M(s("socket.cleared","All WebSocket logs cleared"))}})},[K,s]),Ie=P(()=>[{id:"all",label:"All",count:w.all,color:t.purple,icon:e=><Ye size={12}color={e}/>},{id:"open",label:"Open",count:w.open,color:t.greenColor,icon:e=><S style={{width:6,height:6,borderRadius:3,backgroundColor:e}}/>},{id:"closed",label:"Closed",count:w.closed,color:t.slate500,icon:e=><Tt size={11}color={e}/>},{id:"error",label:"Error",count:w.error,color:t.errorColor,icon:e=><Bt size={9}color={e}/>},{id:"sio",label:"Socket.IO",count:w.sio,color:t.violet600,icon:e=><U size={11}color={e}/>},{id:"wss",label:"WSS",count:w.wss,color:t.emerald600,icon:e=><Ct size={11}color={e}/>},{id:"ws",label:"WS",count:w.ws,color:t.blue600,icon:e=><St size={11}color={e}/>}],[w]),Re=b(()=>{L<i.length&&Y(e=>Math.min(e+Wt,i.length))},[L,i.length]),se=b(e=>{Q(e)},[Q]),We=b(e=>e?.id?String(e.id):"",[]),Fe=b(({item:e,index:o})=><Ne index={o}distance={8}>
3
+ <$e item={e}onPress={()=>se(e)}searchStr={C}isSelected={n.has(e.id)}onToggleSelect={re}serialNumber={o+1}/>
4
+ </Ne>,[C,n,re,se]);return<S style={{flex:1,backgroundColor:t.primaryLight}}>
5
+
6
+ <S style={{marginTop:6}}>
7
+ <S style={k.toolbarRow}>
8
+ <S style={[k.searchContainer,{flex:1,marginRight:8,height:38},ee&&{borderColor:t.purple,borderWidth:1.5}]}>
9
+ <S style={k.searchIcon}>
10
+ <Xe color={ee?t.purple:t.grayTextWeak}size={15}/>
11
+ </S>
12
+ <Oe style={[k.searchInput,{paddingVertical:0}]}placeholder={s("socket.searchSocketsPlaceholder","Search WebSocket URL, payload...")}placeholderTextColor={t.grayTextWeak}value={C}onChangeText={$}onFocus={()=>te(!0)}onBlur={()=>te(!1)}autoCorrect={!1}autoCapitalize="none"returnKeyType="search"clearButtonMode="while-editing"/>
13
+ {C.length>0&&<S style={{flexDirection:"row",alignItems:"center",gap:4,marginRight:6}}>
14
+ <S style={{backgroundColor:`${t.purple}20`,borderRadius:10,paddingHorizontal:6,paddingVertical:1.5}}>
15
+ <T style={{color:t.purple,fontSize:9.5,fontFamily:x.interBold}}>
16
+ {i.length}
17
+ </T>
18
+ </S>
19
+ {Le.OS==="android"&&<De onPress={()=>$("")}hitSlop={10}style={k.clearBtn}>
20
+ <Je color={t.grayTextWeak}size={13}/>
21
+ </De>}
22
+ </S>}
23
+ </S>
24
+
25
+ <S style={k.toolbarRight}>
26
+ <A style={[k.toolbarBtn,!O(y)&&{borderColor:t.purple,backgroundColor:`${t.purple}15`}]}onPress={()=>Z(!0)}hitSlop={6}accessibilityRole="button"accessibilityLabel="Filter WebSockets">
27
+ <Ze color={O(y)?t.grayTextStrong:t.purple}size={15}/>
28
+ {!O(y)&&<S style={k.activeFilterDot}/>}
29
+ </A>
30
+
31
+ <A style={[k.toolbarBtn,{backgroundColor:`${t.amber600}14`,borderColor:`${t.amber600}30`}]}onPress={le}hitSlop={6}accessibilityRole="button"accessibilityLabel="Simulate test WebSocket traffic">
32
+ <U color={t.amber600}size={15}/>
33
+ </A>
34
+
35
+ {R.length>0&&<A style={[k.toolbarBtn,{borderColor:`${t.errorColor}38`,backgroundColor:`${t.errorColor}0F`}]}onPress={ze}hitSlop={6}accessibilityRole="button"accessibilityLabel="Clear all socket logs">
36
+ <Se color={t.errorColor}size={15}/>
37
+ </A>}
38
+ </S>
39
+ </S>
40
+ </S>
41
+
42
+
43
+ <S style={r.carouselWrapper}>
44
+ <Pe horizontal showsHorizontalScrollIndicator={!1}contentContainerStyle={r.carouselContent}>
45
+ {Ie.map(e=>{const o=z===e.id;return<A key={e.id}onPress={()=>N(e.id)}style={[r.filterPill,o&&{backgroundColor:e.color,borderColor:e.color}]}>
46
+ {e.icon?e.icon(o?t.white:e.color):null}
47
+ <T style={[r.filterPillText,o&&{color:t.white,fontFamily:x.interBold}]}>
48
+ {e.label}
49
+ </T>
50
+ {e.count>0&&<S style={[r.countBadge,{backgroundColor:o?"rgba(255, 255, 255, 0.25)":`${e.color}20`}]}>
51
+ <T style={[r.countBadgeText,{color:o?t.white:e.color}]}>
52
+ {e.count>99?"99+":e.count}
53
+ </T>
54
+ </S>}
55
+ </A>})}
56
+ </Pe>
57
+ </S>
58
+
59
+
60
+ {n.size>0&&<S style={r.selectionBar}>
61
+ <S style={r.selectionLeft}>
62
+ <E onPress={Te}style={r.selectAllBtn}hitSlop={{top:6,bottom:6,left:6,right:6}}>
63
+ <T style={r.selectAllText}>
64
+ {n.size===i.length?s("common.deselectAll","Deselect"):s("common.selectAll","Select All")}
65
+ </T>
66
+ </E>
67
+
68
+ <T style={r.selectionCountText}>
69
+ {n.size} / {i.length}
70
+ </T>
71
+ </S>
72
+
73
+ <S style={r.selectionRight}>
74
+ <E onPress={we}style={r.actionBtn}hitSlop={{top:6,bottom:6,left:6,right:6}}>
75
+ <It size={12}color={t.slate600}/>
76
+ <T style={r.actionBtnText}>
77
+ {s("common.copy","Copy")}
78
+ </T>
79
+ </E>
80
+
81
+ <E onPress={xe}style={r.actionBtn}hitSlop={{top:6,bottom:6,left:6,right:6}}>
82
+ <Rt size={12}color={t.sky600}/>
83
+ <T style={[r.actionBtnText,{color:t.sky600}]}>
84
+ {s("common.share","Share")}
85
+ </T>
86
+ </E>
87
+
88
+ <E onPress={Be}style={[r.actionBtn,r.deleteActionBtn]}hitSlop={{top:6,bottom:6,left:6,right:6}}>
89
+ <Se size={12}color={t.red500}/>
90
+ <T style={[r.actionBtnText,{color:t.red500}]}>
91
+ {s("common.delete","Delete")}
92
+ </T>
93
+ </E>
94
+ </S>
95
+ </S>}
96
+
97
+
98
+ <Ae ref={J}data={V}keyExtractor={We}renderItem={Fe}initialNumToRender={10}maxToRenderPerBatch={8}windowSize={5}updateCellsBatchingPeriod={40}removeClippedSubviews={!0}renderToHardwareTextureAndroid={!0}contentContainerStyle={[r.listContent,V.length===0&&{flex:1}]}showsVerticalScrollIndicator={!1}ListEmptyComponent={<S style={r.emptyWrapper}>
99
+ <Qe isSearch={!!(C||z!=="all")}searchQuery={C}customTitle={C||z!=="all"?s("socket.noMatching","No matching WebSockets"):s("socket.noSockets","No WebSockets recorded yet")}customSub={C||z!=="all"?s("socket.adjustSearchFilter","Try adjusting your search query or filter chips."):s("socket.noSocketsDesc","WebSocket connections and Socket.IO messages will appear here in real-time.")}onClearSearch={()=>{$(""),N("all")}}showReload={!1}/>
100
+ {!C&&z==="all"&&<A onPress={le}style={r.simulateEmptyBtn}>
101
+ <U color={t.white}size={14}/>
102
+ <T style={r.simulateEmptyBtnText}>
103
+ {s("socket.simulateTraffic","Simulate Demo WebSocket Traffic")}
104
+ </T>
105
+ </A>}
106
+ </S>}ListFooterComponent={V.length>0?<Ke totalCount={i.length}count={V.length}hasMore={V.length<i.length}onLoadMore={Re}/>:null}/>
107
+
108
+
109
+ <He visible={Ce}onClose={()=>Z(!1)}filters={y}onApply={ke}records={R}/>
110
+
111
+ <Ue visible={I.visible}title={I.title}message={I.message}confirmText={I.confirmText}cancelText={I.cancelText}isDestructive={!0}icon="trash"onConfirm={I.onConfirm}onCancel={()=>F(e=>({...e,visible:!1}))}/>
112
+ </S>});export default Ft;const r=Ee.create({carouselWrapper:{paddingVertical:6,borderBottomWidth:1,borderBottomColor:t.dividerColor,backgroundColor:t.white},carouselContent:{paddingHorizontal:8,gap:6,flexDirection:"row",alignItems:"center"},filterPill:{flexDirection:"row",alignItems:"center",gap:5,paddingHorizontal:9,paddingVertical:4.5,borderRadius:20,backgroundColor:t.grayBackground,borderWidth:1,borderColor:t.dividerColor},filterPillText:{fontSize:11,fontFamily:x.interMedium,color:t.primaryBlack},countBadge:{paddingHorizontal:5,paddingVertical:1,borderRadius:10},countBadgeText:{fontSize:9.5,fontFamily:x.interBold},selectionBar:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingHorizontal:12,paddingVertical:7,backgroundColor:`${t.purple}0D`,borderBottomWidth:1,borderBottomColor:`${t.purple}25`},selectionLeft:{flexDirection:"row",alignItems:"center",gap:8},selectAllBtn:{paddingHorizontal:7,paddingVertical:3,borderRadius:5,backgroundColor:`${t.purple}1E`},selectAllText:{fontFamily:x.interSemiBold,fontSize:10.5,color:t.purple},selectionCountText:{fontFamily:x.interMedium,fontSize:11,color:t.grayTextStrong},selectionRight:{flexDirection:"row",alignItems:"center",gap:6},actionBtn:{flexDirection:"row",alignItems:"center",gap:4,paddingHorizontal:7,paddingVertical:3.5,borderRadius:5,backgroundColor:t.white,borderWidth:1,borderColor:t.dividerColor},deleteActionBtn:{backgroundColor:`${t.red500}10`,borderColor:`${t.red500}30`},actionBtnText:{fontFamily:x.interMedium,fontSize:10.5,color:t.grayTextStrong},listContent:{padding:6,paddingBottom:24},emptyWrapper:{flex:1,alignItems:"center",justifyContent:"center",paddingVertical:20},simulateEmptyBtn:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:6,marginTop:14,paddingHorizontal:16,paddingVertical:10,borderRadius:10,backgroundColor:t.amber600,shadowColor:t.amber600,shadowOffset:{width:0,height:2},shadowOpacity:.25,shadowRadius:4,elevation:3},simulateEmptyBtnText:{fontFamily:x.interBold,fontSize:12,color:t.white,letterSpacing:.2}});
@@ -1,209 +1,211 @@
1
- import we,{useState as z,useEffect as je,useMemo as N,useCallback as oe,useRef as Je}from"react";import{View as S,Text as C,ScrollView as Ge,FlatList as Ue,TextInput as Se,Modal as Ye,Alert as ke,StyleSheet as _e,ActivityIndicator as Qe,Platform as ve}from"react-native";import V from"../TouchableScale";import Xe from"../EndOfListFooter";import{AppColors as e}from"../../styles/AppColors";import{AppFonts as T}from"../../styles/AppFonts";import{useTranslation as Ze}from"../../i18n";import{DatabaseIcon as Ve,SearchIcon as St,ClearIcon as Ie,PlusIcon as Tt,PencilIcon as Ct,TrashIcon as Pe,CopyIcon as Bt,CheckIcon as Vt,LayersIcon as It,ResetIcon as Pt,ChevronIcon as At,WarningTriangleIcon as Ft}from"../NetworkIcons";import{fetchStorageEntries as Mt,setStorageEntry as Lt,removeStorageEntry as $t,clearStorageDriver as Dt,getRegisteredMMKVInstanceIds as Rt,subscribeToStorageChanges as Wt}from"../../customHooks/storageInspector";import{copyToClipboard as Kt}from"../../helpers";import{showToast as $}from"../../helpers/toast";const Et=w=>{switch(w){case"json":return{label:"JSON",color:e.purple,bg:`${e.purple}16`};case"number":return{label:"NUM",color:e.warningIconGold,bg:`${e.warningIconGold}16`};case"boolean":return{label:"BOOL",color:e.emerald500,bg:`${e.emerald500}16`};case"null":return{label:"NULL",color:e.grayTextWeak,bg:`${e.grayTextWeak}16`};default:return{label:"STR",color:e.blue500,bg:`${e.blue500}16`}}},Ot=we.memo(function({entry:B,isExpanded:r,onToggleExpand:J,onCopy:F,onEdit:q,onDelete:I,badge:D}){const Q=N(()=>B.byteSize<1024?`${B.byteSize.toLocaleString()} B`:`${(B.byteSize/1024).toLocaleString(void 0,{minimumFractionDigits:1,maximumFractionDigits:1})} KB`,[B.byteSize]),G=N(()=>{if(!r)return B.value.length>250?B.value.slice(0,250)+"...":B.value;if(B.type==="json")try{const A=B.parsedValue??JSON.parse(B.value);return JSON.stringify(A,null,2)}catch{return B.value}return B.value},[r,B.value,B.type,B.parsedValue]);return<S style={t.entryCard}>
1
+ import Be,{useState as k,useEffect as we,useMemo as O,useCallback as te,useRef as Je}from"react";import{View as T,Text as C,ScrollView as Ge,FlatList as Ue,TextInput as Te,Modal as _e,StyleSheet as Ye,ActivityIndicator as Qe,Platform as Ze}from"react-native";import B from"../TouchableScale";import Xe from"../EndOfListFooter";import{ConfirmationModal as Tt}from"./ConfirmationModal";import{AppColors as e}from"../../styles/AppColors";import{AppFonts as h}from"../../styles/AppFonts";import{useTranslation as ht}from"../../i18n";import{DatabaseIcon as Ve,SearchIcon as Ct,ClearIcon as Ie,PlusIcon as St,PencilIcon as Bt,TrashIcon as Pe,CopyIcon as Vt,CheckIcon as It,LayersIcon as Pt,ResetIcon as At,ChevronIcon as Mt,WarningTriangleIcon as Ft}from"../NetworkIcons";import{fetchStorageEntries as Lt,setStorageEntry as Dt,removeStorageEntry as $t,clearStorageDriver as Rt,getRegisteredMMKVInstanceIds as Et,subscribeToStorageChanges as Wt}from"../../customHooks/storageInspector";import{copyToClipboard as Kt}from"../../helpers";import{showToast as M}from"../../helpers/toast";const Ot=S=>{switch(S){case"json":return{label:"JSON",color:e.purple,bg:`${e.purple}16`};case"number":return{label:"NUM",color:e.warningIconGold,bg:`${e.warningIconGold}16`};case"boolean":return{label:"BOOL",color:e.emerald500,bg:`${e.emerald500}16`};case"null":return{label:"NULL",color:e.grayTextWeak,bg:`${e.grayTextWeak}16`};default:return{label:"STR",color:e.blue500,bg:`${e.blue500}16`}}},Nt=Be.memo(function({entry:x,isExpanded:r,onToggleExpand:j,onCopy:z,onEdit:Y,onDelete:V,badge:F}){const q=O(()=>x.byteSize<1024?`${x.byteSize.toLocaleString()} B`:`${(x.byteSize/1024).toLocaleString(void 0,{minimumFractionDigits:1,maximumFractionDigits:1})} KB`,[x.byteSize]),J=O(()=>{if(!r)return x.value.length>250?x.value.slice(0,250)+"...":x.value;if(x.type==="json")try{const I=x.parsedValue??JSON.parse(x.value);return JSON.stringify(I,null,2)}catch{return x.value}return x.value},[r,x.value,x.type,x.parsedValue]);return<T style={t.entryCard}>
2
2
 
3
- <S style={t.entryHeader}>
4
- <S style={{flex:1,marginRight:8}}>
5
- <S style={{flexDirection:"row",alignItems:"center",gap:6,flexWrap:"wrap"}}>
3
+ <T style={t.entryHeader}>
4
+ <T style={{flex:1,marginRight:8}}>
5
+ <T style={{flexDirection:"row",alignItems:"center",gap:6,flexWrap:"wrap"}}>
6
6
  <C style={t.entryKey}numberOfLines={1}selectable>
7
- {B.key}
7
+ {x.key}
8
8
  </C>
9
- <S style={[t.typeBadge,{backgroundColor:D.bg,borderColor:`${D.color}33`}]}>
10
- <C style={[t.typeBadgeText,{color:D.color}]}>
11
- {D.label}
9
+ <T style={[t.typeBadge,{backgroundColor:F.bg,borderColor:`${F.color}33`}]}>
10
+ <C style={[t.typeBadgeText,{color:F.color}]}>
11
+ {F.label}
12
12
  </C>
13
- </S>
14
- <C style={t.sizeText}>{Q}</C>
15
- </S>
16
- </S>
13
+ </T>
14
+ <C style={t.sizeText}>{q}</C>
15
+ </T>
16
+ </T>
17
17
 
18
18
 
19
- <S style={t.entryActions}>
20
- <V hitSlop={6}onPress={()=>F(B)}style={t.entryActionBtn}>
21
- <Bt size={12}color={e.grayText}/>
22
- </V>
19
+ <T style={t.entryActions}>
20
+ <B hitSlop={6}onPress={()=>z(x)}style={t.entryActionBtn}>
21
+ <Vt size={12}color={e.grayText}/>
22
+ </B>
23
23
 
24
- <V hitSlop={6}onPress={()=>q(B)}style={t.entryActionBtn}>
25
- <Ct size={12}color={e.purple}/>
26
- </V>
24
+ <B hitSlop={6}onPress={()=>Y(x)}style={t.entryActionBtn}>
25
+ <Bt size={12}color={e.purple}/>
26
+ </B>
27
27
 
28
- <V hitSlop={6}onPress={()=>I(B.key)}style={[t.entryActionBtn,{backgroundColor:`${e.errorColor}12`}]}>
28
+ <B hitSlop={6}onPress={()=>V(x.key)}style={[t.entryActionBtn,{backgroundColor:`${e.errorColor}12`}]}>
29
29
  <Pe size={12}color={e.errorColor}/>
30
- </V>
31
- </S>
32
- </S>
30
+ </B>
31
+ </T>
32
+ </T>
33
33
 
34
34
 
35
- <V onPress={()=>J(B.key)}style={t.valuePreviewBox}>
35
+ <B onPress={()=>j(x.key)}style={t.valuePreviewBox}>
36
36
  <C style={t.valuePreviewText}numberOfLines={r?void 0:3}selectable={r}>
37
- {G}
37
+ {J}
38
38
  </C>
39
- {B.value.length>80&&<S style={{flexDirection:"row",alignItems:"center",gap:4,marginTop:4}}>
39
+ {x.value.length>80&&<T style={{flexDirection:"row",alignItems:"center",gap:4,marginTop:4}}>
40
40
  <C style={t.expandHint}>
41
41
  {r?"Collapse":"Expand"}
42
42
  </C>
43
- <At direction={r?"up":"down"}size={10}color={e.purple}/>
44
- </S>}
45
- </V>
46
- </S>});export const StorageTab=we.memo(()=>{const{t:w}=Ze(),B=Je(null),[r,J]=z("asyncStorage"),[F,q]=z("default"),[I,D]=z([]),[Q,G]=z(!0),[A,X]=z(""),[Z,Ae]=z(100),[Te,Fe]=z({}),[Me,K]=z(!1),[U,xe]=z("create"),[E,ee]=z(""),[H,Y]=z(""),[R,_]=z("string"),[te,M]=z(null),Ce=N(()=>Rt(),[]),W=oe(async()=>{G(!0);try{const o=await Mt(r,r==="mmkv"?F:void 0);D(o)}catch{D([])}finally{G(!1)}},[r,F]);je(()=>(W(),Wt(W)),[W]);const Le=o=>{Fe(P=>({...P,[o]:!P[o]}))},$e=()=>{xe("create"),ee(""),Y(""),_("string"),M(null),K(!0)},De=o=>{xe("edit"),ee(o.key),Y(o.value),_(o.type==="json"?"json":o.type==="number"?"number":o.type==="boolean"?"boolean":"string"),M(null),K(!0)},Re=o=>{ke.alert(w("storage.deleteKeyTitle","Delete Key"),w("storage.deleteKeyMessage",{key:o,defaultValue:`Are you sure you want to delete key "${o}"?`}),[{text:w("common.cancel","Cancel"),style:"cancel"},{text:w("common.clear","Delete"),style:"destructive",onPress:async()=>{await $t(r,o,r==="mmkv"?F:void 0)?($(`Deleted "${o}"`),W()):$(`Failed to delete "${o}"`)}}])},We=()=>{ke.alert(w("storage.clearTitle","Clear Storage Driver"),w("storage.clearMessage",{driver:r==="asyncStorage"?"AsyncStorage":"MMKV",defaultValue:`Are you sure you want to delete all keys in ${r==="asyncStorage"?"AsyncStorage":"MMKV"}?`}),[{text:w("common.cancel","Cancel"),style:"cancel"},{text:w("storage.clearConfirm","Clear All"),style:"destructive",onPress:async()=>{await Dt(r,r==="mmkv"?F:void 0)&&($("All storage keys wiped"),W())}}])},Ke=async()=>{if(!E.trim()){$("Key name cannot be empty");return}let o=H;if(R==="json")try{const j=JSON.parse(H);o=JSON.stringify(j)}catch(j){M("Invalid JSON: "+j.message);return}else if(R==="number"&&isNaN(Number(H))){M("Value must be a valid number");return}await Lt(r,E.trim(),o,r==="mmkv"?F:void 0)?($(U==="create"?`Added "${E.trim()}"`:`Updated "${E.trim()}"`),K(!1),W()):$("Error saving storage key")},Ee=()=>{try{const o=JSON.parse(H);Y(JSON.stringify(o,null,2)),M(null),_("json"),$("Formatted JSON")}catch{M("Cannot format: invalid JSON syntax")}},L=N(()=>{if(!A.trim())return I;const o=A.toLowerCase().trim().split(/\s+/).filter(Boolean);return I.filter(P=>{const j=`${P.key} ${P.value}`.toLowerCase();return o.every(He=>j.includes(He))})},[I,A]),O=N(()=>I.reduce((o,P)=>o+P.byteSize,0),[I]),Oe=N(()=>O<1024?`${O.toLocaleString()} B`:O<1024*1024?`${(O/1024).toLocaleString(void 0,{minimumFractionDigits:1,maximumFractionDigits:1})} KB`:`${(O/(1024*1024)).toLocaleString(void 0,{minimumFractionDigits:2,maximumFractionDigits:2})} MB`,[O]),Be=oe(o=>{Kt(o.value,o.key),$(`Copied value of "${o.key}"`)},[]),Ne=oe(({item:o})=><Ot entry={o}isExpanded={!!Te[o.key]}onToggleExpand={Le}onCopy={Be}onEdit={De}onDelete={Re}badge={Et(o.type)}/>,[Te,Be]);return<S style={t.container}>
43
+ <Mt direction={r?"up":"down"}size={10}color={e.purple}/>
44
+ </T>}
45
+ </B>
46
+ </T>}),Ae=50,Me=10;export const StorageTab=Be.memo(()=>{const{t:S}=ht(),x=Je(null),[r,j]=k("asyncStorage"),[z,Y]=k("default"),[V,F]=k([]),[q,J]=k(!0),[I,Q]=k(""),[Z,he]=k(Ae),[Ce,Fe]=k({});we(()=>{he(Ae),x.current?.scrollToOffset({offset:0,animated:!1})},[I,r,z]);const[Le,R]=k(!1),[G,Se]=k("create"),[E,X]=k(""),[N,U]=k(""),[L,_]=k("string"),[ee,P]=k(null),xe=O(()=>Et(),[]),D=te(async()=>{J(!0);try{const o=await Lt(r,r==="mmkv"?z:void 0);F(o)}catch{F([])}finally{J(!1)}},[r,z]);we(()=>(D(),Wt(D)),[D]);const De=o=>{Fe(w=>({...w,[o]:!w[o]}))},$e=()=>{Se("create"),X(""),U(""),_("string"),P(null),R(!0)},Re=o=>{Se("edit"),X(o.key),U(o.value),_(o.type==="json"?"json":o.type==="number"?"number":o.type==="boolean"?"boolean":"string"),P(null),R(!0)},[W,H]=k({visible:!1,title:"",message:"",onConfirm:()=>{}}),Ee=o=>{H({visible:!0,title:S("storage.deleteKeyTitle","Delete Key"),message:S("storage.deleteKeyMessage",{key:o,defaultValue:`Are you sure you want to delete key "${o}"?`}),confirmText:S("common.clear","Delete"),cancelText:S("common.cancel","Cancel"),onConfirm:async()=>{H($=>({...$,visible:!1})),await $t(r,o,r==="mmkv"?z:void 0)?(M(`Deleted "${o}"`),D()):M(`Failed to delete "${o}"`)}})},We=()=>{H({visible:!0,title:S("storage.clearTitle","Clear Storage Driver"),message:S("storage.clearMessage",{driver:r==="asyncStorage"?"AsyncStorage":"MMKV",defaultValue:`Are you sure you want to delete all keys in ${r==="asyncStorage"?"AsyncStorage":"MMKV"}?`}),confirmText:S("storage.clearConfirm","Clear All"),cancelText:S("common.cancel","Cancel"),onConfirm:async()=>{H(w=>({...w,visible:!1})),await Rt(r,r==="mmkv"?z:void 0)&&(M(S("storage.cleared","All storage keys wiped")),D())}})},Ke=async()=>{if(!E.trim()){M(S("storage.keyNameEmpty","Key name cannot be empty"));return}let o=N;if(L==="json")try{const $=JSON.parse(N);o=JSON.stringify($)}catch($){P("Invalid JSON: "+$.message);return}else if(L==="number"&&isNaN(Number(N))){P("Value must be a valid number");return}await Dt(r,E.trim(),o,r==="mmkv"?z:void 0)?(M(G==="create"?`Added "${E.trim()}"`:`Updated "${E.trim()}"`),R(!1),D()):M(S("storage.saveError","Error saving storage key"))},Oe=()=>{try{const o=JSON.parse(N);U(JSON.stringify(o,null,2)),P(null),_("json"),M(S("storage.beautifyJson","Formatted JSON"))}catch{P("Cannot format: invalid JSON syntax")}},A=O(()=>{if(!I.trim())return V;const o=I.toLowerCase().trim().split(/\s+/).filter(Boolean);return V.filter(w=>{const $=`${w.key} ${w.value}`.toLowerCase();return o.every(je=>$.includes(je))})},[V,I]),K=O(()=>V.reduce((o,w)=>o+w.byteSize,0),[V]),Ne=O(()=>K<1024?`${K.toLocaleString()} B`:K<1024*1024?`${(K/1024).toLocaleString(void 0,{minimumFractionDigits:1,maximumFractionDigits:1})} KB`:`${(K/(1024*1024)).toLocaleString(void 0,{minimumFractionDigits:2,maximumFractionDigits:2})} MB`,[K]),ve=te(o=>{Kt(o.value,o.key),M(`Copied value of "${o.key}"`)},[]),He=te(({item:o})=><Nt entry={o}isExpanded={!!Ce[o.key]}onToggleExpand={De}onCopy={ve}onEdit={Re}onDelete={Ee}badge={Ot(o.type)}/>,[Ce,ve]);return<T style={t.container}>
47
47
 
48
- <S style={t.driverTabsWrapper}>
48
+ <T style={t.driverTabsWrapper}>
49
49
  <Ge horizontal showsHorizontalScrollIndicator={!1}contentContainerStyle={t.driverTabsContainer}>
50
- <V onPress={()=>J("asyncStorage")}style={[t.driverTabPill,r==="asyncStorage"&&{backgroundColor:e.brandPurple,borderColor:e.brandPurple},r!=="asyncStorage"&&{backgroundColor:`${e.brandPurple}12`,borderColor:`${e.brandPurple}30`}]}>
50
+ <B onPress={()=>j("asyncStorage")}style={[t.driverTabPill,r==="asyncStorage"&&{backgroundColor:e.brandPurple,borderColor:e.brandPurple},r!=="asyncStorage"&&{backgroundColor:`${e.brandPurple}12`,borderColor:`${e.brandPurple}30`}]}>
51
51
  <Ve size={11}color={r==="asyncStorage"?e.white:e.brandPurple}/>
52
52
  <C style={[t.driverTabText,{color:r==="asyncStorage"?e.white:e.primaryBlack}]}>
53
- {w("storage.subTabs.asyncStorage","AsyncStorage")}
53
+ {S("storage.subTabs.asyncStorage","AsyncStorage")}
54
54
  </C>
55
- {I.length>0&&r==="asyncStorage"&&<S style={[t.driverCountBadge,{backgroundColor:"rgba(255,255,255,0.25)"}]}>
55
+ {V.length>0&&r==="asyncStorage"&&<T style={[t.driverCountBadge,{backgroundColor:"rgba(255,255,255,0.25)"}]}>
56
56
  <C style={[t.driverCountText,{color:e.white}]}>
57
- {I.length}
57
+ {V.length}
58
58
  </C>
59
- </S>}
60
- </V>
59
+ </T>}
60
+ </B>
61
61
 
62
- <V onPress={()=>J("mmkv")}style={[t.driverTabPill,r==="mmkv"&&{backgroundColor:e.teal600,borderColor:e.teal600},r!=="mmkv"&&{backgroundColor:`${e.teal600}12`,borderColor:`${e.teal600}30`}]}>
63
- <It size={11}color={r==="mmkv"?e.white:e.teal600}/>
62
+ <B onPress={()=>j("mmkv")}style={[t.driverTabPill,r==="mmkv"&&{backgroundColor:e.teal600,borderColor:e.teal600},r!=="mmkv"&&{backgroundColor:`${e.teal600}12`,borderColor:`${e.teal600}30`}]}>
63
+ <Pt size={11}color={r==="mmkv"?e.white:e.teal600}/>
64
64
  <C style={[t.driverTabText,{color:r==="mmkv"?e.white:e.primaryBlack}]}>
65
- {w("storage.subTabs.mmkv","MMKV")}
65
+ {S("storage.subTabs.mmkv","MMKV")}
66
66
  </C>
67
- {I.length>0&&r==="mmkv"&&<S style={[t.driverCountBadge,{backgroundColor:"rgba(255,255,255,0.25)"}]}>
67
+ {V.length>0&&r==="mmkv"&&<T style={[t.driverCountBadge,{backgroundColor:"rgba(255,255,255,0.25)"}]}>
68
68
  <C style={[t.driverCountText,{color:e.white}]}>
69
- {I.length}
69
+ {V.length}
70
70
  </C>
71
- </S>}
72
- </V>
71
+ </T>}
72
+ </B>
73
73
 
74
74
 
75
- {r==="mmkv"&&Ce.length>1&&<S style={{flexDirection:"row",alignItems:"center",gap:4,marginLeft:6}}>
76
- {Ce.map(o=><V key={o}onPress={()=>q(o)}style={[t.instancePill,F===o&&t.instancePillActive]}>
77
- <C style={[t.instancePillText,F===o&&t.instancePillTextActive]}>
75
+ {r==="mmkv"&&xe.length>1&&<T style={{flexDirection:"row",alignItems:"center",gap:4,marginLeft:6}}>
76
+ {xe.map(o=><B key={o}onPress={()=>Y(o)}style={[t.instancePill,z===o&&t.instancePillActive]}>
77
+ <C style={[t.instancePillText,z===o&&t.instancePillTextActive]}>
78
78
  {o}
79
79
  </C>
80
- </V>)}
81
- </S>}
80
+ </B>)}
81
+ </T>}
82
82
  </Ge>
83
- </S>
83
+ </T>
84
84
 
85
85
 
86
- <S style={t.actionBar}>
87
- <S style={t.searchBar}>
88
- <St size={14}color={e.grayTextWeak}/>
89
- <Se value={A}onChangeText={X}placeholder={w("storage.searchPlaceholder","Search keys, values, types...")}placeholderTextColor={e.grayTextWeak}style={t.searchInput}clearButtonMode="while-editing"/>
90
- {A.length>0&&<S style={{flexDirection:"row",alignItems:"center",gap:4}}>
91
- <S style={{backgroundColor:`${e.purple}20`,borderRadius:10,paddingHorizontal:6,paddingVertical:1.5}}>
92
- <C style={{color:e.purple,fontSize:9.5,fontFamily:T.interBold}}>
93
- {L.length}
86
+ <T style={t.actionBar}>
87
+ <T style={t.searchBar}>
88
+ <Ct size={14}color={e.grayTextWeak}/>
89
+ <Te value={I}onChangeText={Q}placeholder={S("storage.searchPlaceholder","Search keys, values, types...")}placeholderTextColor={e.grayTextWeak}style={t.searchInput}clearButtonMode="while-editing"/>
90
+ {I.length>0&&<T style={{flexDirection:"row",alignItems:"center",gap:4}}>
91
+ <T style={{backgroundColor:`${e.purple}20`,borderRadius:10,paddingHorizontal:6,paddingVertical:1.5}}>
92
+ <C style={{color:e.purple,fontSize:9.5,fontFamily:h.interBold}}>
93
+ {A.length}
94
94
  </C>
95
- </S>
96
- <V onPress={()=>X("")}hitSlop={8}>
95
+ </T>
96
+ <B onPress={()=>Q("")}hitSlop={8}>
97
97
  <Ie size={13}color={e.grayTextWeak}/>
98
- </V>
99
- </S>}
100
- </S>
98
+ </B>
99
+ </T>}
100
+ </T>
101
101
 
102
102
 
103
- <V onPress={$e}style={t.addKeyBtn}hitSlop={6}>
104
- <Tt size={13}color={e.white}/>
105
- <C style={t.addKeyBtnText}>{w("storage.add","Add")}</C>
106
- </V>
103
+ <B onPress={$e}style={t.addKeyBtn}hitSlop={6}>
104
+ <St size={13}color={e.white}/>
105
+ <C style={t.addKeyBtnText}>{S("storage.add","Add")}</C>
106
+ </B>
107
107
 
108
- <V onPress={W}style={t.actionIconBtn}hitSlop={6}>
109
- <Pt size={13}color={e.grayText}/>
110
- </V>
108
+ <B onPress={D}style={t.actionIconBtn}hitSlop={6}>
109
+ <At size={13}color={e.grayText}/>
110
+ </B>
111
111
 
112
- {I.length>0&&<V onPress={We}style={[t.actionIconBtn,{borderColor:`${e.errorColor}33`,backgroundColor:`${e.errorColor}12`}]}hitSlop={6}>
112
+ {V.length>0&&<B onPress={We}style={[t.actionIconBtn,{borderColor:`${e.errorColor}33`,backgroundColor:`${e.errorColor}12`}]}hitSlop={6}>
113
113
  <Pe size={13}color={e.errorColor}/>
114
- </V>}
115
- </S>
114
+ </B>}
115
+ </T>
116
116
 
117
117
 
118
- <S style={t.statsStrip}>
118
+ <T style={t.statsStrip}>
119
119
  <C style={t.statsText}>
120
- {L.length.toLocaleString()} of {I.length.toLocaleString()} Keys • {Oe}
120
+ {A.length.toLocaleString()} of {V.length.toLocaleString()} Keys • {Ne}
121
121
  </C>
122
122
  <C style={t.statsSubtext}>
123
- {r==="asyncStorage"?"SQLite Key-Value":`MMKV (${F})`}
123
+ {r==="asyncStorage"?"SQLite Key-Value":`MMKV (${z})`}
124
124
  </C>
125
- </S>
125
+ </T>
126
126
 
127
127
 
128
- {Q?<S style={t.loadingContainer}>
128
+ {q?<T style={t.loadingContainer}>
129
129
  <Qe size="small"color={e.purple}/>
130
- <C style={t.loadingText}>{w("storage.loading","Loading storage entries...")}</C>
131
- </S>:<>
132
- <Ue ref={B}data={L.slice(0,Z)}keyExtractor={o=>o.key}renderItem={Ne}initialNumToRender={10}maxToRenderPerBatch={10}windowSize={5}removeClippedSubviews={ve.OS==="android"}style={t.scrollArea}contentContainerStyle={L.length===0?t.emptyScrollContent:t.scrollContent}showsVerticalScrollIndicator={!1}ListEmptyComponent={<S style={t.emptyContainer}>
133
- <S style={t.emptyIconWrap}>
130
+ <C style={t.loadingText}>{S("storage.loading","Loading storage entries...")}</C>
131
+ </T>:<>
132
+ <Ue ref={x}data={A.slice(0,Z)}keyExtractor={o=>o.key}renderItem={He}initialNumToRender={10}maxToRenderPerBatch={8}windowSize={5}updateCellsBatchingPeriod={40}removeClippedSubviews={!0}renderToHardwareTextureAndroid={!0}style={t.scrollArea}contentContainerStyle={A.length===0?t.emptyScrollContent:t.scrollContent}showsVerticalScrollIndicator={!1}ListEmptyComponent={<T style={t.emptyContainer}>
133
+ <T style={t.emptyIconWrap}>
134
134
  <Ve size={28}color={e.grayTextWeak}/>
135
- </S>
135
+ </T>
136
136
  <C style={t.emptyTitle}>
137
- {A.trim().length>0?"No matching keys found":`No ${r==="asyncStorage"?"AsyncStorage":"MMKV"} Keys`}
137
+ {I.trim().length>0?"No matching keys found":`No ${r==="asyncStorage"?"AsyncStorage":"MMKV"} Keys`}
138
138
  </C>
139
139
  <C style={t.emptySubtitle}>
140
- {A.trim().length>0?`No keys or values match "${A}"`:`Storage is auto-detected. Tap "+ Add" above to create your first ${r==="asyncStorage"?"AsyncStorage":"MMKV"} key!`}
140
+ {I.trim().length>0?`No keys or values match "${I}"`:`Storage is auto-detected. Tap "+ Add" above to create your first ${r==="asyncStorage"?"AsyncStorage":"MMKV"} key!`}
141
141
  </C>
142
- {A.trim().length>0&&<V onPress={()=>X("")}style={{marginTop:12,paddingHorizontal:14,paddingVertical:6,borderRadius:8,backgroundColor:e.grayBackground,borderWidth:1,borderColor:e.grayBorderSecondary}}>
143
- <C style={{color:e.brandPurple,fontSize:12,fontFamily:T.interBold}}>
142
+ {I.trim().length>0&&<B onPress={()=>Q("")}style={{marginTop:12,paddingHorizontal:14,paddingVertical:6,borderRadius:8,backgroundColor:e.grayBackground,borderWidth:1,borderColor:e.grayBorderSecondary}}>
143
+ <C style={{color:e.brandPurple,fontSize:12,fontFamily:h.interBold}}>
144
144
  Clear Search
145
145
  </C>
146
- </V>}
147
- </S>}ListFooterComponent={L.length>0?<Xe count={Math.min(Z,L.length)}totalCount={L.length}label="keys"hasMore={L.length>Z}onLoadMore={()=>Ae(o=>o+10)}/>:<S style={{height:60}}/>}/>
146
+ </B>}
147
+ </T>}ListFooterComponent={A.length>0?<Xe count={Math.min(Z,A.length)}totalCount={A.length}label="keys"loadMoreStep={Me}hasMore={A.length>Z}onLoadMore={()=>he(o=>o+Me)}/>:<T style={{height:60}}/>}/>
148
148
  </>}
149
149
 
150
150
 
151
- <Ye visible={Me}transparent animationType="fade"onRequestClose={()=>K(!1)}>
152
- <S style={t.modalOverlay}>
153
- <S style={t.modalCard}>
154
- <S style={t.modalHeader}>
151
+ <_e visible={Le}transparent animationType="fade"onRequestClose={()=>R(!1)}>
152
+ <T style={t.modalOverlay}>
153
+ <T style={t.modalCard}>
154
+ <T style={t.modalHeader}>
155
155
  <C style={t.modalTitle}>
156
- {U==="create"?"Add Storage Key":`Edit: ${E}`}
156
+ {G==="create"?"Add Storage Key":`Edit: ${E}`}
157
157
  </C>
158
- <V onPress={()=>K(!1)}hitSlop={8}>
158
+ <B onPress={()=>R(!1)}hitSlop={8}>
159
159
  <Ie size={16}color={e.grayText}/>
160
- </V>
161
- </S>
160
+ </B>
161
+ </T>
162
162
 
163
163
 
164
- <S style={t.inputGroup}>
165
- <C style={t.inputLabel}>{w("storage.keyName","KEY NAME").toUpperCase()}</C>
166
- <Se value={E}onChangeText={ee}placeholder="e.g. user_session, auth_token"placeholderTextColor={e.grayTextWeak}editable={U==="create"}style={[t.textInput,U==="edit"&&t.textInputDisabled]}autoCapitalize="none"/>
167
- </S>
164
+ <T style={t.inputGroup}>
165
+ <C style={t.inputLabel}>{S("storage.keyName","KEY NAME").toUpperCase()}</C>
166
+ <Te value={E}onChangeText={X}placeholder="e.g. user_session, auth_token"placeholderTextColor={e.grayTextWeak}editable={G==="create"}style={[t.textInput,G==="edit"&&t.textInputDisabled]}autoCapitalize="none"/>
167
+ </T>
168
168
 
169
169
 
170
- <S style={t.inputGroup}>
171
- <S style={{flexDirection:"row",alignItems:"center",justifyContent:"space-between",marginBottom:4}}>
172
- <C style={t.inputLabel}>{w("storage.type","VALUE TYPE").toUpperCase()}</C>
173
- {R==="json"&&<V onPress={Ee}hitSlop={6}>
174
- <C style={t.formatJsonBtn}>{w("storage.beautifyJson","Beautify JSON")}</C>
175
- </V>}
176
- </S>
177
- <S style={t.typeSelectorStrip}>
178
- {["string","json","number","boolean"].map(o=>{const P=R===o;return<V key={o}onPress={()=>{_(o),M(null)}}style={[t.typePill,P&&t.typePillActive]}>
179
- <C style={[t.typePillText,P&&t.typePillTextActive]}>
170
+ <T style={t.inputGroup}>
171
+ <T style={{flexDirection:"row",alignItems:"center",justifyContent:"space-between",marginBottom:4}}>
172
+ <C style={t.inputLabel}>{S("storage.type","VALUE TYPE").toUpperCase()}</C>
173
+ {L==="json"&&<B onPress={Oe}hitSlop={6}>
174
+ <C style={t.formatJsonBtn}>{S("storage.beautifyJson","Beautify JSON")}</C>
175
+ </B>}
176
+ </T>
177
+ <T style={t.typeSelectorStrip}>
178
+ {["string","json","number","boolean"].map(o=>{const w=L===o;return<B key={o}onPress={()=>{_(o),P(null)}}style={[t.typePill,w&&t.typePillActive]}>
179
+ <C style={[t.typePillText,w&&t.typePillTextActive]}>
180
180
  {o.toUpperCase()}
181
181
  </C>
182
- </V>})}
183
- </S>
184
- </S>
182
+ </B>})}
183
+ </T>
184
+ </T>
185
185
 
186
186
 
187
- <S style={t.inputGroup}>
188
- <C style={t.inputLabel}>{w("storage.valueContent","VALUE CONTENT").toUpperCase()}</C>
189
- <Se value={H}onChangeText={o=>{Y(o),te&&M(null)}}placeholder={R==="json"?'{"userId": 123, "isLoggedIn": true}':R==="number"?"42":R==="boolean"?"true":"String value..."}placeholderTextColor={e.grayTextWeak}style={[t.textInput,t.textAreaInput]}multiline textAlignVertical="top"autoCapitalize="none"/>
190
- {te&&<S style={{flexDirection:"row",alignItems:"center",gap:5,marginTop:4}}>
187
+ <T style={t.inputGroup}>
188
+ <C style={t.inputLabel}>{S("storage.valueContent","VALUE CONTENT").toUpperCase()}</C>
189
+ <Te value={N}onChangeText={o=>{U(o),ee&&P(null)}}placeholder={L==="json"?'{"userId": 123, "isLoggedIn": true}':L==="number"?"42":L==="boolean"?"true":"String value..."}placeholderTextColor={e.grayTextWeak}style={[t.textInput,t.textAreaInput]}multiline textAlignVertical="top"autoCapitalize="none"/>
190
+ {ee&&<T style={{flexDirection:"row",alignItems:"center",gap:5,marginTop:4}}>
191
191
  <Ft size={12}color={e.errorColor}/>
192
- <C style={t.errorText}>{te}</C>
193
- </S>}
194
- </S>
192
+ <C style={t.errorText}>{ee}</C>
193
+ </T>}
194
+ </T>
195
195
 
196
196
 
197
- <S style={t.modalActions}>
198
- <V onPress={()=>K(!1)}style={t.cancelBtn}>
199
- <C style={t.cancelBtnText}>{w("common.cancel","Cancel")}</C>
200
- </V>
201
- <V onPress={Ke}style={t.saveBtn}>
202
- <Vt size={14}color={e.white}/>
203
- <C style={t.saveBtnText}>{w("storage.saveKey","Save Key")}</C>
204
- </V>
205
- </S>
206
- </S>
207
- </S>
208
- </Ye>
209
- </S>});const t=_e.create({container:{flex:1,backgroundColor:e.grayBackground},driverTabsWrapper:{backgroundColor:e.primaryLight,borderBottomWidth:1,borderBottomColor:e.dividerColor,paddingVertical:8},driverTabsContainer:{paddingHorizontal:12,flexDirection:"row",alignItems:"center",gap:6},driverTabPill:{flexDirection:"row",alignItems:"center",gap:5,paddingHorizontal:9,paddingVertical:4.5,borderRadius:8,backgroundColor:e.grayBackground,borderWidth:1,borderColor:e.grayBorderSecondary},driverTabPillActive:{backgroundColor:e.purple,borderColor:e.purple},driverTabText:{fontFamily:T.interBold,fontSize:10.5,color:e.grayText},driverTabTextActive:{color:e.white},driverCountBadge:{backgroundColor:"rgba(255, 255, 255, 0.25)",paddingHorizontal:5,paddingVertical:1,borderRadius:8},driverCountText:{fontFamily:T.interBold,fontSize:9.5,color:e.white},instancePill:{paddingHorizontal:7,paddingVertical:3,borderRadius:6,backgroundColor:`${e.purple}14`,borderWidth:1,borderColor:`${e.purple}30`},instancePillActive:{backgroundColor:e.purple,borderColor:e.purple},instancePillText:{fontFamily:T.interBold,fontSize:10,color:e.purple},instancePillTextActive:{color:e.white},actionBar:{flexDirection:"row",alignItems:"center",paddingHorizontal:12,paddingVertical:8,backgroundColor:e.primaryLight,borderBottomWidth:1,borderBottomColor:e.dividerColor,gap:6},searchBar:{flex:1,flexDirection:"row",alignItems:"center",backgroundColor:e.grayBackground,borderRadius:8,paddingHorizontal:9,paddingVertical:ve.OS==="ios"?6:2,borderWidth:1,borderColor:e.grayBorderSecondary,gap:6},searchInput:{flex:1,fontFamily:T.interMedium,fontSize:12,color:e.primaryBlack,padding:0},addKeyBtn:{flexDirection:"row",alignItems:"center",gap:4,paddingHorizontal:10,paddingVertical:6,borderRadius:8,backgroundColor:e.purple},addKeyBtnText:{fontFamily:T.interBold,fontSize:11,color:e.white},actionIconBtn:{width:30,height:30,borderRadius:8,alignItems:"center",justifyContent:"center",backgroundColor:e.grayBackground,borderWidth:1,borderColor:e.grayBorderSecondary},statsStrip:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingHorizontal:12,paddingVertical:5,backgroundColor:`${e.grayBorderSecondary}40`},statsText:{fontFamily:T.interMedium,fontSize:10,color:e.grayText},statsSubtext:{fontFamily:T.interBold,fontSize:9.5,color:e.grayTextWeak},scrollArea:{flex:1},scrollContent:{padding:12,gap:10,paddingBottom:100},emptyScrollContent:{flexGrow:1,justifyContent:"center",alignItems:"center",padding:24,paddingBottom:60},entryCard:{backgroundColor:e.primaryLight,borderRadius:10,borderWidth:1,borderColor:e.grayBorderSecondary,padding:10,gap:8,shadowColor:e.black,shadowOpacity:.02,shadowRadius:3,shadowOffset:{width:0,height:1},elevation:1},entryHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between"},entryKey:{fontFamily:T.interBold,fontSize:12.5,color:e.primaryBlack},typeBadge:{paddingHorizontal:5,paddingVertical:1,borderRadius:4,borderWidth:1},typeBadgeText:{fontFamily:T.interBold,fontSize:8.5},sizeText:{fontFamily:T.interRegular,fontSize:10,color:e.grayTextWeak},entryActions:{flexDirection:"row",alignItems:"center",gap:5},entryActionBtn:{padding:5,borderRadius:5,backgroundColor:e.grayBackground},valuePreviewBox:{backgroundColor:e.grayBackground,borderRadius:6,padding:8,borderWidth:1,borderColor:`${e.grayBorderSecondary}80`},valuePreviewText:{fontFamily:T.interRegular,fontSize:11,color:e.primaryBlack,lineHeight:16},expandHint:{fontFamily:T.interBold,fontSize:9.5,color:e.purple,marginTop:4},loadingContainer:{flex:1,alignItems:"center",justifyContent:"center",gap:8},loadingText:{fontFamily:T.interMedium,fontSize:12,color:e.grayText},emptyContainer:{padding:24,alignItems:"center",justifyContent:"center"},emptyIconWrap:{width:56,height:56,borderRadius:28,backgroundColor:`${e.grayBorderSecondary}40`,alignItems:"center",justifyContent:"center",marginBottom:12},emptyTitle:{fontFamily:T.interBold,fontSize:14,color:e.primaryBlack,marginBottom:4},emptySubtitle:{fontFamily:T.interRegular,fontSize:11.5,color:e.grayText,textAlign:"center",maxWidth:280},connectGuideCard:{marginTop:20,width:"100%",backgroundColor:e.primaryLight,borderRadius:10,borderWidth:1,borderColor:e.grayBorderSecondary,padding:12,gap:6},connectGuideTitle:{fontFamily:T.interBold,fontSize:11,color:e.purple},connectGuideCode:{fontFamily:T.interRegular,fontSize:10,color:e.grayText,lineHeight:15},modalOverlay:{flex:1,backgroundColor:"rgba(0, 0, 0, 0.5)",justifyContent:"center",alignItems:"center",padding:16},modalCard:{width:"100%",maxWidth:400,backgroundColor:e.primaryLight,borderRadius:14,padding:16,gap:12,shadowColor:e.black,shadowOpacity:.2,shadowRadius:10,shadowOffset:{width:0,height:4},elevation:5},modalHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",borderBottomWidth:1,borderBottomColor:e.dividerColor,paddingBottom:10},modalTitle:{fontFamily:T.interBold,fontSize:14,color:e.primaryBlack},inputGroup:{gap:4},inputLabel:{fontFamily:T.interBold,fontSize:9.5,color:e.grayTextWeak,letterSpacing:.5},textInput:{backgroundColor:e.grayBackground,borderRadius:8,paddingHorizontal:10,paddingVertical:8,fontFamily:T.interMedium,fontSize:12,color:e.primaryBlack,borderWidth:1,borderColor:e.grayBorderSecondary},textInputDisabled:{backgroundColor:`${e.grayBorderSecondary}40`,color:e.grayText},textAreaInput:{minHeight:90,maxHeight:160,fontFamily:T.interRegular,fontSize:11},typeSelectorStrip:{flexDirection:"row",alignItems:"center",gap:6},typePill:{flex:1,alignItems:"center",paddingVertical:6,borderRadius:6,backgroundColor:e.grayBackground,borderWidth:1,borderColor:e.grayBorderSecondary},typePillActive:{backgroundColor:e.purple,borderColor:e.purple},typePillText:{fontFamily:T.interBold,fontSize:10,color:e.grayText},typePillTextActive:{color:e.white},formatJsonBtn:{fontFamily:T.interBold,fontSize:10,color:e.purple},errorText:{fontFamily:T.interMedium,fontSize:10,color:e.errorColor,marginTop:2},modalActions:{flexDirection:"row",alignItems:"center",gap:10,marginTop:4},cancelBtn:{flex:1,alignItems:"center",paddingVertical:10,borderRadius:8,backgroundColor:e.grayBackground,borderWidth:1,borderColor:e.grayBorderSecondary},cancelBtnText:{fontFamily:T.interBold,fontSize:12,color:e.grayText},saveBtn:{flex:1.5,flexDirection:"row",alignItems:"center",justifyContent:"center",gap:5,paddingVertical:10,borderRadius:8,backgroundColor:e.purple},saveBtnText:{fontFamily:T.interBold,fontSize:12,color:e.white}});export default StorageTab;
197
+ <T style={t.modalActions}>
198
+ <B onPress={()=>R(!1)}style={t.cancelBtn}>
199
+ <C style={t.cancelBtnText}>{S("common.cancel","Cancel")}</C>
200
+ </B>
201
+ <B onPress={Ke}style={t.saveBtn}>
202
+ <It size={14}color={e.white}/>
203
+ <C style={t.saveBtnText}>{S("storage.saveKey","Save Key")}</C>
204
+ </B>
205
+ </T>
206
+ </T>
207
+ </T>
208
+ </_e>
209
+
210
+ <Tt visible={W.visible}title={W.title}message={W.message}confirmText={W.confirmText}cancelText={W.cancelText}isDestructive={!0}icon="trash"onConfirm={W.onConfirm}onCancel={()=>H(o=>({...o,visible:!1}))}/>
211
+ </T>});const t=Ye.create({container:{flex:1,backgroundColor:e.grayBackground},driverTabsWrapper:{backgroundColor:e.primaryLight,borderBottomWidth:1,borderBottomColor:e.dividerColor,paddingVertical:8},driverTabsContainer:{paddingHorizontal:12,flexDirection:"row",alignItems:"center",gap:6},driverTabPill:{flexDirection:"row",alignItems:"center",gap:5,paddingHorizontal:9,paddingVertical:4.5,borderRadius:8,backgroundColor:e.grayBackground,borderWidth:1,borderColor:e.grayBorderSecondary},driverTabPillActive:{backgroundColor:e.purple,borderColor:e.purple},driverTabText:{fontFamily:h.interBold,fontSize:10.5,color:e.grayText},driverTabTextActive:{color:e.white},driverCountBadge:{backgroundColor:"rgba(255, 255, 255, 0.25)",paddingHorizontal:5,paddingVertical:1,borderRadius:8},driverCountText:{fontFamily:h.interBold,fontSize:9.5,color:e.white},instancePill:{paddingHorizontal:7,paddingVertical:3,borderRadius:6,backgroundColor:`${e.purple}14`,borderWidth:1,borderColor:`${e.purple}30`},instancePillActive:{backgroundColor:e.purple,borderColor:e.purple},instancePillText:{fontFamily:h.interBold,fontSize:10,color:e.purple},instancePillTextActive:{color:e.white},actionBar:{flexDirection:"row",alignItems:"center",paddingHorizontal:12,paddingVertical:8,backgroundColor:e.primaryLight,borderBottomWidth:1,borderBottomColor:e.dividerColor,gap:6},searchBar:{flex:1,flexDirection:"row",alignItems:"center",backgroundColor:e.grayBackground,borderRadius:8,paddingHorizontal:9,paddingVertical:Ze.OS==="ios"?6:2,borderWidth:1,borderColor:e.grayBorderSecondary,gap:6},searchInput:{flex:1,fontFamily:h.interMedium,fontSize:12,color:e.primaryBlack,padding:0},addKeyBtn:{flexDirection:"row",alignItems:"center",gap:4,paddingHorizontal:10,paddingVertical:6,borderRadius:8,backgroundColor:e.purple},addKeyBtnText:{fontFamily:h.interBold,fontSize:11,color:e.white},actionIconBtn:{width:30,height:30,borderRadius:8,alignItems:"center",justifyContent:"center",backgroundColor:e.grayBackground,borderWidth:1,borderColor:e.grayBorderSecondary},statsStrip:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingHorizontal:12,paddingVertical:5,backgroundColor:`${e.grayBorderSecondary}40`},statsText:{fontFamily:h.interMedium,fontSize:10,color:e.grayText},statsSubtext:{fontFamily:h.interBold,fontSize:9.5,color:e.grayTextWeak},scrollArea:{flex:1},scrollContent:{padding:12,gap:10,paddingBottom:100},emptyScrollContent:{flexGrow:1,justifyContent:"center",alignItems:"center",padding:24,paddingBottom:60},entryCard:{backgroundColor:e.primaryLight,borderRadius:10,borderWidth:1,borderColor:e.grayBorderSecondary,padding:10,gap:8,shadowColor:e.black,shadowOpacity:.02,shadowRadius:3,shadowOffset:{width:0,height:1},elevation:1},entryHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between"},entryKey:{fontFamily:h.interBold,fontSize:12.5,color:e.primaryBlack},typeBadge:{paddingHorizontal:5,paddingVertical:1,borderRadius:4,borderWidth:1},typeBadgeText:{fontFamily:h.interBold,fontSize:8.5},sizeText:{fontFamily:h.interRegular,fontSize:10,color:e.grayTextWeak},entryActions:{flexDirection:"row",alignItems:"center",gap:5},entryActionBtn:{padding:5,borderRadius:5,backgroundColor:e.grayBackground},valuePreviewBox:{backgroundColor:e.grayBackground,borderRadius:6,padding:8,borderWidth:1,borderColor:`${e.grayBorderSecondary}80`},valuePreviewText:{fontFamily:h.interRegular,fontSize:11,color:e.primaryBlack,lineHeight:16},expandHint:{fontFamily:h.interBold,fontSize:9.5,color:e.purple,marginTop:4},loadingContainer:{flex:1,alignItems:"center",justifyContent:"center",gap:8},loadingText:{fontFamily:h.interMedium,fontSize:12,color:e.grayText},emptyContainer:{padding:24,alignItems:"center",justifyContent:"center"},emptyIconWrap:{width:56,height:56,borderRadius:28,backgroundColor:`${e.grayBorderSecondary}40`,alignItems:"center",justifyContent:"center",marginBottom:12},emptyTitle:{fontFamily:h.interBold,fontSize:14,color:e.primaryBlack,marginBottom:4},emptySubtitle:{fontFamily:h.interRegular,fontSize:11.5,color:e.grayText,textAlign:"center",maxWidth:280},connectGuideCard:{marginTop:20,width:"100%",backgroundColor:e.primaryLight,borderRadius:10,borderWidth:1,borderColor:e.grayBorderSecondary,padding:12,gap:6},connectGuideTitle:{fontFamily:h.interBold,fontSize:11,color:e.purple},connectGuideCode:{fontFamily:h.interRegular,fontSize:10,color:e.grayText,lineHeight:15},modalOverlay:{flex:1,backgroundColor:"rgba(0, 0, 0, 0.5)",justifyContent:"center",alignItems:"center",padding:16},modalCard:{width:"100%",maxWidth:400,backgroundColor:e.primaryLight,borderRadius:14,padding:16,gap:12,shadowColor:e.black,shadowOpacity:.2,shadowRadius:10,shadowOffset:{width:0,height:4},elevation:5},modalHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",borderBottomWidth:1,borderBottomColor:e.dividerColor,paddingBottom:10},modalTitle:{fontFamily:h.interBold,fontSize:14,color:e.primaryBlack},inputGroup:{gap:4},inputLabel:{fontFamily:h.interBold,fontSize:9.5,color:e.grayTextWeak,letterSpacing:.5},textInput:{backgroundColor:e.grayBackground,borderRadius:8,paddingHorizontal:10,paddingVertical:8,fontFamily:h.interMedium,fontSize:12,color:e.primaryBlack,borderWidth:1,borderColor:e.grayBorderSecondary},textInputDisabled:{backgroundColor:`${e.grayBorderSecondary}40`,color:e.grayText},textAreaInput:{minHeight:90,maxHeight:160,fontFamily:h.interRegular,fontSize:11},typeSelectorStrip:{flexDirection:"row",alignItems:"center",gap:6},typePill:{flex:1,alignItems:"center",paddingVertical:6,borderRadius:6,backgroundColor:e.grayBackground,borderWidth:1,borderColor:e.grayBorderSecondary},typePillActive:{backgroundColor:e.purple,borderColor:e.purple},typePillText:{fontFamily:h.interBold,fontSize:10,color:e.grayText},typePillTextActive:{color:e.white},formatJsonBtn:{fontFamily:h.interBold,fontSize:10,color:e.purple},errorText:{fontFamily:h.interMedium,fontSize:10,color:e.errorColor,marginTop:2},modalActions:{flexDirection:"row",alignItems:"center",gap:10,marginTop:4},cancelBtn:{flex:1,alignItems:"center",paddingVertical:10,borderRadius:8,backgroundColor:e.grayBackground,borderWidth:1,borderColor:e.grayBorderSecondary},cancelBtnText:{fontFamily:h.interBold,fontSize:12,color:e.grayText},saveBtn:{flex:1.5,flexDirection:"row",alignItems:"center",justifyContent:"center",gap:5,paddingVertical:10,borderRadius:8,backgroundColor:e.purple},saveBtnText:{fontFamily:h.interBold,fontSize:12,color:e.white}});export default StorageTab;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ interface SupportModalProps {
3
+ visible: boolean;
4
+ onClose: () => void;
5
+ }
6
+ export declare const SupportModal: React.FC<SupportModalProps>;
7
+ export {};