@onairos/react-native 1.0.0 → 1.0.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 (30) hide show
  1. package/lib/commonjs/components/OnairosButton.js +6 -415
  2. package/lib/commonjs/components/OnairosButton.js.map +1 -1
  3. package/lib/commonjs/components/Overlay.js +0 -549
  4. package/lib/commonjs/components/PinInput.js +160 -0
  5. package/lib/commonjs/components/PinInput.js.map +1 -0
  6. package/lib/commonjs/components/PlatformList.js +137 -0
  7. package/lib/commonjs/components/PlatformList.js.map +1 -0
  8. package/lib/commonjs/components/TrainingModal.js +130 -0
  9. package/lib/commonjs/components/TrainingModal.js.map +1 -0
  10. package/lib/module/components/OnairosButton.js +121 -514
  11. package/lib/module/components/OnairosButton.js.map +1 -1
  12. package/lib/module/components/Overlay.js +0 -565
  13. package/lib/module/components/PinInput.js +151 -0
  14. package/lib/module/components/PinInput.js.map +1 -0
  15. package/lib/module/components/PlatformList.js +129 -0
  16. package/lib/module/components/PlatformList.js.map +1 -0
  17. package/lib/module/components/TrainingModal.js +122 -0
  18. package/lib/module/components/TrainingModal.js.map +1 -0
  19. package/package.json +7 -6
  20. package/src/components/OnairosButton.tsx +5 -5
  21. package/src/components/PinInput.tsx +189 -0
  22. package/src/components/PlatformList.tsx +145 -0
  23. package/src/components/TrainingModal.tsx +132 -0
  24. package/lib/commonjs/components/Notification.js +0 -106
  25. package/lib/commonjs/components/Notification.js.map +0 -1
  26. package/lib/module/components/Notification.js +0 -99
  27. package/lib/module/components/Notification.js.map +0 -1
  28. package/src/components/Notification.js +0 -101
  29. package/src/components/OnairosButton.js +0 -604
  30. package/src/components/Overlay.js +0 -854
@@ -1,550 +1,157 @@
1
- import React, { useEffect, useState, useRef } from 'react';
2
- import { TouchableOpacity, Text, View, Image, Platform, StyleSheet } from 'react-native';
3
- import { Othent } from '@othent/kms-react-native';
4
- import { rsaEncrypt } from '../utils/crypto';
5
- import { getPin } from '../utils/auth';
6
- import Overlay from './Overlay';
7
- import { sha256 } from 'react-native-crypto-js';
8
- import AsyncStorage from '@react-native-async-storage/async-storage';
9
- import axios from 'axios';
10
- const API_URL = 'https://api2.onairos.uk';
11
- const OnairosButton = ({
1
+ import React, { useCallback, useEffect, useState } from 'react';
2
+ import { TouchableOpacity, StyleSheet, Text, Linking } from 'react-native';
3
+ import Icon from 'react-native-vector-icons/MaterialIcons';
4
+ import { UniversalOnboarding } from './UniversalOnboarding';
5
+ import { DataRequestModal } from './DataRequestModal';
6
+ import { useCredentials } from '../hooks/useCredentials';
7
+ // import { validateCredentials } from '../utils/auth';
8
+ // import { COLORS } from '../constants';
9
+
10
+ export const OnairosButton = ({
11
+ AppName,
12
12
  requestData,
13
- webpageName,
14
- inferenceData = null,
15
- onComplete = null,
16
- autoFetch = true,
17
- proofMode = false,
18
- textLayout = 'below',
19
- textColor = 'white',
13
+ returnLink,
14
+ embedd = false,
15
+ color = '#00BFA5',
16
+ icon = 'auto_awesome',
17
+ onResolved,
20
18
  login = false,
21
- buttonType = 'pill',
22
- loginReturn = null,
23
- loginType = 'signIn',
24
- visualType = 'full'
19
+ buttonType = 'circle',
20
+ debug = false,
21
+ test = false
25
22
  }) => {
26
- const [userData, setUserData] = useState(null);
27
- const [showOverlay, setShowOverlay] = useState(false);
28
- const [activeModels, setActiveModels] = useState([]);
29
- const [granted, setGranted] = useState(0);
30
- const [selectedRequests, setSelectedRequests] = useState({});
31
- const [avatar, setAvatar] = useState(false);
32
- const [traits, setTraits] = useState(false);
33
- const [othentUser, setOthentUser] = useState(false);
34
- const [othentConnected, setOthentConnected] = useState(false);
35
- const NoAccount = useRef(false);
36
- const NoModel = useRef(false);
37
- const [isAuthenticated, setIsAuthenticated] = useState(false);
38
- const [authToken, setAuthToken] = useState(null);
39
- const [loading, setLoading] = useState(true);
40
- const [hashedOthentSub, setHashedOthentSub] = useState(null);
41
- const [encryptedPin, setEncryptedPin] = useState(null);
42
- const [accountInfo, setAccountInfo] = useState(null);
43
- const [isLoading, setIsLoading] = useState(false);
44
- const [isProcessingAuth, setIsProcessingAuth] = useState(false);
45
- const hasProcessedCallback = useRef(false);
46
- const [authError, setAuthError] = useState(null);
47
- const [notif, setNotif] = useState({
48
- show: false,
49
- color: null,
50
- message: null
51
- });
52
-
53
- // The Onairos public key for encryption
54
- const OnairosPublicKey = `
55
- -----BEGIN PUBLIC KEY-----
56
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4wkWvRPaJiY8CwQ5BoJI
57
- amcGAYV91Bk8NrvWq4PXM+J/RJugfgTNCYKQ/c6g4xa1YES/tJEzFS7nf0Kdoqxm
58
- 5aav0ru5vS4fc4vCOLTI9W1T7nj02NY91rogsQm2/KMxUQ8DaLeTZKi+0Wjsa9YO
59
- 6XGGd1wh4azgQkj04MWW5J1EBCcBavKoY+C85oA9jkkklQ8nGWgbugmZs7eXHNQb
60
- qH8/ZHcB9Kx1CZ6XjQuVd6YE/A+swV+DksbkXANcYjr6SY/2TbB8GfpcOMM3bkyN
61
- Q8e0A51q5a8abfuAkDZXe67MwKMWu/626abwPZhJrKr5HhRZZDwPtnXlktYHhOK6
62
- lQIDAQAB
63
- -----END PUBLIC KEY-----
64
- `;
65
-
66
- // Find the largest data object based on hierarchy
67
- const findLargestDataObject = arrayOfObjects => {
68
- const hierarchy = {
69
- 'Small': 16,
70
- 'Medium': 32,
71
- 'Large': 64
72
- };
73
- let largestValue = 0;
74
- arrayOfObjects.forEach(obj => {
75
- const currentValue = hierarchy[obj.data];
76
- if (currentValue > largestValue) {
77
- largestValue = currentValue;
78
- }
79
- });
80
- return largestValue;
81
- };
82
-
83
- // Handle API response for auto-fetch
84
- useEffect(() => {
85
- if (autoFetch && inferenceData && typeof onComplete === 'function') {
86
- // In React Native, we'll handle this differently since we don't have window.addEventListener
87
- // We'll use the sendDataRequest function to handle this
88
- }
89
- }, []);
90
-
91
- // Handle connection selection
92
- const handleConnectionSelection = (dataRequester, key, index, type, reward, isSelected) => {
93
- setSelectedRequests(prev => ({
94
- ...prev,
95
- [`${dataRequester}-${key}-${index}`]: {
96
- type,
97
- reward,
98
- isSelected
99
- }
100
- }));
101
- };
102
-
103
- // Change granted value
104
- const changeGranted = value => {
105
- setGranted(prev => Math.max(prev + value, 0));
106
- };
107
-
108
- // Handle API request for mobile
109
- const handleAPIRequestForMobile = async () => {
110
- setShowOverlay(true);
111
- return;
112
- };
113
-
114
- // Reject data request
115
- const rejectDataRequest = () => {
116
- setShowOverlay(false);
117
- if (onComplete) {
118
- onComplete('rejected');
119
- }
120
- };
121
-
122
- // Make API call
123
- const makeApiCall = async (approvedRequests, pin, othentSub) => {
124
- const jsonData = {
125
- Info: {
126
- EncryptedUserPin: pin,
127
- confirmations: approvedRequests,
128
- web3Type: 'othent',
129
- Domain: Platform.OS,
130
- // Using platform instead of window.location
131
- proofMode: false,
132
- OthentSub: othentSub
133
- }
134
- };
135
- try {
136
- const response = await axios.post(`${API_URL}/getAPIurl`, jsonData);
137
- const data = response.data;
138
- if (autoFetch && onComplete) {
139
- onComplete(data);
140
- } else {
141
- // In React Native, we'll handle this differently
142
- // For now, just call onComplete with the data
143
- if (onComplete) {
144
- onComplete(data);
145
- }
146
- }
147
- } catch (error) {
148
- console.error(error);
149
- if (onComplete) {
150
- onComplete(null, error);
151
- }
152
- }
153
- };
154
-
155
- // Send data request
156
- const sendDataRequest = async () => {
157
- if (granted <= 0) return;
23
+ const [showOnboarding, setShowOnboarding] = useState(false);
24
+ const [showDataRequest, setShowDataRequest] = useState(false);
25
+ const {
26
+ hasCredentials,
27
+ getCredentials,
28
+ validateCredentials
29
+ } = useCredentials();
30
+ const [loading, setLoading] = useState(false);
31
+ const handlePress = useCallback(async () => {
32
+ setLoading(true);
158
33
  try {
159
- // Retrieve approved requests
160
- const approvedRequests = Object.values(selectedRequests).filter(req => req.isSelected).map(req => ({
161
- type: req.type,
162
- reward: req.reward
163
- }));
164
- if (encryptedPin == null && othentUser && !othentConnected) {
165
- const appInfo = {
166
- name: 'Onairos',
167
- version: '1.0.0',
168
- env: 'production'
169
- };
170
- const othent = new Othent({
171
- appInfo,
172
- throwErrors: false
173
- });
174
- const userDetails = await othent.connect();
175
- const hashedSub = sha256(userDetails.sub).toString();
176
- setHashedOthentSub(hashedSub);
177
-
178
- // Wait for the pin to be retrieved
179
- const userOnairosDetails = await getPin(hashedSub);
180
- const pin = userOnairosDetails.result;
181
- setEncryptedPin(pin);
182
- setOthentConnected(true);
183
-
184
- // Make API call with newly retrieved data
185
- await makeApiCall(approvedRequests, pin, hashedSub);
186
- } else {
187
- // Make API call with existing state
188
- if (encryptedPin && hashedOthentSub) {
189
- await makeApiCall(approvedRequests, encryptedPin, hashedOthentSub);
190
- } else {
191
- console.error('Missing required authentication data');
192
- }
193
- }
194
- } catch (error) {
195
- console.error('Error in sendDataRequest:', error);
196
- } finally {
197
- setShowOverlay(false);
198
- }
199
- };
200
-
201
- // Validate request data
202
- const validateRequestData = () => {
203
- const validKeys = ['Small', 'Medium', 'Large'];
204
- const requiredProperties = ['type', 'descriptions', 'reward'];
205
- if (typeof webpageName !== 'string') {
206
- throw new Error(`Property webpageName must be a String`);
207
- }
208
- for (const key of validKeys) {
209
- if (!(key in requestData)) {
210
- throw new Error(`Missing key '${key}' in requestData.`);
34
+ const hasExisting = await hasCredentials();
35
+ if (!hasExisting) {
36
+ setShowOnboarding(true);
37
+ return;
211
38
  }
212
- for (const prop of requiredProperties) {
213
- if (!(prop in requestData[key])) {
214
- throw new Error(`Missing property '${prop}' in requestData.${key}.`);
215
- }
216
- if (prop !== 'reward' && typeof requestData[key][prop] !== 'string') {
217
- throw new Error(`Property '${prop}' in requestData.${key} must be a string.`);
218
- }
219
- if (prop !== 'reward' && requestData[key][prop].trim() === '') {
220
- throw new Error(`Property '${prop}' in requestData.${key} cannot be empty.`);
221
- }
39
+ const credentials = await getCredentials();
40
+ if (!credentials) {
41
+ setShowOnboarding(true);
42
+ return;
222
43
  }
223
- }
224
- };
225
-
226
- // Validate domain
227
- const validateDomain = async () => {
228
- try {
229
- const response = await axios.post(`${API_URL}/valid/validate-domain`);
230
- return response.data;
231
- } catch (error) {
232
- console.error(error);
233
- return {
234
- status: false
235
- };
236
- }
237
- };
238
-
239
- // Connect to Onairos
240
- const ConnectOnairos = async () => {
241
- try {
242
- const appInfo = {
243
- name: "Onairos",
244
- version: "1.0.0",
245
- env: "production"
246
- };
247
- const othent = new Othent({
248
- appInfo,
249
- throwErrors: false
250
- });
251
-
252
- // Get User Othent Secure Details
253
- const userDetails = await othent.connect();
254
- const hashedOthentSub = sha256(userDetails.sub).toString();
255
- const encryptedPinResponse = await getPin(hashedOthentSub);
256
-
257
- // Check if user account exists
258
- if (encryptedPinResponse.result === "No user account") {
259
- // No user account found, trigger universal onboarding
260
- console.log("No user account found, triggering universal onboarding");
261
-
262
- // In React Native, we'll handle this differently
263
- // For now, just show the overlay for onboarding
264
- NoAccount.current = true;
265
- setShowOverlay(true);
44
+ const validationResult = await validateCredentials(credentials.username);
45
+ if (!validationResult.isValid) {
46
+ setShowOnboarding(true);
266
47
  return;
267
48
  }
268
49
 
269
- // Convert to buffer and decrypt
270
- const bufferPIN = Buffer.from(encryptedPinResponse.result, 'base64');
271
- const userPin = await othent.decrypt(bufferPIN);
272
-
273
- // RSA Encrypt the PIN
274
- const encryptedData = await rsaEncrypt(OnairosPublicKey, userPin);
275
-
276
- // In React Native, we'll handle this differently
277
- // For now, just show the overlay with the data
278
- setEncryptedPin(encryptedData);
279
- setHashedOthentSub(hashedOthentSub);
280
- setShowOverlay(true);
281
- } catch (e) {
282
- console.error("Error Connecting to Onairos: ", e);
283
- }
284
- };
285
-
286
- // Fetch account info
287
- const fetchAccountInfo = async (identifier, isEmail = false) => {
288
- try {
289
- setIsLoading(true);
290
- const jsonData = isEmail ? {
291
- Info: {
292
- identifier: identifier
293
- }
294
- } : {
295
- Info: {
296
- userName: identifier
297
- }
298
- };
299
- const endpoint = isEmail ? '/getAccountInfo/email' : '/getAccountInfo';
300
- const token = await AsyncStorage.getItem('onairosToken');
301
- const response = await axios.post(`${API_URL}${endpoint}`, jsonData, {
302
- headers: {
303
- 'Content-Type': 'application/json',
304
- 'Authorization': `Bearer ${token}`
305
- }
306
- });
307
- const data = response.data;
308
- if (data.AccountInfo === "No Account Found") {
309
- NoAccount.current = true;
310
- setAccountInfo(null);
311
- return null;
312
- }
313
- setAccountInfo(data.AccountInfo);
314
- if (data.AccountInfo.models) {
315
- setActiveModels(data.AccountInfo.models);
316
- } else {
317
- NoModel.current = true;
318
- }
319
- if (data.AccountInfo.avatar) {
320
- setAvatar(true);
321
- }
322
- if (data.AccountInfo.UserTraits) {
323
- setTraits(true);
324
- }
325
- if (data.AccountInfo.othent) {
326
- setOthentUser(true);
327
- }
328
- return data.AccountInfo;
50
+ // If we have valid credentials, show data request modal
51
+ setShowDataRequest(true);
329
52
  } catch (error) {
330
- console.error('Error fetching account info:', error);
331
- throw error;
53
+ console.error('Error in button press:', error);
54
+ setShowOnboarding(true);
332
55
  } finally {
333
- setIsLoading(false);
56
+ setLoading(false);
334
57
  }
335
- };
336
-
337
- // Check existing token
338
- const checkExistingToken = async () => {
58
+ }, [hasCredentials, getCredentials, validateCredentials]);
59
+ const handleDataRequestAccept = useCallback(async () => {
339
60
  try {
340
- const onairosToken = await AsyncStorage.getItem('onairosToken');
341
- const legacyToken = await AsyncStorage.getItem('token');
342
- const token = onairosToken || legacyToken;
343
- if (token) {
344
- const response = await axios.get(`${API_URL}/verifyToken`, {
345
- headers: {
346
- 'Authorization': `Bearer ${token}`
347
- }
348
- });
349
- if (response.status === 200) {
350
- const data = response.data;
351
- if (data.valid) {
352
- setAuthToken(token);
353
- setIsAuthenticated(true);
354
- const username = await AsyncStorage.getItem('username');
355
- await fetchAccountInfo(username);
356
- } else {
357
- await AsyncStorage.removeItem('onairosToken');
358
- await AsyncStorage.removeItem('token');
359
- }
360
- }
61
+ const credentials = await getCredentials();
62
+ if (credentials) {
63
+ onResolved('https://api2.onairos.uk', credentials.accessToken, credentials);
361
64
  }
65
+ setShowDataRequest(false);
362
66
  } catch (error) {
363
- console.error('Token verification failed:', error);
364
- } finally {
365
- setLoading(false);
67
+ console.error('Error handling data request accept:', error);
366
68
  }
367
- };
368
-
369
- // Check for existing token on mount
370
- useEffect(() => {
371
- checkExistingToken();
372
- }, []);
373
-
374
- // Handle close overlay
375
- const handleCloseOverlay = () => {
376
- setGranted(0);
377
- setShowOverlay(false);
378
- };
379
-
380
- // Check for existing token and fetch account info on mount
69
+ }, [getCredentials, onResolved]);
381
70
  useEffect(() => {
382
- const checkStoredAuth = async () => {
383
- const token = await AsyncStorage.getItem('onairosToken');
384
- const username = await AsyncStorage.getItem('username');
385
- const othentToken = await AsyncStorage.getItem('othentToken');
386
- if (token) {
387
- try {
388
- // Verify token is still valid
389
- const response = await axios.post(`${API_URL}/verifyToken`, {}, {
390
- headers: {
391
- 'Content-Type': 'application/json',
392
- 'Authorization': `Bearer ${token}`
393
- }
394
- });
395
- if (response.status === 200) {
396
- setIsAuthenticated(true);
397
- if (username) {
398
- await fetchAccountInfo(username, false);
399
- } else if (othentToken) {
400
- // Handle Othent stored session
401
- const userDetails = JSON.parse(othentToken);
402
- await fetchAccountInfo(userDetails.email, true);
403
- }
404
- } else {
405
- // Clear invalid tokens
406
- await AsyncStorage.removeItem('onairosToken');
407
- await AsyncStorage.removeItem('username');
408
- await AsyncStorage.removeItem('othentToken');
409
- }
410
- } catch (error) {
411
- console.error('Token verification failed:', error);
71
+ // Setup deep linking
72
+ const handleDeepLink = ({
73
+ url
74
+ }) => {
75
+ if (url.includes('onairosreact://authenticate')) {
76
+ // Handle authentication callback
77
+ const params = new URL(url).searchParams;
78
+ const nonce = params.get('nonce');
79
+ const callback = params.get('callback');
80
+ if (nonce && callback) {
81
+ // Process authentication
82
+ setShowOnboarding(false);
412
83
  }
413
84
  }
414
85
  };
415
- checkStoredAuth();
86
+ Linking.addEventListener('url', handleDeepLink);
87
+ return () => {
88
+ // Cleanup deep linking
89
+ // Note: Remove event listener based on RN version
90
+ // if (Platform.OS === 'android') {
91
+ // Linking.removeEventListener('url', handleDeepLink);
92
+ // }
93
+ };
416
94
  }, []);
417
-
418
- // Handle login success
419
- const handleLoginSuccess = async (identifier, isEmail = false) => {
420
- try {
421
- const accountData = await fetchAccountInfo(identifier, isEmail);
422
- // Update authentication first
423
- setIsAuthenticated(true);
424
- // Then update account info
425
- setShowOverlay(true);
426
- return accountData;
427
- } catch (error) {
428
- console.error('Login process failed:', error);
429
- throw error;
430
- }
431
- };
432
-
433
- // Get text based on login type
434
- const getText = () => {
435
- switch (loginType) {
436
- case 'signUp':
437
- return 'Sign Up with Onairos';
438
- case 'signOut':
439
- return 'Sign Out of Onairos';
440
- default:
441
- return 'Sign In with Onairos';
442
- }
443
- };
444
-
445
- // Button press handler
446
- const handleButtonPress = () => {
447
- handleAPIRequestForMobile();
448
- };
449
- return /*#__PURE__*/React.createElement(View, {
450
- style: styles.container
451
- }, /*#__PURE__*/React.createElement(TouchableOpacity, {
452
- style: [styles.button, buttonType === 'pill' ? styles.pillButton : styles.circleButton, login ? styles.loginButton : styles.transparentButton, {
453
- flexDirection: textLayout === 'below' ? 'column' : 'row'
454
- }],
455
- onPress: handleButtonPress
456
- }, (visualType === 'full' || visualType === 'icon') && /*#__PURE__*/React.createElement(Image, {
457
- source: {
458
- uri: login ? "https://onairos.sirv.com/Images/OnairosWhite.png" : "https://onairos.sirv.com/Images/OnairosBlack.png"
459
- },
460
- style: [styles.logo, buttonType === 'pill' ? styles.pillLogo : styles.circleLogo, visualType === 'full' ? styles.fullLogo : styles.iconOnlyLogo]
461
- }), (visualType === 'full' || visualType === 'textOnly') && /*#__PURE__*/React.createElement(Text, {
462
- style: [styles.buttonText, {
463
- color: login ? 'black' : textColor === 'black' ? 'black' : 'white'
464
- }, textLayout === 'right' ? styles.textRight : textLayout === 'left' ? styles.textLeft : styles.textBelow]
465
- }, getText())), showOverlay && !isLoading && /*#__PURE__*/React.createElement(Overlay, {
466
- setOthentConnected: setOthentConnected,
467
- dataRequester: webpageName,
468
- NoAccount: NoAccount,
469
- NoModel: NoModel,
470
- accountInfo: accountInfo,
471
- activeModels: activeModels,
472
- avatar: avatar,
473
- traits: traits,
95
+ const buttonStyles = [styles.button, buttonType === 'pill' ? styles.pillButton : styles.circleButton, {
96
+ backgroundColor: color
97
+ }];
98
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(TouchableOpacity, {
99
+ style: buttonStyles,
100
+ onPress: handlePress,
101
+ disabled: loading
102
+ }, /*#__PURE__*/React.createElement(Icon, {
103
+ name: icon,
104
+ size: 24,
105
+ color: "white"
106
+ }), buttonType === 'pill' && /*#__PURE__*/React.createElement(Text, {
107
+ style: styles.buttonText
108
+ }, "Connect with Onairos")), /*#__PURE__*/React.createElement(UniversalOnboarding, {
109
+ visible: showOnboarding,
110
+ onClose: () => setShowOnboarding(false),
111
+ AppName: AppName,
474
112
  requestData: requestData,
475
- handleConnectionSelection: handleConnectionSelection,
476
- changeGranted: changeGranted,
477
- granted: granted,
478
- allowSubmit: granted > 0,
479
- rejectDataRequest: rejectDataRequest,
480
- sendDataRequest: sendDataRequest,
481
- isAuthenticated: isAuthenticated,
482
- onLoginSuccess: handleLoginSuccess,
483
- onClose: handleCloseOverlay,
484
- setOthentUser: setOthentUser,
485
- setHashedOthentSub: setHashedOthentSub,
486
- setEncryptedPin: setEncryptedPin
113
+ returnLink: returnLink,
114
+ onComplete: onResolved,
115
+ embedd: embedd,
116
+ debug: debug,
117
+ test: test
118
+ }), /*#__PURE__*/React.createElement(DataRequestModal, {
119
+ visible: showDataRequest,
120
+ onClose: () => setShowDataRequest(false),
121
+ onAccept: handleDataRequestAccept,
122
+ requestData: requestData,
123
+ AppName: AppName
487
124
  }));
488
125
  };
489
126
  const styles = StyleSheet.create({
490
- container: {
491
- alignItems: 'center',
492
- justifyContent: 'center'
493
- },
494
127
  button: {
495
128
  alignItems: 'center',
496
129
  justifyContent: 'center',
497
- borderRadius: 8
498
- },
499
- pillButton: {
500
- paddingHorizontal: 16,
501
- paddingVertical: 8,
502
- borderRadius: 20
130
+ elevation: 3,
131
+ shadowColor: '#000',
132
+ shadowOffset: {
133
+ width: 0,
134
+ height: 2
135
+ },
136
+ shadowOpacity: 0.25,
137
+ shadowRadius: 3.84
503
138
  },
504
139
  circleButton: {
505
- width: 48,
506
- height: 48,
507
- borderRadius: 24
508
- },
509
- loginButton: {
510
- backgroundColor: '#ffffff',
511
- borderWidth: 1,
512
- borderColor: '#dddddd'
513
- },
514
- transparentButton: {
515
- backgroundColor: 'transparent',
516
- borderWidth: 1,
517
- borderColor: 'transparent'
518
- },
519
- logo: {
520
- resizeMode: 'contain'
521
- },
522
- pillLogo: {
523
- width: 24,
524
- height: 24
525
- },
526
- circleLogo: {
527
- width: 32,
528
- height: 32
140
+ width: 60,
141
+ height: 60,
142
+ borderRadius: 30
529
143
  },
530
- fullLogo: {
531
- marginRight: 12
532
- },
533
- iconOnlyLogo: {
534
- marginRight: 0
144
+ pillButton: {
145
+ flexDirection: 'row',
146
+ paddingHorizontal: 16,
147
+ paddingVertical: 12,
148
+ borderRadius: 25
535
149
  },
536
150
  buttonText: {
537
- fontWeight: 'bold'
538
- },
539
- textRight: {
540
- marginLeft: 8
541
- },
542
- textLeft: {
543
- marginRight: 8
544
- },
545
- textBelow: {
546
- marginTop: 4
151
+ color: 'white',
152
+ marginLeft: 8,
153
+ fontSize: 16,
154
+ fontWeight: '600'
547
155
  }
548
156
  });
549
- export default OnairosButton;
550
157
  //# sourceMappingURL=OnairosButton.js.map