From 91bd04bf694b843fc7db25ad4d39f7d8ed95ce84 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Milla Date: Wed, 2 Jun 2021 17:30:03 +0200 Subject: [PATCH 01/14] adds custom header and query string parameter --- package.json | 1 + src/config.ts | 10 ++++++ .../components/WebView/CachedWebView.tsx | 14 ++++++++- yarn.lock | 31 ++++++++++++++++++- 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/config.ts diff --git a/package.json b/package.json index 1f0e295b..b1f9ccc9 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "react-native-safe-area-context": "^3.2.0", "react-native-screens": "^3.1.0", "react-native-svg": "^12.1.0", + "react-native-url-polyfill": "^1.3.0", "react-native-webview": "^11.3.2", "react-redux": "^7.2.1", "redux": "^4.0.5", diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 00000000..ec39f6f0 --- /dev/null +++ b/src/config.ts @@ -0,0 +1,10 @@ +export const WEBVIEW_DEFAULT_HEADERS = { + [`X-WFD-CheckIn`]: 'true', +}; + +export const WEBVIEW_DEFAULT_QUERY_PARAMS = [ + { + name: 'WFD-CheckIn', + value: true, + }, +]; diff --git a/src/shared/components/WebView/CachedWebView.tsx b/src/shared/components/WebView/CachedWebView.tsx index caf667dc..d5b0010f 100644 --- a/src/shared/components/WebView/CachedWebView.tsx +++ b/src/shared/components/WebView/CachedWebView.tsx @@ -1,7 +1,10 @@ +import {URL} from 'react-native-url-polyfill'; import React, {createRef} from 'react'; import {ProgressBar} from 'react-native-paper'; import WebView, {WebViewProps} from 'react-native-webview'; +import {WEBVIEW_DEFAULT_HEADERS, WEBVIEW_DEFAULT_QUERY_PARAMS} from 'src/config'; + const renderLoading = () => ; export const webviewRef = createRef(); @@ -27,6 +30,12 @@ const CachedWebView: React.FC = ({ injectedJavaScript, ...restProps }) => { + const uri = new URL(url); + + WEBVIEW_DEFAULT_QUERY_PARAMS.forEach(el => { + uri.searchParams.append(el.name, el.value); + }); + return ( = ({ injectedJavaScript={injectedJavaScript} startInLoadingState={true} {...restProps} - source={{uri: url}} + source={{ + uri: uri.toString(), + headers: WEBVIEW_DEFAULT_HEADERS, + }} /> ); }; diff --git a/yarn.lock b/yarn.lock index 95edf783..a28bfd23 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2076,7 +2076,7 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= -base64-js@^1.1.2, base64-js@^1.5.1: +base64-js@^1.1.2, base64-js@^1.3.1, base64-js@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -2196,6 +2196,14 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== +buffer@^5.4.3: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + bunyan-debug-stream@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/bunyan-debug-stream/-/bunyan-debug-stream-1.1.1.tgz#4740a00b7d5c2d9d1b714925ab0802516040813e" @@ -3953,6 +3961,11 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" @@ -6769,6 +6782,13 @@ react-native-svg@^12.1.0: css-select "^2.1.0" css-tree "^1.0.0-alpha.39" +react-native-url-polyfill@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/react-native-url-polyfill/-/react-native-url-polyfill-1.3.0.tgz#c1763de0f2a8c22cc3e959b654c8790622b6ef6a" + integrity sha512-w9JfSkvpqqlix9UjDvJjm1EjSt652zVQ6iwCIj1cVVkwXf4jQhQgTNXY6EVTwuAmUjg6BC6k9RHCBynoLFo3IQ== + dependencies: + whatwg-url-without-unicode "8.0.0-3" + react-native-webview@^11.3.2: version "11.3.2" resolved "https://registry.yarnpkg.com/react-native-webview/-/react-native-webview-11.3.2.tgz#17155a69caf1910233ae3d606dce6caf57b0169c" @@ -8353,6 +8373,15 @@ whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0: resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== +whatwg-url-without-unicode@8.0.0-3: + version "8.0.0-3" + resolved "https://registry.yarnpkg.com/whatwg-url-without-unicode/-/whatwg-url-without-unicode-8.0.0-3.tgz#ab6df4bf6caaa6c85a59f6e82c026151d4bb376b" + integrity sha512-HoKuzZrUlgpz35YO27XgD28uh/WJH4B0+3ttFqRo//lmq+9T/mIOJ6kqmINI9HpUpz1imRC/nR/lxKpJiv0uig== + dependencies: + buffer "^5.4.3" + punycode "^2.1.1" + webidl-conversions "^5.0.0" + whatwg-url@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" From 6d05c2c07a13cb22c11d2fee7b91fa55aa6a2c44 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Milla Date: Wed, 2 Jun 2021 17:30:50 +0200 Subject: [PATCH 02/14] adds custom header and query string parameter --- src/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.ts b/src/config.ts index ec39f6f0..21367677 100644 --- a/src/config.ts +++ b/src/config.ts @@ -5,6 +5,6 @@ export const WEBVIEW_DEFAULT_HEADERS = { export const WEBVIEW_DEFAULT_QUERY_PARAMS = [ { name: 'WFD-CheckIn', - value: true, + value: 'true', }, ]; From 242bd29e8233d03b96e46ae0906c45b9c95a33c8 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Milla Date: Wed, 2 Jun 2021 17:35:53 +0200 Subject: [PATCH 03/14] use app id as value for header and query string --- src/config.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/config.ts b/src/config.ts index 21367677..5588a5f9 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,10 +1,12 @@ +export const APP_ID = 'de.railslove.wfdcheckin'; + export const WEBVIEW_DEFAULT_HEADERS = { - [`X-WFD-CheckIn`]: 'true', + 'x-requested-with': APP_ID, }; export const WEBVIEW_DEFAULT_QUERY_PARAMS = [ { - name: 'WFD-CheckIn', - value: 'true', + name: 'requestedWith', + value: APP_ID, }, ]; From 8ed222af084a6a9817937e627c590066ad9f7bf3 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Milla Date: Wed, 2 Jun 2021 17:41:05 +0200 Subject: [PATCH 04/14] cleanup --- .../components/WebView/CachedWebView.tsx | 14 ++------------ src/shared/format/webView.ts | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 12 deletions(-) create mode 100644 src/shared/format/webView.ts diff --git a/src/shared/components/WebView/CachedWebView.tsx b/src/shared/components/WebView/CachedWebView.tsx index d5b0010f..43321c2f 100644 --- a/src/shared/components/WebView/CachedWebView.tsx +++ b/src/shared/components/WebView/CachedWebView.tsx @@ -1,9 +1,8 @@ -import {URL} from 'react-native-url-polyfill'; import React, {createRef} from 'react'; import {ProgressBar} from 'react-native-paper'; import WebView, {WebViewProps} from 'react-native-webview'; -import {WEBVIEW_DEFAULT_HEADERS, WEBVIEW_DEFAULT_QUERY_PARAMS} from 'src/config'; +import {formatWebViewSource} from 'src/shared/format/webView'; const renderLoading = () => ; @@ -30,12 +29,6 @@ const CachedWebView: React.FC = ({ injectedJavaScript, ...restProps }) => { - const uri = new URL(url); - - WEBVIEW_DEFAULT_QUERY_PARAMS.forEach(el => { - uri.searchParams.append(el.name, el.value); - }); - return ( = ({ injectedJavaScript={injectedJavaScript} startInLoadingState={true} {...restProps} - source={{ - uri: uri.toString(), - headers: WEBVIEW_DEFAULT_HEADERS, - }} + source={formatWebViewSource(url)} /> ); }; diff --git a/src/shared/format/webView.ts b/src/shared/format/webView.ts new file mode 100644 index 00000000..67870c99 --- /dev/null +++ b/src/shared/format/webView.ts @@ -0,0 +1,18 @@ +import {URL} from 'react-native-url-polyfill'; +import {WebViewSource} from 'react-native-webview/lib/WebViewTypes'; +import {WEBVIEW_DEFAULT_HEADERS, WEBVIEW_DEFAULT_QUERY_PARAMS} from 'src/config'; + +export const formatWebViewSource = (url: string): WebViewSource => { + const uri = new URL(url); + + WEBVIEW_DEFAULT_QUERY_PARAMS.forEach(el => { + uri.searchParams.append(el.name, el.value); + }); + + return { + uri: uri.toString(), + headers: { + ...WEBVIEW_DEFAULT_HEADERS, + }, + }; +}; From 2ccb9a9b6a5ced4e11281162fb551feceb4845b9 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Milla Date: Wed, 2 Jun 2021 17:42:08 +0200 Subject: [PATCH 05/14] cleanup comment --- src/shared/components/WebView/CachedWebView.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/shared/components/WebView/CachedWebView.tsx b/src/shared/components/WebView/CachedWebView.tsx index 43321c2f..c4782e8b 100644 --- a/src/shared/components/WebView/CachedWebView.tsx +++ b/src/shared/components/WebView/CachedWebView.tsx @@ -20,8 +20,7 @@ export type CachedWebViewProps = Omit & { * CachedWebView * * We need to maintain the website state while we use navigation on the app. - * The id should be unique per check-in not per provider. - * The component is cached and cleared when check-out is done or a check-in is discarded. + * We use the id here to make the WebView unique per check-in not per provider. */ const CachedWebView: React.FC = ({ id: _cachedID, From 6992a788bb5ca21e3e418c8dfb530bc9c0e156a2 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Milla Date: Wed, 2 Jun 2021 19:05:22 +0200 Subject: [PATCH 06/14] adds navigation to webview --- src/features/check-ins/ProviderFormScreen.tsx | 81 ++++++++++++++++--- .../check-ins/components/CheckInItemCard.tsx | 4 +- src/features/navigation/navigationLocales.ts | 1 + src/shared/components/Icon/ArrowLeftIcon.tsx | 11 +++ ...hevronRightIcon.tsx => ArrowRightIcon.tsx} | 8 +- src/shared/components/Icon/types.ts | 1 + src/shared/components/Layout/Box.tsx | 3 +- .../components/WebView/CachedWebView.tsx | 21 +++-- 8 files changed, 101 insertions(+), 29 deletions(-) create mode 100644 src/shared/components/Icon/ArrowLeftIcon.tsx rename src/shared/components/Icon/{ChevronRightIcon.tsx => ArrowRightIcon.tsx} (84%) diff --git a/src/features/check-ins/ProviderFormScreen.tsx b/src/features/check-ins/ProviderFormScreen.tsx index b83f423a..209c30e0 100644 --- a/src/features/check-ins/ProviderFormScreen.tsx +++ b/src/features/check-ins/ProviderFormScreen.tsx @@ -1,7 +1,8 @@ -import {useDispatch, useSelector} from 'react-redux'; import {useTheme} from 'react-native-paper'; -import React, {useCallback} from 'react'; -import {WebViewMessageEvent} from 'react-native-webview'; +import {useDispatch, useSelector} from 'react-redux'; +import React, {useCallback, useState, useRef} from 'react'; +import {SafeAreaView, TouchableOpacity} from 'react-native'; +import WebView, {WebViewMessageEvent, WebViewNavigation} from 'react-native-webview'; import { providerCheckInAction, @@ -19,13 +20,41 @@ import NavigationService from 'src/features/navigation/services/NavigationServic import Box from 'src/shared/components/Layout/Box'; import CachedWebView from 'src/shared/components/WebView/CachedWebView'; +import ArrowRightIcon from 'src/shared/components/Icon/ArrowRightIcon'; +import ArrowLeftIcon from 'src/shared/components/Icon/ArrowLeftIcon'; const ProviderFormScreen = () => { const theme = useTheme(); const dispatch = useDispatch(); + const webviewRef = useRef(null); const user = useSelector(state => state.user.item); const checkIn = useSelector(state => state.checkIns.current); + const [canGoBack, setCanGoBack] = useState(); + const [canGoForward, setCanGoForward] = useState(); + + const {current: browserWindow} = webviewRef; + + const handleGoBack = useCallback(() => { + if (!browserWindow || !canGoBack) { + return null; + } + + browserWindow.goBack(); + }, [canGoBack, browserWindow]); + + const handleGoForward = useCallback(() => { + if (!browserWindow || !canGoForward) { + return null; + } + + browserWindow.goForward(); + }, [canGoForward, browserWindow]); + + const handleNavigationStateChange = useCallback((ev: WebViewNavigation) => { + setCanGoBack(ev.canGoBack); + setCanGoForward(ev.canGoForward); + }, []); const handleMessage = useCallback( (ev: WebViewMessageEvent) => { @@ -90,14 +119,44 @@ const ProviderFormScreen = () => { const injectedJavaScript = user ? prepareFillFormInWebViewInject({user, __DEV__}) : undefined; return ( - - - + + + {canGoBack || canGoForward ? ( + + {canGoBack ? ( + + + + ) : ( + + )} + + {canGoForward ? ( + + + + ) : ( + + )} + + ) : null} + + + ); }; diff --git a/src/features/check-ins/components/CheckInItemCard.tsx b/src/features/check-ins/components/CheckInItemCard.tsx index 643da794..207414ed 100644 --- a/src/features/check-ins/components/CheckInItemCard.tsx +++ b/src/features/check-ins/components/CheckInItemCard.tsx @@ -6,9 +6,9 @@ import {CompletedCheckInItem} from 'src/shared/models/Provider'; import Box from 'src/shared/components/Layout/Box'; import Space from 'src/shared/components/Layout/Space'; -import {formatItemDate} from 'src/shared/format/date'; -import ChevronRightIcon from 'src/shared/components/Icon/ChevronRightIcon'; import CheckInLogo from 'src/features/check-ins/components/CheckInLogo'; +import {formatItemDate} from 'src/shared/format/date'; +import ChevronRightIcon from 'src/shared/components/Icon/ArrowRightIcon'; const useStyles = () => { return StyleSheet.create({ diff --git a/src/features/navigation/navigationLocales.ts b/src/features/navigation/navigationLocales.ts index 8e3fa59d..53798bd1 100644 --- a/src/features/navigation/navigationLocales.ts +++ b/src/features/navigation/navigationLocales.ts @@ -1,4 +1,5 @@ export default { + back: 'Zurück', profile: 'Profil', checkIns: 'Check-ins', }; diff --git a/src/shared/components/Icon/ArrowLeftIcon.tsx b/src/shared/components/Icon/ArrowLeftIcon.tsx new file mode 100644 index 00000000..b3cb73c8 --- /dev/null +++ b/src/shared/components/Icon/ArrowLeftIcon.tsx @@ -0,0 +1,11 @@ +import React from 'react'; +import Box from 'src/shared/components/Layout/Box'; +import ArrowRightIcon from 'src/shared/components/Icon/ArrowRightIcon'; + +const ArrowLeftIcon: React.FC = () => ( + + + +); + +export default ArrowLeftIcon; diff --git a/src/shared/components/Icon/ChevronRightIcon.tsx b/src/shared/components/Icon/ArrowRightIcon.tsx similarity index 84% rename from src/shared/components/Icon/ChevronRightIcon.tsx rename to src/shared/components/Icon/ArrowRightIcon.tsx index d11b619e..b5110c10 100644 --- a/src/shared/components/Icon/ChevronRightIcon.tsx +++ b/src/shared/components/Icon/ArrowRightIcon.tsx @@ -1,14 +1,14 @@ import React from 'react'; import {useTheme} from 'react-native-paper'; -import Svg, {Path} from 'react-native-svg'; +import Svg, {Path, SvgProps} from 'react-native-svg'; import {px2dp} from 'src/shared/styles/createStyles'; const size = px2dp(19); -const ChevronRightIcon: React.FC = () => { +const ArrowRightIcon: React.FC = props => { const {colors} = useTheme(); return ( - + { ); }; -export default ChevronRightIcon; +export default ArrowRightIcon; diff --git a/src/shared/components/Icon/types.ts b/src/shared/components/Icon/types.ts index a8d95f38..2b2753c7 100644 --- a/src/shared/components/Icon/types.ts +++ b/src/shared/components/Icon/types.ts @@ -1,4 +1,5 @@ export type SvgIconProps = Partial<{ stroke: string; + transform: string; isSelected: boolean; }>; diff --git a/src/shared/components/Layout/Box.tsx b/src/shared/components/Layout/Box.tsx index 49c69f10..8d371359 100644 --- a/src/shared/components/Layout/Box.tsx +++ b/src/shared/components/Layout/Box.tsx @@ -1,10 +1,11 @@ import React from 'react'; import {View, ViewStyle} from 'react-native'; +import {transformStyleRules} from 'src/shared/styles/createStyles'; export type BoxProps = Partial; const Box: React.FC = ({children, ...style}) => { - return {children}; + return {children}; }; export default Box; diff --git a/src/shared/components/WebView/CachedWebView.tsx b/src/shared/components/WebView/CachedWebView.tsx index caf667dc..5bfa3781 100644 --- a/src/shared/components/WebView/CachedWebView.tsx +++ b/src/shared/components/WebView/CachedWebView.tsx @@ -1,17 +1,16 @@ -import React, {createRef} from 'react'; +import React from 'react'; import {ProgressBar} from 'react-native-paper'; import WebView, {WebViewProps} from 'react-native-webview'; const renderLoading = () => ; -export const webviewRef = createRef(); - export type CachedWebViewProps = Omit & { /** * makes the webview re-render for different check-ins on the same provider */ id: string; url: string; + children?: React.ReactNode; }; /** @@ -21,15 +20,15 @@ export type CachedWebViewProps = Omit & { * The id should be unique per check-in not per provider. * The component is cached and cleared when check-out is done or a check-in is discarded. */ -const CachedWebView: React.FC = ({ - id: _cachedID, - url, - injectedJavaScript, - ...restProps -}) => { +const CachedWebView = React.forwardRef(function CachedWebViewWithRef( + props, + ref +) { + const {id: _cachedID, url, injectedJavaScript, ...restProps} = props; + return ( = ({ source={{uri: url}} /> ); -}; +}); export default React.memo(CachedWebView); From de62f7a8e3f55e93f2f59315a1a240c686e757f0 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Milla Date: Wed, 2 Jun 2021 19:58:30 +0200 Subject: [PATCH 07/14] adds back and forward navigation --- src/features/check-ins/ProviderFormScreen.tsx | 2 +- src/features/{scan => check-ins}/constants.ts | 2 +- src/features/check-ins/providerFormLib.ts | 9 +++------ src/features/scan/ScanQRCodeScreen.tsx | 12 ++++++++---- src/shared/components/WebView/CachedWebView.tsx | 3 ++- 5 files changed, 15 insertions(+), 13 deletions(-) rename src/features/{scan => check-ins}/constants.ts (81%) diff --git a/src/features/check-ins/ProviderFormScreen.tsx b/src/features/check-ins/ProviderFormScreen.tsx index 209c30e0..7a4c7104 100644 --- a/src/features/check-ins/ProviderFormScreen.tsx +++ b/src/features/check-ins/ProviderFormScreen.tsx @@ -112,7 +112,7 @@ const ProviderFormScreen = () => { [checkIn, dispatch] ); - if (!checkIn) { + if (checkIn == null) { return null; } diff --git a/src/features/scan/constants.ts b/src/features/check-ins/constants.ts similarity index 81% rename from src/features/scan/constants.ts rename to src/features/check-ins/constants.ts index 02c4f1b3..34563657 100644 --- a/src/features/scan/constants.ts +++ b/src/features/check-ins/constants.ts @@ -10,4 +10,4 @@ export enum PROVIDER_SITE_MESSAGE { parseMessageError = 'parseMessageError', } -export type MessageKey = keyof typeof PROVIDER_SITE_MESSAGE; +export type ProviderSiteMessageKey = keyof typeof PROVIDER_SITE_MESSAGE; diff --git a/src/features/check-ins/providerFormLib.ts b/src/features/check-ins/providerFormLib.ts index b2d7f07b..1d1a42f1 100644 --- a/src/features/check-ins/providerFormLib.ts +++ b/src/features/check-ins/providerFormLib.ts @@ -1,8 +1,8 @@ import WebView, {WebViewMessageEvent} from 'react-native-webview'; import User from 'src/shared/models/User'; -import {MessageKey} from 'src/features/scan/constants'; import {AutoCompleteValues} from 'src/shared/types/autoComplete'; +import {ProviderSiteMessageKey} from 'src/features/check-ins/constants'; declare global { interface Window { @@ -16,7 +16,7 @@ type InjectJSValues = { }; export type ProviderFormMessage = { - key: MessageKey; + key: ProviderSiteMessageKey; value?: string; }; @@ -38,7 +38,7 @@ export function fillFormInWebView(values: InjectJSValues) { postMessage('start', JSON.stringify(state)); } - function postMessage(key: MessageKey, value?: string) { + function postMessage(key: ProviderSiteMessageKey, value?: string) { const message = JSON.stringify({key, value}); window.ReactNativeWebView.postMessage(message); } @@ -201,9 +201,6 @@ export function fillFormInWebView(values: InjectJSValues) { const checkInterval = setInterval(() => { if (!state.hasFilledInputs && canCheckIn()) { - // Makes sure the bottom of the page has space enough to click on the check-in button - document.body.style.paddingBottom = document.body.style.paddingBottom || '100px'; - fillCheckInForm(); } else if (isCheckOut()) { findProviderLocation(); diff --git a/src/features/scan/ScanQRCodeScreen.tsx b/src/features/scan/ScanQRCodeScreen.tsx index cd0d0fd2..75e0eb60 100644 --- a/src/features/scan/ScanQRCodeScreen.tsx +++ b/src/features/scan/ScanQRCodeScreen.tsx @@ -37,11 +37,15 @@ const ScanQRCodeScreen: React.FC = () => { }; const handleSuccess = ({data: url}: Pick) => { - NavigationService.fromScanQRScreen(); + // clear current provider => will also clear the webview + dispatch(providerDiscardAction()); - // dispatch action with a bit of delay - // otherwise the case where there is a current provider flashes - setTimeout(() => dispatch(providerRegisterAction({url})), 0); + // dispatch action with a bit of delay so the clear action takes place + setTimeout(() => { + dispatch(providerRegisterAction({url})); + + NavigationService.fromScanQRScreen(); + }, 125); }; useEffect(() => { diff --git a/src/shared/components/WebView/CachedWebView.tsx b/src/shared/components/WebView/CachedWebView.tsx index 5bfa3781..35727e7e 100644 --- a/src/shared/components/WebView/CachedWebView.tsx +++ b/src/shared/components/WebView/CachedWebView.tsx @@ -10,6 +10,7 @@ export type CachedWebViewProps = Omit & { */ id: string; url: string; + ref?: React.MutableRefObject; children?: React.ReactNode; }; @@ -24,7 +25,7 @@ const CachedWebView = React.forwardRef(function Cac props, ref ) { - const {id: _cachedID, url, injectedJavaScript, ...restProps} = props; + const {url, injectedJavaScript, ...restProps} = props; return ( Date: Wed, 2 Jun 2021 20:01:33 +0200 Subject: [PATCH 08/14] silly formatting --- src/features/check-ins/ProviderFormScreen.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/features/check-ins/ProviderFormScreen.tsx b/src/features/check-ins/ProviderFormScreen.tsx index 7a4c7104..a8db1f09 100644 --- a/src/features/check-ins/ProviderFormScreen.tsx +++ b/src/features/check-ins/ProviderFormScreen.tsx @@ -20,8 +20,8 @@ import NavigationService from 'src/features/navigation/services/NavigationServic import Box from 'src/shared/components/Layout/Box'; import CachedWebView from 'src/shared/components/WebView/CachedWebView'; -import ArrowRightIcon from 'src/shared/components/Icon/ArrowRightIcon'; import ArrowLeftIcon from 'src/shared/components/Icon/ArrowLeftIcon'; +import ArrowRightIcon from 'src/shared/components/Icon/ArrowRightIcon'; const ProviderFormScreen = () => { const theme = useTheme(); From 18cedec7d874ad8d6d8e38d844cfec42fa4b3629 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Milla Date: Wed, 2 Jun 2021 20:12:27 +0200 Subject: [PATCH 09/14] adds discard alert for new check-in when another in progress --- src/features/scan/ScanQRCodeScreen.tsx | 16 ++++++++++++++-- src/features/scan/scanQRCodeScreenLocales.ts | 5 +++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/features/scan/ScanQRCodeScreen.tsx b/src/features/scan/ScanQRCodeScreen.tsx index cd0d0fd2..c2a0b603 100644 --- a/src/features/scan/ScanQRCodeScreen.tsx +++ b/src/features/scan/ScanQRCodeScreen.tsx @@ -1,7 +1,8 @@ +import {Alert} from 'react-native'; import {useTranslation} from 'react-i18next'; +import React, {useEffect} from 'react'; import {BarCodeReadEvent} from 'react-native-camera'; import {useDispatch, useSelector} from 'react-redux'; -import React, {useEffect} from 'react'; import {px2dp} from 'src/shared/styles/createStyles'; import {TEST_PROVIDERS} from 'src/testData'; @@ -54,7 +55,18 @@ const ScanQRCodeScreen: React.FC = () => { }; const handleDiscardCheckIn = () => { - dispatch(providerDiscardAction()); + const title = t('checkInProgressTitle'); + const message = t('checkInProgressDiscardAlertMessage'); + + Alert.alert(title, message, [ + { + text: t('yes'), + onPress: () => dispatch(providerDiscardAction()), + }, + { + text: t('no'), + }, + ]); }; return ( diff --git a/src/features/scan/scanQRCodeScreenLocales.ts b/src/features/scan/scanQRCodeScreenLocales.ts index c5a2b3c3..e67aa558 100644 --- a/src/features/scan/scanQRCodeScreenLocales.ts +++ b/src/features/scan/scanQRCodeScreenLocales.ts @@ -12,4 +12,9 @@ export default { checkInProgressDiscard: 'Neuer Check-in', checkInProgressContinue: 'zum aktuellen Check-in', + + no: 'Nein', + yes: 'Ja', + checkInProgressDiscardAlertMessage: + 'Willst Du dich neu einchecken ohne dich ausgecheckt zu haben?', }; From a13b2b20c245d8395f1d74be96a600db19deb142 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Milla Date: Wed, 2 Jun 2021 20:29:08 +0200 Subject: [PATCH 10/14] clean translations --- src/features/navigation/navigationLocales.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/features/navigation/navigationLocales.ts b/src/features/navigation/navigationLocales.ts index 53798bd1..8e3fa59d 100644 --- a/src/features/navigation/navigationLocales.ts +++ b/src/features/navigation/navigationLocales.ts @@ -1,5 +1,4 @@ export default { - back: 'Zurück', profile: 'Profil', checkIns: 'Check-ins', }; From eb4414e9b568f5f6c86eda346092a13784a88dc7 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Milla Date: Wed, 2 Jun 2021 20:31:00 +0200 Subject: [PATCH 11/14] reuse SvgProps for SvgIconProps --- src/shared/components/Icon/types.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/shared/components/Icon/types.ts b/src/shared/components/Icon/types.ts index 2b2753c7..4bb053f8 100644 --- a/src/shared/components/Icon/types.ts +++ b/src/shared/components/Icon/types.ts @@ -1,5 +1,6 @@ -export type SvgIconProps = Partial<{ - stroke: string; - transform: string; - isSelected: boolean; -}>; +import {SvgProps} from 'react-native-svg'; + +export type SvgIconProps = SvgProps & + Partial<{ + isSelected: boolean; + }>; From 84f5d1b278b113eaf86d1543ec52278070b0a579 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Milla Date: Wed, 2 Jun 2021 21:02:30 +0200 Subject: [PATCH 12/14] update provider logos --- src/features/check-ins/MyCheckInsScreen.tsx | 7 ++++- .../components/CheckInProviderLogos.tsx | 28 +++++++++++++----- src/shared/services/checkInProvidersList.ts | 20 +++++++++++++ src/shared/services/img/shapefruit-logo.png | Bin 0 -> 16256 bytes src/shared/services/img/undo-logo.png | Bin 0 -> 6983 bytes src/shared/services/img/visito-logo.png | Bin 0 -> 8024 bytes src/shared/services/img/zzeus-logo.png | Bin 0 -> 36842 bytes src/testData.ts | 3 ++ 8 files changed, 49 insertions(+), 9 deletions(-) create mode 100644 src/shared/services/img/shapefruit-logo.png create mode 100644 src/shared/services/img/undo-logo.png create mode 100644 src/shared/services/img/visito-logo.png create mode 100644 src/shared/services/img/zzeus-logo.png diff --git a/src/features/check-ins/MyCheckInsScreen.tsx b/src/features/check-ins/MyCheckInsScreen.tsx index 6ca7fb35..7cc0ad19 100644 --- a/src/features/check-ins/MyCheckInsScreen.tsx +++ b/src/features/check-ins/MyCheckInsScreen.tsx @@ -15,6 +15,7 @@ import CheckInsList from 'src/features/check-ins/components/CheckInsList'; import MyCheckInsEmpty from 'src/features/check-ins/components/MyCheckInsEmpty'; import MyCheckInsLinks from 'src/features/check-ins/components/MyCheckInsLinks'; import CheckInProviderLogos from 'src/features/check-ins/components/CheckInProviderLogos'; +import CHECK_IN_PROVIDER_LIST from 'src/shared/services/checkInProvidersList'; const MyCheckInsScreen: React.FC = () => { const {t} = useTranslation('myCheckInsScreen'); @@ -46,7 +47,11 @@ const MyCheckInsScreen: React.FC = () => { {t('providerListHeader')} - + diff --git a/src/features/check-ins/components/CheckInProviderLogos.tsx b/src/features/check-ins/components/CheckInProviderLogos.tsx index 9120a190..3f4ad8e6 100644 --- a/src/features/check-ins/components/CheckInProviderLogos.tsx +++ b/src/features/check-ins/components/CheckInProviderLogos.tsx @@ -6,7 +6,16 @@ import Box, {BoxProps} from 'src/shared/components/Layout/Box'; import CheckInLogo from 'src/features/check-ins/components/CheckInLogo'; import {EMPTY_CHECK_IN_LOGO_DIMENSIONS} from 'src/features/check-ins/components/constants'; -const CheckInProviderLogos: React.FC = props => { +export type CheckInProviderLogosProps = BoxProps & { + displayCount?: number; +}; + +const randomSort = () => 0.5 - Math.random(); + +const CheckInProviderLogos: React.FC = ({ + displayCount = 5, + ...props +}) => { return ( = props => { justifyContent="center" {...props} > - {CHECK_IN_PROVIDER_LIST.slice(0, 5).map(el => { - return ( - - - - ); - })} + {CHECK_IN_PROVIDER_LIST.slice() + .sort(randomSort) + .slice(0, displayCount) + .map(el => { + return ( + + + + ); + })} ); }; diff --git a/src/shared/services/checkInProvidersList.ts b/src/shared/services/checkInProvidersList.ts index 1362f78a..2f303ce6 100644 --- a/src/shared/services/checkInProvidersList.ts +++ b/src/shared/services/checkInProvidersList.ts @@ -37,6 +37,26 @@ const CHECK_IN_PROVIDER_LIST = Object.freeze([ logoUrl: require('./img/pandasafe-logo.png'), hostname: /pandasafe\.app$/, }, + { + name: 'UNDO', + logoUrl: require('./img/undo-logo.png'), + hostname: /undo-app.de\.de$/, + }, + { + name: 'Visito', + logoUrl: require('./img/visito-logo.png'), + hostname: /(visito\.me|vsto\.me)$/, + }, + { + name: 'shapefruit', + logoUrl: require('./img/shapefruit-logo.png'), + hostname: /shapefruit\.de$/, + }, + { + name: 'ZzEuS', + logoUrl: require('./img/zzeus-logo.png'), + hostname: /zzeus\.de$/, + }, ]); export default CHECK_IN_PROVIDER_LIST; diff --git a/src/shared/services/img/shapefruit-logo.png b/src/shared/services/img/shapefruit-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..01cc57654f413bde0dd4cd300838bf04ce80cb53 GIT binary patch literal 16256 zcma)jRaab1v@PxuoIv9e+@%RFL4vz`kl^kv!8O5x26uP&Cb&az8rR0Pfx~z24>;$c z_I{{cV~?^`HRqZ$N<~Qq6O9B71_lOGPF70o{r&V_l2MS}pLX&~|5czm$?Ceoz+esj zS71|^u}EQHC}HHJ#5KIK&boZv0Qc?(k8PR@*gPbZC?S-xA^74+AHK*p(vBsw#MDy% zRRVw#6qIlsE%`F!`2K!_%6P<2*-f5iWoMn{eB*1#yrs2D{wD_(o{_V>)=3bK0t4%4 z$BMsov8u91Q_}{6@ess6BuE!fEV$n%9H0Am6p$jwCLXe5&uHHI`UPs{;)D4dvLTL43PUCi$qU5{iqG?$?n4rj znHD@WfzP8keE%MH8s`S<^D@l;-Ym$y3Vph-3G^_M{wEQC1m-30dw3(IZr&2+9FMH@ zOraPqEoNa*VSXy*4^n#Gy(9z{L`j%0uyu%EgVf`8VCbfkLs(@$@?fjMp^1r8eL8n0 zPuCvVHX4J!e*P2>bgN}4Y#@Ib9(outMW;PNWBq8bEzk6u;NC~mS`Pl>G=^+$yTm$O zB4T~@mV7-)&M*Pg#wZzI+mv_#S`kvcu=9J1IT{!su3eg)CT9PElp%<)ygvuo1&vO- zmKT|;#F|`t>j06_YujN*WrC(85t%Vg2~bzlzhks?XnjLUlC0XOoVboAh=4@Uj9QO< zNOXvdRPpwc_YZzyPH6suE2cq-&uI@XI6h0J20=iGEh_H7d9mgfelcQkFn4qgEIpzC zwu`|QzQeNLfSJPwH=ZZ=*vq6kBNJIu9TWUz#Lo!z@WfR%TZN0f)!^UDI-0I4rN38x z=%e@d0}@J2kR+q*8P*aP4pfi_`ty@I^lCDsCYh-n>SYxQ-F- zALlLZ>He&im6=`=7?v4M7GtlzTgSW!z6-`^UCA&Cuk01$H6r9e=i2%`RWA`y@k!yb zpOEnAb`a+~3R*8dN6ld;A zMtBOMnl??uh9Bs~GWbJ5&EYa@;6#F|?%Qf4uqO0kh(n3YRd%Q#S!TrIskVWy>RD7uc6yMi?UJ*#t}c>`pu}< zo$tKjiN(e#XeXK+ZJh4V&OL$I_E zyRc=oBU)faU!!O$7#~7gu?FJv zjBAJ~J~lW#PrWR3yZ7XGApQ%t4S^uuZJ~KJr?MF!W@c8*pshxGci;e5_H2W^O}@_X z2UDPA!3vaIbmys4wlVXZMQFNfNiB|ZE_1FgeOL(a#0BO#wNSRed%_~?T56f?9204~ z3)eI^{y}xrzzVFMAdO08{b7{XVgn9@O-B%>8Yw`Viar_dz_rgJ)GeE9u%h~yM$xR z`SLQEqVf6d!LeYTEdCbWle{N@)C;g%gD=eg`O=O1Pp6`01N9YG?dclSqfx*O!C&`% zy`I5h1#SEpu^POMzt?)Rs$g#Uz3ZeH5%n3M_;0Zo=W>0hGru83fzeNMOLuGeHT?@; z`ESIhFW(Z%$%&GH+#98e)vB5$G>6(j<%{HlhA{Qo)2fM?&e=BiTWnp8HvYYN|8!4G zeIg+-NC~J#cJotqVOTQh1J9&Nq|J0T-LQe1{wV_GN`fzZBh0-O3v~}4djyOLwpeQQ zH4nZFR-?JvH|1gi%k{2Mz21BMUwDHT`=gxL5&SF`2p~rMi(uYT?5&sELzZTIp+_@} zB~t;2dxmPqzG$_;rwy`rN|`l5Tl%mjjin%SLeJFo zo<82Asmg_?2TYp7g`-kId@{UU`PRuMaelWm{pXXu-7ZyNwd6S58_q+``#AtGL=Pd= zn_fp{D@1$*T*z%D_H&$rapleSpIVMBZTF*fMckQF__OqV<7S5UbDm_bVl(<=w(7GyYDMyL_2ebp^AOh%7~9j#zZHlS^8 zTmMqFC4bu+b>{`nuRqy*opD6J(wyFT{*>cjm1>~ArVaH?H4;iIO4+jaKij7p+j$jeOaN1Tk1heu7v*XZ<^u6~bRUEq;%)m> z!(pFJC@EBL5`uaR=`&NE)@^TAluGkNOPo~7={wrdm5(LA1t2Rk>xcx<%)Qv$5DB&> zsWuT$p}1f?5KNab-wqq6g&5uD>7)4u`GfBU0&zUOttlE85736c8;h+TTo@NvbniWt zk;U(OH~#SW)w{6Oi*rvyV2l(G0|8AWIT9>Y961Etp zIbShyja{O_^%&N(ArxDTx6n92hkz@K>%+^&m~H65*DZ)aOqf`kyoXRkYy+3$-7~cCD@_8U#9X z3KIx1-Pruy9k+AQzeESBrHsJuqS(cE*z97hw6!vDS8fgr=_o%%H@LiCBhApNIATng z8iOPmM{$E{)~gSW%CtjwhQkP*MCoo(o%!?ZY|D<@=MQ&i%wKxR!`ZigA9Wbw4cp@E zFpE{B6wt@Uh1LI)`kmt3$bY)nS@S9B$`iOqcoHm`+?$w}z;MOl)S11ul>Ocjzy`X@ z2Xzsfo1(zMwa&6lS^5(!es`urHPq+O@0~ey6wc~+!l6vR=}Br*jm&n81tO&S!5kxPkaSLuS}!XijC{#BvAHp0guzW*_R@2wuxks4@A>z z`#zL`oAHm`YzQxdBRX1JY~g{77kT-*oS0)I8xoKbQ5l;XF<}RbJKQ1uge2b^6!Gnl z;r>ONlXipl6j#|X!l5g`EamA}V4-L@Z+-ao+l?>r`noI^;tyDG%mITL-QunP!w!8j zR`OaCvaQpy=fA$wvw_272fb#GbMwd63ecZg$wa~6=U^*qoF$EETiZcIk)lJ>U_tzP zFdG%(fLJAhG?%9G4lS<9kC^q!@Eg(6RcUsve$ny|p0#teD>mT&uCi^;4KVO8(_8TG>mPbaemS`dakgGJ- zcHDg^a^!1{6{?o4+rm~X*yDG$enp@AKVHd^ttd|^`zPNhwjf;T2|WSsGRn&HKu#b0 zR=2-*Pat&cJyRMKd_#8f9UriXv@M&t4~~WH(Px#}^8HqQN!TtNCGyLXfbR3+Ka>r4 z1^@rzta3cZ?>o|!tp-A7{PWmtT$#`qlq1PBL9~PP?AtBysb=N z9#s{Yvj5&&z8jcjau@Cx_)8Sn;sBwE?VkfNc6s~=7k#W|FVAmQe7yNK2hiWsSqJFt zB{oWIMkUn+Os^dd&W%;;_Sl4oh;UgltmvQV`ysWGy44({qW)GB8+5~_w&w6&>JK3_ zdco(TrkTVt{nh;^9421~o{uy(n{UOjxgadBSXlzH&iv?O%4 zB&^Gb4I8@Tml2ZLv8T@mFn1*oV@XbbYpT%ieX-P6uRP+<7%%{{(Y#n}xwhJZq8!g` zt*V;yRJYOhXHJV2$sJfdXeOC=rqgRnO&1@$A1XSfXAM6_6ei2|qdkb(h~OT~`)Q6W zz4?b-qn5-ctj4EyyTmWFV9uAK%8$W++I#d1}UL>p(a5*tr6yxy- z)%|pTdfioYAi8{_z;+Y0acm3qnZCZ$58}o>$vw_AdFyI5~Ve;pT)JVdNtbq5UuQ%)chH&Cc&B3ZNSw z3s?Jz5Bm?5X{0p(gY_IOp62He_c0D_DI$BfI^5Z&OUS6PgV|)7>jv-s2gw;&XRC46 zm?lEEf~U8%@tg_l3Uz^RZmYUaOozRRKRdrulyxEh+)K#y{JMiT7c(WQ&(I^#2EXbY zvE=7sbPpF}VmCVbvU8vG_|Qe`;Q(4&ifLg+W!zX8lEBb522Rtd;HLpW_RQHv(udaA2O)68QTo&#`MlX0+*1oRK4%tJr$GZUa5j&!wtA% zH`hOIG+g&vnc5V4oj>Wz+s>33CU!FM3i+0r7)I!;@k0qPT%u{uy%qW#C`Tt6)8x+m zcN+(zC+{B9#G1r*&az$P&a|>B^gVvdt`L}=9St0>_V2U5-m}DYi@zU1`zHKl+rq>j zAr;yw6Yv@v9bpd$eSvS5Q}na^n;~tCwarn3(|n^{KW|$t14aLCZ*M)9YH)C^vwZ6g znsQBbO$!2orVQx?EL|Uo$ zuicl^*GDe)l-7OD`jlqgh_255Q#w`=_a_|9%GWC53EVtOu1PyYS=*WPE9k`Pl};xe9g0r{uNmm9w)^;^>+j>>M>$`0h?gEmFN zyKr5vZQx9`r4zX^_aJ7~7xiI`O2o5Jo)fWYR?RLMsqVsZ^QP#Xn%!G-?wPdZHs)r^ww4@?>96=S$-k*t?9C_|EQE`&I>N zT95N6O!VAOKRg&wXCLy{x?w*N;tZDcdtoUvFYGo) z;h}Mg7di!^<04G{&x+dI<--(9S8~N1KN-ingJnfbv3zaNd|i?Uo9z|729}^xt-8A5 z#gGD2y@V6btc6arCM8Xs9+1E>3J?10veDWeP}ayc&H<(e!B0;UG{|Sgo>;3Ghf$;`4oy(<&Gs;k`WTfN(Q0CpL2 zZWs~Z^fKmyxj&CY*8UAmoqObbx4%vcwpng^uo)sJrW*E|)SZlo-2Qn25@Ly3UpJ4O z_puNV%d$CQH%IkD!(`GjpTd53!qzhS_$$TcJCKVMtro8~f_d`}b#uP|$Y9$xzV~)t z!Sebtrs6CMoo}`Vuxp3(pP&3e3;qF27ilySnjVpgZmWMrxl5x7M2&Rn3}yAQ3Xrj2 z22{lpw(6jZPn8}E_YT;kVOy6SvOt%58kk(s+h!T3X$cp8(Fp^U^Cv{C+oa&f2F>D9@yW_R|~ z?uV9H>H=9{+;nyJ0Fs$qGc;{{#S5k#s(ijcKi-A?KAKitg`2qCPHv?Uno=2?fH zX)8jDT8xIeff0oA>H0ph6b~Pi0+MErutx$9EJh*Opi_u_j&@!?vO75y-Ik0-EO>i- zpP`d)Qep~^*0DQda56hR!;Ugu*fVN&5Lu&m{n^N82XnN9{Q*dV>UOqfoVrza;8C3& zF_7tug4W#lfV#Ip=mzh3pO#CQ^qj56X+EW(Xb2spIHxg|Q*$|PF+D$Jq;nu+xqbP` zJ~{6HQr8Eb!TXraytI@>%CpF($EGggn%vg&Xd4YtP-&|byGj-RFU)25p3^Nfl#y#= z{G3;Oeg|Mw>!?{Fp)e^&LX-WvmOXd8PaRyPTItUnARV7mMFy?osnt#k?se?Vgtj6g z?v64eLL90#-}KpDgdxHw%SkZYkY~K}W6f(ac(sv5EZzqVCJlcKU?Y_r%eY+QJt?AS|ug2cUzrQx_1rYb1 zx)?Y7>q!~k4~RWm2ObdBm9TSNmn6)(zZtp(-k9rzu69{rMKZY>zmeRH$7X&X`s3$7 z(y)1LCAAT^6J%()T?S(8eq~Gfhp5(aHoP(~^Vsk0G8LFxR06`$(V8C6*FcbBoUe+J zCv78CJGdJfV+nw0ex=ANya$Pd&SX}h`><|a4PEbcKO@N3bnh1n^aL5{p*hKRRlfE~ z)(pl$XbuDKK|`J!k?^(p3&$0#huEdZR#LmU@EZGU%B)>?R~QXB1LayQ2d5JCULI5e zkAseuFZ`_Cz&JhoXD|;@z)nkD!c<;NHKK};FYa?!PyWSM(k{2>JEk)xRVD93L+K!$J>aHy2pea*MmGNu0Xs*5|Y>WsxQ znA&jz6*&DHbL$!&lozq7xSh?f>vgO@?!N~)UK$kzDxc2~l^=|zV zo$0h3^{JnGvzx~C;3b!{qrsg$X`zK~^(E;!A}!!5&isA)x5uYQCnZFV##t@0!qt8l z2*5YhU0e4^nlpu}>lAWvhrYZ5^ia@>xwA`LeBwv@En*ee&7QOvGk!daVugRr+dwRF zLD6F|HO@h&Rjp$CcjL+v?0=4X_xRDcoBXSl^3U`YO(HiKPQ_R|Y+|J0VvMLvB$NW4 zOSZe4q4rC{YJ8fFw0c0Bn8 zKF$5SoByTR#$&F@Hbt5egC6h72mz*DDOm)FXlHcU0nuX!+tgNaJuBt3nEu4XbpO-q zuKhx4<$?Msci?aoPJ{~I`CvahiI0=tohGAEP~%r=b<5os-j;haOuM*ZUQBKIL5!3z z)waeU*S6-8+_3&)=lxJj)E`kvldXEK%;5sd2O9;O+NP`NFI}|Q=TUo&NG*d{q`L6> zC+4fpD)x&w-_KJ#Er}Q@M2ScNIViIvD@5rFxL4BNyuYXGf79vYz>8TSw&{@=&h}2v zR@A(FU5YqgPFm{%wam+~;MBE?UR`#W;jSD5!>=B(E->iBW9cV;*GoUZ(q=e3Mn^lVGe zbk`zVSwvPPu%`9r(ti%utETj$1BjvWAaf0A9v5sDANu!FF={1;Qvj6BNe&N28_F{8 z^rV|VF>1|w+{A^FrfaQ?-}P2!atY_Yx&^*QEq%Rf`v{LLFL@cN<1H$SG+THsBzyOh z;!~Y1f3j?t2ibR;8tJ70i)uwA52#)h2`KR}o(j%E0m0j?%@>4;2GQ5wJ(lqt z%?bn@s{b9l+m4-C$fh+7B912xA^8#do%+Z3$Rlr1?77`%*TeJm#qPe3pIRch^((Qh zhqZfCdVsE8c!r+qN*tiKp)%f$V~=fE5{as-wZ|J6JHPLC-| zY$7B4Y=+c2=(gGmLwaOEJ=8SUxEho`ApJ;i!T^8Khx>pox&c=qj zWgM!-=9Q?)a^bY=+1ueaY7GC~>q@j4;D6gS-_7;PdFS8vgCn$vkquB3COBSFJ1FjZly5*>iM!yP~LBAy*gTs>|5pK^4Vo zA7x=NRG(Gk*tO^851sUbi26KydrFn`?W;&%Ooc5Fk++N6cn6ol932?F-5f*xo1)>u zocf->7bsK1-H?$GR(=R9hqg5#`|hjp*o_g6D^iu{4*f}SJX2axkPXN1IYP`3<9LYb>33U5?h<0%Bg}M35E1 z=Y;FkmMvwE{uGropc}m28;bT4K*i4$_09=semz|~`XvI)b|bu!i;myJPm>UuOV{T= zIBU!BIjgcAk%Hq?-1&+*NCM``{I^b~BZIlMi~egWOY$H_lj_3lcOhf@>D#`o3jZ z*_fMctM|%uwRd&{8OFW346XN`m^e;cnoRGvoSDRQs*e(8JXL@w?+c-EU~pX`6m`vmY}s{%(`a zNZC`mU%-^<--RAk*;1RDZOqFrRUylrcQU5;HalBdtxd37Uj0&5__LSap=;hGLEj9a z_dj4bQf`%(;Ds*Xj@t|0yq-!Hg6>S?2H9UKspdje^{5z{L#Up^BS!qd=gcf$4EnN`XV4p(Ma5%uY&o^Pz9jy9&&lDZCY+ffPULT3 zUybDqyBZr@y{vJFe2qzzXg*;>jLV&If+Q7fgN%T1&n?FZBnE}J6F(3rr!J;gxj zJur(>cVr=p8U+cR>w)1n2nG5sj@vLR#Obf!Aq{N{=A1hug0b_JNr%vK)3P1nA2fKE zjicUJpKgA+m*$j;rs6g&FF!8&sL18%AG>>JXw-dAPVav)uzMa50*>-59iPZ2h#1_` zQY&alUK9OlGbNHmG5Is_2yy>)b&1jMWUzjU0X*U83Kfh!#KUDuBh>MO@-{;o^2}AF zYLSqRy5Dddo)*PV!@U~~sOv14_j_TIjr<$B>NygGg}-=_`MW$=HbX0nP3AEYaEvNC&ph-w)-E7CMUl z;%)DkLra}mKO-*tws?5<&-Cs-rBMS8B(BC-8Eh{{vz|gQSAK0f)ZC;oLS!uXPrr>L z*TEDGjoH6-=w2zAq>I;SV#Mv|ny>^U!5?daXgV1)HJBGDW@arY?dhbcKK*g2KT(c4 zxUDVsCRl&nP#XhY&NGR4C7xFOk3|XJq+L819g;7_N5uN= zU)L!*M9m$J<(YMOu|G$BTU4NJuyp6u_2Nd}WMTp7j;4Jr5gAF@%mBDpULm2*xt zXvQ?hJdfSJQ2EQMA|fhx)HJ73{e;d$kZR=h4#3W-IUC~!?@T$ykLz_~=5tile5K)` zu#v&MwJGnl5bi3*PP_VxOx#AUv)nN>XSMWz1R z)}Oc6fs;?*QQQEn*G`1L!Q_YnErH;p=AMKNt+~=eWi)`AAI0e3l*-YljE%MX+$=U@ z;7`ZJPj`;Qs?XSY;ZW!-w$WeZ*Oi{L8iOqEQtP~g4eNp^*;mt@Y0$RJBl3Z+-<80A zuGje9y})U|1s+bLMj@AHnQ4wQ+y}OX&wU~$=>rLCNuM&Fhu^dbT++lfot5^|U*>wu z_Ge_u406g34vZ&P4_}*F2WKnTT`%unm9u`LTUW2C$nzWRkewAEpVQDQI^`>PZ4&UG z&O!oG)_y7%3>8^G3Kp%OAYBXhGYmPD8XG+dml>YAevc?h4uAFa?fixi2BH^U*T7<34e@oks0rc9Bp@ z+eb9V9;Mf|0{l%8xko8;D|?fdzz31)+63}$>_AY33mXW^PhRryifs4#m`ly6vkpT& zon5xIyPy6x*~00|Kl3v4%;B3UNR%d1`>fpt1daDRv;PXX;xVM?j=MP&k4jV78 zED4Xu){Zsry>89@>TrV2%G+quZiOg-f&ueA(6=~Yz8=xV{t**M4H z+wjB9lZtW9P=H?S%M2aqr!;=1hK9xWnN{=KDb#G^NSjaI*)vc*ooiqbxuq`h>{P_f z9zq-~nfeeQcYDzWh)EDlXnS1m^*f)f!*;Ull;fD(0~GlMzk}=&mw@2G$#?EuKj~L^ z$8$xTt9Nk!B|l?s?qE*$AT$RAZ?K1M#n9u~Y^vLfmjizAT_$1!8!(xj5%(V|Q5}T| zGCOvQS%^e%3xdGv>}mqu9}m<-_(b1%sL2Tx9i5=B8M6-p$%4veXUp-liX1}(iOGr< z0ZF4p@7vHnvwz03RADlo)BOAnIZemsmDP<(gG|HFit>+Xok7yo1ENddGg&Qe@I!b3 z$ZU+vo9*?WN#hUnRUj)I5M{smPH)A}EXB;ENn^lUmBq3VmKt=9gI%Xg?{4ylQWK|t zX@|LVr7AM%> z&K4a7&CTqTOzr-P^}DeX+A|%vT32Hre!7V4w=YoRzSAfld=v1f+FnX`$_iD6OP4Uw*O(>znnz+-19r10f06{~Y0=J+3$zxplWT;dik zsiSQIS#vS=&g+yTusvwdmKQvk6_5Uf>2hfZasaU`s7WWO+xd*rxKDR93rqo_R%2cDKA;8r2Plb z1{83hpcBDBxq!{g<1_hsRh=Gs$c?_aRPKxq$im)d%+kA9k7@3kvBq9BIg49eGxc{? zfq66zvZ|IE`GY9#NmMgkaY!y+sV7MOcKdTH2I0dk!RAs;ijE-}MwCeM186UBcbnYg zBE`$E&)7J}XAdwzS=#Z(W*kMrJYFx9ge?K0TL$_5BTPaoO483+ShT(xHR3roi(mtp z6VTLnyc5l5d=hDnz zVEhWYGrI*HVBw-TAVDvn?*L~?wL@>LXL0R&9<N@9A1jqo=e4fb&6j~mQ>YG+*Eyt7xOBbjh-0| z%V3dJR+K6b43I5c&T$&vtSq5|iJv_cMou6mh?19JI zH~+-C5bsx90iol?)$6GZGc;4(VX(P+SbZ^}E8E+0_Oh53`xjz}2ocd5Rqe=&SAR>e zxm}`|f{f1o0QCKk^)nS0k8G)bpOCku8iv99YSNO9AAq^MK&;O0_kVHa4t~e3Nhv%79<$CznF7^V9NF$;vwF5!+K^#;F9(%hBAMetdeh zIF}^(95NTWQlzU`@0y3Rujx~P!sGqCTOSx0cEx(=F2>*W)CnM30|FN2LsO9CvK=Y~ z^3*_?A;QE}Eq#Lg_7wjz$A@-8%m)xBhT55V(=zK!B2xKp;DuJX z7F-dQOGA<%=2Z)|9l*hukzMnO&tt_k&iPMU3PHZ;VZSxJ^rVd{Y-0jU!6m>3HZMwG zv3ji|vTpw-?zRoEX6W`5wmU{x9UcBHIEoWdyY)N<&Ui2iaNchr5?sSGwvTthQk7?n zAK1)#*x{33-PWmgSO7nr9Bb|}1a+fAc`pnpUnSiuVl5C2sS-Nk;yi~Ur0G2$5FhoA zYmpMjLAGytUbS%v%o$?@_SVn^)(r!F=6GqsXi97|+~Hi*&P8U&%r%ybYrIM858y!HQjX*{%82t~RMDM- z=V@{&qySB3dn)LYcy7X9yNQ`-ZU@4294Ca>(hHv&no3Z9NEvMK?TI2}&9}~UJBs`M zW$ER@HEid}-Dx>1migJn31OhKqRM%C+d7n{(z(lL=Xg!})*2INCvJ%^%s65UFLSRf z^b$ZjR}rK|Kdum}B|63Q*Se>}<6Yi=2+BA&Eg=jxufajhRDTtsG%%$7)zUMQm<|o~ zu4I!j@1PtdrQo+icL$QVe!w&GHNJ#Q$v2e)5VtIXH(}!|_t$Pc>MFS%+`y6WT$nBh zk(&WS_mm;=DNca5jFN#DR@;XbLL))62t?O7o9!)1Sq^^#PqQju@fv*jaI`jU*gA$YdX~kJH>!bdhF0? z;!A7?DTwbD^Oj&&fY-Ls9Nf9k{(Z5V_3-2StpM014n0Ohw}uMCCgXjJMZB#Ao}yY; z;r9t?g~ESRTO-qd!@FP^$?y=(Z6vh*Ufq#@9ny*LbWIuGo(rjnh0@UlL%IQK6hFHV35pwo$1b!DR0$^&nbtW0-%)-}39ARc@|f&xd^?S67#z zepN;VRLTV+Pc|-6xylXK9$*h(zUg2X|5Kd&92+v(O zbX%xjNd5k>uWZ`fC`)|rkG%Gf-tk3pWi_s0-&=wM@5J3BMzT-pIX~novwngwe4LW}qklR|yRig239{5v&|01}hjsI#i^RrU25h_RTiIgCO=_0ZIy)KwYOLDpJ z{_VOybYExL3G2yX!2Cq@;riaVV(;T#!W-sYvv%6R=7+(dxShzc%?cl~cxk``u+wdp zr&1A1CNY^(hQM1Q5ftQzo<(BV=Q&f2wDK|n#)Cr^Cx=6VVpG{|3})2iP=+hsKRh(? zygr!X38pipJ1(zb^OG2r?{n{Hg-ZGb76_TH(oc#Lh$Q3>s8-N4aliSZ{XPwd|NW`V z9Sg9wR}@HlVV`(kv#7C{l3yg!PVq^4_#9S*?xN?>m+9CyF<{~_NrW+f4=z><0BR3(e8(5~7oI~>!*e0AS4%xl~T z2dpd|qGV~@d<@5f8=(AH)spWJ+lnl6xcr6^B^1CuzInwyg~Og6kmL2hJF(&g6Z|aO=>E!GZcNr!LQ*s$2^2 z;%=;(fyK8(d|Yb%3Fou^Ho;>F^ml8mRILE`;W+z$50qS}WT#l@zl3Y&16;l+ymf(` zr3S!*g#$QPF;B|*{x@FCliFA^eXx&#PW+Kx-fx3R56Wvs$kzIJlJE$9!Y za{**j6oX_NSbj(W|3>`qa{TCSUJNq*QtXTQNgC_jWq|^%?}w*MW#)3mGZ1<(mgiQF z7c+Wo%(3FN28UO~mw0CihC>5Fnzkc1%y$|t8ZI(3#{LYJ+D@W*98;KK z%!F=EB_m8%qA1YDeC#1q>nzLE>02#;+T6MA7!H;(TXk+pwi{_mfo{9X zlkS=_-W$DBqtB@U_JGBinI;06iQl(VmCh+Zm2|wtPt7>_k`Ul*bOj;H(B8E!Q7#VXy|>3h8FkQi+u)sI<2%_ zchgsT=IdBoKDAw3GGdM2Cn>>ktoSYn=;NT?jut_`3hVukVFg4{b^WQcAz2UI4L%rJ z*WLNqOGL1~R9dr(=^Vye&;x6|{}9cVSeEfU4A}4Q-*Y`>+}yN%vDuR*|3Ll%c;$G* zJ9c6L!5*`b`I7;eE`S&9tv`*cJN~j&1ZyrG^1i!lZeb(v{Z$fkRory)dcNu>5D_>* zN|O#&rHvj-|52RbdI4tqXw`zhVG8{I z4sCt5^QSc{aNW|F6F^fBA=ljX1v}ITxe8Cn7|U0dApp9aawi+%5U|#^y9}a#VhQcjflVJR z&ti9sH>ibCWeoEb$_B#5z)&ZWso6LCEOkH)+!1S=S7JIxs`95TpOk9r?tt380^b!}Uv zz0tH~Js&xg+k$uh;~;$~yXlVlLUHRbPN>e}J;$PWPl@0XorMsfXh7AYI5UMN1ee^$ z-@rDxj78#S>W{-)#`~cqW1-dq&}1G+F)vR6!tp#$@HKa4IBs3hH-e21?nb)8IB!<; z4$q>zbwqcY{#>0QeQ)mft&(W@kCW`QulOCDFFsZf{SL2x7U!~1C2w3eAHawtO2D@8 zU+Ngd=Rk#&w#KRaGYel-hwvQ2x#xf~EF^U0dFk)#;S%#=_>9D9mRXrVr%f- z0k^b!l23|xqBRZsZa!qmGoA?$MJEshfBYWEI*dHggX;-uZ1OeF2P(eg@LeGLB-Nd!qPT{%RFn88N(=6hT zq;S%R(!mKZzD^|zcTArd&f^=8wl3oNZ>d=pO_$U<2E>^6BF7ps=swsbhp^S!j&E-T znDQq)Q%!nL`?&*85uCKvFVFD6IR|`KJoC0uCts%r-d&EX@POWh^IX_F*w8#_kejhD z)))EnT>@cL7mXS1ik0W}cbsBrhU@7R=QQzSNei_^Y>M#;}p;OFU`( z&b;lI%jeT+pO14qYvY{^ZErY~Vqp)zu8i_z4L;4~11E0mYiWJ_Hc&hZZrQ9^w8M^Pk z4)k2SGDJqi~`_*xm6^3XGA|VuNoUVMKqtU zN%!LDCwqdMWR)1C64Rune&5D>UmgY>*4QU8;9Fqed-Hs&2heoI%PY>RGew@>t%j`> ztLX^z1jPt!TUgEu2+tTQhq3yb%gfUtSWQ$yip+%-{aJkr$8z_->BVPTe|kIxu{hl4 z$s}S}^D5LY@W`piukpyaCt&7Um<(a=KPG~1EwzPLj)RupbpY6EYWEEb;pLtkFzpCj z#)_H9SJC?jbWV|vThr(i$LS~RW47PipIe_v5(+^R#vYQ zslWVHd58POFc<{G8Cr0W^m?s!+rqR4(9*=YH`@G)od*1K!yh+z>OgY&^*+3u=r@5K29j(v* zubpA0-Gw{OO3^x2l-cb-5Qv@szeWctC=>>PL=Vl4uigy(u|CcEP<$_f1!Z29)1=8- z!C=mM&{F?POuPe(N&L)Y=z2y*s#eC}hXG%~YS~*Esb_`-f}-~<-57RddCYv>!gnmfo`I-qjh|^(mB{++#_8<9{j%xi{gMsprS`*& zn?}Loybb)!4?@OAPg69~kN%g0X`7u4%KF17-I210%L}J%;?CkP0C%>Dn>_?Rl{46DU`#Q3k4Z>Kd3!otu)-ifBnA(z{JJoDrA(7hN)~^(Hy3folWDUE5dD>Bi0%uf>rCV-*5Q)pfaM6kU`^86gflR_eOt~+9V{ZoBlFS2L zt1!y}zH>4^_AHisdPKfB{rSim0ByTz|D%8xk(uK}HG@ayG-BtJIVQ?@09PKx-yiB|Jr zuL)q1i9q&K_74}?@=~iX%ls4X7Ym;DThzhke>iyq@875i5IP+cJmlu9$KMc1;YZCLJo$3<3baSXxJ_WvfXk0D>6gK`u5mA1hcL?QOuld4NP zeJ1*X8JF+F*Q@F_}xe7 zm33+SiLZ$Qz$VmlvEKSEDxrLF)F`_DHG*kgT>$fS?l-F%w5k`56~L&^Az2-`fOBkl z9kTKy$J~-0#dKwf?|~_ksG#HMs*(Wg8tbCz)moGyu-)Q#`#I5xH+4fU@dLZfRTmk8SYN03jRhF^Lv8ny&CX)R$R>Rx*0@-$65h#;|+tO7; zDcv5nrHAGs*z$&={OdIU?^*P?tteC(PoJi2cMCh9zo^ZG@@`?Y$A%wR*3+D$ESntO z$qjV=>b?b02S&0`-u9q8A{#FCx(pml`K=^`No=54^!c&n0QLfKL94evHd z37GCFhy-p~TK%o zFofd*r5m0b$X(ul1UJDg-3bfQK;1m^j(G+Uu1TkZxc3Q`keb*i9e!!b<;CSDtU?B) zf6FXptEZ-!aWL6Av0Cm;rZ`F3caVZ}&**&l5=%8x-%aT>_rk@Rpz){v%@?ycsR0@y zj~C*0)4qFpJgP8B?2oRYvqw^+B(L)6>nF>QIWHYmGxp>DNrhgxGS?OqGIVxzLpxFD z(GbTm_R6eQV)b!_Na^WJN$;PY3V!<93|yd`;#mWt)GNUNyliLjJDwZjQOjQZ5xYRv zOwdJh{XkuF{Rma_j0irvNGWTzngsV0hF&cLpNvoPFNUy=v4=MU@5GXyo3%_l+uQU~ zb83w()CvI~Zr@$Z+S0Rkz|vzkr)VYd8X1;ez>fBw-qUcAJosbU3xsloPwRi)3oS@hbT##y+i81z zY85tnlI<`$q5c7PK7;$@Xk1=RcJ|-A%J$b!!q$x*9fr9QLUU%{&#OdSFh4r<&mNdM zl_`-p`+%x`bT#X6OxS#*jiF9;ei-DTb1n15@Ynd1aYUrRZfje|^Nvck8-p%&S%vho zT?r`;&+cwkfb}r`Tdu>DrTM0v?IU6BN8{=Z$V2r2KG3K6jsyWP(LI#P-u~*ELrwfK zT;*JUuBv=W0sL7TOU7A`rd*lFr7LQdS8I2Wu5s(KORCZ-vI*a8=k8q9B&??3LEZw-(aBXA2{6|bTfxWFHP=rX%u)U$~V|J+&vFGb6N*g zt)h@?ANj9;@$2!p2g`!lEfRyHj(ECpq>erv(}O;awjG_lN(GHPAFZi4D;U7DVi3lW_{se#cU zzby6>YZyIJUgl*t4&5t zY+Veuq`cyF#G(goUnk*eZ-ew79tg`bXr7RQ@`l`*J||VpWCGSI&57{rfzLx0?|8Co z0#5rqMt64xrYLHi55wq8iN))}4{ zsX{NVH5XP=zqqiR@JtkeiM@~e!R46n4a*CCf7`>6Gib5dnMg{~ZZmnuu{MM$$;jne z%lDB=yFh%-OeAaRu+|eM#hiMC=S)_sK8j*x@k&4Q9oCzb><+H^;%4XFKa}2;lGX3<938;-*uMJ5~D{P3z8!5 z4%?Xag#Mi^?66-;Z`Z}sFIr(n8kYqW>?}_%%vgY0Ev44e5vG}{`)}pB&K>n?cZEjO zJP#v&e=!ruWGd+18%|(y4=gERR_4oN)^J@^IxE1FhxA36?O^s6Zs_((mAoY zxn8|&8yt9jw5gX*#Yqbm`txyHunys&!pPi@rLUSZPkM|!BDlrPsrpr+^D_bKzKvXC z_li=QA-gjagwxdB&Y0fOp&4Tz^2u7!9=XmHG1!HXIVe%ekqf0CJREVE|Cw?Sx^Z{i41jdynEh5`eU&P z!|}>QM#YMmGlvV2$9l|{fu9XhyAgA4U?K_kpp7|t&sYJkVA<^{>zG8#XPjpcL4R=9 zv|-#>U)Dul65DIXOL)5Ow4xVA6%s1NyaVz!{&L545}>}!-z_1_ezK1)*JVKJ^xoYaluPG2$n)a`_UJ0`L@M)LTRL%0Y|BITZT@Q=>Vr9g% zA&`OU{>`GcJ(aB39;@byhq-{Sax^&Br}y+H(gu-Xfzz2&Qou{zrG*Udj}T0e`Aj^O zByZzWo}fY0I$(AU6cIQ@JNr1L2r%dP)= zcfaXTgv85l%ieEJuyPtVC}Rrh?i&&NJ=0VkbH5JB+xF&6U-*SAVGz^^<_eQTkx;%6 z;61V=+Ax7g35BSL!BpDX!`8(OgNehg!jfC$i955b{Ogc81+JGB1!mA{{HGmIr<|`_ zFrqKL!vfqiPfrEp~U8h*;nb)k*6Ho1t zt_Z(J(VXUfOlnoqIY5p!VNJLnoxGts0%SU`})OfGEeCwS*tu^f1udy+u%>f4InTB^)Wo)mUcYr~i`N8aw)r8<# z&&S~rQ#pdLA{4FgOu~``ZX3kzEx8TJg4Tm9VHvo(8PO+~_8aq5-}p-lo~9U&aGPA& zuY>h*aO3uC?xZ;|Y7Q~cJRnyWDPIQ;Mt~H*>?mES`|`KpTu-{=78b>hhOgQf@QU5qd7{lh*#uw z_b28nr>}fjxyl{&5Xa>6HgSy3_@XEDVgaE3xD=aA^d*E{tgKd@MBY@)`sbn#a!3ND zcsdN!!YfJr`{75-`cbijV^UuNR<1=cxhtU}DuABi$5u0RY;jXR`i@ja{{z@9v=bnm z967Vn&UxiD6h)8A5+_Nsz^pD2DevXoKHZ0E-}$C=6!p7}YE}@9tV|OELetO7!$Jq0 z3Wes+-7S!>SFF>=(OTZQ&r;g38?7PqP<#}@@PnUq!~DPxC34*G#4+CELhd*e^L7;suGGg9d znjtBuY7A_4ukvqFUzofs_pQ+tpoV)Y$vM5h*kOZUP^qC9$$a^{)RI%TdwxbFamXZk zuT5S^Ld+yK=c#4kzqdhSj;e=SgODn_2b~b#B z$~fCw?VcT|F|xi%6pv|mmIf_SU`)^T-Z@BWRXgkBDk8;rd5+=VV)$ot`7^pQ_R ze5%mW4?1M)Zmscbn4Eq`*SRjIu;=e&(`A0(6tBCT_7-@R-Ku$EbWCOmN`JJFuf#xe zTTlX7w6|qJt|L0_`)Ggv=F2CQXQ4zb3dORwLe15TzqcPZq`Q>r#r7R2W8)!C2Xg2R zJ+-!r-(_K`tG#Oun}Tevc}+;o-;feqbHj$~S@RZ-=2_y5IlWvzpD9Y=B(e{=8bh^1 zct2vF#<5bg)A1UDD!DKfg^?w?Gmv?nkTOxGVn8drV`SICJKVeJgJ9P{x zmEqJF^0~0X!Vjam+H}wMzYIHQuXl^9Aq5HfykoTRyI=5GBdtJMPc&q(xLTCc*Mp0iWsGY6nV!l{#f7M1J7fu)-yw~hleI-KQgy>v8#=mnJ zPim%<>$!AWWSxXHKlxQsyupo~G(y(c{$KFP0|8H5HyVvPzkSvY+fIGp;|QmcCWcqP z1*W--#G+paxtpckM6bM9JV=n)_G@iY0f(eBAKx3&wQ@wW=E?)#Rt1?_uIUw!azlRE zYkUN3s5e1*EirQWRO|`$m;c^OC%^W8tUmq(z4lZfOS|M`q;2YTYOcTuYg!YzPZg><7UDltj?4(QM zq^J?bF(!;E*&H)WzR%5rvCiqt`7zAM>cEM;494`~Ol*Vi62@y$hsjknN2s#b_ZKea zcX+;v;$X+*&QThyGuhxz%L&is8suriJvj=TdF7}r#;V2GwnFTWuft1hBAD;?XR4i? zd2_nP9bVC*H~YLI&_=efX2uNSX)x6>suvZM$O!idq9AeqEy)UNw>o{l&NZQ52=HUe z%R#WgL(zV0P}(l12#{Y2vUlaYhtcR@tpkws+ni=1fzOJ}#)26ncY69aDFL^sIw>8u z#GzHp_Sh5r_cr-g6ug(|v104TCMh7PG;*0K3du6j)Ey z0W={8IReDw=<-Nzramw#YK09RjlSq0o_7xao(KLoX$)D_@k>*cjaGSC0XJq*-sACA zX$)-r z?#L;iH%)nf?VjlVNfYxu4<^lC3?9G<;(tSbBQSw?!i$=vtW7|TNV{!tDPZ;k$N{&F z-0%xu9fsutp@CdyFtogCk*uh0h20gmd=O4({-}f1sKshBbHm>o0DTv&i2}DpG57YX zqLT4Bzu*cv=~ehn^`&i+ueX_JaV<2-A L8)J+iBKH3Q!pLPo literal 0 HcmV?d00001 diff --git a/src/shared/services/img/visito-logo.png b/src/shared/services/img/visito-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e5e02fca2f77c312306fda02b8608b39539684ce GIT binary patch literal 8024 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 Date: Wed, 2 Jun 2021 21:15:06 +0200 Subject: [PATCH 13/14] debuggin new provdiers; more consistent check-out selector --- src/features/check-ins/providerFormLib.ts | 39 ++++++++++------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/src/features/check-ins/providerFormLib.ts b/src/features/check-ins/providerFormLib.ts index b2d7f07b..13abfe2e 100644 --- a/src/features/check-ins/providerFormLib.ts +++ b/src/features/check-ins/providerFormLib.ts @@ -174,24 +174,7 @@ export function fillFormInWebView(values: InjectJSValues) { }; } - function waitForCheckout() { - if (!state.hasCheckOut) { - postMessage('checkOutSuccess'); - state.hasCheckOut = true; - } - } - try { - document.body.addEventListener('mousedown', (ev: any) => { - const el = ev.target?.closest('[data-wfd-action="check-out"], a, button, input, div'); - - if (isCheckOut(el)) { - findProviderLocation(); - setTimeout(waitForCheckout, 0); - window.addEventListener('unload', waitForCheckout); - } - }); - // only once so we don't dispatch more actions // which then re-renders the screen => we might loose the website state setTimeout(() => { @@ -201,14 +184,26 @@ export function fillFormInWebView(values: InjectJSValues) { const checkInterval = setInterval(() => { if (!state.hasFilledInputs && canCheckIn()) { - // Makes sure the bottom of the page has space enough to click on the check-in button - document.body.style.paddingBottom = document.body.style.paddingBottom || '100px'; - fillCheckInForm(); - } else if (isCheckOut()) { + return; + } + + const button = getButton(); + + if (button && isCheckOut(button)) { + clearInterval(checkInterval); + findProviderLocation(); postMessage('checkInSuccess'); - clearInterval(checkInterval); + + button.addEventListener('click', function wait() { + if (!state.hasCheckOut) { + findProviderLocation(); + postMessage('checkOutSuccess'); + state.hasCheckOut = true; + } + button.removeEventListener('click', wait); + }); } }, 1000); } catch (error) { From 3c054cf117359c57c7014660a82623508b5e01c9 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Milla Date: Wed, 2 Jun 2021 21:25:28 +0200 Subject: [PATCH 14/14] release v1.10.0: - WebView back and forward navigation per check-in: #104 and #60 - Custom headers and query string for WebView: - railslove/wfd-masterapp-backlog#26 - railslove/wfd-masterapp-backlog#31 - Confirm scan for new check-in when another one in progress: #105 - Update provider logos --- android/app/build.gradle | 4 ++-- .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 1313 -> 1313 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 1745 -> 1745 bytes .../src/main/res/mipmap-ldpi/ic_launcher.png | Bin 813 -> 813 bytes .../res/mipmap-ldpi/ic_launcher_round.png | Bin 1004 -> 1004 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 1033 -> 1033 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 1379 -> 1379 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 1521 -> 1521 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 2069 -> 2069 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 1999 -> 1999 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 2921 -> 2921 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 2429 -> 2429 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 5869 -> 5869 bytes ios/WFDCheckIn.xcodeproj/project.pbxproj | 4 ++-- ios/WFDCheckIn/Info.plist | 4 ++-- ios/WFDCheckInTests/Info.plist | 4 ++-- package.json | 2 +- 17 files changed, 9 insertions(+), 9 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 57b73476..3d271b55 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -133,8 +133,8 @@ android { applicationId "de.railslove.wfdcheckin" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 29 - versionName "1.9.3" + versionCode 30 + versionName "1.10.0" // Detox testBuildType System.getProperty('testBuildType', 'debug') // This will later be used to control the test apk build type diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index 4821d0671fd40d988453e8cb98fe468b877d8318..9d0ae0888d22a6e84abda890659963a4e4e42e9f 100644 GIT binary patch delta 107 zcmZ3;wUBEAGZQBpldz=Jb+Letn|YWHGKHAw8W@EbT3Q*I0+F_Xft7*5R<60t3=9ma sC9V-ADTyViR=N2pnQ4^_Mg~TPx&~M@90^yo2WnvOboFyt=akR{0OLR#xc~qF delta 107 zcmZ3;wUBEAGZQDP5U()rdhL0gn|YWHGKHAx8d`)H8e17!S{WK^8yHv_7#L39VamY3 tpjzS@QIe8al4_NkpOTqY$zWt)WTc8R{Bf(eQP@{UV?S22WQ%mvv4FO#nAa9eDr% delta 107 zcmcb}dy#iTIuj?W5U((wnbLXV%>_)nEFq@4h87`)##V-wR)!|p1_o9J244)?b~7+A tsFt`!l%ync8R{Bf(a@S}#}3rM;OXk;vd$@?2>|JU8<+q9 diff --git a/android/app/src/main/res/mipmap-ldpi/ic_launcher.png b/android/app/src/main/res/mipmap-ldpi/ic_launcher.png index 9c61ac3f64bb2aaba6f1d0d0c9740ab63e1fda47..99cbfccc816f1b47bd43572bfc72c7181ad83fdc 100644 GIT binary patch delta 86 zcmZ3>ww7%}IwL0=ldz=p0>Omz%>|5^jN)dx21X%ww7%}IwL2m5U()5qw4>qn+q5-8O2R?4J|?pjjaqVtqe`I4GgRd41(Ny`6qv1 Yl2XPZrz~ZmHg98m#3*j2YhV;&XlZ3+YGq`hZD3$!U~uK`ALq&I YnWdDm$SrMf`Og3Zp00i_>zopr0Gmo06aWAK delta 86 zcmaFE{)TPfnY-V=D&FVdQ&MBb@02ccgAOHXW delta 86 zcmeC==;YY&g^`n0h*y};OzFJw=D&4J|?pjjaqVtqe`H4GgRd489n&?Vfyw YSxOm;Tx+f!I|C4Sy85}Sb4q9e00tNq^Z)<= diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png index 26deb6d9d565cd8c2e32ae6aee94cf9c267a7341..564766f522c84fc41966585a1e0eb256b4a595b8 100644 GIT binary patch delta 107 zcmaFN^_XizG!rKqldz=p0>Omz%_&T)nL^BT4U9qzEv<}9t&GgI4GgRd43wt!tYTnb tP%UwdC`m~yNwvz&PsvQHWH2%?GSoG|q9OQ%i5O4=gQu&X%Q~loCIA%e92x)s delta 107 zcmaFN^_XizG!rMQ5U()5qw4>qn^TxpGliJy8d`)H8e17!S{a&Z8yHv_7zDZZ@-r|n tsFt`!l%ync8R{Bf(V#44x*4c}!PC{xWt~$(695ya8>;{S diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 0c56ec1fde40d29485a6b1956ef972678dd14073..fac033ed96d23112d47fb7a64bc28c4a505b77c5 100644 GIT binary patch delta 107 zcmey!{gHb^5fdjHldzeb+_pds44$rjF6*2UngCce9ccgn diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png index 57a78217f2fb372fac079dcc31eeebac1ab987a3..4898b79ae7a02be6cc0a57205174277eae029fde 100644 GIT binary patch delta 107 zcmbO#FjZi~Vw6roZwK6i%HZZUV?Ru6{1-oD!MT)78&qol`;+01^}zWB>pF diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index e1800c46462617a61d48bb1c53fc2713ba3e11f7..8340ec2f53ad20c76e496a076d84486314747d9a 100644 GIT binary patch delta 86 zcmew>^jByDH!~+2ldz=t%H=vfn?;yK*~HCs4U9qzEv<}9t&EJd4GgRd46fZ;v2(Hm Yr<5`lx#jHwtPDWl>FVdQ&MBb@0Mru}Bme*a delta 86 zcmew>^jByDH!~-z5U((|n}_wD%_7XAY~rT6h87`)##V-wR)&V!1_o9J2Fo~B%1n0P Ylv2hbcRf^a0Rs?ty85}Sb4q9e0D%=0)Bpeg diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png index b40b9c9cbdf2c1e9e45a73426dd881c3f254a3ea..8dd9532735f9657054eba9b6847edc5e1fec5d5f 100644 GIT binary patch delta 84 zcmaE>`&M^CA151=u%!6P^J delta 84 zcmaE>`&M^CA1A92uQ0cphxML~)0xD?O?3?|LJW=d#Wzp$P!cQx-x1 diff --git a/ios/WFDCheckIn.xcodeproj/project.pbxproj b/ios/WFDCheckIn.xcodeproj/project.pbxproj index edcf863f..6f4fcbd7 100644 --- a/ios/WFDCheckIn.xcodeproj/project.pbxproj +++ b/ios/WFDCheckIn.xcodeproj/project.pbxproj @@ -525,7 +525,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 29; + CURRENT_PROJECT_VERSION = 30; DEVELOPMENT_TEAM = 5AXEB2NPQJ; ENABLE_BITCODE = NO; INFOPLIST_FILE = WFDCheckIn/Info.plist; @@ -549,7 +549,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 29; + CURRENT_PROJECT_VERSION = 30; DEVELOPMENT_TEAM = 5AXEB2NPQJ; INFOPLIST_FILE = WFDCheckIn/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; diff --git a/ios/WFDCheckIn/Info.plist b/ios/WFDCheckIn/Info.plist index e1f024fb..9bf7bbdd 100644 --- a/ios/WFDCheckIn/Info.plist +++ b/ios/WFDCheckIn/Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.9.3 + 1.10.0 CFBundleSignature ???? CFBundleVersion - 29 + 30 LSRequiresIPhoneOS NSAppTransportSecurity diff --git a/ios/WFDCheckInTests/Info.plist b/ios/WFDCheckInTests/Info.plist index d7e01a38..ec15f25a 100644 --- a/ios/WFDCheckInTests/Info.plist +++ b/ios/WFDCheckInTests/Info.plist @@ -15,10 +15,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.9.3 + 1.10.0 CFBundleSignature ???? CFBundleVersion - 29 + 30 diff --git a/package.json b/package.json index b1f9ccc9..a8590d0d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "private": true, - "version": "1.9.3", + "version": "1.10.0", "scripts": { "ios": "react-native run-ios", "start": "react-native start",