@teamvortexsoftware/vortex-react-native 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/InviteFormCore-D4HkMMo0.d.mts +721 -0
- package/dist/InviteFormCore-D9oUCbu7.d.ts +721 -0
- package/dist/VortexClient.js +192 -0
- package/dist/VortexClient.js.map +1 -0
- package/dist/VortexDeferredLinks.js +127 -0
- package/dist/VortexDeferredLinks.js.map +1 -0
- package/dist/clientInfo.js +45 -0
- package/dist/clientInfo.js.map +1 -0
- package/dist/components/ContactsPickerModal.js +182 -0
- package/dist/components/ContactsPickerModal.js.map +1 -0
- package/dist/components/InviteFormCore.js +2141 -0
- package/dist/components/InviteFormCore.js.map +1 -0
- package/dist/components/InviteFormMobile.js +463 -0
- package/dist/components/InviteFormMobile.js.map +1 -0
- package/dist/components/InviteFormWeb.js +295 -0
- package/dist/components/InviteFormWeb.js.map +1 -0
- package/dist/components/PlacedItemToolbar.js +147 -0
- package/dist/components/PlacedItemToolbar.js.map +1 -0
- package/dist/components/ShareButtons.js +181 -0
- package/dist/components/ShareButtons.js.map +1 -0
- package/dist/components/VrtxContactsImport.js +234 -0
- package/dist/components/VrtxContactsImport.js.map +1 -0
- package/dist/components/VrtxEmailInvitations.js +341 -0
- package/dist/components/VrtxEmailInvitations.js.map +1 -0
- package/dist/components/VrtxFindFriends.js +400 -0
- package/dist/components/VrtxFindFriends.js.map +1 -0
- package/dist/components/VrtxHeading.js +58 -0
- package/dist/components/VrtxHeading.js.map +1 -0
- package/dist/components/VrtxIncomingInvitations.js +657 -0
- package/dist/components/VrtxIncomingInvitations.js.map +1 -0
- package/dist/components/VrtxInvitationSuggestions.js +506 -0
- package/dist/components/VrtxInvitationSuggestions.js.map +1 -0
- package/dist/components/VrtxInviteContacts.js +512 -0
- package/dist/components/VrtxInviteContacts.js.map +1 -0
- package/dist/components/VrtxOutgoingInvitations.js +572 -0
- package/dist/components/VrtxOutgoingInvitations.js.map +1 -0
- package/dist/components/VrtxSearchBox.js +487 -0
- package/dist/components/VrtxSearchBox.js.map +1 -0
- package/dist/components/VrtxSelect.js +27 -0
- package/dist/components/VrtxSelect.js.map +1 -0
- package/dist/components/VrtxShareOptions.js +435 -0
- package/dist/components/VrtxShareOptions.js.map +1 -0
- package/dist/components/VrtxSubmit.js +132 -0
- package/dist/components/VrtxSubmit.js.map +1 -0
- package/dist/components/VrtxText.js +146 -0
- package/dist/components/VrtxText.js.map +1 -0
- package/dist/constants/mockData.d.mts +7 -0
- package/dist/constants/mockData.d.ts +7 -0
- package/dist/constants/mockData.js +48 -0
- package/dist/constants/mockData.js.map +1 -0
- package/dist/constants/mockData.mjs +22 -0
- package/dist/constants/mockData.mjs.map +1 -0
- package/dist/context/VortexModulesContext.js +135 -0
- package/dist/context/VortexModulesContext.js.map +1 -0
- package/dist/hooks/useInvitationFormLogic.d.mts +2 -0
- package/dist/hooks/useInvitationFormLogic.d.ts +2 -0
- package/dist/hooks/useInvitationFormLogic.js +300 -0
- package/dist/hooks/useInvitationFormLogic.js.map +1 -0
- package/dist/hooks/useInvitationFormLogic.mjs +276 -0
- package/dist/hooks/useInvitationFormLogic.mjs.map +1 -0
- package/dist/hooks/usePrefetchWidgetConfiguration.js +117 -0
- package/dist/hooks/usePrefetchWidgetConfiguration.js.map +1 -0
- package/dist/hooks/useThemeStyles.js +41 -0
- package/dist/hooks/useThemeStyles.js.map +1 -0
- package/dist/hooks/useVortexInvite.js +732 -0
- package/dist/hooks/useVortexInvite.js.map +1 -0
- package/dist/index-web.d.mts +93 -0
- package/dist/index-web.d.ts +93 -0
- package/dist/index-web.js +7397 -0
- package/dist/index-web.js.map +1 -0
- package/dist/index-web.mjs +7445 -0
- package/dist/index-web.mjs.map +1 -0
- package/dist/index.d.mts +656 -0
- package/dist/index.d.ts +656 -0
- package/dist/index.js +10206 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +10244 -0
- package/dist/index.mjs.map +1 -0
- package/dist/types/VortexClient.d.ts +106 -0
- package/dist/types/VortexClient.d.ts.map +1 -0
- package/dist/types/VortexDeferredLinks.d.ts +73 -0
- package/dist/types/VortexDeferredLinks.d.ts.map +1 -0
- package/dist/types/clientInfo.d.ts +5 -0
- package/dist/types/clientInfo.d.ts.map +1 -0
- package/dist/types/components/ContactsPickerModal.d.ts +18 -0
- package/dist/types/components/ContactsPickerModal.d.ts.map +1 -0
- package/dist/types/components/InviteFormCore.d.ts +166 -0
- package/dist/types/components/InviteFormCore.d.ts.map +1 -0
- package/dist/types/components/InviteFormMobile.d.ts +42 -0
- package/dist/types/components/InviteFormMobile.d.ts.map +1 -0
- package/dist/types/components/InviteFormWeb.d.ts +87 -0
- package/dist/types/components/InviteFormWeb.d.ts.map +1 -0
- package/dist/types/components/PlacedItemToolbar.d.ts +16 -0
- package/dist/types/components/PlacedItemToolbar.d.ts.map +1 -0
- package/dist/types/components/ShareButtons.d.ts +29 -0
- package/dist/types/components/ShareButtons.d.ts.map +1 -0
- package/dist/types/components/VrtxContactsImport.d.ts +14 -0
- package/dist/types/components/VrtxContactsImport.d.ts.map +1 -0
- package/dist/types/components/VrtxEmailInvitations.d.ts +31 -0
- package/dist/types/components/VrtxEmailInvitations.d.ts.map +1 -0
- package/dist/types/components/VrtxFindFriends.d.ts +25 -0
- package/dist/types/components/VrtxFindFriends.d.ts.map +1 -0
- package/dist/types/components/VrtxHeading.d.ts +6 -0
- package/dist/types/components/VrtxHeading.d.ts.map +1 -0
- package/dist/types/components/VrtxIncomingInvitations.d.ts +27 -0
- package/dist/types/components/VrtxIncomingInvitations.d.ts.map +1 -0
- package/dist/types/components/VrtxInvitationSuggestions.d.ts +25 -0
- package/dist/types/components/VrtxInvitationSuggestions.d.ts.map +1 -0
- package/dist/types/components/VrtxInviteContacts.d.ts +24 -0
- package/dist/types/components/VrtxInviteContacts.d.ts.map +1 -0
- package/dist/types/components/VrtxOutgoingInvitations.d.ts +27 -0
- package/dist/types/components/VrtxOutgoingInvitations.d.ts.map +1 -0
- package/dist/types/components/VrtxSearchBox.d.ts +28 -0
- package/dist/types/components/VrtxSearchBox.d.ts.map +1 -0
- package/dist/types/components/VrtxSelect.d.ts +6 -0
- package/dist/types/components/VrtxSelect.d.ts.map +1 -0
- package/dist/types/components/VrtxShareOptions.d.ts +41 -0
- package/dist/types/components/VrtxShareOptions.d.ts.map +1 -0
- package/dist/types/components/VrtxSubmit.d.ts +18 -0
- package/dist/types/components/VrtxSubmit.d.ts.map +1 -0
- package/dist/types/components/VrtxText.d.ts +8 -0
- package/dist/types/components/VrtxText.d.ts.map +1 -0
- package/dist/types/constants/mockData.d.ts +4 -0
- package/dist/types/constants/mockData.d.ts.map +1 -0
- package/dist/types/context/VortexModulesContext.d.ts +238 -0
- package/dist/types/context/VortexModulesContext.d.ts.map +1 -0
- package/dist/types/findFriends.js +10 -0
- package/dist/types/findFriends.js.map +1 -0
- package/dist/types/hooks/useInvitationFormLogic.d.ts +55 -0
- package/dist/types/hooks/useInvitationFormLogic.d.ts.map +1 -0
- package/dist/types/hooks/usePrefetchWidgetConfiguration.d.ts +39 -0
- package/dist/types/hooks/usePrefetchWidgetConfiguration.d.ts.map +1 -0
- package/dist/types/hooks/useThemeStyles.d.ts +35 -0
- package/dist/types/hooks/useThemeStyles.d.ts.map +1 -0
- package/dist/types/hooks/useVortexInvite.d.ts +86 -0
- package/dist/types/hooks/useVortexInvite.d.ts.map +1 -0
- package/dist/types/index-web.d.ts +23 -0
- package/dist/types/index-web.d.ts.map +1 -0
- package/dist/types/index.d.ts +23 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/invitations.js +13 -0
- package/dist/types/invitations.js.map +1 -0
- package/dist/types/inviteContacts.js +14 -0
- package/dist/types/inviteContacts.js.map +1 -0
- package/dist/types/platformOperations.js +3 -0
- package/dist/types/platformOperations.js.map +1 -0
- package/dist/types/searchBox.js +11 -0
- package/dist/types/searchBox.js.map +1 -0
- package/dist/types/types/findFriends.d.ts +101 -0
- package/dist/types/types/findFriends.d.ts.map +1 -0
- package/dist/types/types/invitations.d.ts +301 -0
- package/dist/types/types/invitations.d.ts.map +1 -0
- package/dist/types/types/inviteContacts.d.ts +86 -0
- package/dist/types/types/inviteContacts.d.ts.map +1 -0
- package/dist/types/types/platformOperations.d.ts +185 -0
- package/dist/types/types/platformOperations.d.ts.map +1 -0
- package/dist/types/types/searchBox.d.ts +69 -0
- package/dist/types/types/searchBox.d.ts.map +1 -0
- package/dist/types/types/unfurlConfig.d.ts +34 -0
- package/dist/types/types/unfurlConfig.d.ts.map +1 -0
- package/dist/types/unfurlConfig.js +21 -0
- package/dist/types/unfurlConfig.js.map +1 -0
- package/dist/types/utils/analytics.d.ts +54 -0
- package/dist/types/utils/analytics.d.ts.map +1 -0
- package/dist/types/utils/configCache.d.ts +34 -0
- package/dist/types/utils/configCache.d.ts.map +1 -0
- package/dist/types/utils/contactUtils.d.ts +9 -0
- package/dist/types/utils/contactUtils.d.ts.map +1 -0
- package/dist/types/utils/featureWarnings.d.ts +56 -0
- package/dist/types/utils/featureWarnings.d.ts.map +1 -0
- package/dist/types/utils/formUtils.d.ts +93 -0
- package/dist/types/utils/formUtils.d.ts.map +1 -0
- package/dist/types/utils/gradientUtils.d.ts +67 -0
- package/dist/types/utils/gradientUtils.d.ts.map +1 -0
- package/dist/types/utils/invitationEvents.d.ts +21 -0
- package/dist/types/utils/invitationEvents.d.ts.map +1 -0
- package/dist/types/utils/moduleLoaders.d.ts +115 -0
- package/dist/types/utils/moduleLoaders.d.ts.map +1 -0
- package/dist/types/utils/moduleLoaders.web.d.ts +73 -0
- package/dist/types/utils/moduleLoaders.web.d.ts.map +1 -0
- package/dist/types/utils/nameUtils.d.ts +15 -0
- package/dist/types/utils/nameUtils.d.ts.map +1 -0
- package/dist/types/utils/themeUtils.d.ts +38 -0
- package/dist/types/utils/themeUtils.d.ts.map +1 -0
- package/dist/types/vortexInvite.d.ts +165 -0
- package/dist/types/vortexInvite.d.ts.map +1 -0
- package/dist/useInvitationFormLogic-Ct73M19B.d.mts +242 -0
- package/dist/useInvitationFormLogic-Ct73M19B.d.ts +242 -0
- package/dist/utils/analytics.js +92 -0
- package/dist/utils/analytics.js.map +1 -0
- package/dist/utils/configCache.js +68 -0
- package/dist/utils/configCache.js.map +1 -0
- package/dist/utils/contactUtils.d.mts +12 -0
- package/dist/utils/contactUtils.d.ts +12 -0
- package/dist/utils/contactUtils.js +37 -0
- package/dist/utils/contactUtils.js.map +1 -0
- package/dist/utils/contactUtils.mjs +12 -0
- package/dist/utils/contactUtils.mjs.map +1 -0
- package/dist/utils/featureWarnings.js +214 -0
- package/dist/utils/featureWarnings.js.map +1 -0
- package/dist/utils/formUtils.js +284 -0
- package/dist/utils/formUtils.js.map +1 -0
- package/dist/utils/gradientUtils.js +120 -0
- package/dist/utils/gradientUtils.js.map +1 -0
- package/dist/utils/invitationEvents.js +45 -0
- package/dist/utils/invitationEvents.js.map +1 -0
- package/dist/utils/moduleLoaders.js +275 -0
- package/dist/utils/moduleLoaders.js.map +1 -0
- package/dist/utils/moduleLoaders.web.js +72 -0
- package/dist/utils/moduleLoaders.web.js.map +1 -0
- package/dist/utils/nameUtils.js +51 -0
- package/dist/utils/nameUtils.js.map +1 -0
- package/dist/utils/themeUtils.js +141 -0
- package/dist/utils/themeUtils.js.map +1 -0
- package/dist/vortexInvite.js +83 -0
- package/dist/vortexInvite.js.map +1 -0
- package/package.json +21 -56
|
@@ -0,0 +1,463 @@
|
|
|
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
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
45
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
|
+
};
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.InviteFormMobile = InviteFormMobile;
|
|
49
|
+
const react_1 = __importStar(require("react"));
|
|
50
|
+
const react_native_1 = require("react-native");
|
|
51
|
+
const FontAwesome6_1 = __importDefault(require("react-native-vector-icons/FontAwesome6"));
|
|
52
|
+
const InviteFormCore_1 = require("./InviteFormCore");
|
|
53
|
+
const useVortexInvite_1 = require("../hooks/useVortexInvite");
|
|
54
|
+
const nameUtils_1 = require("../utils/nameUtils");
|
|
55
|
+
// Map from generic icon names to FontAwesome6 names
|
|
56
|
+
const iconMap = {
|
|
57
|
+
close: 'xmark',
|
|
58
|
+
'arrow-back': 'arrow-left',
|
|
59
|
+
link: 'link',
|
|
60
|
+
share: 'share-nodes',
|
|
61
|
+
'import-contacts': 'address-book',
|
|
62
|
+
email: 'envelope',
|
|
63
|
+
google: 'google',
|
|
64
|
+
'x-twitter': 'x-twitter',
|
|
65
|
+
instagram: 'instagram',
|
|
66
|
+
sms: 'comment',
|
|
67
|
+
whatsapp: 'whatsapp',
|
|
68
|
+
line: 'line',
|
|
69
|
+
'qr-code': 'qrcode',
|
|
70
|
+
telegram: 'telegram',
|
|
71
|
+
discord: 'discord',
|
|
72
|
+
'facebook-messenger': 'facebook-messenger',
|
|
73
|
+
search: 'magnifying-glass',
|
|
74
|
+
};
|
|
75
|
+
function InviteFormMobile({ platform = 'ios', onClose, widgetConfiguration: propsWidgetConfiguration, componentId, jwt, user, vortexApiUrl, group, groups, scope, scopeType, googleIosClientId, googleWebClientId, analyticsBaseURL, onEvent, analyticsSegmentation, findFriendsConfig, incomingInvitationsConfig, outgoingInvitationsConfig, inviteContactsConfig, searchBoxConfig, locale, invitationSuggestionsConfig, unfurlConfig, }) {
|
|
76
|
+
const hookResult = (0, useVortexInvite_1.useVortexInvite)({
|
|
77
|
+
componentId,
|
|
78
|
+
jwt: jwt,
|
|
79
|
+
user: user,
|
|
80
|
+
vortexApiUrl: vortexApiUrl,
|
|
81
|
+
group,
|
|
82
|
+
groups,
|
|
83
|
+
scope,
|
|
84
|
+
scopeType,
|
|
85
|
+
widgetConfiguration: propsWidgetConfiguration, // Pass prefetched configuration to skip loading
|
|
86
|
+
analyticsBaseURL,
|
|
87
|
+
onEvent,
|
|
88
|
+
analyticsSegmentation,
|
|
89
|
+
locale,
|
|
90
|
+
});
|
|
91
|
+
// Use configuration from hook if available (fresh data), otherwise use prefetched configuration from props
|
|
92
|
+
// This ensures background refetch updates are reflected (stale-while-revalidate pattern)
|
|
93
|
+
const widgetConfiguration = hookResult.widgetConfiguration || propsWidgetConfiguration;
|
|
94
|
+
const { loading, error } = hookResult;
|
|
95
|
+
// Track widget render when configuration is loaded
|
|
96
|
+
(0, react_1.useEffect)(() => {
|
|
97
|
+
if (widgetConfiguration && !loading && !error) {
|
|
98
|
+
hookResult.trackWidgetRender();
|
|
99
|
+
}
|
|
100
|
+
}, [widgetConfiguration, loading, error, hookResult.trackWidgetRender]);
|
|
101
|
+
// Track widget error when error occurs
|
|
102
|
+
(0, react_1.useEffect)(() => {
|
|
103
|
+
if (error) {
|
|
104
|
+
hookResult.trackWidgetError(error.message || 'Unknown error');
|
|
105
|
+
}
|
|
106
|
+
}, [error, hookResult.trackWidgetError]);
|
|
107
|
+
// Platform-specific font families
|
|
108
|
+
const fontFamily = platform === 'ios'
|
|
109
|
+
? '-apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", "Helvetica Neue", sans-serif'
|
|
110
|
+
: 'Roboto, "Segoe UI", "Helvetica Neue", sans-serif';
|
|
111
|
+
const renderIcon = ({ name, size, color, opacity }) => {
|
|
112
|
+
const iconName = iconMap[name] || name;
|
|
113
|
+
return <FontAwesome6_1.default name={iconName} size={size} color={color} solid={true} style={opacity != null ? { opacity } : undefined}/>;
|
|
114
|
+
};
|
|
115
|
+
const renderQRCode = ({ value, size }) => {
|
|
116
|
+
try {
|
|
117
|
+
// Dynamic import to avoid hard dependency
|
|
118
|
+
const QRCode = require('react-native-qrcode-svg').default;
|
|
119
|
+
return <QRCode value={value} size={size} color="#333" backgroundColor="#fff"/>;
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
console.warn('[Vortex] react-native-qrcode-svg not available:', error);
|
|
123
|
+
return (<react_native_1.View style={{ padding: 20, alignItems: 'center' }}>
|
|
124
|
+
<react_native_1.Text style={{ fontSize: 14, color: '#666', textAlign: 'center', fontFamily }}>
|
|
125
|
+
QR Code feature not available. Install react-native-qrcode-svg and react-native-svg to
|
|
126
|
+
enable.
|
|
127
|
+
</react_native_1.Text>
|
|
128
|
+
</react_native_1.View>);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
// Native platform operations using the hook's methods for copy/share (handles API calls)
|
|
132
|
+
// Wrapped in useMemo to prevent recreation on every render, which would cause infinite loops
|
|
133
|
+
const platformOperations = (0, react_1.useMemo)(() => ({
|
|
134
|
+
copyToClipboard: () => __awaiter(this, void 0, void 0, function* () {
|
|
135
|
+
yield hookResult.handleCopyLink();
|
|
136
|
+
}),
|
|
137
|
+
share: () => __awaiter(this, void 0, void 0, function* () {
|
|
138
|
+
yield hookResult.handleShareLink();
|
|
139
|
+
}),
|
|
140
|
+
close: () => __awaiter(this, void 0, void 0, function* () {
|
|
141
|
+
// Sign out from Google to allow account switching on next open
|
|
142
|
+
try {
|
|
143
|
+
const module = yield Promise.resolve().then(() => __importStar(require('@react-native-google-signin/google-signin')));
|
|
144
|
+
const { GoogleSignin } = module;
|
|
145
|
+
yield GoogleSignin.signOut();
|
|
146
|
+
console.info('[Vortex] Signed out from Google to allow account switching.');
|
|
147
|
+
}
|
|
148
|
+
catch (signOutErr) {
|
|
149
|
+
// Ignore sign-out errors (user might not have been signed in, or library not available)
|
|
150
|
+
console.debug('[Vortex] Google sign-out skipped:', signOutErr);
|
|
151
|
+
}
|
|
152
|
+
if (onClose) {
|
|
153
|
+
onClose();
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
console.log('[Vortex] Close bottom sheet');
|
|
157
|
+
}
|
|
158
|
+
}),
|
|
159
|
+
triggerHaptic: (style) => __awaiter(this, void 0, void 0, function* () {
|
|
160
|
+
try {
|
|
161
|
+
// Dynamic import to avoid hard dependency
|
|
162
|
+
const Haptics = yield Promise.resolve().then(() => __importStar(require('expo-haptics')));
|
|
163
|
+
const feedbackStyle = style === 'light'
|
|
164
|
+
? Haptics.ImpactFeedbackStyle.Light
|
|
165
|
+
: style === 'medium'
|
|
166
|
+
? Haptics.ImpactFeedbackStyle.Medium
|
|
167
|
+
: Haptics.ImpactFeedbackStyle.Heavy;
|
|
168
|
+
yield Haptics.impactAsync(feedbackStyle);
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
// Silent fail if expo-haptics not installed - this is expected and acceptable
|
|
172
|
+
console.debug('[Vortex] Haptic feedback not available:', error);
|
|
173
|
+
}
|
|
174
|
+
}),
|
|
175
|
+
fetchContacts: () => __awaiter(this, void 0, void 0, function* () {
|
|
176
|
+
// Call the existing fetchContactsWithEmailsIOS from the hook
|
|
177
|
+
if (!hookResult.fetchContactsWithEmailsIOS) {
|
|
178
|
+
console.warn('[Vortex] fetchContactsWithEmailsIOS method not available');
|
|
179
|
+
return [];
|
|
180
|
+
}
|
|
181
|
+
const contactsWithEmails = yield hookResult.fetchContactsWithEmailsIOS();
|
|
182
|
+
// Use a Map to deduplicate by unique key (contact.id + email)
|
|
183
|
+
const contactMap = new Map();
|
|
184
|
+
for (const contact of contactsWithEmails) {
|
|
185
|
+
for (const email of contact.emails) {
|
|
186
|
+
const key = `${contact.id}-${email}`;
|
|
187
|
+
// Only add if not already in the map (prevents duplicates)
|
|
188
|
+
if (!contactMap.has(key)) {
|
|
189
|
+
// Infer name from email if contact name is missing or empty
|
|
190
|
+
const displayName = contact.name && contact.name.trim() ? contact.name : (0, nameUtils_1.inferNameFromEmail)(email);
|
|
191
|
+
contactMap.set(key, {
|
|
192
|
+
id: key,
|
|
193
|
+
name: displayName,
|
|
194
|
+
email,
|
|
195
|
+
imageUri: contact.imageUri,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// Sort alphabetically by name
|
|
201
|
+
return Array.from(contactMap.values()).sort((a, b) => a.name.localeCompare(b.name));
|
|
202
|
+
}),
|
|
203
|
+
invite: (email, contactName) => __awaiter(this, void 0, void 0, function* () {
|
|
204
|
+
// Build content tokens for the invitation
|
|
205
|
+
const contentTokens = {
|
|
206
|
+
invitee_email: { value: email, type: 'email' },
|
|
207
|
+
};
|
|
208
|
+
// Add inviter name if available (could be extracted from JWT or config)
|
|
209
|
+
// For now, using a placeholder that the backend can override
|
|
210
|
+
contentTokens.inviter_name = { value: 'Current User', type: 'string' };
|
|
211
|
+
// Add contact name if provided
|
|
212
|
+
if (contactName) {
|
|
213
|
+
contentTokens.invitee_name = { value: contactName, type: 'string' };
|
|
214
|
+
}
|
|
215
|
+
// Add group information if available
|
|
216
|
+
if (group) {
|
|
217
|
+
contentTokens.group_name = { value: group.name, type: 'string' };
|
|
218
|
+
}
|
|
219
|
+
// Call the handleInviteClick from useVortexInvite hook
|
|
220
|
+
yield hookResult.handleInviteClick(contentTokens);
|
|
221
|
+
}),
|
|
222
|
+
fetchGoogleContacts: () => __awaiter(this, void 0, void 0, function* () {
|
|
223
|
+
var _a, _b, _c, _d, _e, _f;
|
|
224
|
+
try {
|
|
225
|
+
const { Platform } = require('react-native');
|
|
226
|
+
if ((Platform === null || Platform === void 0 ? void 0 : Platform.OS) === 'web') {
|
|
227
|
+
console.info('[Vortex] Web preview: skipping Google auth, returning [] (mocks).');
|
|
228
|
+
return [];
|
|
229
|
+
}
|
|
230
|
+
try {
|
|
231
|
+
const module = require('@react-native-google-signin/google-signin');
|
|
232
|
+
const { GoogleSignin, isSuccessResponse, isCancelledResponse, isNoSavedCredentialFoundResponse, } = module;
|
|
233
|
+
const iosClientId = googleIosClientId || '';
|
|
234
|
+
const webClientId = googleWebClientId || '';
|
|
235
|
+
// Check for required client ID based on platform
|
|
236
|
+
if ((Platform === null || Platform === void 0 ? void 0 : Platform.OS) === 'ios' && !iosClientId) {
|
|
237
|
+
console.warn('[Vortex] googleIosClientId prop not provided (required for iOS).');
|
|
238
|
+
throw new Error('missing-ios-client-id');
|
|
239
|
+
}
|
|
240
|
+
if ((Platform === null || Platform === void 0 ? void 0 : Platform.OS) === 'android' && !webClientId) {
|
|
241
|
+
console.warn('[Vortex] googleWebClientId prop not provided (required for Android).');
|
|
242
|
+
throw new Error('missing-web-client-id');
|
|
243
|
+
}
|
|
244
|
+
// IMPORTANT: Make sure Info.plist has the reversed client id URL scheme (iOS).
|
|
245
|
+
// For Android, ensure google-services.json is configured properly.
|
|
246
|
+
// If using Expo, add the plugin: ["react-native-google-signin"] and prebuild.
|
|
247
|
+
GoogleSignin.configure({
|
|
248
|
+
iosClientId,
|
|
249
|
+
webClientId, // Required for Android
|
|
250
|
+
offlineAccess: false,
|
|
251
|
+
scopes: ['https://www.googleapis.com/auth/contacts.readonly', 'email', 'profile'],
|
|
252
|
+
});
|
|
253
|
+
// 1) Try silent sign-in first (uses cached credentials)
|
|
254
|
+
const silent = yield GoogleSignin.signInSilently();
|
|
255
|
+
if ((isSuccessResponse === null || isSuccessResponse === void 0 ? void 0 : isSuccessResponse(silent)) || (silent === null || silent === void 0 ? void 0 : silent.type) === 'success') {
|
|
256
|
+
console.info('[Vortex] Google silent sign-in success.');
|
|
257
|
+
}
|
|
258
|
+
else if ((isNoSavedCredentialFoundResponse === null || isNoSavedCredentialFoundResponse === void 0 ? void 0 : isNoSavedCredentialFoundResponse(silent)) ||
|
|
259
|
+
(silent === null || silent === void 0 ? void 0 : silent.type) === 'noSavedCredentialFound') {
|
|
260
|
+
console.info('[Vortex] No saved credential; prompting interactive sign-in...');
|
|
261
|
+
const interactive = yield GoogleSignin.signIn();
|
|
262
|
+
if (!((isSuccessResponse === null || isSuccessResponse === void 0 ? void 0 : isSuccessResponse(interactive)) || (interactive === null || interactive === void 0 ? void 0 : interactive.type) === 'success')) {
|
|
263
|
+
if ((isCancelledResponse === null || isCancelledResponse === void 0 ? void 0 : isCancelledResponse(interactive)) || (interactive === null || interactive === void 0 ? void 0 : interactive.type) === 'cancelled') {
|
|
264
|
+
console.warn('[Vortex] Google sign-in cancelled by user.');
|
|
265
|
+
return [];
|
|
266
|
+
}
|
|
267
|
+
console.warn('[Vortex] Google sign-in did not succeed.');
|
|
268
|
+
return [];
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
// unexpected silent state; try interactive as a fallback
|
|
273
|
+
const interactive = yield GoogleSignin.signIn();
|
|
274
|
+
if (!((isSuccessResponse === null || isSuccessResponse === void 0 ? void 0 : isSuccessResponse(interactive)) || (interactive === null || interactive === void 0 ? void 0 : interactive.type) === 'success')) {
|
|
275
|
+
if ((isCancelledResponse === null || isCancelledResponse === void 0 ? void 0 : isCancelledResponse(interactive)) || (interactive === null || interactive === void 0 ? void 0 : interactive.type) === 'cancelled') {
|
|
276
|
+
console.warn('[Vortex] Google sign-in cancelled by user.');
|
|
277
|
+
return [];
|
|
278
|
+
}
|
|
279
|
+
console.warn('[Vortex] Google sign-in did not succeed.');
|
|
280
|
+
return [];
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// Only now are we guaranteed to be signed in
|
|
284
|
+
const tokens = yield GoogleSignin.getTokens();
|
|
285
|
+
const accessToken = tokens === null || tokens === void 0 ? void 0 : tokens.accessToken;
|
|
286
|
+
if (!accessToken) {
|
|
287
|
+
console.warn('[Vortex] No access token after sign-in.');
|
|
288
|
+
return [];
|
|
289
|
+
}
|
|
290
|
+
const response = yield fetch('https://people.googleapis.com/v1/people/me/connections?personFields=names,emailAddresses,photos&pageSize=1000', { headers: { Authorization: `Bearer ${accessToken}` } });
|
|
291
|
+
if (!response.ok)
|
|
292
|
+
throw new Error(`Google API error: ${response.status}`);
|
|
293
|
+
const data = yield response.json();
|
|
294
|
+
const contactMap = new Map();
|
|
295
|
+
if (data.connections && Array.isArray(data.connections)) {
|
|
296
|
+
for (const person of data.connections) {
|
|
297
|
+
if (person.emailAddresses && Array.isArray(person.emailAddresses)) {
|
|
298
|
+
for (const emailObj of person.emailAddresses) {
|
|
299
|
+
const key = `${person.resourceName}-${emailObj.value}`;
|
|
300
|
+
if (!contactMap.has(key)) {
|
|
301
|
+
// Infer name from email if Google contact name is missing
|
|
302
|
+
const displayName = ((_b = (_a = person.names) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.displayName) || (0, nameUtils_1.inferNameFromEmail)(emailObj.value);
|
|
303
|
+
// Extract photo URL (skip default silhouette photos)
|
|
304
|
+
const photoUrl = (_d = (_c = person.photos) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.url;
|
|
305
|
+
const isDefaultPhoto = ((_f = (_e = person.photos) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.default) === true;
|
|
306
|
+
if (__DEV__ && person.photos) {
|
|
307
|
+
console.log('[Vortex] Google contact photo:', displayName, { photoUrl, isDefaultPhoto, photos: person.photos });
|
|
308
|
+
}
|
|
309
|
+
contactMap.set(key, Object.assign({ id: key, name: displayName, email: emailObj.value }, (photoUrl && !isDefaultPhoto ? { imageUri: photoUrl } : {})));
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
// Sort alphabetically by name
|
|
316
|
+
return Array.from(contactMap.values()).sort((a, b) => a.name.localeCompare(b.name));
|
|
317
|
+
}
|
|
318
|
+
catch (gsErr) {
|
|
319
|
+
console.warn('[Vortex] Google Sign-In unavailable or failed. Returning [].', gsErr);
|
|
320
|
+
return [];
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
catch (error) {
|
|
324
|
+
console.error('[Vortex] Failed to fetch Google contacts:', error);
|
|
325
|
+
return [];
|
|
326
|
+
}
|
|
327
|
+
}),
|
|
328
|
+
shareViaEmail: () => __awaiter(this, void 0, void 0, function* () {
|
|
329
|
+
yield hookResult.handleEmailShare();
|
|
330
|
+
}),
|
|
331
|
+
shareViaSms: () => __awaiter(this, void 0, void 0, function* () {
|
|
332
|
+
yield hookResult.handleSmsShare();
|
|
333
|
+
}),
|
|
334
|
+
shareViaTwitter: () => __awaiter(this, void 0, void 0, function* () {
|
|
335
|
+
const invitationLink = yield hookResult.getShareableLink();
|
|
336
|
+
if (!invitationLink) {
|
|
337
|
+
console.warn('No invitation link available');
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
const text = `Join our team: ${invitationLink}`;
|
|
341
|
+
const twitterUrl = `twitter://messages/compose?text=${encodeURIComponent(text)}`;
|
|
342
|
+
const { Linking } = require('react-native');
|
|
343
|
+
yield Linking.openURL(twitterUrl).catch(() => {
|
|
344
|
+
// Fallback to web URL if app not installed
|
|
345
|
+
Linking.openURL(`https://twitter.com/messages/compose?text=${encodeURIComponent(text)}`);
|
|
346
|
+
});
|
|
347
|
+
}),
|
|
348
|
+
shareViaInstagram: () => __awaiter(this, void 0, void 0, function* () {
|
|
349
|
+
const { Linking } = require('react-native');
|
|
350
|
+
yield Linking.openURL('instagram://direct-inbox').catch(() => {
|
|
351
|
+
console.warn('Instagram app not installed');
|
|
352
|
+
});
|
|
353
|
+
}),
|
|
354
|
+
shareViaWhatsApp: () => __awaiter(this, void 0, void 0, function* () {
|
|
355
|
+
yield hookResult.handleWhatsAppShare();
|
|
356
|
+
}),
|
|
357
|
+
shareViaLine: () => __awaiter(this, void 0, void 0, function* () {
|
|
358
|
+
const invitationLink = yield hookResult.getShareableLink();
|
|
359
|
+
if (!invitationLink) {
|
|
360
|
+
console.warn('No invitation link available');
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
const { Linking } = require('react-native');
|
|
364
|
+
const lineUrl = `https://line.me/R/msg/text/?${encodeURIComponent(invitationLink)}`;
|
|
365
|
+
yield Linking.openURL(lineUrl);
|
|
366
|
+
}),
|
|
367
|
+
shareViaLineLiff: () => __awaiter(this, void 0, void 0, function* () {
|
|
368
|
+
const { Linking } = require('react-native');
|
|
369
|
+
const liffUrl = 'https://liff.line.me/2008909352-RwnncfLZ';
|
|
370
|
+
yield Linking.openURL(liffUrl);
|
|
371
|
+
}),
|
|
372
|
+
shareViaFacebookMessenger: () => __awaiter(this, void 0, void 0, function* () {
|
|
373
|
+
const invitationLink = yield hookResult.getShareableLink();
|
|
374
|
+
if (!invitationLink) {
|
|
375
|
+
console.warn('No invitation link available');
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
const { Linking } = require('react-native');
|
|
379
|
+
const messengerUrl = `fb-messenger://share?link=${encodeURIComponent(invitationLink)}`;
|
|
380
|
+
yield Linking.openURL(messengerUrl).catch(() => {
|
|
381
|
+
// Fallback to web URL if app not installed
|
|
382
|
+
Linking.openURL(`https://www.facebook.com/dialog/send?link=${encodeURIComponent(invitationLink)}&app_id=0&redirect_uri=${encodeURIComponent(invitationLink)}`);
|
|
383
|
+
});
|
|
384
|
+
}),
|
|
385
|
+
shareViaTelegram: () => __awaiter(this, void 0, void 0, function* () {
|
|
386
|
+
const invitationLink = yield hookResult.getShareableLink();
|
|
387
|
+
if (!invitationLink) {
|
|
388
|
+
console.warn('No invitation link available');
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
const { Linking } = require('react-native');
|
|
392
|
+
const telegramUrl = `tg://msg?text=${encodeURIComponent(invitationLink)}`;
|
|
393
|
+
yield Linking.openURL(telegramUrl).catch(() => {
|
|
394
|
+
// Fallback to web URL if app not installed
|
|
395
|
+
Linking.openURL(`https://t.me/share/url?url=${encodeURIComponent(invitationLink)}`);
|
|
396
|
+
});
|
|
397
|
+
}),
|
|
398
|
+
shareViaDiscord: () => __awaiter(this, void 0, void 0, function* () {
|
|
399
|
+
const { Linking } = require('react-native');
|
|
400
|
+
yield Linking.openURL('discord://').catch(() => {
|
|
401
|
+
// Fallback to web URL if app not installed
|
|
402
|
+
Linking.openURL('https://discord.com/channels/@me');
|
|
403
|
+
});
|
|
404
|
+
}),
|
|
405
|
+
showQrCode: () => __awaiter(this, void 0, void 0, function* () {
|
|
406
|
+
// Navigation to QR code view is handled in InviteFormCore
|
|
407
|
+
console.log('[Vortex] Navigating to QR Code view');
|
|
408
|
+
}),
|
|
409
|
+
}), [hookResult, onClose, group, googleIosClientId, googleWebClientId]);
|
|
410
|
+
// Container styles for bottom sheet appearance
|
|
411
|
+
const containerStyle = react_native_1.StyleSheet.create({
|
|
412
|
+
container: {
|
|
413
|
+
position: 'absolute',
|
|
414
|
+
bottom: 0,
|
|
415
|
+
left: 0,
|
|
416
|
+
right: 0,
|
|
417
|
+
height: '80%',
|
|
418
|
+
backgroundColor: '#fff',
|
|
419
|
+
borderTopLeftRadius: 20,
|
|
420
|
+
borderTopRightRadius: 20,
|
|
421
|
+
},
|
|
422
|
+
}).container;
|
|
423
|
+
// Show loading state while fetching configuration
|
|
424
|
+
if (loading) {
|
|
425
|
+
return (<react_native_1.View style={[containerStyle, { justifyContent: 'center', alignItems: 'center' }]}>
|
|
426
|
+
<react_native_1.ActivityIndicator size="large" color="#6291d5"/>
|
|
427
|
+
<react_native_1.Text style={{ marginTop: 16, fontSize: 16, color: '#666', fontFamily }}>Loading...</react_native_1.Text>
|
|
428
|
+
</react_native_1.View>);
|
|
429
|
+
}
|
|
430
|
+
// Show error state if configuration fetch failed
|
|
431
|
+
if (error) {
|
|
432
|
+
return (<react_native_1.View style={[containerStyle, { justifyContent: 'center', alignItems: 'center', padding: 20 }]}>
|
|
433
|
+
<react_native_1.Text style={{
|
|
434
|
+
fontSize: 18,
|
|
435
|
+
fontWeight: 'bold',
|
|
436
|
+
color: '#d9534f',
|
|
437
|
+
marginBottom: 8,
|
|
438
|
+
fontFamily,
|
|
439
|
+
}}>
|
|
440
|
+
Error
|
|
441
|
+
</react_native_1.Text>
|
|
442
|
+
<react_native_1.Text style={{ fontSize: 14, color: '#666', textAlign: 'center', fontFamily }}>
|
|
443
|
+
{error.message || 'Failed to load widget configuration'}
|
|
444
|
+
</react_native_1.Text>
|
|
445
|
+
</react_native_1.View>);
|
|
446
|
+
}
|
|
447
|
+
return (<InviteFormCore_1.InviteFormCore renderIcon={renderIcon} renderQRCode={renderQRCode} platformOperations={platformOperations} fontFamily={fontFamily} containerStyle={containerStyle} widgetConfiguration={widgetConfiguration} getShareableInviteLink={hookResult.getShareableInviteLink}
|
|
448
|
+
// Analytics callbacks
|
|
449
|
+
onShareLinkClick={hookResult.trackShareLinkClick} onEmailFieldFocus={hookResult.trackEmailFieldFocus} onEmailFieldBlur={hookResult.trackEmailFieldBlur} onEmailValidation={hookResult.trackEmailValidation} onEmailInvitationsSubmitted={hookResult.trackEmailInvitationsSubmitted} onEmailValidationError={hookResult.trackEmailValidationError} onEmailSubmitError={hookResult.trackEmailSubmitError}
|
|
450
|
+
// Find Friends configuration
|
|
451
|
+
findFriendsConfig={findFriendsConfig} createUserIdInvitation={hookResult.createUserIdInvitation}
|
|
452
|
+
// Incoming/Outgoing Invitations configuration
|
|
453
|
+
incomingInvitationsConfig={incomingInvitationsConfig} outgoingInvitationsConfig={outgoingInvitationsConfig}
|
|
454
|
+
// Invite Contacts configuration
|
|
455
|
+
inviteContactsConfig={inviteContactsConfig}
|
|
456
|
+
// Invitation Suggestions configuration
|
|
457
|
+
invitationSuggestionsConfig={invitationSuggestionsConfig}
|
|
458
|
+
// Search Box configuration
|
|
459
|
+
searchBoxConfig={searchBoxConfig}
|
|
460
|
+
// API configuration for outgoing invitations
|
|
461
|
+
apiUrl={vortexApiUrl} jwt={jwt}/>);
|
|
462
|
+
}
|
|
463
|
+
//# sourceMappingURL=InviteFormMobile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InviteFormMobile.js","sourceRoot":"","sources":["../../src/components/InviteFormMobile.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useMemo, useEffect } from 'react';\nimport { StyleSheet, View, Text, ActivityIndicator } from 'react-native';\nimport Icon from 'react-native-vector-icons/FontAwesome6';\nimport { InviteFormCore, type IconRendererProps } from './InviteFormCore';\nimport { PlatformOperations } from '../types/platformOperations';\nimport { FindFriendsConfig } from '../types/findFriends';\nimport { IncomingInvitationsConfig, OutgoingInvitationsConfig, InvitationSuggestionsConfig } from '../types/invitations';\nimport { InviteContactsConfig } from '../types/inviteContacts';\nimport { UnfurlConfig } from '../types/unfurlConfig';\nimport { SearchBoxConfig } from '../types/searchBox';\nimport { useVortexInvite } from '../hooks/useVortexInvite';\nimport { inferNameFromEmail } from '../utils/nameUtils';\nimport { UnsignedData } from '@teamvortexsoftware/vortex-types';\nimport { VortexAnalyticsEvent, GroupDTO } from '../utils/analytics';\n\ninterface InvitationFormProps {\n platform?: 'ios' | 'android';\n onClose?: () => void;\n widgetConfiguration?: any;\n // Props for fetching configuration from server\n componentId: string;\n jwt?: string;\n user?: string | UnsignedData | undefined;\n vortexApiUrl?: string;\n group?: {\n name: string;\n type: string;\n id?: string;\n groupId?: string;\n };\n groups?: GroupDTO[];\n scope?: string;\n scopeType?: string;\n googleIosClientId?: string;\n googleWebClientId?: string; // Required for Google Contacts on Android\n // Analytics props\n analyticsBaseURL?: string; // Defaults to production collector\n onEvent?: (event: VortexAnalyticsEvent) => void; // Callback for analytics events\n analyticsSegmentation?: Record<string, any>; // Segmentation data for analytics\n // Find Friends configuration\n findFriendsConfig?: FindFriendsConfig;\n // Incoming/Outgoing Invitations configuration\n incomingInvitationsConfig?: IncomingInvitationsConfig;\n outgoingInvitationsConfig?: OutgoingInvitationsConfig;\n // Invitation Suggestions configuration\n invitationSuggestionsConfig?: InvitationSuggestionsConfig;\n // Invite Contacts configuration\n inviteContactsConfig?: InviteContactsConfig;\n // Search Box configuration\n searchBoxConfig?: SearchBoxConfig;\n // Internationalization\n locale?: string;\n // Unfurl configuration for link previews\n unfurlConfig?: UnfurlConfig;\n}\n\n// Map from generic icon names to FontAwesome6 names\nconst iconMap: Record<string, string> = {\n close: 'xmark',\n 'arrow-back': 'arrow-left',\n link: 'link',\n share: 'share-nodes',\n 'import-contacts': 'address-book',\n email: 'envelope',\n google: 'google',\n 'x-twitter': 'x-twitter',\n instagram: 'instagram',\n sms: 'comment',\n whatsapp: 'whatsapp',\n line: 'line',\n 'qr-code': 'qrcode',\n telegram: 'telegram',\n discord: 'discord',\n 'facebook-messenger': 'facebook-messenger',\n search: 'magnifying-glass',\n};\n\nexport function InviteFormMobile({\n platform = 'ios',\n onClose,\n widgetConfiguration: propsWidgetConfiguration,\n componentId,\n jwt,\n user,\n vortexApiUrl,\n group,\n groups,\n scope,\n scopeType,\n googleIosClientId,\n googleWebClientId,\n analyticsBaseURL,\n onEvent,\n analyticsSegmentation,\n findFriendsConfig,\n incomingInvitationsConfig,\n outgoingInvitationsConfig,\n inviteContactsConfig,\n searchBoxConfig,\n locale,\n invitationSuggestionsConfig,\n unfurlConfig,\n}: InvitationFormProps) {\n\n const hookResult = useVortexInvite({\n componentId,\n jwt: jwt,\n user: user,\n vortexApiUrl: vortexApiUrl!,\n group,\n groups,\n scope,\n scopeType,\n widgetConfiguration: propsWidgetConfiguration, // Pass prefetched configuration to skip loading\n analyticsBaseURL,\n onEvent,\n analyticsSegmentation,\n locale,\n });\n\n // Use configuration from hook if available (fresh data), otherwise use prefetched configuration from props\n // This ensures background refetch updates are reflected (stale-while-revalidate pattern)\n const widgetConfiguration = hookResult.widgetConfiguration || propsWidgetConfiguration;\n const { loading, error } = hookResult;\n\n // Track widget render when configuration is loaded\n useEffect(() => {\n if (widgetConfiguration && !loading && !error) {\n hookResult.trackWidgetRender();\n }\n }, [widgetConfiguration, loading, error, hookResult.trackWidgetRender]);\n\n // Track widget error when error occurs\n useEffect(() => {\n if (error) {\n hookResult.trackWidgetError(error.message || 'Unknown error');\n }\n }, [error, hookResult.trackWidgetError]);\n\n // Platform-specific font families\n const fontFamily =\n platform === 'ios'\n ? '-apple-system, BlinkMacSystemFont, \"SF Pro Text\", \"SF Pro Display\", \"Helvetica Neue\", sans-serif'\n : 'Roboto, \"Segoe UI\", \"Helvetica Neue\", sans-serif';\n\n const renderIcon = ({ name, size, color, opacity }: IconRendererProps) => {\n const iconName = iconMap[name] || name;\n return <Icon name={iconName} size={size} color={color} solid={true} style={opacity != null ? { opacity } : undefined} />;\n };\n\n const renderQRCode = ({ value, size }: { value: string; size: number }) => {\n try {\n // Dynamic import to avoid hard dependency\n const QRCode = require('react-native-qrcode-svg').default;\n return <QRCode value={value} size={size} color=\"#333\" backgroundColor=\"#fff\" />;\n } catch (error) {\n console.warn('[Vortex] react-native-qrcode-svg not available:', error);\n return (\n <View style={{ padding: 20, alignItems: 'center' }}>\n <Text style={{ fontSize: 14, color: '#666', textAlign: 'center', fontFamily }}>\n QR Code feature not available. Install react-native-qrcode-svg and react-native-svg to\n enable.\n </Text>\n </View>\n );\n }\n };\n\n // Native platform operations using the hook's methods for copy/share (handles API calls)\n // Wrapped in useMemo to prevent recreation on every render, which would cause infinite loops\n const platformOperations: PlatformOperations = useMemo(\n () => ({\n copyToClipboard: async () => {\n await hookResult.handleCopyLink();\n },\n share: async () => {\n await hookResult.handleShareLink();\n },\n close: async () => {\n // Sign out from Google to allow account switching on next open\n try {\n const module = await import('@react-native-google-signin/google-signin');\n const { GoogleSignin } = module;\n await GoogleSignin.signOut();\n console.info('[Vortex] Signed out from Google to allow account switching.');\n } catch (signOutErr) {\n // Ignore sign-out errors (user might not have been signed in, or library not available)\n console.debug('[Vortex] Google sign-out skipped:', signOutErr);\n }\n\n if (onClose) {\n onClose();\n } else {\n console.log('[Vortex] Close bottom sheet');\n }\n },\n triggerHaptic: async (style: 'light' | 'medium' | 'heavy') => {\n try {\n // Dynamic import to avoid hard dependency\n const Haptics = await import('expo-haptics');\n const feedbackStyle =\n style === 'light'\n ? Haptics.ImpactFeedbackStyle.Light\n : style === 'medium'\n ? Haptics.ImpactFeedbackStyle.Medium\n : Haptics.ImpactFeedbackStyle.Heavy;\n\n await Haptics.impactAsync(feedbackStyle);\n } catch (error) {\n // Silent fail if expo-haptics not installed - this is expected and acceptable\n console.debug('[Vortex] Haptic feedback not available:', error);\n }\n },\n fetchContacts: async () => {\n // Call the existing fetchContactsWithEmailsIOS from the hook\n if (!hookResult.fetchContactsWithEmailsIOS) {\n console.warn('[Vortex] fetchContactsWithEmailsIOS method not available');\n return [];\n }\n const contactsWithEmails = await hookResult.fetchContactsWithEmailsIOS();\n\n // Use a Map to deduplicate by unique key (contact.id + email)\n const contactMap = new Map<string, { id: string; name: string; email: string; imageUri?: string }>();\n\n for (const contact of contactsWithEmails) {\n for (const email of contact.emails) {\n const key = `${contact.id}-${email}`;\n // Only add if not already in the map (prevents duplicates)\n if (!contactMap.has(key)) {\n // Infer name from email if contact name is missing or empty\n const displayName =\n contact.name && contact.name.trim() ? contact.name : inferNameFromEmail(email);\n\n contactMap.set(key, {\n id: key,\n name: displayName,\n email,\n imageUri: contact.imageUri,\n });\n }\n }\n }\n\n // Sort alphabetically by name\n return Array.from(contactMap.values()).sort((a, b) => a.name.localeCompare(b.name));\n },\n invite: async (email: string, contactName?: string) => {\n // Build content tokens for the invitation\n const contentTokens: Record<string, { value: string; type: string }> = {\n invitee_email: { value: email, type: 'email' },\n };\n\n // Add inviter name if available (could be extracted from JWT or config)\n // For now, using a placeholder that the backend can override\n contentTokens.inviter_name = { value: 'Current User', type: 'string' };\n\n // Add contact name if provided\n if (contactName) {\n contentTokens.invitee_name = { value: contactName, type: 'string' };\n }\n\n // Add group information if available\n if (group) {\n contentTokens.group_name = { value: group.name, type: 'string' };\n }\n\n // Call the handleInviteClick from useVortexInvite hook\n await hookResult.handleInviteClick(contentTokens);\n },\n fetchGoogleContacts: async () => {\n try {\n const { Platform } = require('react-native');\n if (Platform?.OS === 'web') {\n console.info('[Vortex] Web preview: skipping Google auth, returning [] (mocks).');\n return [];\n }\n\n try {\n const module = require('@react-native-google-signin/google-signin');\n const {\n GoogleSignin,\n isSuccessResponse,\n isCancelledResponse,\n isNoSavedCredentialFoundResponse,\n } = module;\n\n const iosClientId = googleIosClientId || '';\n const webClientId = googleWebClientId || '';\n \n // Check for required client ID based on platform\n if (Platform?.OS === 'ios' && !iosClientId) {\n console.warn('[Vortex] googleIosClientId prop not provided (required for iOS).');\n throw new Error('missing-ios-client-id');\n }\n if (Platform?.OS === 'android' && !webClientId) {\n console.warn('[Vortex] googleWebClientId prop not provided (required for Android).');\n throw new Error('missing-web-client-id');\n }\n\n // IMPORTANT: Make sure Info.plist has the reversed client id URL scheme (iOS).\n // For Android, ensure google-services.json is configured properly.\n // If using Expo, add the plugin: [\"react-native-google-signin\"] and prebuild.\n GoogleSignin.configure({\n iosClientId,\n webClientId, // Required for Android\n offlineAccess: false,\n scopes: ['https://www.googleapis.com/auth/contacts.readonly', 'email', 'profile'],\n });\n\n // 1) Try silent sign-in first (uses cached credentials)\n const silent = await GoogleSignin.signInSilently();\n if (isSuccessResponse?.(silent) || silent?.type === 'success') {\n console.info('[Vortex] Google silent sign-in success.');\n } else if (\n isNoSavedCredentialFoundResponse?.(silent) ||\n silent?.type === 'noSavedCredentialFound'\n ) {\n console.info('[Vortex] No saved credential; prompting interactive sign-in...');\n const interactive = await GoogleSignin.signIn();\n if (!(isSuccessResponse?.(interactive) || interactive?.type === 'success')) {\n if (isCancelledResponse?.(interactive) || interactive?.type === 'cancelled') {\n console.warn('[Vortex] Google sign-in cancelled by user.');\n return [];\n }\n console.warn('[Vortex] Google sign-in did not succeed.');\n return [];\n }\n } else {\n // unexpected silent state; try interactive as a fallback\n const interactive = await GoogleSignin.signIn();\n if (!(isSuccessResponse?.(interactive) || interactive?.type === 'success')) {\n if (isCancelledResponse?.(interactive) || interactive?.type === 'cancelled') {\n console.warn('[Vortex] Google sign-in cancelled by user.');\n return [];\n }\n console.warn('[Vortex] Google sign-in did not succeed.');\n return [];\n }\n }\n\n // Only now are we guaranteed to be signed in\n const tokens = await GoogleSignin.getTokens();\n const accessToken: string | undefined = tokens?.accessToken;\n if (!accessToken) {\n console.warn('[Vortex] No access token after sign-in.');\n return [];\n }\n\n const response = await fetch(\n 'https://people.googleapis.com/v1/people/me/connections?personFields=names,emailAddresses,photos&pageSize=1000',\n { headers: { Authorization: `Bearer ${accessToken}` } }\n );\n if (!response.ok) throw new Error(`Google API error: ${response.status}`);\n\n const data = await response.json();\n const contactMap = new Map<string, { id: string; name: string; email: string; imageUri?: string }>();\n if (data.connections && Array.isArray(data.connections)) {\n for (const person of data.connections) {\n if (person.emailAddresses && Array.isArray(person.emailAddresses)) {\n for (const emailObj of person.emailAddresses) {\n const key = `${person.resourceName}-${emailObj.value}`;\n if (!contactMap.has(key)) {\n // Infer name from email if Google contact name is missing\n const displayName =\n person.names?.[0]?.displayName || inferNameFromEmail(emailObj.value);\n\n // Extract photo URL (skip default silhouette photos)\n const photoUrl = person.photos?.[0]?.url;\n const isDefaultPhoto = person.photos?.[0]?.default === true;\n if (__DEV__ && person.photos) {\n console.log('[Vortex] Google contact photo:', displayName, { photoUrl, isDefaultPhoto, photos: person.photos });\n }\n contactMap.set(key, {\n id: key,\n name: displayName,\n email: emailObj.value,\n ...(photoUrl && !isDefaultPhoto ? { imageUri: photoUrl } : {}),\n });\n }\n }\n }\n }\n }\n\n // Sort alphabetically by name\n return Array.from(contactMap.values()).sort((a, b) => a.name.localeCompare(b.name));\n } catch (gsErr) {\n console.warn('[Vortex] Google Sign-In unavailable or failed. Returning [].', gsErr);\n return [];\n }\n } catch (error) {\n console.error('[Vortex] Failed to fetch Google contacts:', error);\n return [];\n }\n },\n shareViaEmail: async () => {\n await hookResult.handleEmailShare();\n },\n shareViaSms: async () => {\n await hookResult.handleSmsShare();\n },\n shareViaTwitter: async () => {\n const invitationLink = await hookResult.getShareableLink();\n if (!invitationLink) {\n console.warn('No invitation link available');\n return;\n }\n const text = `Join our team: ${invitationLink}`;\n const twitterUrl = `twitter://messages/compose?text=${encodeURIComponent(text)}`;\n const { Linking } = require('react-native');\n await Linking.openURL(twitterUrl).catch(() => {\n // Fallback to web URL if app not installed\n Linking.openURL(`https://twitter.com/messages/compose?text=${encodeURIComponent(text)}`);\n });\n },\n shareViaInstagram: async () => {\n const { Linking } = require('react-native');\n await Linking.openURL('instagram://direct-inbox').catch(() => {\n console.warn('Instagram app not installed');\n });\n },\n shareViaWhatsApp: async () => {\n await hookResult.handleWhatsAppShare();\n },\n shareViaLine: async () => {\n const invitationLink = await hookResult.getShareableLink();\n if (!invitationLink) {\n console.warn('No invitation link available');\n return;\n }\n const { Linking } = require('react-native');\n const lineUrl = `https://line.me/R/msg/text/?${encodeURIComponent(invitationLink)}`;\n await Linking.openURL(lineUrl);\n },\n shareViaLineLiff: async () => {\n const { Linking } = require('react-native');\n const liffUrl = 'https://liff.line.me/2008909352-RwnncfLZ';\n await Linking.openURL(liffUrl);\n },\n shareViaFacebookMessenger: async () => {\n const invitationLink = await hookResult.getShareableLink();\n if (!invitationLink) {\n console.warn('No invitation link available');\n return;\n }\n const { Linking } = require('react-native');\n const messengerUrl = `fb-messenger://share?link=${encodeURIComponent(invitationLink)}`;\n await Linking.openURL(messengerUrl).catch(() => {\n // Fallback to web URL if app not installed\n Linking.openURL(`https://www.facebook.com/dialog/send?link=${encodeURIComponent(invitationLink)}&app_id=0&redirect_uri=${encodeURIComponent(invitationLink)}`);\n });\n },\n shareViaTelegram: async () => {\n const invitationLink = await hookResult.getShareableLink();\n if (!invitationLink) {\n console.warn('No invitation link available');\n return;\n }\n const { Linking } = require('react-native');\n const telegramUrl = `tg://msg?text=${encodeURIComponent(invitationLink)}`;\n await Linking.openURL(telegramUrl).catch(() => {\n // Fallback to web URL if app not installed\n Linking.openURL(`https://t.me/share/url?url=${encodeURIComponent(invitationLink)}`);\n });\n },\n shareViaDiscord: async () => {\n const { Linking } = require('react-native');\n await Linking.openURL('discord://').catch(() => {\n // Fallback to web URL if app not installed\n Linking.openURL('https://discord.com/channels/@me');\n });\n },\n showQrCode: async () => {\n // Navigation to QR code view is handled in InviteFormCore\n console.log('[Vortex] Navigating to QR Code view');\n },\n }),\n [hookResult, onClose, group, googleIosClientId, googleWebClientId]\n );\n\n // Container styles for bottom sheet appearance\n const containerStyle = StyleSheet.create({\n container: {\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n height: '80%',\n backgroundColor: '#fff',\n borderTopLeftRadius: 20,\n borderTopRightRadius: 20,\n },\n }).container;\n\n // Show loading state while fetching configuration\n if (loading) {\n return (\n <View style={[containerStyle, { justifyContent: 'center', alignItems: 'center' }]}>\n <ActivityIndicator size=\"large\" color=\"#6291d5\" />\n <Text style={{ marginTop: 16, fontSize: 16, color: '#666', fontFamily }}>Loading...</Text>\n </View>\n );\n }\n\n // Show error state if configuration fetch failed\n if (error) {\n return (\n <View\n style={[containerStyle, { justifyContent: 'center', alignItems: 'center', padding: 20 }]}\n >\n <Text\n style={{\n fontSize: 18,\n fontWeight: 'bold',\n color: '#d9534f',\n marginBottom: 8,\n fontFamily,\n }}\n >\n Error\n </Text>\n <Text style={{ fontSize: 14, color: '#666', textAlign: 'center', fontFamily }}>\n {error.message || 'Failed to load widget configuration'}\n </Text>\n </View>\n );\n }\n\n return (\n <InviteFormCore\n renderIcon={renderIcon}\n renderQRCode={renderQRCode}\n platformOperations={platformOperations}\n fontFamily={fontFamily}\n containerStyle={containerStyle}\n widgetConfiguration={widgetConfiguration}\n getShareableInviteLink={hookResult.getShareableInviteLink}\n // Analytics callbacks\n onShareLinkClick={hookResult.trackShareLinkClick}\n onEmailFieldFocus={hookResult.trackEmailFieldFocus}\n onEmailFieldBlur={hookResult.trackEmailFieldBlur}\n onEmailValidation={hookResult.trackEmailValidation}\n onEmailInvitationsSubmitted={hookResult.trackEmailInvitationsSubmitted}\n onEmailValidationError={hookResult.trackEmailValidationError}\n onEmailSubmitError={hookResult.trackEmailSubmitError}\n // Find Friends configuration\n findFriendsConfig={findFriendsConfig}\n createUserIdInvitation={hookResult.createUserIdInvitation}\n // Incoming/Outgoing Invitations configuration\n incomingInvitationsConfig={incomingInvitationsConfig}\n outgoingInvitationsConfig={outgoingInvitationsConfig}\n // Invite Contacts configuration\n inviteContactsConfig={inviteContactsConfig}\n // Invitation Suggestions configuration\n invitationSuggestionsConfig={invitationSuggestionsConfig}\n // Search Box configuration\n searchBoxConfig={searchBoxConfig}\n // API configuration for outgoing invitations\n apiUrl={vortexApiUrl!}\n jwt={jwt!}\n />\n );\n}\n"]}
|