mirror of
https://github.com/mosip/inji-wallet.git
synced 2026-01-09 05:27:57 -05:00
Sonar Pipeline tw mosip (#768)
* fix(INJI-223): show the camera in scan screen while sharing the VC and click on scan icon Issue Link https://mosip.atlassian.net/browse/INJI-223 * chore: update pod deps' to match development team of 1st project * feat[#211]:[Pooja] fix turncated passcode and confirm password button * feat[#211]:[Pooja] fix truncated histroy title text in iOS * feat[#211]:[Pooja] fix multiple error being displayed when the vc binding fails * fix(INJI-223): disconnect the device while sharing the VC and click on tab icons except scan icon Issue Link https://mosip.atlassian.net/browse/INJI-223 * feat[#211]:[Pooja] fix download card button styles * version code for beta build in pipeline * feat[#211]:[Pooja] add error message when VC activation fails in kebab pop up * chore(INJI-216): bump up tuvali version to v0.4.3 * feat[#225]:[Pooja] fix about inji url in about page * refactor(INJI-223): get the scan string from route config to keep it consistent Issue Link https://mosip.atlassian.net/browse/INJI-223 * feat[mosip#211]:[Pooja] refactor onCancel Co-authored-by: Harsh Vardhan <harsh59v@gmail.com> * feat(INJI-222): add popup for error in decryption * feat(INJI-222): wrap app init component & popups * feat(INJI-222): propagate event from _store to app state machine Co-authored-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com> * chore(INJI-222): move error msg text to errors obj * Implemented Receive Card & Received Cards options in Settings * Fixed all the locals * [Pooja] add quality gate check for critical open bugs in sonar --------- Co-authored-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com> Co-authored-by: vijay151096 <94220135+vijay151096@users.noreply.github.com> Co-authored-by: Harsh Vardhan <harsh59v@gmail.com> Co-authored-by: Pooja Babusingh <68894211+PoojaBabusingh@users.noreply.github.com> Co-authored-by: adityankannan-tw <adityan.kannan@thoughtworks.com> Co-authored-by: Alka <prasadalka1998@gmail.com> Co-authored-by: anil_majji <majjianilkumar050@gmail.com> Co-authored-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com>
This commit is contained in:
25
.github/workflows/sonar.yml
vendored
25
.github/workflows/sonar.yml
vendored
@@ -22,6 +22,31 @@ jobs:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
SONAR_HOST_URL: https://sonarcloud.io
|
||||
SONAR_ORGANIZATION: ${{ secrets.ORG_KEY }}
|
||||
|
||||
- name: Install jq
|
||||
run: sudo apt-get -y install jq
|
||||
|
||||
- name: Check for critical bugs
|
||||
run: |
|
||||
# Fetch SonarQube issues using the API
|
||||
SONAR_HOST_URL=https://sonarcloud.io
|
||||
SONAR_PROJECT_KEY=mosip_inji
|
||||
|
||||
# Fetch issues using the SonarQube API
|
||||
response=$(curl -s "${SONAR_HOST_URL}/api/issues/search?componentKeys=${SONAR_PROJECT_KEY}&severities=CRITICAL&statuses=OPEN")
|
||||
echo "The response is $response"
|
||||
|
||||
# Extract the value of "issues" field
|
||||
issues_count=$(echo "$response" | jq '.issues | length')
|
||||
echo "The number of issues $issues_count"
|
||||
|
||||
if [ "$issues_count" -eq 0 ]; then
|
||||
echo "No critical issues found."
|
||||
else
|
||||
echo "Critical issues found. Failing the pipeline"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# If you wish to fail your job when the Quality Gate is red, uncomment the
|
||||
# following lines. This would typically be used to fail a deployment.
|
||||
# - uses: sonarsource/sonarqube-quality-gate-action@master
|
||||
|
||||
75
App.tsx
75
App.tsx
@@ -6,29 +6,72 @@ import { GlobalContextProvider } from './components/GlobalContextProvider';
|
||||
import { GlobalContext } from './shared/GlobalContext';
|
||||
import { useSelector } from '@xstate/react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { selectIsReadError, selectIsReady } from './machines/app';
|
||||
import {
|
||||
selectIsDecryptError,
|
||||
selectIsReadError,
|
||||
selectIsReady,
|
||||
} from './machines/app';
|
||||
import { DualMessageOverlay } from './components/DualMessageOverlay';
|
||||
import { useApp } from './screens/AppController';
|
||||
import { Alert } from 'react-native';
|
||||
|
||||
const AppInitialization: React.FC = () => {
|
||||
// kludge: this is a bad practice but has been done temporarily to surface
|
||||
// an occurance of a bug with minimal residual code changes, this should
|
||||
// be removed once the bug cause is determined & fixed, ref: INJI-222
|
||||
const DecryptErrorAlert = (controller, t) => {
|
||||
const heading = t('errors.decryptionFailed');
|
||||
const desc = t('errors.decryptionFailed');
|
||||
const ignoreBtnTxt = t('ignore');
|
||||
Alert.alert(heading, desc, [
|
||||
{
|
||||
text: ignoreBtnTxt,
|
||||
onPress: () => controller.ignoreDecrypt(),
|
||||
style: 'cancel',
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
const AppLayoutWrapper: React.FC = () => {
|
||||
const { appService } = useContext(GlobalContext);
|
||||
const isDecryptError = useSelector(appService, selectIsDecryptError);
|
||||
const controller = useApp();
|
||||
const { t } = useTranslation('WelcomeScreen');
|
||||
if (isDecryptError) {
|
||||
DecryptErrorAlert(controller, t);
|
||||
}
|
||||
return <AppLayout />;
|
||||
};
|
||||
|
||||
const AppLoadingWrapper: React.FC = () => {
|
||||
const { appService } = useContext(GlobalContext);
|
||||
const hasFontsLoaded = useFont();
|
||||
const isReady = useSelector(appService, selectIsReady);
|
||||
const isReadError = useSelector(appService, selectIsReadError);
|
||||
const controller = useApp();
|
||||
const { t } = useTranslation('WelcomeScreen');
|
||||
if (isReadError) {
|
||||
return (
|
||||
<DualMessageOverlay
|
||||
isVisible={isReadError}
|
||||
title={t('failedToReadKeys')}
|
||||
message={t('retryRead')}
|
||||
onTryAgain={controller.TRY_AGAIN}
|
||||
onIgnore={controller.IGNORE}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return isReady && hasFontsLoaded ? <AppLayout /> : <AppLoading />;
|
||||
return (
|
||||
<>
|
||||
<AppLoading />
|
||||
{isReadError ? (
|
||||
<DualMessageOverlay
|
||||
isVisible={isReadError}
|
||||
title={t('failedToReadKeys')}
|
||||
message={t('retryRead')}
|
||||
onTryAgain={controller.TRY_AGAIN}
|
||||
onIgnore={controller.IGNORE}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const AppInitialization: React.FC = () => {
|
||||
const { appService } = useContext(GlobalContext);
|
||||
const isReady = useSelector(appService, selectIsReady);
|
||||
const hasFontsLoaded = useFont();
|
||||
return isReady && hasFontsLoaded ? (
|
||||
<AppLayoutWrapper />
|
||||
) : (
|
||||
<AppLoadingWrapper />
|
||||
);
|
||||
};
|
||||
|
||||
export default function App() {
|
||||
|
||||
@@ -55,6 +55,19 @@ lane :android_build_beta do
|
||||
|
||||
git_tag = sh('git describe --abbrev=0 --tags --exact-match HEAD').strip
|
||||
|
||||
def convert_tag_to_code(version)
|
||||
parts = version.split('.')
|
||||
version_code = parts[0].to_i * 1000000 + parts[1].to_i * 1000 + parts[2].to_i
|
||||
return version_code
|
||||
end
|
||||
|
||||
versionCode = convert_tag_to_code(git_tag)
|
||||
|
||||
increment_version_code(
|
||||
gradle_file_path: "app/build.gradle",
|
||||
version_code: versionCode
|
||||
)
|
||||
|
||||
versionName = "Inji #{git_tag}"
|
||||
|
||||
gradle(task: "clean bundleBetaRelease")
|
||||
|
||||
@@ -3,7 +3,6 @@ import { useTranslation } from 'react-i18next';
|
||||
import { Image, ImageBackground, View } from 'react-native';
|
||||
import { getLocalizedField } from '../i18n';
|
||||
import { VerifiableCredential } from '../types/vc';
|
||||
import { RotatingIcon } from './RotatingIcon';
|
||||
import { VcItemTags } from './VcItemTags';
|
||||
import VerifiedIcon from './VerifiedIcon';
|
||||
import { Column, Row, Text } from './ui';
|
||||
@@ -135,7 +134,7 @@ export const VcItemContent: React.FC<VcItemContentProps> = (props) => {
|
||||
{t('idType')}
|
||||
</Text>
|
||||
<Text
|
||||
weight="regular"
|
||||
weight="semibold"
|
||||
color={Theme.Colors.Details}
|
||||
size="smaller"
|
||||
style={
|
||||
|
||||
@@ -466,7 +466,7 @@ export const DefaultTheme = {
|
||||
flex: 1,
|
||||
fontSize: 33,
|
||||
fontFamily: 'Inter_600SemiBold',
|
||||
height: 40,
|
||||
height: 60,
|
||||
lineHeight: 28,
|
||||
margin: 8,
|
||||
textAlign: 'center',
|
||||
|
||||
@@ -480,7 +480,7 @@ export const PurpleTheme = {
|
||||
flex: 1,
|
||||
fontFamily: 'Inter_700Bold',
|
||||
fontSize: 29,
|
||||
height: 40,
|
||||
height: 60,
|
||||
margin: 8,
|
||||
textAlign: 'center',
|
||||
},
|
||||
|
||||
19
ios/Podfile
19
ios/Podfile
@@ -58,6 +58,25 @@ target 'Inji' do
|
||||
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
|
||||
end
|
||||
end
|
||||
# get team-id from project's first target
|
||||
dev_team = ""
|
||||
project = installer.aggregate_targets[0].user_project
|
||||
project.targets.each do |target|
|
||||
target.build_configurations.each do |config|
|
||||
if dev_team.empty? and !config.build_settings['DEVELOPMENT_TEAM'].nil?
|
||||
dev_team = config.build_settings['DEVELOPMENT_TEAM']
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Apply team-id
|
||||
installer.pods_project.targets.each do |target|
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings["DEVELOPMENT_TEAM"] = dev_team
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
permissions_path = '../node_modules/react-native-permissions/ios'
|
||||
|
||||
@@ -718,6 +718,6 @@ SPEC CHECKSUMS:
|
||||
Yoga: d1fc3575b8b68891ff5ef3c276daa855e841eb32
|
||||
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
|
||||
|
||||
PODFILE CHECKSUM: c9f0fe8dbf7e1bc17ab0a1e74d2edd0a76cd4b7f
|
||||
PODFILE CHECKSUM: 81400285e73643c9d2ca00905667d0014ac840fc
|
||||
|
||||
COCOAPODS: 1.12.1
|
||||
|
||||
@@ -129,6 +129,7 @@
|
||||
"SettingScreen": {
|
||||
"header": "إعدادات",
|
||||
"injiAsVerifierApp": " كتطبيق للتحقق إنجي",
|
||||
"receiveCard": "البطاقة المستلمة",
|
||||
"basicSettings": "الإعدادات الأساسية",
|
||||
"bioUnlock": "افتح مع القياسات الحيوية",
|
||||
"language": "لغة",
|
||||
@@ -512,7 +513,11 @@
|
||||
"getStarted": "البدء",
|
||||
"unlockApp": "فتح التطبيق",
|
||||
"failedToReadKeys": "فشلت قراءة المفاتيح",
|
||||
"retryRead": "هل تريد إعادة المحاولة؟"
|
||||
"retryRead": "هل تريد إعادة المحاولة؟",
|
||||
"errors": {
|
||||
"decryptionFailed": "فشل في فك تشفير البيانات"
|
||||
},
|
||||
"ignore": "يتجاهل"
|
||||
},
|
||||
"SetupLanguage": {
|
||||
"header": "حدد اللغة",
|
||||
@@ -541,4 +546,4 @@
|
||||
"copied": "نسخ"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,6 +129,7 @@
|
||||
"SettingScreen": {
|
||||
"header": "Settings",
|
||||
"injiAsVerifierApp": "Inji as verifier app",
|
||||
"receiveCard": "Receive Card",
|
||||
"basicSettings": "Basic settings",
|
||||
"bioUnlock": "Unlock with Biometric",
|
||||
"language": "Language",
|
||||
@@ -354,7 +355,7 @@
|
||||
}
|
||||
},
|
||||
"RequestScreen": {
|
||||
"receiveCard": "REceive Card",
|
||||
"receiveCard": "Receive Card",
|
||||
"bluetoothDenied": "Please enable Bluetooth to be able to request card",
|
||||
"bluetoothStateIos": "Bluetooth is turned OFF, please turn it ON from Control center",
|
||||
"bluetoothStateAndroid": "Bluetooth is turned OFF, please turn it ON from Quick settings menu",
|
||||
@@ -512,7 +513,11 @@
|
||||
"getStarted": "Get started",
|
||||
"unlockApp": "Unlock application",
|
||||
"failedToReadKeys": "Failed to read keys",
|
||||
"retryRead": "Want to retry?"
|
||||
"retryRead": "Want to retry?",
|
||||
"ignore": "Ignore",
|
||||
"errors": {
|
||||
"decryptionFailed": "Failed to decrypt data"
|
||||
}
|
||||
},
|
||||
"SetupLanguage": {
|
||||
"header": "Choose Language",
|
||||
|
||||
@@ -129,6 +129,7 @@
|
||||
"SettingScreen": {
|
||||
"header": "Mga setting",
|
||||
"injiAsVerifierApp": "Inji bilang Verifier App",
|
||||
"receiveCard": "Tumanggap ng Card",
|
||||
"basicSettings": "Mga Pangunahing Setting",
|
||||
"bioUnlock": "I-unlock gamit ang Biometrics",
|
||||
"language": "Wika",
|
||||
@@ -516,7 +517,11 @@
|
||||
"getStarted": "Magsimula",
|
||||
"unlockApp": "Buksan ang aplikasyon",
|
||||
"failedToReadKeys": "Nabigong basahin ang mga susi",
|
||||
"retryRead": "Gustong subukang muli?"
|
||||
"retryRead": "Gustong subukang muli?",
|
||||
"error": {
|
||||
"decryptionFailed": "Nabigong i-decrypt ang data"
|
||||
},
|
||||
"ignore": "Huwag pansinin"
|
||||
},
|
||||
"SetupLanguage": {
|
||||
"header": "Piliin ang Wika",
|
||||
@@ -545,4 +550,4 @@
|
||||
"copied": "Kinopya"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,6 +126,7 @@
|
||||
"SettingScreen": {
|
||||
"header": "समायोजन",
|
||||
"injiAsVerifierApp": "सत्यापनकर्ता ऐप के रूप में इंजी",
|
||||
"receiveCard": "कार्ड प्राप्त करें",
|
||||
"basicSettings": "मूल सेटिंग्स",
|
||||
"bioUnlock": "बायोमेट्रिक्स से अनलॉक करें",
|
||||
"language": "भाषा",
|
||||
@@ -509,7 +510,13 @@
|
||||
"WelcomeScreen": {
|
||||
"title": "ओपन सोर्स आइडेंटिटी सॉल्यूशन",
|
||||
"getStarted": "आरंभ करें",
|
||||
"unlockApp": "एप्लिकेशन अनलॉक करें"
|
||||
"unlockApp": "एप्लिकेशन अनलॉक करें",
|
||||
"failedToReadKeys": "कुंजियाँ पढ़ने में विफल",
|
||||
"retryRead": "पुनः प्रयास करना चाहते हैं?",
|
||||
"errors": {
|
||||
"decryptionFailed": "डेटा डिक्रिप्ट करने में विफल"
|
||||
},
|
||||
"ignore": "अनदेखा करना"
|
||||
},
|
||||
"SetupLanguage": {
|
||||
"header": "भाषा चुनें",
|
||||
@@ -536,4 +543,4 @@
|
||||
"copied": "कॉपी किया गया"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,6 +125,7 @@
|
||||
"SettingScreen": {
|
||||
"header": "ಸಂಯೋಜನೆಗಳು",
|
||||
"injiAsVerifierApp": "ವೆರಿಫೈಯರ್ ಆಪ್ ಆಗಿ ಇಂಜಿ",
|
||||
"receiveCard": "ಕಾರ್ಡ್ ಸ್ವೀಕರಿಸಿ",
|
||||
"basicSettings": "ಮೂಲ ಸೆಟ್ಟಿಂಗ್ಗಳು",
|
||||
"bioUnlock": "ಬಯೋಮೆಟ್ರಿಕ್ಸ್ನೊಂದಿಗೆ ಅನ್ಲಾಕ್ ಮಾಡಿ",
|
||||
"language": "ಭಾಷೆ",
|
||||
@@ -509,7 +510,11 @@
|
||||
"getStarted": "ಪ್ರಾರಂಭಿಸಿ",
|
||||
"unlockApp": "ಅಪ್ಲಿಕೇಶನ್ ಅನ್ಲಾಕ್ ಮಾಡಿ",
|
||||
"failedToReadKeys": "ಕೀಗಳನ್ನು ಓದಲು ವಿಫಲವಾಗಿದೆ",
|
||||
"retryRead": "ಮರುಪ್ರಯತ್ನಿಸಲು ಬಯಸುವಿರಾ?"
|
||||
"retryRead": "ಮರುಪ್ರಯತ್ನಿಸಲು ಬಯಸುವಿರಾ?",
|
||||
"errors": {
|
||||
"decryptionFailed": "ಡೇಟಾವನ್ನು ಡೀಕ್ರಿಪ್ಟ್ ಮಾಡಲು ವಿಫಲವಾಗಿದೆ"
|
||||
},
|
||||
"ignore": "ನಿರ್ಲಕ್ಷಿಸಿ"
|
||||
},
|
||||
"SetupLanguage": {
|
||||
"header": "ಭಾಷೆಯನ್ನು ಆರಿಸಿ",
|
||||
|
||||
@@ -125,6 +125,7 @@
|
||||
"SettingScreen": {
|
||||
"header": "அமைப்புகள்",
|
||||
"injiAsVerifierApp": "சரிபார்ப்பு பயன்பாடாக இன்ஜி",
|
||||
"receiveCard": "பெற்ற அட்டை",
|
||||
"basicSettings": "அடிப்படை அமைப்புகள்",
|
||||
"bioUnlock": "பயோமெட்ரிக்ஸ் மூலம் திறக்கவும்",
|
||||
"language": "மொழி",
|
||||
@@ -509,7 +510,11 @@
|
||||
"getStarted": "தொடங்கு",
|
||||
"unlockApp": "பயன்பாட்டைத் திற",
|
||||
"failedToReadKeys": "விசைகளைப் படிக்க முடியவில்லை",
|
||||
"retryRead": "மீண்டும் முயற்சிக்க வேண்டுமா?"
|
||||
"retryRead": "மீண்டும் முயற்சிக்க வேண்டுமா?",
|
||||
"errors": {
|
||||
"decryptionFailed": "தரவை மறைகுறியாக்க முடியவில்லை"
|
||||
},
|
||||
"ignore": "புறக்கணிக்க"
|
||||
},
|
||||
"SetupLanguage": {
|
||||
"header": "மொழியைத் தேர்ந்தெடுக்கவும்",
|
||||
|
||||
@@ -32,13 +32,16 @@ const model = createModel(
|
||||
info: {} as AppInfo,
|
||||
backendInfo: {} as BackendInfo,
|
||||
serviceRefs: {} as AppServices,
|
||||
isReadError: false,
|
||||
isReadError: true,
|
||||
isDecryptError: false,
|
||||
},
|
||||
{
|
||||
events: {
|
||||
ACTIVE: () => ({}),
|
||||
INACTIVE: () => ({}),
|
||||
ERROR: () => ({}),
|
||||
DECRYPT_ERROR: () => ({}),
|
||||
DECRYPT_ERROR_DISMISS: () => ({}),
|
||||
OFFLINE: () => ({}),
|
||||
ONLINE: (networkType: NetInfoStateType) => ({ networkType }),
|
||||
REQUEST_DEVICE_INFO: () => ({}),
|
||||
@@ -52,6 +55,7 @@ const model = createModel(
|
||||
|
||||
export const appMachine = model.createMachine(
|
||||
{
|
||||
/** @xstate-layout N4IgpgJg5mDOIC5QEMAOqB0BLAdlgLhrPgPYBOYAxAEoCiAggCICaA2gAwC6ioqJsBLCRw8QAD0QBmdgE4MMgIwAmSaoDsADmkb2agDQgAnoiUAWJRnNqZayVvYKArDdMBfVwbSZcBIqQqUtNTUAPLUHNxIIHwC+EIiURIICpJypgBsaqaOSjmOqfmmBsbJjuzyaimaMpJq7BqOOe6e6Nh4hLBgZABuWADGcDQMLBGiMYLCokmZ6RiSSro5NQrsjcUm5pZK1rb2Ti7NIF5tvn0UEGA4ccgANtRgUFjEZIaUAMoAKmG0APp0bwAFEIAOTetFGUXGcUmiUQCgU6VMFW0tVkOXY6XWCCUCjkakqBNMMl0ZjcHiOrR8hFwADMSJR6ACAT8AJLAgBiIT+tAAwrQWQA1WiMCG8fgTBKgJIIjJzdRqRGmDQEjRYnF4gkKLLEtSkw7HKkYC69HB0ygAIXoPIA0rRgYxWRyuXQ+YLhaLouLoZLxCZlI55DjTJJ0jV0vlJGrcRh8VqtUSSaYyS1MBRkBBXnQAIoAVVonx+jFoApZfMdnI9UPiUxM9Rj6URGmJMh0Zg0mKMiEc6Q0GA0GmyPd180kyYpqbA6cMGDpfQArrAGTyPm7K17q7Dkroscre+l2KknAoB8qbPrWmmMzOSPPF2yrSuhWvYhupXDt52EDIbBhGnVJN27CyA2SjnhOU4YDgYD4AA7uQADWlAggAMmy4JcGM64wm+W76J+yhEpYaiOKYGL4jI+4hmBGCXtOUGwQhSHsuyqHAuhkRii+2G+rhWIpD2WwNNsuLdjI7jkjgJAXPAUReJhXE+kkAC0tRYkpZgYEBWnaTpajUVS8kSjW2IyFi6SSJYDS2FqjgaPCMi2fp7R+OQYCGd6xn4mqGKWKimimMoTaOLqTm+J0PT9HA7mvjx5gWeYChJmYEbth2JQLLMwZ1P5gUOSF5IGs5ZyQJc1x3A8Tz4C80XcUk1R9koLbpAiDghgoUZpNImgkSsGhmLUoXUqaJA1YpcJJrM4aVCkShaDI5hFJ+6q+bouz4tIqgaINRpgCadKjcZx7pBYDakZoo6OCkjgdSt1ihkmF1UQVF6ThmB2bvCZmqBgIGaPU5FONRtHXre704c4WK6goGCJQOs2rD2Ohic94FXrOC4YH0AAWYB9PBuBQGDPHwtDWoLDUtn1LN35YjUcgYhRiUNhiTbIymNGvdO6OwBgyB9HE3RuZCWFjdipE-YopE1O2f12DujQ-WR0jNUBl2OEDnMgxjuB8wLQucUZm5mOUoaJbIdiZDocufi4v7OA0KxKM1tRbSjHMQfRcFkPBRNJBD+GyBYDjfri4YtRkGse9BXvwZjON4wTvvvnhJQpLI8gBSsx2NAFdiR1ensIRgwg3Lg+uegpxkqBYo66ko9e5MoZh8fXmWaA3CymPiTRu8Dhfe8XNI0qXUFJ9i8xzF3HeN-Xi2pxdvkpOYx31M16Tia4QA */
|
||||
predictableActionArguments: true,
|
||||
preserveActionOrder: true,
|
||||
tsTypes: {} as import('./app.typegen').Typegen0,
|
||||
@@ -61,6 +65,14 @@ export const appMachine = model.createMachine(
|
||||
},
|
||||
id: 'app',
|
||||
initial: 'init',
|
||||
on: {
|
||||
DECRYPT_ERROR: {
|
||||
actions: ['setIsDecryptError'],
|
||||
},
|
||||
DECRYPT_ERROR_DISMISS: {
|
||||
actions: ['unsetIsDecryptError'],
|
||||
},
|
||||
},
|
||||
states: {
|
||||
init: {
|
||||
initial: 'store',
|
||||
@@ -69,7 +81,7 @@ export const appMachine = model.createMachine(
|
||||
entry: ['spawnStoreActor', 'logStoreEvents'],
|
||||
on: {
|
||||
READY: {
|
||||
actions: 'unsetIsReadError',
|
||||
actions: ['unsetIsReadError', 'unsetIsDecryptError'],
|
||||
target: 'services',
|
||||
},
|
||||
ERROR: {
|
||||
@@ -177,6 +189,12 @@ export const appMachine = model.createMachine(
|
||||
setIsReadError: assign({
|
||||
isReadError: true,
|
||||
}),
|
||||
setIsDecryptError: assign({
|
||||
isDecryptError: true,
|
||||
}),
|
||||
unsetIsDecryptError: assign({
|
||||
isDecryptError: false,
|
||||
}),
|
||||
unsetIsReadError: assign({
|
||||
isReadError: false,
|
||||
}),
|
||||
@@ -423,3 +441,7 @@ export function logState(state: AnyState) {
|
||||
export function selectIsReadError(state: State) {
|
||||
return state.context.isReadError;
|
||||
}
|
||||
|
||||
export function selectIsDecryptError(state: State) {
|
||||
return state.context.isDecryptError;
|
||||
}
|
||||
|
||||
@@ -26,9 +26,11 @@ export interface Typegen0 {
|
||||
requestDeviceInfo: 'REQUEST_DEVICE_INFO';
|
||||
setAppInfo: 'APP_INFO_RECEIVED';
|
||||
setBackendInfo: 'BACKEND_INFO_RECEIVED';
|
||||
setIsDecryptError: 'DECRYPT_ERROR';
|
||||
setIsReadError: 'ERROR';
|
||||
spawnServiceActors: 'READY';
|
||||
spawnStoreActor: 'xstate.init';
|
||||
unsetIsDecryptError: 'DECRYPT_ERROR_DISMISS' | 'READY';
|
||||
unsetIsReadError: 'READY';
|
||||
};
|
||||
'eventsCausingDelays': {};
|
||||
|
||||
@@ -96,6 +96,7 @@ const model = createModel(
|
||||
RETRY_VERIFICATION: () => ({}),
|
||||
VP_CREATED: (vp: VerifiablePresentation) => ({ vp }),
|
||||
TOGGLE_USER_CONSENT: () => ({}),
|
||||
RESET: () => ({}),
|
||||
},
|
||||
}
|
||||
);
|
||||
@@ -125,7 +126,7 @@ export const scanMachine =
|
||||
initial: 'inactive',
|
||||
on: {
|
||||
SCREEN_BLUR: {
|
||||
target: '.inactive',
|
||||
target: '#scan.disconnectDevice',
|
||||
},
|
||||
SCREEN_FOCUS: {
|
||||
target: '.checkStorage',
|
||||
@@ -134,11 +135,24 @@ export const scanMachine =
|
||||
target: '.handlingBleError',
|
||||
actions: 'setBleError',
|
||||
},
|
||||
RESET: {
|
||||
target: '.checkStorage',
|
||||
},
|
||||
},
|
||||
states: {
|
||||
inactive: {
|
||||
entry: 'removeLoggers',
|
||||
},
|
||||
disconnectDevice: {
|
||||
invoke: {
|
||||
src: 'disconnect',
|
||||
},
|
||||
on: {
|
||||
DISCONNECT: {
|
||||
target: '#scan.inactive',
|
||||
},
|
||||
},
|
||||
},
|
||||
checkStorage: {
|
||||
invoke: {
|
||||
src: 'checkStorageAvailability',
|
||||
|
||||
@@ -30,6 +30,7 @@ const model = createModel(
|
||||
TRY_AGAIN: () => ({}),
|
||||
IGNORE: () => ({}),
|
||||
GET: (key: string) => ({ key }),
|
||||
DECRYPT_ERROR: () => ({}),
|
||||
SET: (key: string, value: unknown) => ({ key, value }),
|
||||
APPEND: (key: string, value: unknown) => ({ key, value }),
|
||||
PREPEND: (key: string, value: unknown) => ({ key, value }),
|
||||
@@ -76,7 +77,7 @@ export const storeMachine =
|
||||
},
|
||||
on: {
|
||||
KEY_RECEIVED: {
|
||||
actions: 'setEncryptionKey',
|
||||
actions: ['setEncryptionKey', 'logKey'],
|
||||
target: 'ready',
|
||||
},
|
||||
ERROR: {
|
||||
@@ -190,6 +191,9 @@ export const storeMachine =
|
||||
sendUpdate(),
|
||||
],
|
||||
},
|
||||
DECRYPT_ERROR: {
|
||||
actions: sendParent('DECRYPT_ERROR'),
|
||||
},
|
||||
TAMPERED_VC: {
|
||||
actions: ['setIsTamperedVc'],
|
||||
},
|
||||
@@ -230,10 +234,15 @@ export const storeMachine =
|
||||
checkStorageInitialisedOrNot: () => async (callback) => {
|
||||
const isDirectoryExist = await Storage.isVCStorageInitialised();
|
||||
if (!isDirectoryExist) {
|
||||
// clear the storage
|
||||
callback(model.events.READY());
|
||||
} else {
|
||||
callback(model.events.ERROR(new Error('show the popup for retry')));
|
||||
callback(
|
||||
model.events.ERROR(
|
||||
new Error(
|
||||
'vc directory exists and decryption key is not available'
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -322,6 +331,12 @@ export const storeMachine =
|
||||
} catch (e) {
|
||||
if (e.message === 'Data is tampered') {
|
||||
callback(model.events.TAMPERED_VC());
|
||||
} else if (
|
||||
e.message.includes('JSON') ||
|
||||
e.message.includes('decrypt')
|
||||
) {
|
||||
callback(model.events.DECRYPT_ERROR());
|
||||
sendUpdate();
|
||||
} else {
|
||||
console.error(e);
|
||||
callback(model.events.STORE_ERROR(e, event.requester));
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
|
||||
// This file was automatically generated. Edits will be overwritten
|
||||
|
||||
export interface Typegen0 {
|
||||
'@@xstate/typegen': true;
|
||||
internalEvents: {
|
||||
"done.invoke._store": { type: "done.invoke._store"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"done.invoke.store.resettingStorage:invocation[0]": { type: "done.invoke.store.resettingStorage:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
|
||||
"error.platform._store": { type: "error.platform._store"; data: unknown };
|
||||
"xstate.init": { type: "xstate.init" };
|
||||
};
|
||||
invokeSrcNameMap: {
|
||||
"checkStorageInitialisedOrNot": "done.invoke.store.checkStorageInitialisation:invocation[0]";
|
||||
"clear": "done.invoke.store.resettingStorage:invocation[0]";
|
||||
"generateEncryptionKey": "done.invoke.store.generatingEncryptionKey:invocation[0]";
|
||||
"getEncryptionKey": "done.invoke.store.gettingEncryptionKey:invocation[0]";
|
||||
"store": "done.invoke._store";
|
||||
};
|
||||
missingImplementations: {
|
||||
actions: "logKey";
|
||||
delays: never;
|
||||
guards: never;
|
||||
services: never;
|
||||
};
|
||||
eventsCausingActions: {
|
||||
"forwardStoreRequest": "APPEND" | "CLEAR" | "GET" | "PREPEND" | "REMOVE" | "REMOVE_ITEMS" | "REMOVE_VC_METADATA" | "SET" | "UPDATE";
|
||||
"logKey": "KEY_RECEIVED";
|
||||
"notifyParent": "KEY_RECEIVED" | "done.invoke.store.resettingStorage:invocation[0]";
|
||||
"resetIsTamperedVc": "RESET_IS_TAMPERED";
|
||||
"setEncryptionKey": "KEY_RECEIVED";
|
||||
"setIsTamperedVc": "TAMPERED_VC";
|
||||
};
|
||||
eventsCausingDelays: {
|
||||
|
||||
};
|
||||
eventsCausingGuards: {
|
||||
|
||||
};
|
||||
eventsCausingServices: {
|
||||
"checkStorageInitialisedOrNot": "ERROR";
|
||||
"clear": "KEY_RECEIVED";
|
||||
"generateEncryptionKey": "IGNORE" | "READY";
|
||||
"getEncryptionKey": "TRY_AGAIN" | "xstate.init";
|
||||
"store": "KEY_RECEIVED" | "done.invoke.store.resettingStorage:invocation[0]";
|
||||
};
|
||||
matchesStates: "checkStorageInitialisation" | "failedReadingKey" | "generatingEncryptionKey" | "gettingEncryptionKey" | "ready" | "resettingStorage";
|
||||
tags: never;
|
||||
}
|
||||
|
||||
@@ -360,7 +360,10 @@ export const vcItemMachine =
|
||||
],
|
||||
onError: [
|
||||
{
|
||||
actions: 'setWalletBindingError',
|
||||
actions: [
|
||||
'setWalletBindingError',
|
||||
'logWalletBindingFailure',
|
||||
],
|
||||
target: '#vc-item.kebabPopUp.showingWalletBindingError',
|
||||
},
|
||||
],
|
||||
@@ -1354,7 +1357,10 @@ export function selectAcceptingBindingOtp(state: State) {
|
||||
}
|
||||
|
||||
export function selectShowWalletBindingError(state: State) {
|
||||
return state.matches('showingWalletBindingError');
|
||||
return (
|
||||
state.matches('showingWalletBindingError') ||
|
||||
state.matches('kebabPopUp.showingWalletBindingError')
|
||||
);
|
||||
}
|
||||
|
||||
export function selectWalletBindingInProgress(state: State) {
|
||||
|
||||
@@ -193,6 +193,7 @@ export interface Typegen0 {
|
||||
logWalletBindingFailure:
|
||||
| 'error.platform.vc-item.addKeyPair:invocation[0]'
|
||||
| 'error.platform.vc-item.addingWalletBindingId:invocation[0]'
|
||||
| 'error.platform.vc-item.kebabPopUp.addingWalletBindingId:invocation[0]'
|
||||
| 'error.platform.vc-item.requestingBindingOtp:invocation[0]'
|
||||
| 'error.platform.vc-item.updatingPrivateKey:invocation[0]';
|
||||
logWalletBindingSuccess:
|
||||
|
||||
@@ -11,6 +11,8 @@ import { MainLayout } from '../screens/MainLayout';
|
||||
import { NotificationsScreen } from '../screens/NotificationsScreen';
|
||||
import { SetupLanguageScreen } from '../screens/SetupLanguageScreen';
|
||||
import { IntroSlidersScreen } from '../screens/Home/IntroSlidersScreen';
|
||||
import { RequestLayout } from '../screens/Request/RequestLayout';
|
||||
import { RequestStackParamList } from '../screens/Request/RequestLayoutController';
|
||||
|
||||
export const baseRoutes: Screen[] = [
|
||||
{
|
||||
@@ -40,6 +42,13 @@ export const baseRoutes: Screen[] = [
|
||||
name: 'Biometric',
|
||||
component: BiometricScreen,
|
||||
},
|
||||
{
|
||||
name: 'Request',
|
||||
component: RequestLayout,
|
||||
options: {
|
||||
headerShown: false,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const authRoutes: Screen[] = [
|
||||
@@ -89,3 +98,8 @@ export type BiometricRouteProps = NativeStackScreenProps<
|
||||
RootStackParamList,
|
||||
'Biometric'
|
||||
>;
|
||||
|
||||
export type RequestRouteProps = NativeStackScreenProps<
|
||||
RequestStackParamList,
|
||||
'Request'
|
||||
>;
|
||||
|
||||
@@ -6,11 +6,9 @@ import {
|
||||
import { Image } from 'react-native';
|
||||
import { HomeScreen } from '../screens/Home/HomeScreen';
|
||||
import { RootStackParamList } from './index';
|
||||
import { RequestLayout } from '../screens/Request/RequestLayout';
|
||||
import { ScanLayout } from '../screens/Scan/ScanLayout';
|
||||
import { HistoryScreen } from '../screens/History/HistoryScreen';
|
||||
import i18n from '../i18n';
|
||||
import { Platform } from 'react-native';
|
||||
|
||||
const home: TabScreen = {
|
||||
name: 'Home',
|
||||
@@ -25,7 +23,7 @@ const home: TabScreen = {
|
||||
}),
|
||||
},
|
||||
};
|
||||
const scan: TabScreen = {
|
||||
export const scan: TabScreen = {
|
||||
name: 'Scan',
|
||||
component: ScanLayout,
|
||||
icon: 'qr-code-scanner',
|
||||
@@ -34,15 +32,6 @@ const scan: TabScreen = {
|
||||
headerShown: false,
|
||||
},
|
||||
};
|
||||
const request: TabScreen = {
|
||||
name: 'Request',
|
||||
component: RequestLayout,
|
||||
icon: 'file-download',
|
||||
options: {
|
||||
title: i18n.t('MainLayout:request'),
|
||||
headerShown: false,
|
||||
},
|
||||
};
|
||||
const history: TabScreen = {
|
||||
name: 'History',
|
||||
component: HistoryScreen,
|
||||
@@ -56,11 +45,6 @@ const history: TabScreen = {
|
||||
export const mainRoutes: TabScreen[] = [];
|
||||
mainRoutes.push(home);
|
||||
mainRoutes.push(scan);
|
||||
|
||||
if (Platform.OS !== 'ios') {
|
||||
mainRoutes.push(request);
|
||||
}
|
||||
|
||||
mainRoutes.push(history);
|
||||
|
||||
export type MainBottomTabParamList = {
|
||||
@@ -68,7 +52,6 @@ export type MainBottomTabParamList = {
|
||||
activeTab: number;
|
||||
};
|
||||
Scan: undefined;
|
||||
Request: undefined;
|
||||
History: undefined;
|
||||
};
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ import { StoreEvents } from '../machines/store';
|
||||
export function useApp() {
|
||||
const { appService } = useContext(GlobalContext);
|
||||
const storeService = appService.children.get('store');
|
||||
|
||||
return {
|
||||
ignoreDecrypt: () => appService.send('DECRYPT_ERROR_DISMISS'),
|
||||
IGNORE: () => storeService.send(StoreEvents.IGNORE()),
|
||||
TRY_AGAIN: () => storeService.send(StoreEvents.TRY_AGAIN()),
|
||||
};
|
||||
|
||||
@@ -9,7 +9,10 @@ import { GetVcModal } from './MyVcs/GetVcModal';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { VcItem } from '../../components/VcItem';
|
||||
import { GET_INDIVIDUAL_ID } from '../../shared/constants';
|
||||
import { ErrorMessageOverlay } from '../../components/MessageOverlay';
|
||||
import {
|
||||
ErrorMessageOverlay,
|
||||
MessageOverlay,
|
||||
} from '../../components/MessageOverlay';
|
||||
import { Icon } from 'react-native-elements';
|
||||
|
||||
export const MyVcsTab: React.FC<HomeScreenTabProps> = (props) => {
|
||||
@@ -102,7 +105,6 @@ export const MyVcsTab: React.FC<HomeScreenTabProps> = (props) => {
|
||||
</Column>
|
||||
<Button
|
||||
type="gradient"
|
||||
isVcThere
|
||||
disabled={controller.isRefreshingVcs}
|
||||
title={t('downloadCard')}
|
||||
onPress={controller.DOWNLOAD_ID}
|
||||
@@ -152,6 +154,11 @@ export const MyVcsTab: React.FC<HomeScreenTabProps> = (props) => {
|
||||
error={storeErrorTranslationPath}
|
||||
onDismiss={controller.DISMISS}
|
||||
/>
|
||||
<MessageOverlay
|
||||
isVisible={controller.isBindingError}
|
||||
title={controller.walletBindingError}
|
||||
onCancel={controller.DISMISS}
|
||||
/>
|
||||
<ErrorMessageOverlay
|
||||
translationPath={'MyVcsTab'}
|
||||
isVisible={controller.isMinimumStorageLimitReached}
|
||||
|
||||
@@ -7,6 +7,10 @@ import {
|
||||
selectMyVcs,
|
||||
VcEvents,
|
||||
} from '../../machines/vc';
|
||||
import {
|
||||
selectWalletBindingError,
|
||||
selectShowWalletBindingError,
|
||||
} from '../../machines/vcItem';
|
||||
import { vcItemMachine } from '../../machines/vcItem';
|
||||
import { GlobalContext } from '../../shared/GlobalContext';
|
||||
import { HomeScreenTabProps } from './HomeScreen';
|
||||
@@ -39,6 +43,8 @@ export function useMyVcsTab(props: HomeScreenTabProps) {
|
||||
isRequestSuccessful: useSelector(service, selectIsRequestSuccessful),
|
||||
isOnboarding: useSelector(service, selectIsOnboarding),
|
||||
isSavingFailedInIdle: useSelector(service, selectIsSavingFailedInIdle),
|
||||
walletBindingError: useSelector(service, selectWalletBindingError),
|
||||
isBindingError: useSelector(service, selectShowWalletBindingError),
|
||||
isMinimumStorageLimitReached: useSelector(
|
||||
service,
|
||||
selectIsMinimumStorageLimitReached
|
||||
|
||||
@@ -45,12 +45,6 @@ export const ViewVcModal: React.FC<ViewVcModalProps> = (props) => {
|
||||
isBindingPending={controller.isWalletBindingPending}
|
||||
activeTab={props.activeTab}
|
||||
/>
|
||||
|
||||
{controller.walletBindingError !== '' && (
|
||||
<Text style={{ color: 'red', fontSize: 20 }}>
|
||||
Error Occured : {controller.walletBindingError}
|
||||
</Text>
|
||||
)}
|
||||
</Column>
|
||||
</Column>
|
||||
{controller.isEditingTag && (
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import React from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
import {
|
||||
BottomTabNavigationOptions,
|
||||
createBottomTabNavigator,
|
||||
} from '@react-navigation/bottom-tabs';
|
||||
import { Icon } from 'react-native-elements';
|
||||
import { mainRoutes } from '../routes/main';
|
||||
import { RootRouteProps } from '../routes';
|
||||
import { RequestRouteProps, RootRouteProps } from '../routes';
|
||||
import { mainRoutes, scan } from '../routes/main';
|
||||
import { Theme } from '../components/ui/styleUtils';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Row } from '../components/ui';
|
||||
@@ -13,10 +13,16 @@ import { Image } from 'react-native';
|
||||
import { SettingScreen } from './Settings/SettingScreen';
|
||||
import { HelpScreen } from '../components/HelpScreen';
|
||||
|
||||
import { GlobalContext } from '../shared/GlobalContext';
|
||||
import { ScanEvents } from '../machines/bleShare/scan/scanMachine';
|
||||
const { Navigator, Screen } = createBottomTabNavigator();
|
||||
|
||||
export const MainLayout: React.FC<RootRouteProps> = (props) => {
|
||||
export const MainLayout: React.FC<RootRouteProps & RequestRouteProps> = (
|
||||
props
|
||||
) => {
|
||||
const { t } = useTranslation('MainLayout');
|
||||
const { appService } = useContext(GlobalContext);
|
||||
const scanService = appService.children.get('scan');
|
||||
|
||||
const options: BottomTabNavigationOptions = {
|
||||
headerRight: () => (
|
||||
@@ -50,7 +56,7 @@ export const MainLayout: React.FC<RootRouteProps> = (props) => {
|
||||
headerTitleStyle: {
|
||||
fontFamily: 'Inter_600SemiBold',
|
||||
fontSize: 30,
|
||||
margin: 8,
|
||||
margin: 4,
|
||||
},
|
||||
headerRightContainerStyle: { paddingEnd: 13 },
|
||||
headerLeftContainerStyle: { paddingEnd: 13 },
|
||||
@@ -77,6 +83,13 @@ export const MainLayout: React.FC<RootRouteProps> = (props) => {
|
||||
key={route.name}
|
||||
name={route.name}
|
||||
component={route.component}
|
||||
listeners={{
|
||||
tabPress: (e) => {
|
||||
if (route.name == scan.name) {
|
||||
scanService.send(ScanEvents.RESET());
|
||||
}
|
||||
},
|
||||
}}
|
||||
options={{
|
||||
...route.options,
|
||||
title: t(route.name),
|
||||
|
||||
@@ -49,7 +49,7 @@ export const RequestLayout: React.FC = () => {
|
||||
name="RequestScreen"
|
||||
component={RequestScreen}
|
||||
options={{
|
||||
title: t('request').toUpperCase(),
|
||||
title: t('receiveCard').toUpperCase(),
|
||||
}}
|
||||
/>
|
||||
</RequestStack.Navigator>
|
||||
|
||||
@@ -20,7 +20,8 @@ import {
|
||||
} from '../../machines/bleShare/commonSelectors';
|
||||
import { RequestEvents } from '../../machines/bleShare/request/requestMachine';
|
||||
|
||||
type RequestStackParamList = {
|
||||
export type RequestStackParamList = {
|
||||
Request: undefined;
|
||||
RequestScreen: undefined;
|
||||
ReceiveVcScreen: undefined;
|
||||
};
|
||||
|
||||
@@ -86,7 +86,9 @@ export const AboutInji: React.FC<AboutInjiProps> = ({ appId }) => {
|
||||
</Text>
|
||||
<TouchableOpacity
|
||||
activeOpacity={1}
|
||||
onPress={() => Linking.openURL(aboutInjiUrl)}>
|
||||
onPress={() => {
|
||||
aboutInjiUrl && Linking.openURL(aboutInjiUrl);
|
||||
}}>
|
||||
<Text color={Theme.Colors.AddIdBtnBg} weight="bold">
|
||||
{t('clickHere')}
|
||||
</Text>
|
||||
|
||||
77
screens/Settings/ReceivedCards.tsx
Normal file
77
screens/Settings/ReceivedCards.tsx
Normal file
@@ -0,0 +1,77 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { RefreshControl } from 'react-native';
|
||||
import { Pressable, TouchableOpacity } from 'react-native';
|
||||
import { Centered, Column, Row, Text } from '../../components/ui';
|
||||
import { Icon } from 'react-native-elements';
|
||||
import { Theme } from '../../components/ui/styleUtils';
|
||||
import { Image } from 'react-native';
|
||||
import { Modal } from '../../components/ui/Modal';
|
||||
import { HomeScreenTabProps } from '../Home/HomeScreen';
|
||||
import { useReceivedVcsTab } from '../Home/ReceivedVcsTabController';
|
||||
import { VcItem } from '../../components/VcItem';
|
||||
|
||||
export const ReceivedCards: React.FC<HomeScreenTabProps> = (props) => {
|
||||
const { t } = useTranslation('ReceivedVcsTab');
|
||||
const controller = useReceivedVcsTab(props);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Pressable onPress={controller.TOGGLE_RECEIVED_CARDS}>
|
||||
<Column style={Theme.Styles.receiveCardsContainer}>
|
||||
<Image
|
||||
source={Theme.ReceivedCardsIcon}
|
||||
style={{ marginLeft: 10, marginRight: 9 }}
|
||||
/>
|
||||
<Text margin="6" weight="semibold">
|
||||
{t('receivedCards')}
|
||||
</Text>
|
||||
</Column>
|
||||
</Pressable>
|
||||
|
||||
<Modal
|
||||
isVisible={controller.isVisible}
|
||||
arrowLeft={<Icon name={''} />}
|
||||
headerTitle={t('header')}
|
||||
headerElevation={2}
|
||||
onDismiss={controller.TOGGLE_RECEIVED_CARDS}>
|
||||
<Column
|
||||
scroll
|
||||
pX={15}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={controller.isRefreshingVcs}
|
||||
onRefresh={controller.REFRESH}
|
||||
/>
|
||||
}>
|
||||
{controller.vcKeys.map((vcKey) => (
|
||||
<VcItem
|
||||
key={vcKey}
|
||||
vcKey={vcKey}
|
||||
margin="0 2 8 2"
|
||||
isSharingVc
|
||||
onPress={controller.VIEW_VC}
|
||||
/>
|
||||
))}
|
||||
{controller.vcKeys.length === 0 && (
|
||||
<React.Fragment>
|
||||
<Centered fill>
|
||||
<Icon
|
||||
style={{ marginBottom: 20 }}
|
||||
size={40}
|
||||
name="sentiment-dissatisfied"
|
||||
/>
|
||||
<Text align="center" weight="semibold" margin="0 0 4 0">
|
||||
{t('noReceivedVcsTitle')}
|
||||
</Text>
|
||||
<Text align="center" color={Theme.Colors.textLabel}>
|
||||
{t('noReceivedVcsText')}
|
||||
</Text>
|
||||
</Centered>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</Column>
|
||||
</Modal>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { Platform, Pressable, View } from 'react-native';
|
||||
import { Platform, Pressable, View, Image } from 'react-native';
|
||||
import { Icon, ListItem, Switch } from 'react-native-elements';
|
||||
import { Column, Text } from '../../components/ui';
|
||||
import { Column, Row, Text } from '../../components/ui';
|
||||
import { Theme } from '../../components/ui/styleUtils';
|
||||
import { MessageOverlay } from '../../components/MessageOverlay';
|
||||
|
||||
@@ -13,7 +13,8 @@ import { Modal } from '../../components/ui/Modal';
|
||||
import { CREDENTIAL_REGISTRY_EDIT } from 'react-native-dotenv';
|
||||
import { AboutInji } from './AboutInji';
|
||||
import { EditableListItem } from '../../components/EditableListItem';
|
||||
import { RootRouteProps } from '../../routes';
|
||||
import { RequestRouteProps } from '../../routes';
|
||||
import { ReceivedCards } from './ReceivedCards';
|
||||
|
||||
const LanguageSetting: React.FC = () => {
|
||||
const { t } = useTranslation('SettingScreen');
|
||||
@@ -46,7 +47,7 @@ const LanguageSetting: React.FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export const SettingScreen: React.FC<SettingProps & RootRouteProps> = (
|
||||
export const SettingScreen: React.FC<SettingProps & RequestRouteProps> = (
|
||||
props
|
||||
) => {
|
||||
const { t } = useTranslation('SettingScreen');
|
||||
@@ -63,8 +64,43 @@ export const SettingScreen: React.FC<SettingProps & RootRouteProps> = (
|
||||
headerTitle={t('header')}
|
||||
headerElevation={2}
|
||||
onDismiss={controller.TOGGLE_SETTINGS}>
|
||||
<ScrollView>
|
||||
<Column fill backgroundColor={Theme.Colors.lightGreyBackgroundColor}>
|
||||
<ScrollView backgroundColor={Theme.Colors.lightGreyBackgroundColor}>
|
||||
<Column style={{ display: Platform.OS !== 'ios' ? 'flex' : 'none' }}>
|
||||
<Text
|
||||
weight="semibold"
|
||||
margin="10"
|
||||
color={Theme.Colors.aboutVersion}>
|
||||
{t('injiAsVerifierApp')}
|
||||
</Text>
|
||||
<Row
|
||||
align="space-evenly"
|
||||
backgroundColor={Theme.Colors.whiteBackgroundColor}>
|
||||
<Pressable onPress={controller.RECEIVE_CARD}>
|
||||
<Column style={Theme.Styles.receiveCardsContainer}>
|
||||
<Image
|
||||
source={Theme.ReceiveCardIcon}
|
||||
style={{ alignSelf: 'center' }}
|
||||
/>
|
||||
<Text margin="6" weight="semibold">
|
||||
{t('receiveCard')}
|
||||
</Text>
|
||||
</Column>
|
||||
</Pressable>
|
||||
<ReceivedCards
|
||||
isVisible={false}
|
||||
service={undefined}
|
||||
vcItemActor={undefined}
|
||||
/>
|
||||
</Row>
|
||||
|
||||
<Text
|
||||
weight="semibold"
|
||||
margin="10"
|
||||
color={Theme.Colors.aboutVersion}>
|
||||
{t('basicSettings')}
|
||||
</Text>
|
||||
</Column>
|
||||
<Column fill>
|
||||
<MessageOverlay
|
||||
isVisible={controller.alertMsg != ''}
|
||||
onBackdropPress={controller.hideAlert}
|
||||
|
||||
@@ -26,10 +26,10 @@ import {
|
||||
} from '../../machines/biometrics';
|
||||
import { GlobalContext } from '../../shared/GlobalContext';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { RootRouteProps } from '../../routes';
|
||||
import { Platform } from 'react-native';
|
||||
import { RequestRouteProps } from '../../routes';
|
||||
|
||||
export function useSettingsScreen(props: RootRouteProps) {
|
||||
export function useSettingsScreen(props: RequestRouteProps) {
|
||||
const { appService } = useContext(GlobalContext);
|
||||
const authService = appService.children.get('auth');
|
||||
const settingsService = appService.children.get('settings');
|
||||
@@ -138,6 +138,11 @@ export function useSettingsScreen(props: RootRouteProps) {
|
||||
)
|
||||
),
|
||||
|
||||
RECEIVE_CARD: () => {
|
||||
props.navigation.navigate('Request');
|
||||
setIsVisible(false);
|
||||
},
|
||||
|
||||
TOGGLE_BIOMETRIC: (enable: boolean) =>
|
||||
settingsService.send(SettingsEvents.TOGGLE_BIOMETRIC_UNLOCK(enable)),
|
||||
|
||||
@@ -145,7 +150,6 @@ export function useSettingsScreen(props: RootRouteProps) {
|
||||
setIsVisible(false);
|
||||
const navigate = () => {
|
||||
authService.send(AuthEvents.LOGOUT());
|
||||
props.navigation.navigate('Welcome');
|
||||
};
|
||||
|
||||
if (Platform.OS === 'ios') {
|
||||
|
||||
@@ -9,7 +9,6 @@ import { useWelcomeScreen } from './WelcomeScreenController';
|
||||
export const WelcomeScreen: React.FC<RootRouteProps> = (props) => {
|
||||
const { t } = useTranslation('WelcomeScreen');
|
||||
const controller = useWelcomeScreen(props);
|
||||
|
||||
return (
|
||||
<Column
|
||||
fill
|
||||
|
||||
Reference in New Issue
Block a user