Code Monkey home page Code Monkey logo

skunkworks-crow's Introduction

skunkworks-crow

This project is not actively maintained. It is archived here for reference purposes.

If you wish to maintain it, please contact the ODK team at https://getodk.org.

Overview

Platform License Build status Slack status

Table of Contents

  1. Introduction
    1. About skunkworks-crow
    2. Why skunkworks-crow
  2. Installation and setup
    1. Install and setting up ODK Collect
    2. Install skunkworks-crow
  3. Using skunkworks-crow
    1. Viewing category of forms
      1. View statistics of forms received
      2. View sent forms
      3. View Received forms
      4. Review forms
    2. Send filled forms
      1. hotspot
      2. bluetooth
    3. Receive filled forms
      1. hotspot
      2. bluetooth
  4. Switch Transferring Method
  5. Setting up your development environment
  6. Contributing code

1. Introduction

1.1 About skunkworks-crow

skunkworks-crow is an Android application which is a companion app to ODK Collect and it helps different enumerators to share the filled and blanks forms with each other, it also helps organization’s supervisor in reviewing the forms before actually submitting to the server.

1.2 Why skunkworks-crow

skunkworks-crow is designed to enable offline transfer of blank and filled forms. There are three major use cases for this: multi-part surveys, supervisor review and blank form distribution. ODK Collect is designed in such a way that it allows enumerators to download the blank forms and provide them with the interface to fill the blank forms, but sometimes there can be more than one enumerators who want to fill the same form. Collect doesn’t allow more than one enumerators to collaborate on a single form. This is where skunkworks-crow comes into the picture using skunkworks-crow one can select any number of forms and can send to the other enumerator will all the resources attached to it.

Also, sometimes organizations want to review filled forms before sending to the server. So enumerators can send the forms to the supervisor then the supervisor can mark forms as reviewed (accepted/rejected) with some feedback and then can send back to the same enumerator if required.

In some areas, enumerators don’t have any internet connectivity, so they can’t fetch blank forms from the server. skunkworks-crow also allows to send a blank form in case of no internet connectivity provided the devices should be close enough to create a local connection.

2. Installation and setup

The skunkworks-crow app requires ODK Collect installed on the device first because it uses its database and storage for all its forms transfer.

2.1 Install and setting up ODK Collect

To install ODK Collect visit this link. To know more about ODK Collect visit the documentation page

2.2 Install skunkworks-crow

skunkworks-crow app can be downloaded and installed from the link provided below.

Download APK

3. Using skunkworks-crow

Skunkworks-crow app can be used by enumerators in sharing forms and by supervisor in reviewing the forms.

3.1 Viewing category of forms

On launching the app, the first screen that we see contains a list of forms available in ODK Collect. Tapping on any form opens a screen with 4 tabs - statistics, sent, received, and reviewed.

To view details of any form category tap on any category shown on home screen.

3.1.1 View statistics of forms received

To view the statistics of any specific blank form on the device, tap on any item on the home screen. The statistics screen will show the number of filled forms sent, filled forms reviewed and unreviewed. This will give the supervisor a glimpse of all the details of form transfer that happened through the device.

3.1.2 View sent forms

To view the details of the form sent from the device, navigate to ‘Sent’ tabs, the screen shows the details of sent filled forms. If any forms were sent for a review and the supervisor sent back the forms with feedback, then the user will be able to see the form reviewed status with feedback.

3.1.3 View Received forms

To view the details of forms received, navigate to the ‘Received’ tab. To review the forms, tap on any received form to open the filled form in ODK Collect. After viewing the form, the user will be navigated to a screen asking for feedback and can mark the form as approved or rejected. If the user is not ready to provide feedback, he can review later tap by tapping “Review later”. Using this option user will be navigated back to the receive screen so that user can review other forms. If supervisor already opened the form previously then the user will be navigated to a feedback screen directly. If the supervisor wants to view the form again then he can tap on “View from in ODK Collect” to view it again.

3.1.4 Review forms

To view the details of forms reviewed, tap on the ‘Reviewed’ tab. This shows all the forms reviewed by you with the form status. To send it back to the enumerator who asked for the feedback, select the forms and tap on ‘Send’. This will send all the forms with reviewed status as well as feedback back to the enumerator. If the enumerator didn’t send those forms for review then it won’t send any forms back, only those enumerators will get the feedback who asked for it.

3.2 Send filled forms

After the launch of the app, on the home screen a 'Send' button is shown at the bottom. Tap on that button to open the screen which consists of a list showing all the filled forms available in ODK Collect and user can select any number of forms of any version of blank form which is required to be sent. It contains all the filled forms irrespective of its send/receive status.

It will display all the filled forms available in ODK Collect (it also contains the received forms so that user can pass that to another enumerator for further form filling)

After selecting the forms, press ‘Send’ to initiate the connection process so that receiver can connect to your device and start receiving.

Tapping on ‘Send’ button opens up the screen which will initiate the communication process and start the wifi hotspot so that receiver can connect to it and start receiving the forms.

In the Skunkworks-crow, forms can be exchanged using either Wifi Hotspot or Bluetooth. The default preference for the transferring method can be modified through the settings page.

3.2.1 Wifi Hotspot

A Wifi Hotspot is used as the sender’s communication method, which creates a wifi network and sends files using the socket connection. When the wifi hotspot is initiated, it turns off the wifi if already enabled and creates new wifi configuration and saves the last saved hotspot configuration which is restored at the end of a transfer.

If hotspot initiation is successful then the screen will show the QR Code generated so that receiver can scan the QR Code to connect to it and start receiving the forms.

If user wants to manually connect to it then the screen shows the network name so that user can connect to it by tapping on the network, and after wifi is connected it will ask for a port number which is required to create the connection.

For devices having Android version 7.0 and 7.1 user will be sent to settings to enable the wifi hotspot functionality. The user will then need to tap the device back button to come back to skunkworks-crow. And for other device it will be enabled automatically.

3.2.2 Bluetooth

The bluetooth has a shorter transferring distance than hotspot, so you may need to put sender and receiver closed to establish a valid connection. In the receiver's settings page, you can enable the secure mode of bluetooth, it allows you to establish an encrypted transmission (needs a pair code when first pairing).

The bluetooth feature needs location permission. After a bluetooth socket was create, you will see a dialog to ask to make your device discoverable, after clicking that, You have 120s to let the receiver connect. Our application will automatically start data transfer if the bluetooth connection is successful.

3.3 Receive filled forms

3.3.1 Wifi Hotspot

Tap on the 'Receive' button shown at the bottom of the home screen to see a list of all wifi networks available in the nearby area which are started by only skunkworks-crow app.

A receiver will need to connect to the network the sender has created. There are two ways to connect to the network: A QR code generated by the sender that can be scanned by a receiver, it will get all the information required to connect to the sender (wifi name, port, and password if the connection is protected). Or else, tap on the wifi network available to connect and after successful connection enter port number to start receiving the forms.

Connecting to the sender’s network will disable all the wifi network available so that no other network can interrupt the current connection. After receiving the forms it will restore the last saved state.

For some devices, the user is not allowed to configure the wifi hotspot from the app. Currently for Android versions < 8, “ODK-SKUNKWORKS-odk-skunkworks” is set as the default network name and for versions >= 8 it is AndroidShare-XXXX which is set by Android.

3.3.2 Bluetooth

If we use bluetooth to receive forms, you can find a bluetooth device list in the receiver page. Just clicking the sender's item, the Skunkworks-crow will connect and start receiving once connected. You can click the refresh button to refresh the list if you cannot find your target sender.

4. Switch Transferring Method

We have two methods to use, you can set a default method in settings. But when you have trouble sending/receiving forms, you can click the switch icon button in the tool bar, that offers a quick way for you to switch from this method to another.

If you changed the method of sender/receiver, don't forget to be consistent with another device.

5. Setting up your development environment

  1. Download and install Git and add it to your PATH

  2. Download and install Android Studio

  3. Fork the Skunkworks-crow project (why and how to fork)

  4. Clone your fork of the project locally. At the command line:

     git clone https://github.com/YOUR-GITHUB-USERNAME/skunkworks-crow
    

    If you prefer not to use the command line, you can use Android Studio to create a new project from version control using https://github.com/YOUR-GITHUB-USERNAME/skunkworks-crow.

  5. Open the project in the folder of your clone from Android Studio. To run the project, click on the green arrow at the top of the screen.

6. Contributing code

Any and all contributions to the project are welcome. Skunkworks-Crow is used across the world primarily by organizations with a social purpose so you can have real impact!

Issues tagged as good first issue should be a good place to start. There are also currently many issues tagged as needs reproduction which need someone to try to reproduce them with the current version of Skunkwork-Crow and comment on the issue with their findings. If you're ready to contribute code, see the contribution guide.

skunkworks-crow's People

Contributors

ajay-prabhakar avatar devanshi7799 avatar dreamyphobic avatar huangyz0918 avatar iadeelzafar avatar iamvasuh avatar jasonrogena avatar kabhijeet2105 avatar konishon avatar lakshyagupta21 avatar lognaturel avatar manit-alokgupta avatar naman653 avatar prajurock avatar rkodev avatar rohap97 avatar saumiasinghal avatar shobhitagarwal1612 avatar shubhamkumar1739 avatar sushmita0810 avatar udhay24 avatar yanokwa 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

skunkworks-crow's Issues

Handle cancel event of Async Tasks

Noticed in PR #25
Not able to send/receive forms if a user tries again after an activity is destroyed by pressing back button or cancel button of a progress bar.

New Async task won't start until the previous one gets finished. So need to handle the cancelling event of Async tasks.

Screen for showing stats, sent, received, review forms

Create screen with tabs that show statistics, sent forms, received forms, reviewed forms, etc.
I've added 2-3 wireframes showing different options of selection i.e, Selection on long tap and checkbox
I wanted to know which option would be preferable.

22
33
11

SQLiteConnection leaked

On Android 4.1.1 and master, I get a constant stream of the following error in logcat:

W/SQLiteConnectionPool(12326): A SQLiteConnection object for database '/storage/sdcard0/odk/metadata/forms.db' was leaked! Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.

Confirm sending can work with Samsung devices

I can't get the Samsung Galaxy Tab A that I have to send. In conversation with @lakshyagupta21 it sounded like Samsung may limit configurability of hotspots. Initially he thought there might be a way around it but it's still not working for me. Samsung devices are the most popular ones for ODK users so there should be a path to them being able to share forms this way.

First step is to figure out whether this is in fact a Samsung-wide limitation. See what I'm experiencing at #51. Note this also happens with an older Alcatel device I have.

Unable to set the wifi hotspot name in android oreo

In android oreo, only system apps which are signed and have the below permission can change the configuration.

<permission
        android:name="android.permission.OVERRIDE_WIFI_CONFIG"
        android:protectionLevel="signature|privileged" />

https://stackoverflow.com/questions/46392277/changing-android-hotspot-settings

So, this causes a problem if the sender is unable to change the name and uses that name to create the QR Code which later fails due to mismatch.
Since there is no way to change the name, I suggest we provide a setting to configure hotspot name in setting for devices < Oreo and read the actual wifi hotspot name after turning it on to create the QR code or writing instructions

Main Screen to show all the forms available

  1. Show all the forms available in device.
  2. Tapping on any category will open a activity which will show instances of that category only.
  3. Add send and receive buttons to send the forms (Activity will show all the instances of all the forms)

3

Write up status, lessons learned and next steps

This will be great for the community to see on the forum. It should link to the APK on Github in addition to saying user documentation is available in the readme.

Is the community or development category a better place? Or somewhere else?

"Successfully received 0 form(s)" message doesn't make sense

I'm not sure how to reproduce this but it's currently happening consistently with two of my devices. After I pick a filled form to send, the sender is showing the QR code and port number. The receiver successfully connects. The sender doesn't show a dialog but the receiver shows "Successfully received 0 form(s)".

It seems like something went wrong though I don't know what. In general, it seems that if the receiver gets 0 forms, it should show an error message rather than a success message.

Adding README

@lakshyagupta21 In your GSoC proposal you have defined the goals and purpose of this project really well. It would be really cool if you can update the README with some of the relevant information from there

Give users the option to archive transferred filled forms

As a survey manager, I would like to instruct enumerators to "move" filled forms from their device to another device rather than copying them. I would like to be able to retrieve filled forms from the original device in case some transfer error occurs.

I was talking to a user today who maintains https://github.com/Last-Mile-Health/ODK-Liberia, a fork of Collect with bluetooth transfer capabilities. They would like to move off of their fork and are very excited about Share. One of their requirements is that when User A sends a filled form to User B, it no longer appears in their Edit Saved Form list. They achieve this by moving filled forms to an archive folder in the odk folder upon transfer. That way they don't show up but can still be retrieved if something goes wrong.

This doesn't need to be completed by the end of summer @lakshyagupta21 but I wanted to make sure we kept track of the requirement.

Provide more feedback and/or instructions when attempting to send

When I set a device to send, I see "Waiting for connection to accept". I'm not sure what action I need to take. It seems unclear what I'm waiting for. Maybe it could say that the other device needs to tap on the receive button and to connect to the network?

Eventually, the receiver gets a message to enter port number. I no longer see any way to see the port number so I can't establish a connection.

Connect hotspot by scanning QR Code

  1. Add functionality to generate QR Code for hotspot - QR Code can contain two or three attributes depending on whether wifi is protected or not. Three attributes -> ssid, isProtected, password
  2. Add functionality to scan the QR code in WifiActivity so that hotspot can be connected.

After being in receiving mode, wifi is disabled in settings

  1. Connect to a wifi network from settings
  2. Launch Share and tap on the "receive" button
  3. Scan for a connection, no connection is found
  4. Tap the back button

Wifi is now disabled. Ideally it would be back in the state it was in prior to using Share. This is important for enumerators who may not be very mobile-savvy and need the internet connection for sending forms.

Add About screen

Add some information about the the open source libraries and the code which is being used in Share.

Receiver hangs on "Connecting to wifi"

Continuing from #54 (comment).

I can reproduce this consistently with the Alcatel One Touch / Android 4.1.1 device receiving. It also seems to happen sporadically on other devices after updating versions.

The devices hang on the "Connecting to wifi" dialog and there is no way to exit other than killing the app. The back button is disabled. Before that it flashes a "already connected" toast.

I'm not certain this is related but on the One Touch, after a while I got:

07-19 21:48:28.886 13902-13902/org.odk.share E/WifiActivity: java.lang.IllegalArgumentException: Receiver not registered: org.odk.share.activities.WifiActivity$8@417e6710
        at android.app.LoadedApk.forgetReceiverDispatcher(LoadedApk.java:654)
        at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:1214)
        at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:378)
        at org.odk.share.activities.WifiActivity.onStop(WifiActivity.java:183)
        at android.app.Instrumentation.callActivityOnStop(Instrumentation.java:1210)
        at android.app.Activity.performStop(Activity.java:5158)
        at android.app.ActivityThread.handleSleeping(ActivityThread.java:3289)
        at android.app.ActivityThread.access$2700(ActivityThread.java:181)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1510)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:153)
        at android.app.ActivityThread.main(ActivityThread.java:5042)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:821)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:584)
        at dalvik.system.NativeStart.main(Native Method)

Error opening forms in collect

Instances file path is not entered correctly in instances db.

Actual file path: /storage/emulated/0/share/instances/N_Biggest_2018-07-14_23-21-47
Expected file path: /storage/emulated/0/odk/instances/Biggest N of Set_2018-07-14_23-21-47/Biggest N of Set_2018-07-14_23-21-47.xml

Storing received instance detail in collect's instance db

Storing the downloaded instance detail in instance.db in odk/metadata may create some confusion.

Currently, it is being stored in instances.db because of one use case i.e. when a user wants to share the form without any feedback. But it can create some confusion because the forms will also appear in collect.

Two possible solutions

  1. Archiving the instances sent/received. (Issue #27)
  2. Add a setting to adjust the behaviour according to user needs.

Add usage instructions to README

A first pass in the README would be great. It should include a few screenshots where helpful but not so many that they're hard to keep up to date.

Some of the information to include:

  • Who is it for?
  • Typical connection workflows
  • Troubleshooting common issues
  • Known limitations

Receiver not registered crash

Alcatel OneTouch, Android 4.1.1. When receiving and not finding a network, after some time, Share crashes with:

07-19 21:48:28.886 13902-13902/org.odk.share E/WifiActivity: java.lang.IllegalArgumentException: Receiver not registered: org.odk.share.activities.WifiActivity$8@417e6710
        at android.app.LoadedApk.forgetReceiverDispatcher(LoadedApk.java:654)
        at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:1214)
        at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:378)
        at org.odk.share.activities.WifiActivity.onStop(WifiActivity.java:183)
        at android.app.Instrumentation.callActivityOnStop(Instrumentation.java:1210)
        at android.app.Activity.performStop(Activity.java:5158)
        at android.app.ActivityThread.handleSleeping(ActivityThread.java:3289)
        at android.app.ActivityThread.access$2700(ActivityThread.java:181)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1510)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:153)
        at android.app.ActivityThread.main(ActivityThread.java:5042)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:821)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:584)
        at dalvik.system.NativeStart.main(Native Method)

If portable hotspot configuration fails, no feedback is given

On two of the devices I've tried (Galaxy Tab A and Alcatel One Touch 5020D, details at https://github.com/opendatakit/collect#contributing-testing), when I tap "Send" and select filled forms, I go straight to a screen that shows "Waiting for connection to accept". What does this state means? It looks like it's not possible to set up a hostpot on those devices? I don't get promtped to enable from the settings.

On the Moto G4 I do get prompted to enable the hotspot from settings. Then I see the QR code and port number information.

Add user documentation

A first pass in the README would be great. It should include a few screenshots where helpful but not so many that they're hard to keep up to date.

Some of the information to include:

  • Who is it for?
  • Typical connection workflows
  • Troubleshooting common issues
  • Known limitations

Add a unique identifier with the form

Add some unique id with the form and send so that when it comes after review, it can be checked if it already exists in DB or not (if that instance is sent for some review then receive review otherwise display that no such form sent for review)

Crash when going back from stats screen

To reproduce go to Share home screen with a list of forms. Click one form. You will now be at the statistics page. Press back and there will be a crash.

java.lang.RuntimeException: Unable to resume activity {org.odk.share/org.odk.share.activities.MainActivity}: android.database.StaleDataException: Attempted to access a cursor after it has been closed.
	at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3421)
	at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3461)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1523)
	at android.os.Handler.dispatchMessage(Handler.java:102)
	at android.os.Looper.loop(Looper.java:154)
	at android.app.ActivityThread.main(ActivityThread.java:6123)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)
aused by: android.database.StaleDataException: Attempted to access a cursor after it has been closed.
	at android.database.BulkCursorToCursorAdaptor.throwIfCursorIsClosed(BulkCursorToCursorAdaptor.java:63)
	at android.database.BulkCursorToCursorAdaptor.getCount(BulkCursorToCursorAdaptor.java:69)
	at android.database.CursorWrapper.getCount(CursorWrapper.java:60)
	at org.odk.share.activities.MainActivity.onLoadFinished(MainActivity.java:138)
	at org.odk.share.activities.MainActivity.onLoadFinished(MainActivity.java:34)
	at android.support.v4.app.LoaderManagerImpl$LoaderObserver.onChanged(LoaderManagerImpl.java:248)
	at android.arch.lifecycle.LiveData.considerNotify(LiveData.java:109)
	at android.arch.lifecycle.LiveData.dispatchingValue(LiveData.java:126)
	at android.arch.lifecycle.LiveData.setValue(LiveData.java:282)
	at android.arch.lifecycle.MutableLiveData.setValue(MutableLiveData.java:33)
	at android.support.v4.app.LoaderManagerImpl$LoaderInfo.setValue(LoaderManagerImpl.java:188)
	at android.support.v4.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManagerImpl.java:173)
	at android.support.v4.content.Loader.deliverResult(Loader.java:130)
	at android.support.v4.content.CursorLoader.deliverResult(CursorLoader.java:107)
	at android.support.v4.content.CursorLoader.onStartLoading(CursorLoader.java:153)
	at android.support.v4.content.Loader.startLoading(Loader.java:283)
	at android.support.v4.app.LoaderManagerImpl$LoaderInfo.onActive(LoaderManagerImpl.java:76)
	at android.arch.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:410)
	at android.arch.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:368)
	at android.arch.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:354)
	at android.arch.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:292)
	at android.arch.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:332)
	at android.arch.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:137)
	at android.arch.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:123)
	at android.arch.lifecycle.ReportFragment.dispatch(ReportFragment.java:121)
	at android.arch.lifecycle.ReportFragment.onStart(ReportFragment.java:81)
	at android.app.Fragment.performStart(Fragment.java:2378)
	at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1027)
	at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1171)
	at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1153)
	at android.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:2046)
	at android.app.FragmentController.dispatchStart(FragmentController.java:187)
	at android.app.Activity.performStart(Activity.java:6695)
	at android.app.Activity.performRestart(Activity.java:6763)
	at android.app.Activity.performResume(Activity.java:6768)
	at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3398)

QR code scanner is not easily accessible

On the sending side, the QR code is nice and big and looks like the primary way to initiate the connection. On the receiver side, the scanner is hidden in the overflow menu.

I see a few options:

  • use icons for wifi scanning vs QR code scanning so they both fit
  • move the two options into the main view so they're more visible
  • show the QR code scanner by default with an alternate option to look for networks

Clarify that blank list messages are about filled forms

When the detail tabs for forms are selected but no filled forms have yet been transferred using Share, there are default messages as follow:

  • Sent: "Not sent any form"
  • Received: "Not received any form"
  • Reviewed: "Not finalized any received form"

I propose something like the following changes:

  • Sent: "No filled "<form name>" forms sent"
  • Received: "No filled "<form name>" forms received"
  • Reviewed: "No finalized "<form name>" forms received"

e.g. No filled "All Widgets" forms sent

The goal is to provide users with more context on what will eventually appear there.

Clarify what is being shown after tapping Send

After tapping "Send," the list of forms is replaced by a list of filled forms. This is not very clear. Maybe the title could be something like "Filled forms to send" or something like that to provide the user with more context on where they are and what action they can now take.

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.