Giter VIP home page Giter VIP logo

mobile's Introduction

COVID Shield Mobile App

Lint + Typscript

This repository implements a React Native client application for Apple/Google's Exposure Notification framework, informed by the guidance provided by Canada's Privacy Commissioners. For more information on how this all works, read through the COVID Shield Rationale.

Overview

This app is built using React Native and designed to work well with patterns on both Android and iOS devices. It works alongside the COVID Shield Diagnosis Server to provide a reference for how a client application for exposure notifications could work.

Screenshots

Three iOS devices showing the default screen, an exposure notification, and the detail screen in COVID Shield mobile app

User Experience

Aurora Design System

COVID Shield follows design and content guidelines from the Aurora Design System published by the Government of Canada's Digital Enablement Service.

Typeface

The Aurora Design System recommends Nunito for the app's main typeface. You can download this font from Google Fonts or access it directly using the Google Fonts integration in Figma.

Inspiration

Our onboarding flow was inspired in part by the work done in this Medium article which is shared under the CC 4.0 license. Thanks to @jelle.prins and @ppkorevaar for their initial work.

Design

Content

Our glossary of terms.

Local development

Prerequisites

Follow the steps outlined in React Native Development Environment Setup to make sure you have the proper tools installed.

Node

iOS

Android

  • Android device with the ability to run the latest version of Google Play Services or Google Play Services Beta. Sign up for beta program here https://developers.google.com/android/guides/beta-program.
  • You also need a whitelisted APPLICATION_ID that will be used to publish to Google Play. You could use APPLICATION_ID from Google Sample App for testing purposes "com.google.android.apps.exposurenotification". Go to Environment config to see how to change APPLICATION_ID.

1. Check out the repository

git clone [email protected]:CovidShield/mobile.git

2. Install dependencies

yarn install
2.1 Additional step for iOS
2.1.1 Install Cocoapods
sudo gem install cocoapods
2.1.2 Install pods
bundle install && yarn pod-install

3. Environment config

Check .env and adjust configuration if necessary. See react-native-config for more information.

Ex:

ENVFILE=.env.production yarn run-ios
ENVFILE=.env.production yarn run-android

4. Start app in development mode

You can now launch the app using the following commands for both iOS and Android.

yarn run-ios
yarn run-android

You can also build the app with native development tool:

  • For iOS, using Xcode by opening the CovidShield.xcworkspace file in the ios folder.
  • For Android, using Android Studio by opening android folder.

Development mode

When the app is running development mode, you can tap on the COVID Shield logo at the top of the app to open the Test menu. This menu enables you to:

  • Put the app into test mode to bypass the Exposure Notification API check
  • Change the system status
  • Change the exposure status
  • Send a sample notification
  • Reset the app to onboarding state

Note that: Test menu is enabled if the environment config file (.env*) has TEST_MODE=true. To disable test mode UI on production build, simply set it to false in the environment config file TEST_MODE=false.

Customization

You can customize the look and feel of the app largely by editing values found in the Theme File

Localization

The COVID Shield app is available in French and English. Fully localized content can be modified by editing translations files found in the translations directory. More translations can be added by using the same mechanism as French and English.

After modifying the content you must run the generate-translations command in order for the app to reflect your changes.

yarn generate-translations

Add new translation

  1. Create a new i18n file in src/locale/translations/.
  2. Add the new option pt in translations.js.
  3. Regenerate the translations yarn generate-translations.
  4. Add the new option in src/components/LanguageToggle.tsx.
  5. Add the new option in src/screens/language/Language.tsx.
  6. Add the new option in Xcode Localizations settings (Project -> CovidShield -> Info tab -> Localizations) and make sure Launch Screen.storyboard is checked.

Test plan

See Test Plan

Who built COVID Shield?

We are a group of Shopify volunteers who want to help to slow the spread of COVID-19 by offering our skills and experience developing scalable, easy to use applications. We are releasing COVID Shield free of charge and with a flexible open-source license.

For questions, we can be reached at [email protected].

Troubleshooting

[Android] Problem with debug.keystore during run Android version

Logs

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:packageDebug'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
   > com.android.ide.common.signing.KeytoolException: Failed to read key AndroidDebugKey from store "/Users/YOUR_USER/.android/debug.keystore": keystore password was incorrect

Generate a new debug.keystore:

cd android/app
keytool -genkey -v -keystore debug.keystore -storepass android -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000

Copy your debug.keystore to ~/.android/debug.keystore:

cd android/app
cp debug.keystore ~/.android/debug.keystore

Now you can run yarn run-android in your root folder.

mobile's People

Contributors

abhiin1947 avatar abubakarsambo avatar alishagiroux avatar ankitsingh1492 avatar annemarieleger avatar burke avatar candidosales avatar emilybulger avatar evanbacon avatar gavrix avatar guillaumegranger1 avatar henrytao-me avatar honkfestival avatar janicduplessis avatar jeffinwithya avatar jordanatshopify avatar jsoref avatar klautcomputing avatar kpeatt avatar owencraston avatar vtim avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mobile's Issues

[Global] Links open a new window without warning

Issue summary

Links which request and external resource open a new window/tab/app without warning the user. This could confuse visually impaired users who believe they are following a link in the same browser/app window which causes extra effort to switch back to the previous window/app.

Screenshots Screen Shot 2020-05-27 at 8 27 53 AM Screen Shot 2020-05-27 at 8 28 17 AM Screen Shot 2020-05-27 at 8 28 38 AM Screen Shot 2020-05-27 at 8 30 42 AM

Current code

TSX

// InfoShareView.tsx

const InfoShareItem = ({onPress, text, icon}: InfoShareItemProps) => (

// …

<TouchableOpacity onPress={onPress}>
  // …
</TouchableOpacity>

// …

<InfoShareItem onPress={onSymptomps} text={i18n.translate('Info.CheckSymptoms')} icon="icon-external-arrow" />

Steps to reproduce

  1. Load the app into the iOS simulator
  2. Expand the Sheet content
  3. Enable VoiceOver screen reader on macOS
  4. Use the Virtual Cursor to navigate through the Sheet controls

Behavior

Expected

  • Links which open a new window/app will be accompanied by a visible and audible warning.

Actual

  • Links open a new window without any warning.

Recommendation

For each link in the app which opens an external resource:

  1. Add the accessibilityLabel prop, setting its value to the control {text} (This is required for accessibilityHint)
  2. Add the accessibilityHint prop, setting its value to a string which warns the user audibly
  3. If no icon is present, include a "new window" icon to convey the warning visually

Recommended code

TSX

// InfoShareView.tsx

const InfoShareItem = ({onPress, text, icon, role, hint}: InfoShareItemProps) => (

// …

<TouchableOpacity onPress={onPress} accessibilityLabel={text} accessibilityHint={hint} accessibilityRole={role}>
  // …
</TouchableOpacity>

// …

<InfoShareItem onPress={onSymptomps} text={i18n.translate('Info.CheckSymptoms')} icon="icon-external-arrow" role="link" hint="opens in a new window" />

Specifications

  • Component: CovidShield [Global]
  • WCAG Principle: Understandable
  • WCAG SC: 3.2.2 On Input
  • Severity: High
  • Effort: High

getDiagnosisKeysWithCompletionHandler

Do we need to write our own code for getDiagnosisKeysWithCompletionHandler on the iOS side? Currently it is just generating what appears to be a fake ENTemporaryExposureKey and not calling ENManager.getDiagnosisKeys

[Global] Missing header structure

Issue summary

View titles are missing a header role. Headers are one of the primary methods of navigation for screen reader user. Without a this role, a user may have difficulty understanding the content structure which could lead to a frustrating user experience.

Screen Shot 2020-05-22 at 12 23 11 PM

Current code

TSX

// NoExposureView.tsx

<Text
  variant="bodyTitle"
  color="bodyText"
  marginBottom="l"
  textAlign="center"
>
  {i18n.translate('Home.NoExposureDetected')}
</Text>

Steps to reproduce

  1. Install the CovidShield apk on an Android device
  2. Load the app
  3. Go to the first screen with the "Covid Shield is ON" card
  4. Enable TalkBack screen reader
  5. Swipe right to navigate to the header text

Behavior

Expected

  • Header text to be announced as a header.

Actual

  • Header role is missing.

Recommendation

  1. For each variant="bodyTitle" content node, include the accessibilityRole prop.
  2. Set the value to header.

Recommended code

TSX

// NoExposureView.tsx

<Text
  variant="bodyTitle"
  color="bodyText"
  marginBottom="l"
  textAlign="center"
  accessibilityRole="header"
>
  {i18n.translate('Home.NoExposureDetected')}
</Text>

Specifications

  • Component: CovidShield [Global]
  • WCAG Principle: Operable
  • WCAG SC: 2.4.6 Headings and Labels
  • Severity: Medium
  • Effort: Low

[Home] Content underneath sheet is available

Issue summary

When the status Sheet is expanded, content underneath the Sheet is still available/focusable via swipe/touch navigation. Mobile screen readers announce this content as if it were a part of the visible Sheet content. This could lead to a confusing user experience.

Screen Shot 2020-05-25 at 2 59 12 PM

Current code

TSX

// BottomSheet.tsx

return (
  <SheetContentsContainer
    isExpanded={isExpanded}
    toggleExpanded={toggleExpanded}
  >
    <>
      {collapsedContentWrapper}
      {expandedContentWrapper}
    </>
  </SheetContentsContainer>
);

Steps to reproduce

  1. Load the app into the iOS simulator
  2. Expand the Sheet content
  3. Enable VoiceOver screen reader on macOS
  4. Use the Virtual Cursor to navigate through the Sheet control

Behavior

Expected

  • Content underneath to not be available via touch/swipe.

Actual

  • Content underneath is available.

Recommendation

A recommendation is not certain at this point. Some experimentation has been conducted on various content containers using the accessibilityViewIsModal prop without success.

Basically, if the isExpanded prop is true, content other than the Sheet should not be available on touch/swipe.

Specifications

  • Component: CovidShield [Home]
  • WCAG Principle: Operable
  • WCAG SC: 2.4.3 Focus Order
  • Severity: Medium
  • Effort: Unknown

[Global] Focus between views not managed

Issue summary

When activating a "Next" control, opening the Sheet, or loading a view, focus remains on the previously activated control. A screen reader user will not have an audible queue of when the new view has loaded.

Additionally, closing a view renders a similar experience. This may lead to a confusing or frustrating user experience.

Steps to reproduce

  1. Load the app in the iOS simulator.
  2. Enable VoiceOver screen reader on macOS
  3. Use the Virtual Cursor to navigate through views throughout the app

Behavior

Expected

  • Focus to shift to the next section heading.

Actual

  • Focus remains on the control.

Recommendation

  1. When activating a control (button or link), shift focus to the next screen heading container.
  2. When closing a view, send focus back to the control which opened the view.

Focus management examples when opening a view:

  • Opening the Sheet should send focus to the "Covid Shield is ON" heading
  • Opening the Change Language view should send focus to the "Language" heading
  • Opening the Privacy view should send focus to the "Privacy policy" heading
  • Opening the Code form view should send focus to the "Please enter you 8 digit…" heading

Examples when closing a view via "Close", "Back", or "Cancel" controls

  • Closing the Sheet should send focus back to the "Open sheet" control
  • Clicking "Back" on the Language view should send focus back to the "Change language" control
  • Closing the Policy view should send focus back to the "Read privacy policy" control
  • Clicking "Cancel" on the Code form view should send focus back to the "Enter code" control

Specifications

  • Component: CovidShield [Global]
  • Related: #7, #4
  • WCAG Principle: Operable
  • WCAG SC: 2.4.3 Focus Order
  • Severity: Medium
  • Effort: Unknown

[Language] Controls missing role and state

Issue summary

The language select controls are missing their role. A role helps to describe what the control is, how to interact with it, and the expected outcome. Each are also missing their current state which is visually conveyed only using a checkmark icon. Screen readers do not convey the role or state which may cause a confusing user experience when interacting with the controls.

Screenshots Screen Shot 2020-05-28 at 2 27 19 PM

Current code

TSX

// Language.tsx

<TouchableOpacity
  onPress={onPress}
>
  <Box
    
  >
    <Text variant="bodyText" marginVertical="s" color="overlayBodyText">
      {text}
    </Text>
    {isActive && (
      <Box alignSelf="center">
        <Icon size={32} name="icon-check" />
      </Box>
    )}
  </Box>
</TouchableOpacity>

Steps to reproduce

  1. Load the app in the iOS simulator.
  2. Open the Sheet view.
  3. Activate the "Change language" control
  4. Enable VoiceOver screen reader on macOS
  5. Use the Virtual Cursor to navigate through the language controls

Behavior

Expected

  • Controls to convey their role and state, both visually and audibly

Actual

  • Control role and state are not conveyed.

Recommendation

  1. Add the accessibilityRole prop, setting its value to radio to convey a radio button control.
  2. Add the accessibilityState prop, setting its value to and object contain the selected boolean state. (Note: the code below does not function as expected – please adjust as required.)
  3. Add the accessibilityRole prop to the Box container, setting its value to radiogroup.

recommended code

TSX

// Language.tsx

<TouchableOpacity
  onPress={onPress}
  accessibilityRole="radio"
  accessibilityState={{selected: {isActive}}}
>
  <Box
    
  >
    <Text variant="bodyText" marginVertical="s" color="overlayBodyText">
      {text}
    </Text>
    {isActive && (
      <Box alignSelf="center">
        <Icon size={32} name="icon-check" />
      </Box>
    )}
  </Box>
</TouchableOpacity>

// …

<Box
  
  accessibilityRole="radiogroup"
>
  <LanguageSelectItem
    
  />
  <LanguageSelectItem
    
  />
</Box>

Specifications

  • Component: CovidShield [Language]
  • WCAG Principle: Perceivable
  • WCAG SC: 1.3.1 Info and Relationships
  • Severity: High
  • Effort: Medium

Inability to hit /retrieve endpoint (Mismatch between app implementation and server protocol)

Hi,

I've deployed the Covid Shield server locally and when I attempt to hit the retrieve endpoint from an Android client running the Covid Shield app I continuously get 404 errors.

The endpoint in question is /retrieve/:region/:datenumber/:hmac

When looking at the server protocol documentation it describes the datenumber as being "UTC timestamp divided (using integer division) by 86400" which increases by 1 with each day at UTC midnight. I believe there is a mismatch between the server documentation here as when I attempt to use the app to make these requests against my local server the datetime is actually the UTC timestamp divided by 3600 and incrementing hourly.

I've included an image of my HTTP proxy showing the requests from my Android client failing.

Thanks!
retrieve_date_number

Use device language setting as default language

The app should use the device language setting as the default language.

Expected: Setting my phone to Français (Canada) puts COVID Shield into the French language.

Reality: Setting my phone to Français (Canada) keeps the app in English.

Cannot start ExposureNotification service on Android

exposureNotificationClient.start() returns status code of 6. It needs to call startResolutionForResult to show consent dialog.

Ex:

        try {
            exposureNotificationClient.start().await()
        } catch (exception: Exception) {
            if (exception !is ApiException) {
                Log.d("custom", "Unknown error")
                throw exception
            }

            if (exception.statusCode == ExposureNotificationStatusCodes.RESOLUTION_REQUIRED) {
                optInCompleter = CompletableDeferred()
                exception.status.startResolutionForResult(
                    this@MainActivity2,
                    REQUEST_CODE_START_EXPOSURE_NOTIFICATION
                )
                optInCompleter?.await()
                optInCompleter = null
                start()
            }
        }

Clicking “Turn on bluetooth” takes you to wrong settings screen [iOS, bug]

What

Clicking "Turn on exposure notifications" or "Turn on bluetooth" from this screen:
IMG_2746

Takes you to this screen in settings:
IMG_2745

However, that is not the correct screen where you can turn on bluetooth. This one is:
IMG_2744

Notes

  • it does not seem to be possible to find the correct screen in the ios simulator, because bluetooth is not supported there

[Localization] EN Settings in different languages

This issue compiles a list of screenshots from iOS across a range of languages to ease translation efforts.

French (Canada)

IMG_0007

IMG_0009

Spanish (Latin America)

IMG_0010

IMG_0011

Simplified Chinese

IMG_0012

IMG_0013

Japanese

IMG_0014

IMG_0015

Dutch (Netherlands)

IMG_0016

IMG_0017

Portuguese (Brazil)

image

[Privacy] Links are not focusable

Issue summary

When using swipe/touch gestures to navigate through the Privacy Policy, content links do not receive focus. Link text is included in the paragraph text with no notice of their existence. This makes accessing content linked from this view impossible for screen reader users and voice dictation users, leading to a frustrating user experience.

Screen Shot 2020-05-25 at 4 57 57 PM

Current code

JS

// react-native-markdown-display/renderRules.js

link: (node, children, parent, styles, onLinkPress) => (
  <Text
    key={node.key}
    style={styles.link}
    onPress={() => openUrl(node.attributes.href, onLinkPress)}
  >
    {children}
  </Text>
);

Steps to reproduce

  1. Load the app into the iOS or Android simulator
  2. Expand the Sheet content
  3. Activate the "Read privacy policy" control
  4. Enable VoiceOver screen reader on macOS
  5. Use the Virtual Cursor to navigate to the view content

Behavior

Expected

  • Links to be focusable, announce its label, and conveyed as a "link".

Actual

  • Links are not focusable.

Recommendation

Since this is a third-party lib, making changes in a timely manner may be difficult. Try to find an alternate markdown renderer, or output the content in a Text component, using Button components with accessibleRole="link" props to output focusable links.

Specifications

  • Component: CovidShield [Privacy]
  • WCAG Principle: Operable
  • WCAG SC: 2.1.1 Keyboard
  • Severity: High
  • Effort: Unknown

Bluetooth and Exposure Notification should be checked separately

What

Bluetooth and Exposure Notification should be checked separately in app

Context

About Bluetooth and Exposure Notification:

  • They are two separate permission / option. You can still turn on EN but turn off Bluetooth.
  • If EN is ON but Bluetooth is OFF, the framework on Android automatically shows a notification asking user to turn it on. User can dismiss the notification without turning it on.
  • If bluetooth is OFF and user dismisses the notification, it is most likely that EN won't work properly.
  • The 1st screenshot shows both EN is OFF and Bluetooth is OFF but my bluetooth is actually ON.
  • The 2nd screenshot shows EN is ON but bluetooth is OFF but in the app, there is no UI saying it is off and needs to turn on.

Google Play Installation

I assume that there are plans to be able to install this eventually through the Play store, right?

Seems like if you have to learn how to build and install this app on your phone manually that there's going to be pretty slow up-take on this.

Any ETA?

[Data Sharing] Focus set on input control on view load

Issue summary

On Share Code view load, focus is sent to the Code input control via autofocus prop. This interferes with the natural focus order of the view content. As a result, the virtual keyboard opens and focus is sent to the 1 key. This may cause confusion or frustration for voice dictation or screen reader users who need to navigate backward to gain context of the current view.

Screenshots

autofocus

Steps to reproduce

  1. Load the app in the iOS simulator.
  2. Open the Sheet view.
  3. Enable VoiceOver screen reader on macOS
  4. Use the Virtual Cursor to navigate to and activate the "Share code" control (Ctrl + Opt + Space)

Behavior

Expected

  • Focus to shift to the view header.

Actual

  • Focus shifts to the input control.

Recommendation

Remove the autofocus attribute on the input control. Allow focus to shift to the header per #12.

Specifications

  • Component: CovidShield [Data Sharing]
  • Related: #7
  • WCAG Principle: Operable
  • WCAG SC: 2.4.3 Focus Order
  • Severity: Medium
  • Effort: Low

咯咯哦

了咯咯个咯咯环境 ** ** ``

Remove illustration from onboarding screen

We're going to drop the illustration from the onboarding screens (picture below). We're running into positioning and accessibility issues with it.

As part of this change, can we vertically centre the content?

Now

Screen Shot 2020-05-28 at 11 25 44 AM

After

Screen Shot 2020-05-28 at 11 26 01 AM

Can't test notification / user being notified status

Hi! I've been testing the last version in master, and the same way as with previous tests, I've not been able to move the app into a "user being notified of possible exposure" status.

Since I don't have developer access yet, I've been trying with Mock Server and Test mode on, and when I click the "Show Sample Notification" button, the notification appears, but the app doesn't seem aware of this change, and stays the same.
Also, when tapping the notification, nothing seems to happen in the app.

Here's a video of it.
https://drive.google.com/file/d/12AapY-EC8-7TfwUTLY_NBMpJ6QXweOl8/view

Any help is appreciated, I'd like to see how the app changes after a user has been notified.

F-Droid installation

Given the privacy-respecting principles underlined within the whitepaper about Privacy-Preserving Contact Tracing one would imagine that being able to install this application in a manner which is similarly respectful of one's privacy (unlike Google Play) might be desirable.

In order to achieve such a result, one could use the F-Droid software repository, which has a reasonably good reputation regarding these matters and reasonable guidelines for developers.

Add configuration for supported languages when deployment

What?

The repo could have a lot of translations, however it might not be necessary to use all of them when deployment. We should have a configuration for:

  • Default language: hardcoded or use device settings.
  • List of supported languages.

If there are only two languages, a toggle should be applied. If there are more than two languages, a picker should be applied.

[Data Sharing] Disabled control does not convey state

Issue summary

The submit Button control is in a disabled state which is visually conveyed only. Screen readers do not convey the disabled state. This may cause a poor or confusing user experience for screen reader users when someone attempts to interact with a "disabled" control.

Screenshots Screen Shot 2020-05-28 at 9 43 24 AM

Current code

TSX

// Button.tsx

if (Platform.OS === 'android') {
  return (
    <Ripple
      rippleContainerBorderRadius={4}
      rippleDuration={500}
      onPress={onPressHandler}
    >
      {content}
    </Ripple>
  );
}
return (
  <TouchableOpacity
    onPress={onPressHandler}
    style={styles.stretch}
    disabled={disabled}
  >
    {content}
  </TouchableOpacity>
);

Steps to reproduce

  1. Load the app in the iOS simulator.
  2. Open the Sheet view.
  3. Activate the "Share code" control
  4. Enable VoiceOver screen reader on macOS
  5. Use the Virtual Cursor to navigate to the submit Button control

Behavior

Expected

  • Controls in a disabled state to convey this information both visually and audibly

Actual

  • Disabled state is not conveyed audibly.

Recommendation

  1. Create a new buttonState object to house the current disabled state.
  2. Add the accessibilityState prop to both Ripple and TouchableOpacity components, setting its value to the new buttonState object.

recommended code

TSX

// Button.tsx
const buttonState = {disabled: disabled};

// …

if (Platform.OS === 'android') {
  return (
    <Ripple
      rippleContainerBorderRadius={4}
      rippleDuration={500}
      onPress={onPressHandler}
      accessibilityState={buttonState}
    >
      {content}
    </Ripple>
  );
}
return (
  <TouchableOpacity
    onPress={onPressHandler}
    style={styles.stretch}
    disabled={disabled}
    accessibilityState={buttonState}
  >
    {content}
  </TouchableOpacity>
);

Specifications

  • Component: CovidShield [Data Sharing]
  • WCAG Principle: Perceivable
  • WCAG SC: 1.3.1 Info and Relationships
  • Severity: High
  • Effort: Low

Exposure Notification status is flashed when reopening the app

What?

EN status is flashed from OFF to ON when reopening the app after EN status is enabled.

Steps to reproduce:

  • Open the app in Android emulator.
  • Go through onboarding flow and make sure EN is enabled.
  • Kill the app and reopen again.
  • Expect EN status stays ON without being OFF initially.

Detect missing translation

What

We have multiple languages now and they could be out of sync pretty quickly. Ex: new string is added en.json but missing in other languages. We need a way to identify new changes and resolves it somehow.

Should show EN consent dialog at the end of onboarding flow

What

  • At the end of onboarding flow, there is a Done button.
  • Tapping on Done button should show EN consent dialog instead of waiting to go to Home screen.

Note

It is not necessary to automatically call start EN service in Home screen anymore. If EN is turned off for some reason, there is already UI for it to turn it back on.

[Home] Overly verbose label

Issue summary

On iOS, when interacting with the Sheet component, its label is the entirety of the collapsed Sheet content. This causes an overly verbose announcement which may lead to a frustrating user experience.

Screen Shot 2020-05-25 at 12 48 04 PM

Current code

TSX

// BottomSheet.tsx

return (
  <TouchableHighlight onPress={toggleExpanded}>{content}</TouchableHighlight>
);

Steps to reproduce

  1. Load the app into the iOS simulator
  2. Enable VoiceOver screen reader on macOS
  3. Use the Virtual Cursor to navigate to the [collapsed] Sheet control

Behavior

Expected

  • Label to be concise and accurate.

Actual

  • Label is overly verbose.

Recommendation

On the TouchableHighlight component, add the accessibilityLabel prop. Set an appropriate label which conveys the control purpose.

Recommended code

TSX

// BottomSheet.tsx

return (
  <TouchableHighlight
    onPress={toggleExpanded}
    accessibilityRole="button"
    accessibilityLabel="Covid Shield is {status}, Tap for more information"
  >
    {content}
  </TouchableHighlight>
);

Specifications

  • Component: CovidShield [Home]
  • Related: #4, CovidShield/portal#66
  • WCAG Principle: Perceivable
  • WCAG SC: 1.3.1 Info and Relationships
  • Severity: Medium
  • Effort: Low

Add watch task for yarn generate-translations

What

Currently, we need to run yarn generate-translations every time we change translations folder src/locale/translations/ and commit the compiled file. It would be better to:

  • Add a watch task to automatically generate it.
  • Ignore compiled file on git to prevent PR conflicts.

[Global] Icon controls missing label

Issue summary

The clickable icon controls are missing a label. A label helps to describe what the control is for by describing its purpose of being. Navigating the app without the label descriptions will lead to a confusing user experience.

Screen Shot 2020-05-22 at 11 56 55 AM

Current code

TSX

// TouchableIcon.tsx

const content = (
  <Box
    width={containerSize}
    height={containerSize}
    justifyContent="center"
    alignItems="center"
  >
    <Icon name={iconName} size={iconSize} />
  </Box>
);

Steps to reproduce

  1. Install the CovidShield apk on an Android device
  2. Load the app
  3. Go to the first screen with the "Covid Shield is ON" card
  4. Enable TalkBack screen reader
  5. Swipe right to navigate to the icon control

Behavior

Expected

  • Controls to be announce with a label description.

Actual

  • Label descriptions are missing.

Recommendation

  1. For each clickable component with an icon, include the accessibilityLabel prop.
  2. Set an appropriate value based on the purpose of the control.

Recommended code

TSX

// TouchableIcon.tsx

const content = (
  <Box
    width={containerSize}
    height={containerSize}
    justifyContent="center"
    alignItems="center"
  >
    <Icon name={iconName} size={iconSize} accessibilityLabel={label} />
  </Box>
);

Specifications

  • Component: CovidShield [Global]
  • WCAG Principle: Understandable
  • WCAG SC: 3.3.2 Labels or Instructions
  • Severity: High
  • Effort: Medium

[Global] Controls are missing roles

Issue summary

Throughout the app, each clickable control is missing a role description. A role helps to describe what the control is, how to interact with it, and the expected outcome. Navigating the app without role descriptions may lead to a confusing user experience.

Current code

TSX

// Button.tsx

if (Platform.OS === 'android') {
  return (
    <Ripple
      
      onPress={onPressHandler}
    >
      {content}
    </Ripple>
  );
}
return (
  <TouchableOpacity
    onPress={onPressHandler}
    
  >
    {content}
  </TouchableOpacity>
);

Steps to reproduce

  1. Install the CovidShield apk on an Android device
  2. Load the app
  3. Enable TalkBack screen reader
  4. Swipe left/right to navigate between content items

Behavior

Expected

  • Controls to be announce with a role description.

Actual

  • Role descriptions are missing.

Recommendation

  1. For each component with an onPress prop, include the accessibilityRole prop.
  2. Set an appropriate value based on the purpose of the control:
    • If its a link, set as link (Does the control request a resource, shift focus, or link out to an external web propert?)
    • If its a button, set as button (Does the control show/hide content, change onscreen data?)

Recommended code

TSX

// Button.tsx

if (Platform.OS === 'android') {
  return (
    <Ripple
      
      onPress={onPressHandler}
      accessibilityRole={role}
    >
      {content}
    </Ripple>
  );
}
return (
  <TouchableOpacity
    onPress={onPressHandler}
    
    accessibilityRole={role}
  >
    {content}
  </TouchableOpacity>
);

Specifications

  • Component: CovidShield [Global]
  • WCAG Principle: Robust
  • WCAG SC: 4.1.2 Name, Role, Value
  • Severity: High
  • Effort: Medium

[Global] Animation persists for reduce motion

Issue summary

The illustrative animations persist when the user has set their Accessibility settings to include the Reduce Motion option as true. The current animation could cause issues for folks with a Vestibular disorder who are susceptible to motion sickness. Animation can also be very distracting for people with a cognitive impairment or who are neurodivergent.

Screenshots Screen Shot 2020-05-27 at 9 51 23 AM Screen Shot 2020-05-27 at 9 51 35 AM

Steps to reproduce

  1. Enable Reduce Motion in iOS (or Android)
  2. Load the app into the iOS simulator
  3. Review animated illustrations

Behavior

Expected

  • Animations to run less frequently.

Actual

  • Animations run at regular iterations.

Recommendation

When Reduce Motion setting is enabled, reduce the frequency of each animated illustration. This will help to provide a less distracting reading experience. This may be possible by using the react-reduce-motion package.

Optionally, consider implementing a Pause Animation button in order to pause all animation throughout the app.

Specifications

  • Component: CovidShield [Global]
  • WCAG Principle: Operable
  • WCAG SC: 2.3.1 Three Flashes or Below Threshold
  • Severity: Medium
  • Effort: Unknown

Configuration option for province/territory selector

Let's add in a configuration option to present a list of provinces/territories to the user before they begin onboarding.

On first open of app: Splash screen > Province / territory selector > Onboarding

It's important that people do not feel like this selection is mandatory, so we've provided a Skip option by default. If the user selects something from the list, the button content changes to Get started.

Screen Shot 2020-06-01 at 11 11 52 AM

Screen Shot 2020-06-01 at 11 12 06 AM

Can't turn on Exposure notifications or Bluetooth

I'm seeing an issue with production iOS and Android builds. TEST_MODE is set to false, and MOCK_SERVER is set to false. I'm running on real hardware. iOS version is 13.5, and Android is version 9, and google play services is the latest, as suggested in your readme. The app is talking to a deployed instance of CovidShield server, which appears to be functioning. This is what I'm seeing:

When getting to the app's home page, COVID Shield is in the "OFF" state. Both the Exposure notifications and Bluetooth tiles are red. When I try to turn on either of those two settings, I'm redirected to the app's settings page, but no permissions are granted, and both tiles remain red.

Enabling Push notifications works, however.

Below are screenshots of the experience on iOS and Android. This might be related to an issue #104 raised yesterday.

Android pics:

image

image

image

iOS pics:

image

image

image

Any ideas?

Dark mode

Offer a dark mode version of the app (images/links wip)

Keyboard not dismissed after typing in code

When you finish typing in the 8th digit of the code, the "submit code" button becomes enabled. When you click the button, the keyboard disappears, but nothing happens. You need to click the button a second time.

Image from iOS

Image from iOS (1)

[Global] Does not support landscape orientation

Issue summary

The app doesn't seem to support landscape orientation on Android devices. On iOS, it's partially supported though some text nodes are not visible.

Supporting landscape orientation is important for people who prefer one orientation to another. Some may not have the physical capability of making an adjustment to their device. Supporting only portrait mode could lead to a frustrating user experience.

Screen Shot 2020-05-22 at 3 37 53 PM

Screen Shot 2020-05-22 at 3 38 15 PM

Steps to reproduce

  1. Install the CovidShield apk on an Android device
  2. Load the app
  3. Adjust to landscape orientation

Behavior

Expected

  • Content to adjust to landscape mode, allowing full use of the app.

Actual

  • App does not switch to landscape mode.

Recommendation

Allow any orientation. Ensure app content, layout, and controls are accessible when switching device orientation.

Specifications

  • Component: CovidShield [Global]
  • WCAG Principle: Perceivable
  • WCAG SC: 1.3.4 Orientation
  • Severity: High
  • Effort: Unknown

Exposure Notification Api Not Enabled on Android

I have tried to run the code in android phone but got the red toasts saying the exposure notification is off. While clicking on the "Turn on exposure notification" button the app was navigated to the App Info view, where there are no options for turning on the exposure notification.

I have tried going to google play services app setting on the phone and manually turned on the exposure notification API, but when running the app the exposure notification client is still not enabled.

Please help, is there any part of the code that I need to change to get it to work? Or is there any step for config that I missed?

[Data Sharing] TextInput control missing role and label

Issue summary

The Code TextInput is missing a role description and a label. A role helps to describe what the control is, how to interact with it, and the expected outcome. A label give the control a name to convey its purpose. Without a role description and label, screen reader and voice dictation users will have great difficulty when filling out the form.

Screenshots

Screen Shot 2020-05-27 at 3 30 01 PM

Current code

TSX

// CodeInput.tsx

<TextInput
  value={value}
  ref={inputRef}
  onChangeText={onChangeTrimmed}
  keyboardType="number-pad"
  
/>
<TouchableWithoutFeedback onPress={giveFocus}>
  // …
</TouchableWithoutFeedback>

// …

const styles = StyleSheet.create({
  input: {
    height: 0,
    width: 0
  },
});

Steps to reproduce

  1. Load the app in the iOS simulator.
  2. Open the Sheet view.
  3. Activate the "Share code" control
  4. Enable VoiceOver screen reader on macOS
  5. Use the Virtual Cursor to navigate to the Code TextInput control

Behavior

Expected

  • Control to be announce with a role description and label.

Actual

  • Role description and label are missing.

Recommendation

  1. To add a label, add the accessibilityLabel prop, setting its value to convey the control purpose.
  2. To convey the role, adjust the StyleSheet of the TextInput to be transparent and positioned overtop of the custom output Text component.
  3. To remove the visible caret, add the caretHidden={true} prop to the TextInput.
  4. To remove the custom output from being focusable, add the accessibilityElementsHidden={true} (for iOS) and importantForAccessibility="no-hide-descendants" (for Android) props to the TouchableWithoutFeedback component.

Recommended code

TSX

// CodeInput.tsx

<TextInput
  value={value}
  ref={inputRef}
  onChangeText={onChangeTrimmed}
  keyboardType="number-pad"
  
  accessibilityLabel="Covid Shield Code"
  caretHidden={true}
/>
<TouchableWithoutFeedback 
  onPress={giveFocus}
  accessibilityElementsHidden={true}
  importantForAccessibility="no-hide-descendants"
>
  // …
</TouchableWithoutFeedback>

// …

const styles = StyleSheet.create({
  input: {
    borderWidth: 0,
    color: 'transparent',
    height: 40,
    left: 15,
    position: 'absolute',
    top: 0,
    width: '100%',
    zIndex: 1
  },
});

Specifications

  • Component: CovidShield [Data Sharing]
  • WCAG Principle: Understandable
  • WCAG SC: 3.3.2 Labels or Instructions
  • Severity: High
  • Effort: Medium

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.