@adminide-stack/yantra-mobile 12.0.73 → 12.0.74-alpha.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/lib/features/messaging/InviteSheet.js +178 -0
- package/lib/features/messaging/InviteSheet.js.map +1 -0
- package/lib/features/messaging/NativeChatExperience.js +62 -35
- package/lib/features/messaging/NativeChatExperience.js.map +1 -1
- package/lib/features/messaging/RegistrationScreen.js +385 -192
- package/lib/features/messaging/RegistrationScreen.js.map +1 -1
- package/lib/features/messaging/chatInviteLink.js +6 -1
- package/lib/features/messaging/chatInviteLink.js.map +1 -1
- package/lib/features/messaging/countryPicker.js +25 -0
- package/lib/features/messaging/countryPicker.js.map +1 -0
- package/lib/features/messaging/mobileNumberCheck.js +56 -0
- package/lib/features/messaging/mobileNumberCheck.js.map +1 -0
- package/lib/features/messaging/phoneCountries.js +981 -0
- package/lib/features/messaging/phoneCountries.js.map +1 -0
- package/lib/features/messaging/phoneNumberRules.js +982 -0
- package/lib/features/messaging/phoneNumberRules.js.map +1 -0
- package/lib/features/messaging/phoneNumbers.js +30 -72
- package/lib/features/messaging/phoneNumbers.js.map +1 -1
- package/lib/features/messaging/usePhoneVerification.js +8 -6
- package/lib/features/messaging/usePhoneVerification.js.map +1 -1
- package/lib/screens/ChatNative/index.js +1 -1
- package/lib/screens/ChatNative/index.js.map +1 -1
- package/package.json +5 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RegistrationScreen.js","sources":["../../../src/features/messaging/RegistrationScreen.tsx"],"sourcesContent":["/**\n * Registration screen for Yantra Chat.\n *\n * First-time users are prompted to register with their phone number.\n * The flow:\n * 1. User enters mobile number (country code in the same row)\n * 2. OTP is sent to their number\n * 3. User enters the OTP code to verify\n * 4. Phone number becomes their member ID in the Yantra Chat organization\n *\n * Follows the design from issue #1312.\n */\nimport React from 'react';\nimport {\n StyleSheet,\n View,\n Text,\n TouchableOpacity,\n TextInput,\n ActivityIndicator,\n ScrollView,\n Modal,\n Platform,\n} from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\nimport { Ionicons } from '@expo/vector-icons';\nimport { CHAT_REGISTRATION_TEST_OTP, isChatTestOtpEnabled, usePhoneVerification } from './usePhoneVerification';\n\ninterface RegistrationScreenProps {\n /** Called when registration completes successfully. */\n onRegistrationComplete: (phoneNumber: string) => void;\n /** Theme configuration. */\n theme: { colors: Record<string, string>; fonts: Record<string, Record<string, string>> };\n testID?: string;\n}\n\ninterface CountryOption {\n code: string;\n name: string;\n callingCode: string;\n}\n\n/** Every country the picker knows. Nothing is removed from here when a country is switched off. */\nconst ALL_COUNTRIES: CountryOption[] = [\n { code: 'US', name: 'United States', callingCode: '+1' },\n { code: 'IN', name: 'India', callingCode: '+91' },\n { code: 'PK', name: 'Pakistan', callingCode: '+92' },\n { code: 'BD', name: 'Bangladesh', callingCode: '+880' },\n { code: 'AE', name: 'United Arab Emirates', callingCode: '+971' },\n { code: 'GB', name: 'United Kingdom', callingCode: '+44' },\n { code: 'CA', name: 'Canada', callingCode: '+1' },\n { code: 'AU', name: 'Australia', callingCode: '+61' },\n { code: 'FR', name: 'France', callingCode: '+33' },\n { code: 'DE', name: 'Germany', callingCode: '+49' },\n { code: 'ES', name: 'Spain', callingCode: '+34' },\n { code: 'IT', name: 'Italy', callingCode: '+39' },\n { code: 'BR', name: 'Brazil', callingCode: '+55' },\n { code: 'MX', name: 'Mexico', callingCode: '+52' },\n { code: 'SG', name: 'Singapore', callingCode: '+65' },\n { code: 'JP', name: 'Japan', callingCode: '+81' },\n { code: 'CN', name: 'China', callingCode: '+86' },\n];\n\n/**\n * Which of those the picker offers. SMS verification is US-only for now: the AWS account is\n * still in the SMS sandbox and the non-US origination registrations are pending. The server\n * enforces the same rule (PHONE_OTP_ALLOWED_DIAL_CODES), so this must be widened together with\n * it. Override at build time with EXPO_PUBLIC_PHONE_OTP_ALLOWED_DIAL_CODES (\"+1,+92\", or \"*\").\n */\nconst DEFAULT_ALLOWED_DIAL_CODES = ['+1'];\n\nexport function allowedDialCodes(\n raw: string | undefined = process.env.EXPO_PUBLIC_PHONE_OTP_ALLOWED_DIAL_CODES,\n): string[] | null {\n const value = raw?.trim();\n if (value === '*') return null;\n if (!value) return DEFAULT_ALLOWED_DIAL_CODES;\n const codes = value\n .split(',')\n .map((c) => c.trim())\n .filter(Boolean)\n .map((c) => (c.startsWith('+') ? c : `+${c}`));\n return codes.length ? codes : DEFAULT_ALLOWED_DIAL_CODES;\n}\n\nexport function pickerCountries(\n all: CountryOption[] = ALL_COUNTRIES,\n allowed: string[] | null = allowedDialCodes(),\n): CountryOption[] {\n if (!allowed) return all;\n const offered = all.filter((c) => allowed.includes(c.callingCode));\n return offered.length ? offered : [all[0]];\n}\n\nconst COUNTRIES: CountryOption[] = pickerCountries();\n\nfunction PhoneRow({\n countryCode,\n callingCode,\n phone,\n onCountryPress,\n onChangePhone,\n disabled,\n theme,\n}: {\n countryCode: string;\n callingCode: string;\n phone: string;\n onCountryPress: () => void;\n onChangePhone: (v: string) => void;\n disabled: boolean;\n theme: RegistrationScreenProps['theme'];\n}) {\n return (\n <View\n style={[\n styles.phoneRow,\n {\n flexDirection: 'row',\n alignItems: 'center',\n borderColor: theme.colors.border,\n backgroundColor: theme.colors.card ?? '#fff',\n },\n ]}\n >\n <TouchableOpacity\n onPress={onCountryPress}\n disabled={disabled}\n style={[styles.countryChip, { flexDirection: 'row', alignItems: 'center' }]}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Select country code\"\n >\n <Text style={[styles.callingCode, { color: theme.colors.text }]}>{callingCode}</Text>\n <Ionicons name=\"chevron-down\" size={18} color={theme.colors.textSecondary} />\n </TouchableOpacity>\n <View style={[styles.phoneDivider, { backgroundColor: theme.colors.border }]} />\n <TextInput\n style={[styles.phoneInput, { color: theme.colors.text }]}\n placeholder=\"\"\n placeholderTextColor={theme.colors.placeholder}\n keyboardType=\"phone-pad\"\n textContentType=\"telephoneNumber\"\n value={phone}\n onChangeText={onChangePhone}\n editable={!disabled}\n maxLength={15}\n testID=\"chat-registration-phone\"\n />\n </View>\n );\n}\n\nexport function RegistrationScreen({ onRegistrationComplete, theme, testID }: RegistrationScreenProps) {\n const phoneVerification = usePhoneVerification('US');\n const selectedCountry = COUNTRIES.find((c) => c.code === phoneVerification.countryCode) || COUNTRIES[0];\n const [countryModalOpen, setCountryModalOpen] = React.useState(false);\n const accent = theme.colors.primary;\n const otpDigits = phoneVerification.otp.replace(/\\D/g, '');\n const testOtpEnabled = isChatTestOtpEnabled();\n const usingTestOtp = testOtpEnabled && (phoneVerification.testOtpMode || otpDigits === CHAT_REGISTRATION_TEST_OTP);\n\n const { registrationFailed } = phoneVerification;\n React.useEffect(() => {\n if (phoneVerification.stage === 'verified' && phoneVerification.verifiedPhone) {\n // A failed registration used to be dropped here, leaving the screen stuck with no reason.\n Promise.resolve(onRegistrationComplete(phoneVerification.verifiedPhone)).catch((err: unknown) => {\n const message = err instanceof Error && err.message ? err.message : '';\n registrationFailed(\n message\n ? `Could not register: ${message}`\n : 'Could not register for Yantra Chat. Please try again.',\n );\n });\n }\n }, [phoneVerification.stage, phoneVerification.verifiedPhone, onRegistrationComplete, registrationFailed]);\n\n const handleBack = React.useCallback(() => {\n if (phoneVerification.stage === 'otp') {\n phoneVerification.resetToInput();\n }\n }, [phoneVerification]);\n\n const handleSendOtp = React.useCallback(async () => {\n await phoneVerification.sendOtp();\n }, [phoneVerification]);\n\n const handleVerifyOtp = React.useCallback(async () => {\n await phoneVerification.verifyOtp();\n }, [phoneVerification]);\n\n const handleResend = React.useCallback(async () => {\n await phoneVerification.sendOtp();\n }, [phoneVerification]);\n\n return (\n <SafeAreaView\n style={[styles.container, { backgroundColor: theme.colors.background }]}\n edges={['top', 'left', 'right']}\n testID={testID}\n >\n <View style={[styles.header, { flexDirection: 'row', alignItems: 'center' }]}>\n {phoneVerification.stage === 'otp' ? (\n <TouchableOpacity onPress={handleBack} hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}>\n <Ionicons name=\"chevron-back\" size={28} color={theme.colors.text} />\n </TouchableOpacity>\n ) : (\n <View style={{ width: 28 }} />\n )}\n <Text style={[styles.title, { color: theme.colors.text, flex: 1, textAlign: 'center' }]}>\n Yantra Chat\n </Text>\n <View style={{ width: 28 }} />\n </View>\n\n <ScrollView\n contentContainerStyle={styles.content}\n showsVerticalScrollIndicator={false}\n keyboardShouldPersistTaps=\"handled\"\n >\n {phoneVerification.stage === 'input' ? (\n <>\n <Text style={[styles.subtitle, { color: theme.colors.text }]}>Register to Chat</Text>\n <Text style={[styles.description, { color: theme.colors.textSecondary }]}>\n Enter your mobile number to get started. You'll receive an OTP to verify.\n </Text>\n\n <View style={styles.form}>\n <PhoneRow\n countryCode={phoneVerification.countryCode}\n callingCode={selectedCountry.callingCode}\n phone={phoneVerification.inputPhone}\n onCountryPress={() => setCountryModalOpen(true)}\n onChangePhone={phoneVerification.setInputPhone}\n disabled={phoneVerification.loading}\n theme={theme}\n />\n\n {phoneVerification.error ? (\n <View style={[styles.errorBox, { backgroundColor: theme.colors.error + '10' }]}>\n <Ionicons name=\"alert-circle\" size={16} color={theme.colors.error} />\n <Text style={[styles.errorText, { color: theme.colors.error }]}>\n {phoneVerification.error}\n </Text>\n </View>\n ) : null}\n\n {testOtpEnabled ? (\n <TouchableOpacity onPress={phoneVerification.continueWithTestOtp}>\n <Text style={[styles.linkText, { color: accent }]}>Continue with test OTP</Text>\n </TouchableOpacity>\n ) : null}\n\n <TouchableOpacity\n onPress={handleSendOtp}\n disabled={phoneVerification.loading || !phoneVerification.inputPhone.trim()}\n style={[\n styles.button,\n {\n backgroundColor: phoneVerification.inputPhone.trim()\n ? accent\n : theme.colors.border,\n },\n ]}\n >\n {phoneVerification.loading ? (\n <ActivityIndicator color=\"#fff\" size=\"small\" />\n ) : (\n <Text style={styles.buttonText}>Send OTP</Text>\n )}\n </TouchableOpacity>\n </View>\n </>\n ) : (\n <>\n <Text style={[styles.subtitle, { color: theme.colors.text }]}>Verify your number</Text>\n <Text style={[styles.description, { color: theme.colors.textSecondary }]}>\n {usingTestOtp\n ? `Test mode: use code ${CHAT_REGISTRATION_TEST_OTP} and tap Continue.`\n : `Enter the 6-digit code sent to ${selectedCountry.callingCode} ${phoneVerification.inputPhone}`}\n </Text>\n\n <View style={styles.form}>\n <View\n style={[\n styles.otpInputContainer,\n {\n flexDirection: 'row',\n alignItems: 'center',\n borderColor: theme.colors.border,\n backgroundColor: theme.colors.card ?? '#fff',\n },\n ]}\n >\n <TextInput\n style={[styles.otpInput, { color: theme.colors.text, flex: 1 }]}\n placeholder=\"\"\n keyboardType=\"number-pad\"\n value={phoneVerification.otp}\n onChangeText={phoneVerification.setOtp}\n editable={!phoneVerification.loading}\n maxLength={6}\n testID=\"chat-registration-otp\"\n />\n </View>\n\n {phoneVerification.error ? (\n <View style={[styles.errorBox, { backgroundColor: theme.colors.error + '10' }]}>\n <Ionicons name=\"alert-circle\" size={16} color={theme.colors.error} />\n <Text style={[styles.errorText, { color: theme.colors.error }]}>\n {phoneVerification.error}\n </Text>\n </View>\n ) : null}\n\n <TouchableOpacity\n onPress={handleVerifyOtp}\n disabled={phoneVerification.loading || otpDigits.length < 6}\n style={[\n styles.button,\n {\n backgroundColor: otpDigits.length >= 6 ? accent : theme.colors.border,\n },\n ]}\n >\n {phoneVerification.loading ? (\n <ActivityIndicator color=\"#fff\" size=\"small\" />\n ) : (\n <Text style={styles.buttonText}>\n {usingTestOtp ? 'Continue' : 'Verify & Register'}\n </Text>\n )}\n </TouchableOpacity>\n\n {!usingTestOtp ? (\n <TouchableOpacity onPress={handleResend} disabled={phoneVerification.loading}>\n <Text style={[styles.linkText, { color: accent }]}>\n Didn't get the code? Resend\n </Text>\n </TouchableOpacity>\n ) : null}\n </View>\n </>\n )}\n </ScrollView>\n\n <Modal visible={countryModalOpen} animationType=\"slide\" presentationStyle=\"pageSheet\">\n <SafeAreaView style={[styles.modalFill, { backgroundColor: theme.colors.background }]}>\n <View style={[styles.modalHeader, { flexDirection: 'row', alignItems: 'center' }]}>\n <Text style={[styles.modalTitle, { color: theme.colors.text }]}>Country code</Text>\n <TouchableOpacity onPress={() => setCountryModalOpen(false)}>\n <Ionicons name=\"close\" size={26} color={theme.colors.text} />\n </TouchableOpacity>\n </View>\n <ScrollView>\n {COUNTRIES.map((country) => (\n <TouchableOpacity\n key={country.code}\n onPress={() => {\n phoneVerification.setCountryCode(country.code);\n setCountryModalOpen(false);\n }}\n style={[\n styles.countryListItem,\n phoneVerification.countryCode === country.code && {\n backgroundColor: accent + '18',\n },\n ]}\n >\n <Text style={[styles.countryListText, { color: theme.colors.text }]}>\n {country.name} ({country.callingCode})\n </Text>\n {phoneVerification.countryCode === country.code ? (\n <Ionicons name=\"checkmark\" size={20} color={accent} />\n ) : null}\n </TouchableOpacity>\n ))}\n </ScrollView>\n </SafeAreaView>\n </Modal>\n </SafeAreaView>\n );\n}\n\nconst styles = StyleSheet.create({\n container: { flex: 1 },\n header: {\n justifyContent: 'space-between',\n paddingHorizontal: 16,\n paddingVertical: 8,\n },\n title: { fontSize: 17, fontWeight: '600' },\n content: { padding: 20, paddingBottom: 40 },\n subtitle: { fontSize: 22, fontWeight: '700', marginBottom: 8 },\n description: { fontSize: 14, marginBottom: 24, lineHeight: 20 },\n form: { gap: 14 },\n phoneRow: {\n borderWidth: 1,\n borderRadius: 10,\n minHeight: 48,\n overflow: 'hidden',\n },\n countryChip: {\n paddingHorizontal: 12,\n paddingVertical: 12,\n },\n callingCode: { fontSize: 16, fontWeight: '600', marginRight: 4 },\n phoneDivider: { width: StyleSheet.hairlineWidth, alignSelf: 'stretch' },\n phoneInput: {\n flex: 1,\n paddingHorizontal: 12,\n paddingVertical: Platform.OS === 'ios' ? 12 : 10,\n fontSize: 16,\n },\n otpInputContainer: {\n borderWidth: 1,\n borderRadius: 10,\n paddingHorizontal: 16,\n },\n otpInput: {\n paddingVertical: 14,\n fontSize: 22,\n fontWeight: '600',\n letterSpacing: 6,\n textAlign: 'center',\n },\n button: {\n borderRadius: 10,\n paddingVertical: 14,\n alignItems: 'center',\n justifyContent: 'center',\n marginTop: 4,\n },\n buttonText: { color: '#fff', fontSize: 16, fontWeight: '600' },\n errorBox: {\n flexDirection: 'row',\n alignItems: 'center',\n borderRadius: 8,\n paddingHorizontal: 12,\n paddingVertical: 10,\n gap: 8,\n },\n errorText: { fontSize: 13, flex: 1 },\n linkText: { fontSize: 14, textAlign: 'center', fontWeight: '500' },\n modalFill: { flex: 1 },\n modalHeader: {\n justifyContent: 'space-between',\n paddingHorizontal: 16,\n paddingVertical: 12,\n },\n modalTitle: { fontSize: 18, fontWeight: '700' },\n countryListItem: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingHorizontal: 16,\n paddingVertical: 14,\n borderBottomWidth: StyleSheet.hairlineWidth,\n borderBottomColor: 'rgba(0,0,0,0.06)',\n },\n countryListText: { fontSize: 16 },\n});\n"],"names":["React"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RegistrationScreen.js","sources":["../../../src/features/messaging/RegistrationScreen.tsx"],"sourcesContent":["/**\n * Registration screen for Yantra Chat.\n *\n * First-time users are prompted to register with their phone number.\n * The flow:\n * 1. User enters mobile number (country code in the same row)\n * 2. OTP is sent to their number\n * 3. User enters the OTP code to verify\n * 4. Phone number becomes their member ID in the Yantra Chat organization\n *\n * Follows the design from issue #1312.\n */\nimport React from 'react';\nimport {\n StyleSheet,\n View,\n Text,\n TouchableOpacity,\n TextInput,\n ActivityIndicator,\n FlatList,\n ScrollView,\n Modal,\n Platform,\n} from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\nimport { Ionicons } from '@expo/vector-icons';\nimport { CHAT_REGISTRATION_TEST_OTP, isChatTestOtpEnabled, usePhoneVerification } from './usePhoneVerification';\nimport { countryFlag, filterCountries, pickerCountries, type CountryOption } from './countryPicker';\nimport { sanitizePhoneInput } from './mobileNumberCheck';\n\ninterface RegistrationScreenProps {\n /** Called when registration completes successfully. */\n onRegistrationComplete: (phoneNumber: string) => void;\n /** Theme configuration. */\n theme: { colors: Record<string, string>; fonts: Record<string, Record<string, string>> };\n testID?: string;\n /** Back from the phone-number step: leave Yantra Chat (back to Apps). */\n onClose?: () => void;\n}\n\n/**\n * Every country is offered (see countryPicker.ts). AWS decides where a code can be sent; when it\n * cannot reach a country the send fails with \"not available in <country> yet\" and the person\n * sees that sentence under the number, so nothing here needs to know which countries work.\n */\nconst COUNTRIES: CountryOption[] = pickerCountries();\n\nfunction PhoneRow({\n countryCode,\n callingCode,\n phone,\n onCountryPress,\n onChangePhone,\n disabled,\n theme,\n}: {\n countryCode: string;\n callingCode: string;\n phone: string;\n onCountryPress: () => void;\n onChangePhone: (v: string) => void;\n disabled: boolean;\n theme: RegistrationScreenProps['theme'];\n}) {\n const [focused, setFocused] = React.useState(false);\n return (\n <View\n style={[\n styles.phoneRow,\n {\n borderColor: focused ? theme.colors.primary : theme.colors.border,\n borderWidth: focused ? 2 : 1,\n backgroundColor: theme.colors.card ?? '#fff',\n },\n ]}\n >\n <TouchableOpacity\n onPress={onCountryPress}\n disabled={disabled}\n style={[styles.countryChip, { backgroundColor: `${theme.colors.primary}12` }]}\n accessibilityRole=\"button\"\n accessibilityLabel={`Country code ${callingCode}. Change country`}\n testID=\"chat-registration-country\"\n >\n <Text style={styles.countryChipFlag}>{countryFlag(countryCode)}</Text>\n <Text style={[styles.callingCode, { color: theme.colors.text }]}>{callingCode}</Text>\n <Ionicons name=\"chevron-down\" size={16} color={theme.colors.textSecondary} />\n </TouchableOpacity>\n <TextInput\n style={[styles.phoneInput, { color: theme.colors.text }]}\n placeholder=\"Phone number\"\n placeholderTextColor={theme.colors.placeholder ?? theme.colors.textSecondary}\n keyboardType=\"phone-pad\"\n textContentType=\"telephoneNumber\"\n autoComplete=\"tel\"\n value={phone}\n onChangeText={(text) => onChangePhone(sanitizePhoneInput(text))}\n onFocus={() => setFocused(true)}\n onBlur={() => setFocused(false)}\n editable={!disabled}\n maxLength={15}\n autoFocus\n testID=\"chat-registration-phone\"\n />\n </View>\n );\n}\n\n/** The round tinted icon above each step's heading. */\nfunction StepIcon({ name, color }: { name: React.ComponentProps<typeof Ionicons>['name']; color: string }) {\n return (\n <View style={[styles.stepIcon, { backgroundColor: `${color}1A` }]}>\n <Ionicons name={name} size={30} color={color} />\n </View>\n );\n}\n\nconst OTP_LENGTH = 6;\n/** Seconds before \"Resend\" unlocks after a code goes out. */\nconst RESEND_COOLDOWN_SECONDS = 30;\n\n/**\n * Six digit boxes over one invisible input, so the keyboard, paste and the iOS / Android\n * \"code from Messages\" suggestion all fill it like a single field.\n */\nfunction OtpCodeInput({\n value,\n onChange,\n disabled,\n hasError,\n theme,\n}: {\n value: string;\n onChange: (v: string) => void;\n disabled: boolean;\n hasError: boolean;\n theme: RegistrationScreenProps['theme'];\n}) {\n const inputRef = React.useRef<TextInput>(null);\n const [focused, setFocused] = React.useState(false);\n const digits = value.replace(/\\D/g, '').slice(0, OTP_LENGTH);\n const accent = theme.colors.primary;\n\n return (\n <View style={styles.otpRow}>\n {Array.from({ length: OTP_LENGTH }, (_, i) => {\n const active = focused && !disabled && i === Math.min(digits.length, OTP_LENGTH - 1);\n const filled = i < digits.length;\n const borderColor = hasError\n ? theme.colors.error\n : active\n ? accent\n : filled\n ? theme.colors.text\n : theme.colors.border;\n return (\n <View\n key={i}\n style={[\n styles.otpCell,\n {\n borderColor,\n borderWidth: active || hasError ? 2 : 1,\n backgroundColor: theme.colors.card ?? '#fff',\n },\n ]}\n >\n {filled ? (\n <Text style={[styles.otpDigit, { color: theme.colors.text }]}>{digits[i]}</Text>\n ) : active ? (\n <View style={[styles.otpCaret, { backgroundColor: accent }]} />\n ) : null}\n </View>\n );\n })}\n <TextInput\n ref={inputRef}\n value={digits}\n onChangeText={(text) => onChange(text.replace(/\\D/g, '').slice(0, OTP_LENGTH))}\n onFocus={() => setFocused(true)}\n onBlur={() => setFocused(false)}\n editable={!disabled}\n keyboardType=\"number-pad\"\n textContentType=\"oneTimeCode\"\n autoComplete={Platform.OS === 'android' ? 'sms-otp' : 'one-time-code'}\n autoFocus\n maxLength={OTP_LENGTH}\n caretHidden\n style={styles.otpHiddenInput}\n accessibilityLabel=\"Verification code\"\n testID=\"chat-registration-otp\"\n />\n </View>\n );\n}\n\nexport function RegistrationScreen({ onRegistrationComplete, theme, testID, onClose }: RegistrationScreenProps) {\n const phoneVerification = usePhoneVerification('US');\n const selectedCountry = COUNTRIES.find((c) => c.code === phoneVerification.countryCode) || COUNTRIES[0];\n const [countryModalOpen, setCountryModalOpen] = React.useState(false);\n const [countryQuery, setCountryQuery] = React.useState('');\n const visibleCountries = React.useMemo(() => filterCountries(COUNTRIES, countryQuery), [countryQuery]);\n const closeCountryModal = React.useCallback(() => {\n setCountryModalOpen(false);\n setCountryQuery('');\n }, []);\n const accent = theme.colors.primary;\n const otpDigits = phoneVerification.otp.replace(/\\D/g, '');\n const testOtpEnabled = isChatTestOtpEnabled();\n const usingTestOtp = testOtpEnabled && (phoneVerification.testOtpMode || otpDigits === CHAT_REGISTRATION_TEST_OTP);\n\n const { registrationFailed } = phoneVerification;\n React.useEffect(() => {\n if (phoneVerification.stage === 'verified' && phoneVerification.verifiedPhone) {\n // A failed registration used to be dropped here, leaving the screen stuck with no reason.\n Promise.resolve(onRegistrationComplete(phoneVerification.verifiedPhone)).catch((err: unknown) => {\n const message = err instanceof Error && err.message ? err.message : '';\n registrationFailed(\n message\n ? `Could not register: ${message}`\n : 'Could not register for Yantra Chat. Please try again.',\n );\n });\n }\n }, [phoneVerification.stage, phoneVerification.verifiedPhone, onRegistrationComplete, registrationFailed]);\n\n // Code step: back to the phone number. Phone step: out of Chat.\n const handleBack = React.useCallback(() => {\n if (phoneVerification.stage === 'otp') {\n phoneVerification.resetToInput();\n return;\n }\n onClose?.();\n }, [phoneVerification, onClose]);\n\n // Counts down from the last successful send; Resend unlocks at 0.\n const [resendIn, setResendIn] = React.useState(0);\n React.useEffect(() => {\n if (resendIn <= 0) return undefined;\n const timer = setTimeout(() => setResendIn((s) => s - 1), 1000);\n return () => clearTimeout(timer);\n }, [resendIn]);\n\n const handleSendOtp = React.useCallback(async () => {\n if (await phoneVerification.sendOtp()) setResendIn(RESEND_COOLDOWN_SECONDS);\n }, [phoneVerification]);\n\n const handleVerifyOtp = React.useCallback(async () => {\n await phoneVerification.verifyOtp();\n }, [phoneVerification]);\n\n const handleResend = React.useCallback(async () => {\n if (await phoneVerification.sendOtp()) setResendIn(RESEND_COOLDOWN_SECONDS);\n }, [phoneVerification]);\n\n // Verify as soon as the sixth digit lands (typed, pasted or autofilled), once per code.\n const autoVerifiedFor = React.useRef('');\n React.useEffect(() => {\n if (phoneVerification.stage !== 'otp' || usingTestOtp || phoneVerification.loading) return;\n if (otpDigits.length !== OTP_LENGTH || autoVerifiedFor.current === otpDigits) return;\n autoVerifiedFor.current = otpDigits;\n void phoneVerification.verifyOtp();\n }, [otpDigits, phoneVerification, usingTestOtp]);\n\n const renderCountryRow = (country: CountryOption) => {\n const selected = phoneVerification.countryCode === country.code;\n return (\n <TouchableOpacity\n onPress={() => {\n phoneVerification.setCountryCode(country.code);\n closeCountryModal();\n }}\n style={styles.countryListItem}\n accessibilityRole=\"button\"\n accessibilityState={{ selected }}\n accessibilityLabel={`${country.name} ${country.callingCode}`}\n >\n <Text style={styles.countryFlag}>{countryFlag(country.code)}</Text>\n <Text\n style={[styles.countryListText, { color: theme.colors.text }, selected && styles.countrySelected]}\n numberOfLines={1}\n >\n {country.name}\n </Text>\n <Text style={[styles.countryDial, { color: theme.colors.textSecondary }]}>{country.callingCode}</Text>\n <View style={styles.countryCheck}>\n {selected ? <Ionicons name=\"checkmark-circle\" size={22} color={accent} /> : null}\n </View>\n </TouchableOpacity>\n );\n };\n\n return (\n <SafeAreaView\n style={[styles.container, { backgroundColor: theme.colors.background }]}\n edges={['top', 'left', 'right']}\n testID={testID}\n >\n <View style={[styles.header, { flexDirection: 'row', alignItems: 'center' }]}>\n {phoneVerification.stage === 'otp' || onClose ? (\n <TouchableOpacity\n onPress={handleBack}\n hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}\n accessibilityRole=\"button\"\n accessibilityLabel={phoneVerification.stage === 'otp' ? 'Change phone number' : 'Back'}\n testID=\"chat-registration-back\"\n >\n <Ionicons name=\"chevron-back\" size={28} color={theme.colors.text} />\n </TouchableOpacity>\n ) : (\n <View style={{ width: 28 }} />\n )}\n <Text style={[styles.title, { color: theme.colors.text, flex: 1, textAlign: 'center' }]}>\n Yantra Chat\n </Text>\n <View style={{ width: 28 }} />\n </View>\n\n <ScrollView\n contentContainerStyle={styles.content}\n showsVerticalScrollIndicator={false}\n keyboardShouldPersistTaps=\"handled\"\n >\n {phoneVerification.stage === 'input' ? (\n <>\n <StepIcon name=\"chatbubbles\" color={accent} />\n <Text style={[styles.subtitle, { color: theme.colors.text }]}>Enter your phone number</Text>\n <Text style={[styles.description, { color: theme.colors.textSecondary }]}>\n Yantra Chat will send you a text with a 6-digit code to verify your number.\n </Text>\n\n <View style={styles.form}>\n <PhoneRow\n countryCode={phoneVerification.countryCode}\n callingCode={selectedCountry.callingCode}\n phone={phoneVerification.inputPhone}\n onCountryPress={() => setCountryModalOpen(true)}\n onChangePhone={(value) => {\n if (phoneVerification.error) phoneVerification.clearError();\n phoneVerification.setInputPhone(value);\n }}\n disabled={phoneVerification.loading}\n theme={theme}\n />\n\n {phoneVerification.error ? (\n <View style={[styles.errorBox, { backgroundColor: `${theme.colors.error}10` }]}>\n <Ionicons name=\"alert-circle\" size={16} color={theme.colors.error} />\n <Text style={[styles.errorText, { color: theme.colors.error }]}>\n {phoneVerification.error}\n </Text>\n </View>\n ) : null}\n\n <TouchableOpacity\n onPress={handleSendOtp}\n disabled={phoneVerification.loading || !phoneVerification.inputPhone.trim()}\n style={[\n styles.button,\n {\n backgroundColor: accent,\n opacity:\n phoneVerification.inputPhone.trim() || phoneVerification.loading ? 1 : 0.4,\n },\n ]}\n >\n {phoneVerification.loading ? (\n <ActivityIndicator color=\"#fff\" size=\"small\" />\n ) : (\n <Text style={styles.buttonText}>Send code</Text>\n )}\n </TouchableOpacity>\n\n {testOtpEnabled ? (\n <TouchableOpacity\n onPress={phoneVerification.continueWithTestOtp}\n style={[styles.testOtpChip, { borderColor: theme.colors.border }]}\n >\n <Ionicons name=\"flask-outline\" size={14} color={theme.colors.textSecondary} />\n <Text style={[styles.testOtpText, { color: theme.colors.textSecondary }]}>\n Continue with test OTP\n </Text>\n </TouchableOpacity>\n ) : null}\n </View>\n </>\n ) : (\n <>\n <StepIcon name=\"shield-checkmark\" color={accent} />\n <Text style={[styles.subtitle, { color: theme.colors.text }]}>Verify your number</Text>\n {usingTestOtp ? (\n <Text style={[styles.description, { color: theme.colors.textSecondary }]}>\n Test mode: use code {CHAT_REGISTRATION_TEST_OTP} and tap Continue.\n </Text>\n ) : (\n <Text style={[styles.description, { color: theme.colors.textSecondary }]}>\n Enter the 6-digit code we sent to{'\\n'}\n <Text style={[styles.phoneStrong, { color: theme.colors.text }]}>\n {selectedCountry.callingCode} {phoneVerification.inputPhone}\n </Text>\n {' '}\n <Text\n style={[styles.inlineLink, { color: accent }]}\n onPress={phoneVerification.loading ? undefined : phoneVerification.resetToInput}\n accessibilityRole=\"link\"\n >\n Wrong number?\n </Text>\n </Text>\n )}\n\n <View style={styles.form}>\n <OtpCodeInput\n value={phoneVerification.otp}\n onChange={phoneVerification.setOtp}\n disabled={phoneVerification.loading}\n hasError={Boolean(phoneVerification.error)}\n theme={theme}\n />\n\n {phoneVerification.error ? (\n <View style={[styles.errorBox, { backgroundColor: `${theme.colors.error}10` }]}>\n <Ionicons name=\"alert-circle\" size={16} color={theme.colors.error} />\n <Text style={[styles.errorText, { color: theme.colors.error }]}>\n {phoneVerification.error}\n </Text>\n </View>\n ) : null}\n\n <TouchableOpacity\n onPress={handleVerifyOtp}\n disabled={phoneVerification.loading || otpDigits.length < OTP_LENGTH}\n style={[\n styles.button,\n {\n backgroundColor: accent,\n opacity: otpDigits.length >= OTP_LENGTH || phoneVerification.loading ? 1 : 0.4,\n },\n ]}\n >\n {phoneVerification.loading ? (\n <ActivityIndicator color=\"#fff\" size=\"small\" />\n ) : (\n <Text style={styles.buttonText}>{usingTestOtp ? 'Continue' : 'Verify'}</Text>\n )}\n </TouchableOpacity>\n\n {!usingTestOtp ? (\n <View style={styles.resendRow}>\n <Text style={[styles.resendHint, { color: theme.colors.textSecondary }]}>\n Didn't get the code?\n </Text>\n {resendIn > 0 ? (\n <Text style={[styles.resendHint, { color: theme.colors.textSecondary }]}>\n Resend in 0:{String(resendIn).padStart(2, '0')}\n </Text>\n ) : (\n <TouchableOpacity\n onPress={handleResend}\n disabled={phoneVerification.loading}\n hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}\n >\n <Text style={[styles.inlineLink, { color: accent }]}>Resend code</Text>\n </TouchableOpacity>\n )}\n </View>\n ) : null}\n </View>\n </>\n )}\n </ScrollView>\n\n <Modal\n visible={countryModalOpen}\n animationType=\"slide\"\n presentationStyle=\"pageSheet\"\n onRequestClose={closeCountryModal}\n >\n <SafeAreaView style={[styles.modalFill, { backgroundColor: theme.colors.background }]}>\n <View style={styles.modalHandle}>\n <View style={[styles.modalHandleBar, { backgroundColor: theme.colors.border }]} />\n </View>\n <View style={styles.modalHeader}>\n <TouchableOpacity\n onPress={closeCountryModal}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Close\"\n hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}\n style={[styles.modalClose, { backgroundColor: `${theme.colors.text}0D` }]}\n >\n <Ionicons name=\"close\" size={20} color={theme.colors.text} />\n </TouchableOpacity>\n <Text style={[styles.modalTitle, { color: theme.colors.text }]}>Choose a country</Text>\n <View style={styles.modalClose} />\n </View>\n <View style={[styles.countrySearch, { backgroundColor: `${theme.colors.text}0D` }]}>\n <Ionicons name=\"search\" size={18} color={theme.colors.textSecondary ?? theme.colors.text} />\n <TextInput\n value={countryQuery}\n onChangeText={setCountryQuery}\n placeholder=\"Search countries\"\n placeholderTextColor={theme.colors.textSecondary ?? '#888'}\n autoCorrect={false}\n autoCapitalize=\"none\"\n clearButtonMode=\"while-editing\"\n returnKeyType=\"search\"\n style={[styles.countrySearchInput, { color: theme.colors.text }]}\n testID=\"country-search\"\n />\n </View>\n <FlatList\n data={visibleCountries}\n keyExtractor={(country) => country.code}\n keyboardShouldPersistTaps=\"handled\"\n keyboardDismissMode=\"on-drag\"\n initialNumToRender={24}\n ListHeaderComponent={\n countryQuery.trim() ? null : (\n <>\n <Text style={[styles.countrySection, { color: theme.colors.textSecondary }]}>\n SELECTED\n </Text>\n {renderCountryRow(selectedCountry)}\n <Text style={[styles.countrySection, { color: theme.colors.textSecondary }]}>\n ALL COUNTRIES\n </Text>\n </>\n )\n }\n ListEmptyComponent={\n <Text\n style={[\n styles.countryEmpty,\n { color: theme.colors.textSecondary ?? theme.colors.text },\n ]}\n >\n No country matches "{countryQuery.trim()}"\n </Text>\n }\n renderItem={({ item: country }) => renderCountryRow(country)}\n />\n </SafeAreaView>\n </Modal>\n </SafeAreaView>\n );\n}\n\nconst styles = StyleSheet.create({\n container: { flex: 1 },\n header: {\n justifyContent: 'space-between',\n paddingHorizontal: 16,\n paddingVertical: 8,\n },\n title: { fontSize: 17, fontWeight: '600' },\n content: { padding: 20, paddingBottom: 40 },\n subtitle: { fontSize: 26, fontWeight: '700', letterSpacing: -0.4, marginBottom: 8 },\n description: { fontSize: 15, marginBottom: 28, lineHeight: 22 },\n stepIcon: {\n width: 60,\n height: 60,\n borderRadius: 18,\n alignItems: 'center',\n justifyContent: 'center',\n marginBottom: 20,\n },\n form: { gap: 14 },\n phoneRow: {\n flexDirection: 'row',\n alignItems: 'center',\n borderRadius: 14,\n minHeight: 56,\n padding: 5,\n gap: 6,\n },\n countryChip: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 6,\n borderRadius: 10,\n paddingHorizontal: 10,\n alignSelf: 'stretch',\n },\n countryChipFlag: { fontSize: 22 },\n callingCode: { fontSize: 16, fontWeight: '600' },\n phoneInput: {\n flex: 1,\n paddingHorizontal: 8,\n paddingVertical: Platform.OS === 'ios' ? 12 : 8,\n fontSize: 18,\n letterSpacing: 0.3,\n },\n testOtpChip: {\n flexDirection: 'row',\n alignItems: 'center',\n alignSelf: 'center',\n gap: 6,\n borderWidth: 1,\n borderStyle: 'dashed',\n borderRadius: 999,\n paddingHorizontal: 14,\n paddingVertical: 8,\n marginTop: 8,\n },\n testOtpText: { fontSize: 13, fontWeight: '500' },\n otpRow: {\n flexDirection: 'row',\n justifyContent: 'space-between',\n gap: 8,\n },\n otpCell: {\n flex: 1,\n maxWidth: 52,\n aspectRatio: 0.85,\n borderRadius: 12,\n alignItems: 'center',\n justifyContent: 'center',\n },\n otpDigit: { fontSize: 24, fontWeight: '600' },\n otpCaret: { width: 2, height: 26, borderRadius: 1 },\n // Covers the boxes so a tap anywhere focuses it; near-zero opacity keeps iOS code autofill working.\n otpHiddenInput: {\n ...StyleSheet.absoluteFillObject,\n opacity: 0.011,\n color: 'transparent',\n fontSize: 1,\n },\n phoneStrong: { fontWeight: '600' },\n inlineLink: { fontSize: 14, fontWeight: '600' },\n resendRow: {\n flexDirection: 'row',\n justifyContent: 'center',\n alignItems: 'center',\n gap: 6,\n marginTop: 4,\n },\n resendHint: { fontSize: 14 },\n button: {\n borderRadius: 14,\n minHeight: 54,\n paddingVertical: 14,\n alignItems: 'center',\n justifyContent: 'center',\n marginTop: 4,\n },\n buttonText: { color: '#fff', fontSize: 17, fontWeight: '600' },\n errorBox: {\n flexDirection: 'row',\n alignItems: 'center',\n borderRadius: 12,\n paddingHorizontal: 12,\n paddingVertical: 10,\n gap: 8,\n },\n errorText: { fontSize: 13, flex: 1 },\n modalFill: { flex: 1 },\n modalHandle: { alignItems: 'center', paddingTop: 8 },\n modalHandleBar: { width: 36, height: 5, borderRadius: 3 },\n modalHeader: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingHorizontal: 16,\n paddingVertical: 12,\n },\n modalClose: {\n width: 32,\n height: 32,\n borderRadius: 16,\n alignItems: 'center',\n justifyContent: 'center',\n },\n modalTitle: { fontSize: 17, fontWeight: '700' },\n countrySearch: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 8,\n marginHorizontal: 16,\n marginBottom: 4,\n paddingHorizontal: 12,\n borderRadius: 12,\n minHeight: 42,\n },\n countrySearchInput: { flex: 1, fontSize: 16, paddingVertical: Platform.OS === 'ios' ? 10 : 6 },\n countryEmpty: { textAlign: 'center', padding: 24, fontSize: 14 },\n countrySection: {\n fontSize: 12,\n fontWeight: '600',\n letterSpacing: 0.6,\n paddingHorizontal: 20,\n paddingTop: 18,\n paddingBottom: 6,\n },\n countryListItem: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 14,\n paddingHorizontal: 20,\n minHeight: 52,\n },\n countryFlag: { fontSize: 26, width: 32, textAlign: 'center' },\n countryListText: { flex: 1, fontSize: 16 },\n countrySelected: { fontWeight: '600' },\n countryDial: { fontSize: 15, minWidth: 48, textAlign: 'right' },\n countryCheck: { width: 22, alignItems: 'center' },\n});\n"],"names":["React"],"mappings":"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"}
|
|
@@ -49,4 +49,9 @@ function chatInviteMessage(inviterName, url) {
|
|
|
49
49
|
return `${who} invited you to chat on Yantra. Tap the link below to join.
|
|
50
50
|
|
|
51
51
|
${url}`;
|
|
52
|
-
}
|
|
52
|
+
}
|
|
53
|
+
function whatsAppInviteUrl(phoneE164, message) {
|
|
54
|
+
const digits = String(phoneE164 != null ? phoneE164 : "").replace(/\D/g, "");
|
|
55
|
+
if (digits.length < 7) return null;
|
|
56
|
+
return `https://wa.me/${digits}?text=${encodeURIComponent(message)}`;
|
|
57
|
+
}export{CHAT_INVITE_PATH,buildChatInviteUrl,chatInviteMessage,parseChatInviteUrl,whatsAppInviteUrl};//# sourceMappingURL=chatInviteLink.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chatInviteLink.js","sources":["../../../src/features/messaging/chatInviteLink.ts"],"sourcesContent":["/**\n * Yantra Chat invite links (issue #1312).\n *\n * https://<web>/chat/invite?by=<inviterAccountId>&n=<inviterName>\n *\n * The same link must work as a universal/app link (app installed), as a web page\n * (app not installed - the landing page offers the stores and an \"Open in Yantra\"\n * button), and through the app's custom schemes. It carries the inviter's account\n * id so the app can open the conversation straight away - and deliberately NO phone\n * numbers, which the previous `?phone=&inviter=` form leaked into every forwarded SMS.\n *\n * Hand-parsed rather than `new URL(...)`: React Native's URL has no `searchParams`\n * without a polyfill and throws on custom schemes.\n */\n\nexport const CHAT_INVITE_PATH = '/chat/invite';\nexport const CHAT_INVITE_SCHEME = 'yantraapp';\n\nexport interface ChatInvite {\n inviterId: string;\n inviterName: string | null;\n}\n\nconst ACCOUNT_ID = /^[a-f0-9]{24}$/i;\n/** `chat/invite` as whole path segments, after any scheme/host/`--` prefix. */\nconst CHAT_INVITE_SEGMENTS = /(?:^|[/:])chat\\/invite(?:$|[/?#])/i;\n\nfunction query(url: string): Record<string, string> {\n const withoutFragment = url.split('#')[0];\n const at = withoutFragment.indexOf('?');\n const out: Record<string, string> = {};\n if (at === -1) return out;\n for (const pair of withoutFragment.slice(at + 1).split('&')) {\n const eq = pair.indexOf('=');\n if (eq <= 0) continue;\n try {\n const key = decodeURIComponent(pair.slice(0, eq)).trim();\n const value = decodeURIComponent(pair.slice(eq + 1).replace(/\\+/g, ' ')).trim();\n if (key && value && !(key in out)) out[key] = value;\n } catch {\n // A malformed escape in one pair must not discard the others.\n }\n }\n return out;\n}\n\nfunction inviteQuery(invite: ChatInvite): string {\n const params = [`by=${encodeURIComponent(invite.inviterId)}`];\n const name = invite.inviterName?.trim();\n if (name) params.push(`n=${encodeURIComponent(name.slice(0, 60))}`);\n return params.join('&');\n}\n\nexport function buildChatInviteUrl(baseUrl: string, invite: ChatInvite): string {\n const base = baseUrl.trim().replace(/\\/+$/, '');\n return `${base}${CHAT_INVITE_PATH}?${inviteQuery(invite)}`;\n}\n\n/** The app's own scheme for the same invite - what the web page's \"Open in Yantra\" uses. */\nexport function chatInviteAppUrl(invite: ChatInvite): string {\n return `${CHAT_INVITE_SCHEME}://chat/invite?${inviteQuery(invite)}`;\n}\n\nexport function parseChatInviteUrl(url: string | null | undefined): ChatInvite | null {\n if (!url) return null;\n const value = String(url);\n const queryAt = value.indexOf('?');\n const path = queryAt === -1 ? value : value.slice(0, queryAt);\n if (!CHAT_INVITE_SEGMENTS.test(path)) return null;\n const params = query(value);\n const inviterId = params.by ?? '';\n if (!ACCOUNT_ID.test(inviterId)) return null;\n return { inviterId, inviterName: params.n || null };\n}\n\n/**\n * The invite SMS/iMessage text. The link goes last and on its own line: iMessage turns a\n * trailing link into a preview card (the text above must read fine without it), and plain\n * SMS shows it as a tappable link.\n */\nexport function chatInviteMessage(inviterName: string | null | undefined, url: string): string {\n const who = inviterName?.trim() || 'A friend';\n return `${who} invited you to chat on Yantra. Tap the link below to join.\\n\\n${url}`;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chatInviteLink.js","sources":["../../../src/features/messaging/chatInviteLink.ts"],"sourcesContent":["/**\n * Yantra Chat invite links (issue #1312).\n *\n * https://<web>/chat/invite?by=<inviterAccountId>&n=<inviterName>\n *\n * The same link must work as a universal/app link (app installed), as a web page\n * (app not installed - the landing page offers the stores and an \"Open in Yantra\"\n * button), and through the app's custom schemes. It carries the inviter's account\n * id so the app can open the conversation straight away - and deliberately NO phone\n * numbers, which the previous `?phone=&inviter=` form leaked into every forwarded SMS.\n *\n * Hand-parsed rather than `new URL(...)`: React Native's URL has no `searchParams`\n * without a polyfill and throws on custom schemes.\n */\n\nexport const CHAT_INVITE_PATH = '/chat/invite';\nexport const CHAT_INVITE_SCHEME = 'yantraapp';\n\nexport interface ChatInvite {\n inviterId: string;\n inviterName: string | null;\n}\n\nconst ACCOUNT_ID = /^[a-f0-9]{24}$/i;\n/** `chat/invite` as whole path segments, after any scheme/host/`--` prefix. */\nconst CHAT_INVITE_SEGMENTS = /(?:^|[/:])chat\\/invite(?:$|[/?#])/i;\n\nfunction query(url: string): Record<string, string> {\n const withoutFragment = url.split('#')[0];\n const at = withoutFragment.indexOf('?');\n const out: Record<string, string> = {};\n if (at === -1) return out;\n for (const pair of withoutFragment.slice(at + 1).split('&')) {\n const eq = pair.indexOf('=');\n if (eq <= 0) continue;\n try {\n const key = decodeURIComponent(pair.slice(0, eq)).trim();\n const value = decodeURIComponent(pair.slice(eq + 1).replace(/\\+/g, ' ')).trim();\n if (key && value && !(key in out)) out[key] = value;\n } catch {\n // A malformed escape in one pair must not discard the others.\n }\n }\n return out;\n}\n\nfunction inviteQuery(invite: ChatInvite): string {\n const params = [`by=${encodeURIComponent(invite.inviterId)}`];\n const name = invite.inviterName?.trim();\n if (name) params.push(`n=${encodeURIComponent(name.slice(0, 60))}`);\n return params.join('&');\n}\n\nexport function buildChatInviteUrl(baseUrl: string, invite: ChatInvite): string {\n const base = baseUrl.trim().replace(/\\/+$/, '');\n return `${base}${CHAT_INVITE_PATH}?${inviteQuery(invite)}`;\n}\n\n/** The app's own scheme for the same invite - what the web page's \"Open in Yantra\" uses. */\nexport function chatInviteAppUrl(invite: ChatInvite): string {\n return `${CHAT_INVITE_SCHEME}://chat/invite?${inviteQuery(invite)}`;\n}\n\nexport function parseChatInviteUrl(url: string | null | undefined): ChatInvite | null {\n if (!url) return null;\n const value = String(url);\n const queryAt = value.indexOf('?');\n const path = queryAt === -1 ? value : value.slice(0, queryAt);\n if (!CHAT_INVITE_SEGMENTS.test(path)) return null;\n const params = query(value);\n const inviterId = params.by ?? '';\n if (!ACCOUNT_ID.test(inviterId)) return null;\n return { inviterId, inviterName: params.n || null };\n}\n\n/**\n * The invite SMS/iMessage text. The link goes last and on its own line: iMessage turns a\n * trailing link into a preview card (the text above must read fine without it), and plain\n * SMS shows it as a tappable link.\n */\nexport function chatInviteMessage(inviterName: string | null | undefined, url: string): string {\n const who = inviterName?.trim() || 'A friend';\n return `${who} invited you to chat on Yantra. Tap the link below to join.\\n\\n${url}`;\n}\n\n/**\n * WhatsApp's click-to-chat link for one number, with the invite prefilled: opens the person's\n * chat in WhatsApp when it is installed, WhatsApp's web page otherwise. Null without a number.\n */\nexport function whatsAppInviteUrl(phoneE164: string | null | undefined, message: string): string | null {\n const digits = String(phoneE164 ?? '').replace(/\\D/g, '');\n if (digits.length < 7) return null;\n return `https://wa.me/${digits}?text=${encodeURIComponent(message)}`;\n}\n"],"names":[],"mappings":"AAeO,MAAM,gBAAmB,GAAA;AAMhC,MAAM,UAAa,GAAA,iBAAA;AAEnB,MAAM,oBAAuB,GAAA,oCAAA;AAC7B,SAAS,MAAM,GAAqC,EAAA;AAClD,EAAA,MAAM,eAAkB,GAAA,GAAA,CAAI,KAAM,CAAA,GAAG,EAAE,CAAC,CAAA;AACxC,EAAM,MAAA,EAAA,GAAK,eAAgB,CAAA,OAAA,CAAQ,GAAG,CAAA;AACtC,EAAA,MAAM,MAA8B,EAAC;AACrC,EAAI,IAAA,EAAA,KAAO,IAAW,OAAA,GAAA;AACtB,EAAW,KAAA,MAAA,IAAA,IAAQ,gBAAgB,KAAM,CAAA,EAAA,GAAK,CAAC,CAAE,CAAA,KAAA,CAAM,GAAG,CAAG,EAAA;AAC3D,IAAM,MAAA,EAAA,GAAK,IAAK,CAAA,OAAA,CAAQ,GAAG,CAAA;AAC3B,IAAA,IAAI,MAAM,CAAG,EAAA;AACb,IAAI,IAAA;AACF,MAAM,MAAA,GAAA,GAAM,mBAAmB,IAAK,CAAA,KAAA,CAAM,GAAG,EAAE,CAAC,EAAE,IAAK,EAAA;AACvD,MAAA,MAAM,KAAQ,GAAA,kBAAA,CAAmB,IAAK,CAAA,KAAA,CAAM,EAAK,GAAA,CAAC,CAAE,CAAA,OAAA,CAAQ,KAAO,EAAA,GAAG,CAAC,CAAA,CAAE,IAAK,EAAA;AAC9E,MAAA,IAAI,OAAO,KAAS,IAAA,EAAE,OAAO,GAAM,CAAA,EAAA,GAAA,CAAI,GAAG,CAAI,GAAA,KAAA;AAAA,KACxC,CAAA,OAAA,CAAA,EAAA;AAAA;AAER;AAEF,EAAO,OAAA,GAAA;AACT;AACA,SAAS,YAAY,MAA4B,EAAA;AA1CjD,EAAA,IAAA,EAAA;AA2CE,EAAA,MAAM,SAAS,CAAC,CAAA,GAAA,EAAM,mBAAmB,MAAO,CAAA,SAAS,CAAC,CAAE,CAAA,CAAA;AAC5D,EAAM,MAAA,IAAA,GAAA,CAAO,EAAO,GAAA,MAAA,CAAA,WAAA,KAAP,IAAoB,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,EAAA;AACjC,EAAI,IAAA,IAAA,EAAa,MAAA,CAAA,IAAA,CAAK,CAAK,EAAA,EAAA,kBAAA,CAAmB,IAAK,CAAA,KAAA,CAAM,CAAG,EAAA,EAAE,CAAC,CAAC,CAAE,CAAA,CAAA;AAClE,EAAO,OAAA,MAAA,CAAO,KAAK,GAAG,CAAA;AACxB;AACgB,SAAA,kBAAA,CAAmB,SAAiB,MAA4B,EAAA;AAC9E,EAAA,MAAM,OAAO,OAAQ,CAAA,IAAA,EAAO,CAAA,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAC9C,EAAA,OAAO,GAAG,IAAI,CAAA,EAAG,gBAAgB,CAAI,CAAA,EAAA,WAAA,CAAY,MAAM,CAAC,CAAA,CAAA;AAC1D;AAMO,SAAS,mBAAmB,GAAmD,EAAA;AAzDtF,EAAA,IAAA,EAAA;AA0DE,EAAI,IAAA,CAAC,KAAY,OAAA,IAAA;AACjB,EAAM,MAAA,KAAA,GAAQ,OAAO,GAAG,CAAA;AACxB,EAAM,MAAA,OAAA,GAAU,KAAM,CAAA,OAAA,CAAQ,GAAG,CAAA;AACjC,EAAA,MAAM,OAAO,OAAY,KAAA,EAAA,GAAK,QAAQ,KAAM,CAAA,KAAA,CAAM,GAAG,OAAO,CAAA;AAC5D,EAAA,IAAI,CAAC,oBAAA,CAAqB,IAAK,CAAA,IAAI,GAAU,OAAA,IAAA;AAC7C,EAAM,MAAA,MAAA,GAAS,MAAM,KAAK,CAAA;AAC1B,EAAM,MAAA,SAAA,GAAA,CAAY,EAAO,GAAA,MAAA,CAAA,EAAA,KAAP,IAAa,GAAA,EAAA,GAAA,EAAA;AAC/B,EAAA,IAAI,CAAC,UAAA,CAAW,IAAK,CAAA,SAAS,GAAU,OAAA,IAAA;AACxC,EAAO,OAAA;AAAA,IACL,SAAA;AAAA,IACA,WAAA,EAAa,OAAO,CAAK,IAAA;AAAA,GAC3B;AACF;AAOgB,SAAA,iBAAA,CAAkB,aAAwC,GAAqB,EAAA;AAC7F,EAAM,MAAA,GAAA,GAAA,CAAM,2CAAa,IAAU,EAAA,KAAA,UAAA;AACnC,EAAA,OAAO,GAAG,GAAG,CAAA;;AAAA,EAAkE,GAAG,CAAA,CAAA;AACpF;AAMgB,SAAA,iBAAA,CAAkB,WAAsC,OAAgC,EAAA;AACtG,EAAA,MAAM,SAAS,MAAO,CAAA,SAAA,IAAA,IAAA,GAAA,SAAA,GAAa,EAAE,CAAE,CAAA,OAAA,CAAQ,OAAO,EAAE,CAAA;AACxD,EAAI,IAAA,MAAA,CAAO,MAAS,GAAA,CAAA,EAAU,OAAA,IAAA;AAC9B,EAAA,OAAO,CAAiB,cAAA,EAAA,MAAM,CAAS,MAAA,EAAA,kBAAA,CAAmB,OAAO,CAAC,CAAA,CAAA;AACpE"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {PHONE_COUNTRIES}from'./phoneCountries.js';function allowedDialCodes(raw = process.env.EXPO_PUBLIC_PHONE_OTP_ALLOWED_DIAL_CODES) {
|
|
2
|
+
const value = raw == null ? void 0 : raw.trim();
|
|
3
|
+
if (!value || value === "*") return null;
|
|
4
|
+
const codes = value.split(",").map((c) => c.trim()).filter(Boolean).map((c) => c.startsWith("+") ? c : `+${c}`).filter((c) => /^\+\d{1,4}$/.test(c));
|
|
5
|
+
return codes.length ? codes : null;
|
|
6
|
+
}
|
|
7
|
+
function pickerCountries(all = PHONE_COUNTRIES, allowed = allowedDialCodes(), defaultCode = "US") {
|
|
8
|
+
var _a;
|
|
9
|
+
if (!allowed) return [...all];
|
|
10
|
+
const offered = all.filter((c) => allowed.includes(c.callingCode));
|
|
11
|
+
if (offered.length) return offered;
|
|
12
|
+
const fallback = (_a = all.find((c) => c.code === defaultCode)) != null ? _a : all[0];
|
|
13
|
+
return fallback ? [fallback] : [];
|
|
14
|
+
}
|
|
15
|
+
function filterCountries(countries, query) {
|
|
16
|
+
const q = query.trim().toLowerCase();
|
|
17
|
+
if (!q) return [...countries];
|
|
18
|
+
const digits = q.replace(/^\+/, "");
|
|
19
|
+
return countries.filter((c) => c.name.toLowerCase().includes(q) || c.code.toLowerCase() === q || digits && /^\d+$/.test(digits) && c.callingCode.slice(1).startsWith(digits));
|
|
20
|
+
}
|
|
21
|
+
function countryFlag(code) {
|
|
22
|
+
const iso = code.trim().toUpperCase();
|
|
23
|
+
if (!/^[A-Z]{2}$/.test(iso)) return "";
|
|
24
|
+
return String.fromCodePoint(...[...iso].map((c) => 127462 + c.charCodeAt(0) - 65));
|
|
25
|
+
}export{allowedDialCodes,countryFlag,filterCountries,pickerCountries};//# sourceMappingURL=countryPicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"countryPicker.js","sources":["../../../src/features/messaging/countryPicker.ts"],"sourcesContent":["import { PHONE_COUNTRIES, type PhoneCountry } from './phoneCountries';\n\n/**\n * The country picker on the chat registration screen.\n *\n * Every country is offered: AWS, not the app, decides where a verification text can go, and\n * when it cannot reach a country the send comes back with \"not available in <country> yet\"\n * (the server turns AWS's refusal into that sentence). EXPO_PUBLIC_PHONE_OTP_ALLOWED_DIAL_CODES\n * stays as a build-time switch for a staged rollout: a comma list of calling codes (\"+1,+92\")\n * narrows the picker; empty, unset or \"*\" offers everything.\n */\nexport type CountryOption = PhoneCountry;\n\nexport function allowedDialCodes(\n raw: string | undefined = process.env.EXPO_PUBLIC_PHONE_OTP_ALLOWED_DIAL_CODES,\n): string[] | null {\n const value = raw?.trim();\n if (!value || value === '*') return null;\n const codes = value\n .split(',')\n .map((c) => c.trim())\n .filter(Boolean)\n .map((c) => (c.startsWith('+') ? c : `+${c}`))\n .filter((c) => /^\\+\\d{1,4}$/.test(c));\n return codes.length ? codes : null;\n}\n\n/** The picker's list: everything, or the narrowed set, with the default country always present. */\nexport function pickerCountries(\n all: readonly CountryOption[] = PHONE_COUNTRIES,\n allowed: string[] | null = allowedDialCodes(),\n defaultCode = 'US',\n): CountryOption[] {\n if (!allowed) return [...all];\n const offered = all.filter((c) => allowed.includes(c.callingCode));\n if (offered.length) return offered;\n const fallback = all.find((c) => c.code === defaultCode) ?? all[0];\n return fallback ? [fallback] : [];\n}\n\n/** Case-insensitive match on the name, the ISO code or the calling code (\"+44\", \"44\", \"uk\"). */\nexport function filterCountries(countries: readonly CountryOption[], query: string): CountryOption[] {\n const q = query.trim().toLowerCase();\n if (!q) return [...countries];\n const digits = q.replace(/^\\+/, '');\n return countries.filter(\n (c) =>\n c.name.toLowerCase().includes(q) ||\n c.code.toLowerCase() === q ||\n (digits && /^\\d+$/.test(digits) && c.callingCode.slice(1).startsWith(digits)),\n );\n}\n\n/** The emoji flag for an ISO 3166-1 alpha-2 code (\"IN\" -> 🇮🇳); empty for anything else. */\nexport function countryFlag(code: string): string {\n const iso = code.trim().toUpperCase();\n if (!/^[A-Z]{2}$/.test(iso)) return '';\n return String.fromCodePoint(...[...iso].map((c) => 0x1f1e6 + c.charCodeAt(0) - 65));\n}\n"],"names":[],"mappings":"kDAYO,SAAS,gBAAiB,CAAA,GAAA,GAA0B,OAAQ,CAAA,GAAA,CAAI,wCAA2D,EAAA;AAChI,EAAA,MAAM,QAAQ,GAAK,IAAA,IAAA,GAAA,MAAA,GAAA,GAAA,CAAA,IAAA,EAAA;AACnB,EAAA,IAAI,CAAC,KAAA,IAAS,KAAU,KAAA,GAAA,EAAY,OAAA,IAAA;AACpC,EAAA,MAAM,KAAQ,GAAA,KAAA,CAAM,KAAM,CAAA,GAAG,CAAE,CAAA,GAAA,CAAI,CAAK,CAAA,KAAA,CAAA,CAAE,IAAK,EAAC,CAAE,CAAA,MAAA,CAAO,OAAO,CAAE,CAAA,GAAA,CAAI,CAAK,CAAA,KAAA,CAAA,CAAE,UAAW,CAAA,GAAG,CAAI,GAAA,CAAA,GAAI,CAAI,CAAA,EAAA,CAAC,CAAE,CAAA,CAAA,CAAE,MAAO,CAAA,CAAA,CAAA,KAAK,aAAc,CAAA,IAAA,CAAK,CAAC,CAAC,CAAA;AAC7I,EAAO,OAAA,KAAA,CAAM,SAAS,KAAQ,GAAA,IAAA;AAChC;AAGO,SAAS,gBAAgB,GAAgC,GAAA,eAAA,EAAiB,UAA2B,gBAAiB,EAAA,EAAG,cAAc,IAAuB,EAAA;AApBrK,EAAA,IAAA,EAAA;AAqBE,EAAA,IAAI,CAAC,OAAA,EAAgB,OAAA,CAAC,GAAG,GAAG,CAAA;AAC5B,EAAM,MAAA,OAAA,GAAU,IAAI,MAAO,CAAA,CAAA,CAAA,KAAK,QAAQ,QAAS,CAAA,CAAA,CAAE,WAAW,CAAC,CAAA;AAC/D,EAAI,IAAA,OAAA,CAAQ,QAAe,OAAA,OAAA;AAC3B,EAAM,MAAA,QAAA,GAAA,CAAW,EAAI,GAAA,GAAA,CAAA,IAAA,CAAK,CAAK,CAAA,KAAA,CAAA,CAAE,SAAS,WAAW,CAAA,KAApC,IAAyC,GAAA,EAAA,GAAA,GAAA,CAAI,CAAC,CAAA;AAC/D,EAAA,OAAO,QAAW,GAAA,CAAC,QAAQ,CAAA,GAAI,EAAC;AAClC;AAGgB,SAAA,eAAA,CAAgB,WAAqC,KAAgC,EAAA;AACnG,EAAA,MAAM,CAAI,GAAA,KAAA,CAAM,IAAK,EAAA,CAAE,WAAY,EAAA;AACnC,EAAA,IAAI,CAAC,CAAA,EAAU,OAAA,CAAC,GAAG,SAAS,CAAA;AAC5B,EAAA,MAAM,MAAS,GAAA,CAAA,CAAE,OAAQ,CAAA,KAAA,EAAO,EAAE,CAAA;AAClC,EAAO,OAAA,SAAA,CAAU,MAAO,CAAA,CAAA,CAAA,KAAK,CAAE,CAAA,IAAA,CAAK,WAAY,EAAA,CAAE,QAAS,CAAA,CAAC,CAAK,IAAA,CAAA,CAAE,IAAK,CAAA,WAAA,EAAkB,KAAA,CAAA,IAAK,MAAU,IAAA,OAAA,CAAQ,IAAK,CAAA,MAAM,CAAK,IAAA,CAAA,CAAE,WAAY,CAAA,KAAA,CAAM,CAAC,CAAA,CAAE,UAAW,CAAA,MAAM,CAAC,CAAA;AAC5K;AAGO,SAAS,YAAY,IAAsB,EAAA;AAChD,EAAA,MAAM,GAAM,GAAA,IAAA,CAAK,IAAK,EAAA,CAAE,WAAY,EAAA;AACpC,EAAA,IAAI,CAAC,YAAA,CAAa,IAAK,CAAA,GAAG,GAAU,OAAA,EAAA;AACpC,EAAA,OAAO,MAAO,CAAA,aAAA,CAAc,GAAG,CAAC,GAAG,GAAG,CAAA,CAAE,GAAI,CAAA,CAAA,CAAA,KAAK,SAAU,CAAE,CAAA,UAAA,CAAW,CAAC,CAAA,GAAI,EAAE,CAAC,CAAA;AAClF"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {MOBILE_NUMBER_RULES}from'./phoneNumberRules.js';import {PHONE_COUNTRIES}from'./phoneCountries.js';import {toE164}from'./phoneNumbers.js';const patternCache = /* @__PURE__ */ new Map();
|
|
2
|
+
function matchesRule(region, national) {
|
|
3
|
+
const rule = MOBILE_NUMBER_RULES[region];
|
|
4
|
+
if (!rule) return false;
|
|
5
|
+
let pattern = patternCache.get(region);
|
|
6
|
+
if (!pattern) {
|
|
7
|
+
pattern = new RegExp(`^(?:${rule.pattern})$`);
|
|
8
|
+
patternCache.set(region, pattern);
|
|
9
|
+
}
|
|
10
|
+
return pattern.test(national);
|
|
11
|
+
}
|
|
12
|
+
function describeLengths(lengths) {
|
|
13
|
+
if (lengths.length === 1) return `${lengths[0]} digits`;
|
|
14
|
+
const last = lengths[lengths.length - 1];
|
|
15
|
+
return `${lengths.slice(0, -1).join(", ")} or ${last} digits`;
|
|
16
|
+
}
|
|
17
|
+
function sanitizePhoneInput(text) {
|
|
18
|
+
return text.replace(/[^\d\s()+\-.]/g, "");
|
|
19
|
+
}
|
|
20
|
+
function checkMobileNumber(input, countryCode) {
|
|
21
|
+
var _a;
|
|
22
|
+
const country = PHONE_COUNTRIES.find((c) => c.code === countryCode);
|
|
23
|
+
const countryName = (_a = country == null ? void 0 : country.name) != null ? _a : "your country";
|
|
24
|
+
if (!input.replace(/\D/g, "")) return {
|
|
25
|
+
ok: false,
|
|
26
|
+
message: "Enter your phone number."
|
|
27
|
+
};
|
|
28
|
+
const e164 = toE164(input, countryCode);
|
|
29
|
+
if (!e164) return {
|
|
30
|
+
ok: false,
|
|
31
|
+
message: `Enter a valid ${countryName} mobile number.`
|
|
32
|
+
};
|
|
33
|
+
const digits = e164.slice(1);
|
|
34
|
+
const regions = PHONE_COUNTRIES.filter((c) => digits.startsWith(c.callingCode.slice(1))).sort((a, b) => Number(b.code === countryCode) - Number(a.code === countryCode));
|
|
35
|
+
if (regions.some((r) => matchesRule(r.code, digits.slice(r.callingCode.length - 1)))) {
|
|
36
|
+
return {
|
|
37
|
+
ok: true,
|
|
38
|
+
e164
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const rule = MOBILE_NUMBER_RULES[countryCode];
|
|
42
|
+
const typedForChosen = country && digits.startsWith(country.callingCode.slice(1));
|
|
43
|
+
if (rule && typedForChosen) {
|
|
44
|
+
const nationalLength = digits.length - (country.callingCode.length - 1);
|
|
45
|
+
if (!rule.lengths.includes(nationalLength)) {
|
|
46
|
+
return {
|
|
47
|
+
ok: false,
|
|
48
|
+
message: `${countryName} mobile numbers have ${describeLengths(rule.lengths)}.`
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
ok: false,
|
|
54
|
+
message: `That isn't a valid ${countryName} mobile number.`
|
|
55
|
+
};
|
|
56
|
+
}export{checkMobileNumber,sanitizePhoneInput};//# sourceMappingURL=mobileNumberCheck.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mobileNumberCheck.js","sources":["../../../src/features/messaging/mobileNumberCheck.ts"],"sourcesContent":["/**\n * Is what was typed on the registration screen a real mobile number for the chosen country?\n *\n * The verification code goes out as a text, so a number has to be a mobile one: the right\n * length and the right leading digits for its country (India 10 digits from 6-9, the UK 10\n * from 7, ...). The rules come from libphonenumber's metadata, generated into\n * phoneNumberRules.ts, so the app gets real validation without shipping the library.\n */\nimport { MOBILE_NUMBER_RULES } from './phoneNumberRules';\nimport { PHONE_COUNTRIES } from './phoneCountries';\nimport { toE164 } from './phoneNumbers';\n\nexport type MobileNumberCheck =\n | { ok: true; e164: string; message?: undefined }\n | { ok: false; e164?: undefined; message: string };\n\nconst patternCache = new Map<string, RegExp>();\n\nfunction matchesRule(region: string, national: string): boolean {\n const rule = MOBILE_NUMBER_RULES[region];\n if (!rule) return false;\n let pattern = patternCache.get(region);\n if (!pattern) {\n pattern = new RegExp(`^(?:${rule.pattern})$`);\n patternCache.set(region, pattern);\n }\n return pattern.test(national);\n}\n\nfunction describeLengths(lengths: readonly number[]): string {\n if (lengths.length === 1) return `${lengths[0]} digits`;\n const last = lengths[lengths.length - 1];\n return `${lengths.slice(0, -1).join(', ')} or ${last} digits`;\n}\n\n/** Characters a person may type in the phone field; everything else is dropped as typed. */\nexport function sanitizePhoneInput(text: string): string {\n return text.replace(/[^\\d\\s()+\\-.]/g, '');\n}\n\nexport function checkMobileNumber(input: string, countryCode: string): MobileNumberCheck {\n const country = PHONE_COUNTRIES.find((c) => c.code === countryCode);\n const countryName = country?.name ?? 'your country';\n\n if (!input.replace(/\\D/g, '')) return { ok: false, message: 'Enter your phone number.' };\n\n const e164 = toE164(input, countryCode);\n if (!e164) return { ok: false, message: `Enter a valid ${countryName} mobile number.` };\n\n // The number may carry a different +code than the chosen country (pasted \"+44 ...\"): judge\n // it by every region on the calling code it actually has, the chosen country first.\n const digits = e164.slice(1);\n const regions = PHONE_COUNTRIES.filter((c) => digits.startsWith(c.callingCode.slice(1))).sort(\n (a, b) => Number(b.code === countryCode) - Number(a.code === countryCode),\n );\n if (regions.some((r) => matchesRule(r.code, digits.slice(r.callingCode.length - 1)))) {\n return { ok: true, e164 };\n }\n\n const rule = MOBILE_NUMBER_RULES[countryCode];\n const typedForChosen = country && digits.startsWith(country.callingCode.slice(1));\n if (rule && typedForChosen) {\n const nationalLength = digits.length - (country.callingCode.length - 1);\n if (!rule.lengths.includes(nationalLength)) {\n return {\n ok: false,\n message: `${countryName} mobile numbers have ${describeLengths(rule.lengths)}.`,\n };\n }\n }\n return { ok: false, message: `That isn't a valid ${countryName} mobile number.` };\n}\n"],"names":[],"mappings":"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"}
|