Browse Source

Added disabled button appearance. Fixed login bug (typo). Moved app-level stuff to App.java instead of MainActivity. Implemented some global observable variables. Added loading state to WithdrawFragment. Fixed Resources.getSystem().getString() bug. Fixed AsyncTasks callback bug. Refactored.

Víctor Hernández 3 years ago
parent
commit
785ef8ea88
25 changed files with 550 additions and 283 deletions
  1. 2
    2
      app/src/main/AndroidManifest.xml
  2. 90
    0
      app/src/main/java/uprrp/tania/App.java
  3. 64
    0
      app/src/main/java/uprrp/tania/GlobalValues.java
  4. 0
    36
      app/src/main/java/uprrp/tania/MarleApplication.java
  5. 0
    2
      app/src/main/java/uprrp/tania/MyFirebaseMessagingService.java
  6. 4
    2
      app/src/main/java/uprrp/tania/SendLoginToServer.java
  7. 75
    35
      app/src/main/java/uprrp/tania/activities/ExperienceRegistrationActivity.java
  8. 1
    41
      app/src/main/java/uprrp/tania/activities/MainActivity.java
  9. 168
    90
      app/src/main/java/uprrp/tania/fragments/AssessmentsFragment.java
  10. 71
    26
      app/src/main/java/uprrp/tania/fragments/WithdrawFragment.java
  11. 19
    3
      app/src/main/java/uprrp/tania/models/UserStatusModel.java
  12. 3
    5
      app/src/main/java/uprrp/tania/networking/FetchAssessment.java
  13. 2
    4
      app/src/main/java/uprrp/tania/networking/FetchUserStatus.java
  14. 3
    4
      app/src/main/java/uprrp/tania/networking/SendAnswers.java
  15. 3
    4
      app/src/main/java/uprrp/tania/networking/SendExperienceRegistration.java
  16. 3
    4
      app/src/main/java/uprrp/tania/networking/SendWithdrawal.java
  17. 1
    1
      app/src/main/java/uprrp/tania/unused/AppPrefs.java
  18. 1
    1
      app/src/main/java/uprrp/tania/unused/CognitoSettings.java
  19. 7
    4
      app/src/main/res/drawable/button_background.xml
  20. 12
    0
      app/src/main/res/drawable/button_disabled.xml
  21. 4
    3
      app/src/main/res/layout/activity_experience_registration.xml
  22. 4
    5
      app/src/main/res/layout/fragment_assessments.xml
  23. 3
    2
      app/src/main/res/layout/fragment_withdrawal.xml
  24. 1
    1
      app/src/main/res/values/colors.xml
  25. 9
    8
      app/src/main/res/values/strings.xml

+ 2
- 2
app/src/main/AndroidManifest.xml View File

7
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
7
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
8
 
8
 
9
     <application
9
     <application
10
-        android:name=".MarleApplication"
10
+        android:name=".App"
11
         android:allowBackup="true"
11
         android:allowBackup="true"
12
         android:icon="@mipmap/ic_launcher"
12
         android:icon="@mipmap/ic_launcher"
13
         android:label="TANIA"
13
         android:label="TANIA"
45
             android:windowSoftInputMode="adjustResize" />
45
             android:windowSoftInputMode="adjustResize" />
46
         <activity
46
         <activity
47
             android:name="org.researchstack.backbone.ui.ViewWebDocumentActivity"
47
             android:name="org.researchstack.backbone.ui.ViewWebDocumentActivity"
48
-            android:label="@string/app_name"
48
+            android:label="@string/appName"
49
             android:parentActivityName=".activities.MainActivity"
49
             android:parentActivityName=".activities.MainActivity"
50
             android:theme="@style/Theme.MarleApp" />
50
             android:theme="@style/Theme.MarleApp" />
51
         <activity
51
         <activity

+ 90
- 0
app/src/main/java/uprrp/tania/App.java View File

1
+package uprrp.tania;
2
+
3
+import android.app.Application;
4
+import android.content.Intent;
5
+import android.content.SharedPreferences;
6
+import android.util.Log;
7
+import android.widget.Toast;
8
+
9
+import androidx.annotation.NonNull;
10
+
11
+import com.amazonaws.auth.CognitoCachingCredentialsProvider;
12
+import com.amazonaws.regions.Regions;
13
+import com.google.android.gms.tasks.OnFailureListener;
14
+import com.google.android.gms.tasks.OnSuccessListener;
15
+import com.google.firebase.iid.FirebaseInstanceId;
16
+import com.google.firebase.iid.InstanceIdResult;
17
+
18
+import org.researchstack.backbone.StorageAccess;
19
+import org.researchstack.backbone.storage.database.AppDatabase;
20
+import org.researchstack.backbone.storage.database.sqlite.DatabaseHelper;
21
+import org.researchstack.backbone.storage.file.EncryptionProvider;
22
+import org.researchstack.backbone.storage.file.FileAccess;
23
+import org.researchstack.backbone.storage.file.PinCodeConfig;
24
+import org.researchstack.backbone.storage.file.SimpleFileAccess;
25
+import org.researchstack.backbone.storage.file.UnencryptedProvider;
26
+
27
+import uprrp.tania.activities.GettingStartedActivity;
28
+
29
+public class App extends Application {
30
+
31
+    private static final String TAG = "App";
32
+
33
+    @Override
34
+    public void onCreate() {
35
+        super.onCreate();
36
+
37
+        // Customize your pin code preferences
38
+        PinCodeConfig pinCodeConfig = new PinCodeConfig(); // default pin config (4-digit, 1 min lockout)
39
+
40
+        // Customize encryption preferences
41
+        EncryptionProvider encryptionProvider = new UnencryptedProvider(); // No pin, no encryption
42
+
43
+        // If you have special file handling needs, implement FileAccess
44
+        FileAccess fileAccess = new SimpleFileAccess();
45
+
46
+        // If you have your own custom database, implement AppDatabase
47
+        AppDatabase database = new DatabaseHelper(this,
48
+                DatabaseHelper.DEFAULT_NAME,
49
+                null,
50
+                DatabaseHelper.DEFAULT_VERSION);
51
+
52
+        StorageAccess.getInstance().init(pinCodeConfig, encryptionProvider, fileAccess, database);
53
+
54
+        // We need to know if the user has already registered, otherwise they need to do that first
55
+        SharedPreferences prefs = getSharedPreferences("prefs", MODE_PRIVATE);
56
+        boolean needsToRegister = prefs.getBoolean("needsToRegister", true);
57
+        if(needsToRegister) {
58
+            Intent needsRegisterIntent = new Intent(this, GettingStartedActivity.class);
59
+            startActivity(needsRegisterIntent);
60
+        }
61
+
62
+        // Enable notifications
63
+        CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
64
+                getApplicationContext(),
65
+                getString(R.string.identityPoolID), // Identity pool ID
66
+                Regions.US_EAST_1 // Region
67
+        );
68
+        SNSRegister snsRegister = new SNSRegister(credentialsProvider);
69
+        snsRegister.execute();
70
+
71
+        // Get device token (store globally
72
+        FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
73
+            @Override
74
+            public void onSuccess(InstanceIdResult instanceIdResult) {
75
+                String token = instanceIdResult.getToken();
76
+                GlobalValues.getInstance().setDeviceToken(token);
77
+                Log.d(TAG, "Got token: " + GlobalValues.getInstance().getDeviceToken());
78
+            }
79
+        }).addOnFailureListener(new OnFailureListener() {
80
+            @Override
81
+            public void onFailure(@NonNull Exception e) {
82
+                GlobalValues.getInstance().setDeviceToken(null);
83
+                Toast.makeText(getApplicationContext(), "Couldn't retrieve token!", Toast.LENGTH_LONG).show();
84
+                Log.e(TAG, "Error occurred while retrieving token...");
85
+                e.printStackTrace();
86
+            }
87
+        });
88
+
89
+    }
90
+}

+ 64
- 0
app/src/main/java/uprrp/tania/GlobalValues.java View File

1
+package uprrp.tania;
2
+
3
+import androidx.annotation.Nullable;
4
+
5
+import java.util.Observable;
6
+
7
+import uprrp.tania.models.UserStatusModel;
8
+
9
+// TAKEN FROM https://stackoverflow.com/questions/21886768/is-there-any-method-i-can-listen-for-changes-to-global-variable-to-trigger-an-ev
10
+public class GlobalValues extends Observable {
11
+
12
+    private static GlobalValues mInstance = null;
13
+
14
+    public static GlobalValues getInstance() {
15
+        if(mInstance == null) {
16
+            mInstance = new GlobalValues();
17
+        }
18
+        return mInstance;
19
+    }
20
+
21
+    // WHENEVER ADDING ANOTHER GLOBAL VARIABLE...
22
+    // 1. ADD ITS NAME IN ValueName
23
+    // 2. ADD A DECLARATION (AND INITIALIZATION; OPTIONAL)
24
+    // 3. ADD A GETTER AND A SETTER (TAKE A GOOD LOOK AT THE SETTER)
25
+    public enum ValueName {
26
+        DEVICE_TOKEN,
27
+        USER_STATUS,
28
+    }
29
+
30
+    public static class ValueKey {
31
+        private final ValueName mValueName;
32
+        public ValueKey(ValueName valueName) {
33
+            mValueName = valueName;
34
+        }
35
+        public ValueName getKey() {
36
+            return mValueName;
37
+        }
38
+    }
39
+
40
+    // DEVICE TOKEN
41
+    @Nullable
42
+    private String mDeviceToken;
43
+    public String getDeviceToken() {
44
+        return mDeviceToken;
45
+    }
46
+    public void setDeviceToken(@Nullable String value) {
47
+        mDeviceToken = value;
48
+        this.setChanged();
49
+        this.notifyObservers(new ValueKey(ValueName.DEVICE_TOKEN));
50
+    }
51
+
52
+    // USER STATUS
53
+    @Nullable
54
+    private UserStatusModel mUserStatus;
55
+    public UserStatusModel getUserStatus() {
56
+        return mUserStatus;
57
+    }
58
+    public void setUserStatus(UserStatusModel value) {
59
+        mUserStatus = value;
60
+        this.setChanged();
61
+        this.notifyObservers(new ValueKey(ValueName.USER_STATUS));
62
+    }
63
+
64
+}

+ 0
- 36
app/src/main/java/uprrp/tania/MarleApplication.java View File

1
-package uprrp.tania;
2
-
3
-import android.app.Application;
4
-
5
-import org.researchstack.backbone.StorageAccess;
6
-import org.researchstack.backbone.storage.database.AppDatabase;
7
-import org.researchstack.backbone.storage.database.sqlite.DatabaseHelper;
8
-import org.researchstack.backbone.storage.file.EncryptionProvider;
9
-import org.researchstack.backbone.storage.file.FileAccess;
10
-import org.researchstack.backbone.storage.file.PinCodeConfig;
11
-import org.researchstack.backbone.storage.file.SimpleFileAccess;
12
-import org.researchstack.backbone.storage.file.UnencryptedProvider;
13
-
14
-public class MarleApplication extends Application {
15
-    @Override
16
-    public void onCreate() {
17
-        super.onCreate();
18
-
19
-        // Customize your pin code preferences
20
-        PinCodeConfig pinCodeConfig = new PinCodeConfig(); // default pin config (4-digit, 1 min lockout)
21
-
22
-        // Customize encryption preferences
23
-        EncryptionProvider encryptionProvider = new UnencryptedProvider(); // No pin, no encryption
24
-
25
-        // If you have special file handling needs, implement FileAccess
26
-        FileAccess fileAccess = new SimpleFileAccess();
27
-
28
-        // If you have your own custom database, implement AppDatabase
29
-        AppDatabase database = new DatabaseHelper(this,
30
-                DatabaseHelper.DEFAULT_NAME,
31
-                null,
32
-                DatabaseHelper.DEFAULT_VERSION);
33
-
34
-        StorageAccess.getInstance().init(pinCodeConfig, encryptionProvider, fileAccess, database);
35
-    }
36
-}

+ 0
- 2
app/src/main/java/uprrp/tania/MyFirebaseMessagingService.java View File

1
 package uprrp.tania;
1
 package uprrp.tania;
2
 
2
 
3
-
4
-
5
 import com.google.firebase.messaging.FirebaseMessagingService;
3
 import com.google.firebase.messaging.FirebaseMessagingService;
6
 import com.google.firebase.messaging.RemoteMessage;
4
 import com.google.firebase.messaging.RemoteMessage;
7
 
5
 

+ 4
- 2
app/src/main/java/uprrp/tania/SendLoginToServer.java View File

8
 import android.content.Context;
8
 import android.content.Context;
9
 import android.content.Intent;
9
 import android.content.Intent;
10
 import android.content.SharedPreferences;
10
 import android.content.SharedPreferences;
11
+import android.content.res.Resources;
11
 import android.os.AsyncTask;
12
 import android.os.AsyncTask;
12
 import android.os.Environment;
13
 import android.os.Environment;
13
 import android.util.Base64;
14
 import android.util.Base64;
28
 
29
 
29
 public class SendLoginToServer extends AsyncTask<String, String, String> {
30
 public class SendLoginToServer extends AsyncTask<String, String, String> {
30
 
31
 
32
+    private static final String loginBaseURL = "https://tania.uprrp.edu/recoverAccount.php";
31
     private Context context;
33
     private Context context;
32
 
34
 
33
     public SendLoginToServer(Context context){
35
     public SendLoginToServer(Context context){
52
         try
54
         try
53
         {
55
         {
54
             // Defined URL  where to send data
56
             // Defined URL  where to send data
55
-            URL url = new URL("https://tania.uprrp.edu7/recoverAccount.php");
57
+            URL url = new URL(loginBaseURL);
56
 
58
 
57
             // Send POST data request
59
             // Send POST data request
58
             URLConnection conn = url.openConnection();
60
             URLConnection conn = url.openConnection();
83
         {
85
         {
84
             try
86
             try
85
             {
87
             {
86
-                assert reader != null;
88
+//                assert reader != null;
87
                 reader.close();
89
                 reader.close();
88
             }
90
             }
89
             catch(Exception ex) {
91
             catch(Exception ex) {

+ 75
- 35
app/src/main/java/uprrp/tania/activities/ExperienceRegistrationActivity.java View File

8
 import android.util.Log;
8
 import android.util.Log;
9
 import android.view.View;
9
 import android.view.View;
10
 import android.widget.Button;
10
 import android.widget.Button;
11
+import android.widget.TextView;
11
 import android.widget.Toast;
12
 import android.widget.Toast;
12
 
13
 
13
 import androidx.annotation.Nullable;
14
 import androidx.annotation.Nullable;
14
 import androidx.appcompat.app.AppCompatActivity;
15
 import androidx.appcompat.app.AppCompatActivity;
15
 
16
 
16
-import com.google.android.gms.tasks.OnSuccessListener;
17
-import com.google.firebase.iid.FirebaseInstanceId;
18
-import com.google.firebase.iid.InstanceIdResult;
17
+import java.util.Observable;
18
+import java.util.Observer;
19
 
19
 
20
+import uprrp.tania.GlobalValues;
20
 import uprrp.tania.R;
21
 import uprrp.tania.R;
21
-import uprrp.tania.networking.SendExperienceRegistration;
22
 import uprrp.tania.URLEventListener;
22
 import uprrp.tania.URLEventListener;
23
+import uprrp.tania.networking.SendExperienceRegistration;
23
 
24
 
24
-public class ExperienceRegistrationActivity  extends AppCompatActivity {
25
+public class ExperienceRegistrationActivity  extends AppCompatActivity implements Observer {
25
 
26
 
26
     private static final String TAG = "ExperienceRegistrationActivity";
27
     private static final String TAG = "ExperienceRegistrationActivity";
27
-    private String DEVICE_TOKEN;
28
     private String EXPERIENCE_ID;
28
     private String EXPERIENCE_ID;
29
 
29
 
30
     @Override
30
     @Override
31
     protected void onCreate(@Nullable Bundle savedInstanceState) {
31
     protected void onCreate(@Nullable Bundle savedInstanceState) {
32
 
32
 
33
-        // Start constructor and fetch UI components
33
+        // Start constructor
34
         super.onCreate(savedInstanceState);
34
         super.onCreate(savedInstanceState);
35
         setContentView(R.layout.activity_experience_registration);
35
         setContentView(R.layout.activity_experience_registration);
36
-        final Button experienceRegistrationButton = findViewById(R.id.buttonEnterExperience);
37
-
38
-        // Change all caps text to normal capitalization
39
-        // TODO: this is a workaround I found, any other acceptable solution is welcome
40
-        experienceRegistrationButton.setTransformationMethod(null);
41
-
42
-        // Request to Firebase...
43
-        // TODO: Should we implement retry logic in onFailureListener?
44
-        FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
45
-            @Override
46
-            public void onSuccess(InstanceIdResult instanceIdResult) {
47
-
48
-            // Get device's token
49
-            // IMPORTANT: must come first before calling
50
-            // another function that uses the token
51
-            DEVICE_TOKEN = instanceIdResult.getToken();
52
-
53
-            // Set onClick listener on button
54
-            experienceRegistrationButton.setOnClickListener(new View.OnClickListener() {
55
-                @Override
56
-                public void onClick(View v) {
57
-                    sendRegistrationRequest();
58
-                }
59
-            });
60
-
61
-            }
62
-        });
63
 
36
 
64
         // Fetch experience ID from URL (only if we launched this Activity from Browser)
37
         // Fetch experience ID from URL (only if we launched this Activity from Browser)
65
         Intent intent = getIntent();
38
         Intent intent = getIntent();
67
             Uri uri = intent.getData();
40
             Uri uri = intent.getData();
68
             assert uri != null; // TODO: figure out if this causes crashes...
41
             assert uri != null; // TODO: figure out if this causes crashes...
69
             EXPERIENCE_ID = uri.getQueryParameter("id");
42
             EXPERIENCE_ID = uri.getQueryParameter("id");
43
+            Log.wtf("EXPERIENCE ID", EXPERIENCE_ID);
44
+        }
45
+
46
+        // Listen for device token changes
47
+        this.startObservingGlobals();
48
+
49
+        // Disable interaction initially while token is being fetched
50
+        if(GlobalValues.getInstance().getDeviceToken() == null) {
51
+            Log.wtf("EXPERIENCE ID", "DISABLING");
52
+            disableInteractionTemporarily();
53
+        } else {
54
+            enableInteraction();
55
+        }
56
+
57
+        // Change all caps text to normal capitalization and add onClick listener
58
+        final Button experienceRegistrationButton = findViewById(R.id.buttonEnterExperience);
59
+        experienceRegistrationButton.setTransformationMethod(null); // TODO: this is a workaround I found, any other acceptable solution is welcome
60
+        experienceRegistrationButton.setOnClickListener(new View.OnClickListener() {
61
+            @Override
62
+            public void onClick(View v) {
63
+                sendRegistrationRequest();
64
+            }
65
+        });
66
+
67
+    }
68
+
69
+    // TAKEN FROM https://stackoverflow.com/questions/21886768/is-there-any-method-i-can-listen-for-changes-to-global-variable-to-trigger-an-ev
70
+    private void startObservingGlobals() {
71
+        GlobalValues.getInstance().addObserver(this);
72
+    }
73
+
74
+    // TAKEN FROM https://stackoverflow.com/questions/21886768/is-there-any-method-i-can-listen-for-changes-to-global-variable-to-trigger-an-ev
75
+    @Override
76
+    public void update(Observable observable, Object o) {
77
+        if(observable instanceof GlobalValues) {
78
+            if(o instanceof GlobalValues.ValueKey) {
79
+                if(((GlobalValues.ValueKey) o).getKey() == GlobalValues.ValueName.DEVICE_TOKEN) {
80
+                    if(GlobalValues.getInstance().getDeviceToken() == null) {
81
+                        disableInteraction();
82
+                    } else {
83
+                        enableInteraction();
84
+                    }
85
+                }
86
+            }
70
         }
87
         }
88
+    }
89
+
90
+    private void enableInteraction() {
91
+        final Button experienceRegistrationButton = findViewById(R.id.buttonEnterExperience);
92
+        final TextView experienceRegistrationTextView = findViewById(R.id.experienceRegistrationText);
93
+
94
+        experienceRegistrationButton.setEnabled(true);
95
+        experienceRegistrationTextView.setText(R.string.experienceRegistrationDescriptionText);
96
+    }
97
+
98
+    private void disableInteraction() {
99
+        final Button experienceRegistrationButton = findViewById(R.id.buttonEnterExperience);
100
+        final TextView experienceRegistrationTextView = findViewById(R.id.experienceRegistrationText);
101
+
102
+        experienceRegistrationButton.setEnabled(false);
103
+        experienceRegistrationTextView.setText(R.string.tokenErrorText);
104
+    }
105
+
106
+    private void disableInteractionTemporarily() {
107
+        final Button experienceRegistrationButton = findViewById(R.id.buttonEnterExperience);
108
+        final TextView experienceRegistrationTextView = findViewById(R.id.experienceRegistrationText);
71
 
109
 
110
+        experienceRegistrationButton.setEnabled(false);
111
+        experienceRegistrationTextView.setText(R.string.loadingText);
72
     }
112
     }
73
 
113
 
74
     private void sendRegistrationRequest() {
114
     private void sendRegistrationRequest() {
100
             }
140
             }
101
         });
141
         });
102
 
142
 
103
-        experienceRegistrationTask.execute(this.DEVICE_TOKEN, this.EXPERIENCE_ID);
143
+        experienceRegistrationTask.execute(GlobalValues.getInstance().getDeviceToken(), this.EXPERIENCE_ID);
104
 
144
 
105
         // UNCOMMENT THIS FOR TESTING (REMEMBER TO COMMENT .execute() LINE)
145
         // UNCOMMENT THIS FOR TESTING (REMEMBER TO COMMENT .execute() LINE)
106
         /*
146
         /*

+ 1
- 41
app/src/main/java/uprrp/tania/activities/MainActivity.java View File

1
 package uprrp.tania.activities;
1
 package uprrp.tania.activities;
2
 
2
 
3
-import android.content.Intent;
4
-import android.content.SharedPreferences;
5
-import android.net.Uri;
6
 import android.os.Bundle;
3
 import android.os.Bundle;
7
-import android.util.Log;
8
 import android.view.MenuItem;
4
 import android.view.MenuItem;
9
 
5
 
10
 import androidx.annotation.NonNull;
6
 import androidx.annotation.NonNull;
12
 import androidx.appcompat.widget.Toolbar;
8
 import androidx.appcompat.widget.Toolbar;
13
 import androidx.fragment.app.Fragment;
9
 import androidx.fragment.app.Fragment;
14
 
10
 
15
-import com.amazonaws.auth.CognitoCachingCredentialsProvider;
16
-import com.amazonaws.regions.Regions;
17
-import com.google.android.gms.tasks.OnSuccessListener;
18
 import com.google.android.material.bottomnavigation.BottomNavigationView;
11
 import com.google.android.material.bottomnavigation.BottomNavigationView;
19
-import com.google.firebase.iid.FirebaseInstanceId;
20
-import com.google.firebase.iid.InstanceIdResult;
21
 
12
 
22
 import org.researchstack.backbone.ui.PinCodeActivity;
13
 import org.researchstack.backbone.ui.PinCodeActivity;
23
 
14
 
24
 import uprrp.tania.R;
15
 import uprrp.tania.R;
25
-import uprrp.tania.SNSRegister;
26
 import uprrp.tania.fragments.AssessmentsFragment;
16
 import uprrp.tania.fragments.AssessmentsFragment;
27
 import uprrp.tania.fragments.ConsentFragment;
17
 import uprrp.tania.fragments.ConsentFragment;
28
 import uprrp.tania.fragments.WithdrawFragment;
18
 import uprrp.tania.fragments.WithdrawFragment;
39
         setContentView(R.layout.activity_main);
29
         setContentView(R.layout.activity_main);
40
 
30
 
41
 
31
 
42
-        // We need to know if the user has already registered, otherwise they need to do that first
43
-        SharedPreferences prefs = getSharedPreferences("prefs", MODE_PRIVATE);
44
-        boolean needsToRegister = prefs.getBoolean("needsToRegister", true);
45
-        if(needsToRegister) {
46
-            Intent needsRegisterIntent = new Intent(this, GettingStartedActivity.class);
47
-            startActivity(needsRegisterIntent);
48
-        }
49
-
50
-
51
-        // Enable notifications
52
-        CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
53
-                getApplicationContext(),
54
-                getString(R.string.identityPoolID), // Identity pool ID
55
-                Regions.US_EAST_1 // Region
56
-        );
57
-        SNSRegister snsRegister = new SNSRegister(credentialsProvider);
58
-        snsRegister.execute();
59
-
60
-
61
         // Create toolbar
32
         // Create toolbar
62
         Toolbar toolbar = findViewById(R.id.toolbar);
33
         Toolbar toolbar = findViewById(R.id.toolbar);
63
         setSupportActionBar(toolbar);
34
         setSupportActionBar(toolbar);
64
         ActionBar actionBar = getSupportActionBar();
35
         ActionBar actionBar = getSupportActionBar();
65
         assert actionBar != null; // TODO: find out if this causes crashes
36
         assert actionBar != null; // TODO: find out if this causes crashes
66
-        actionBar.setTitle(R.string.app_name);
37
+        actionBar.setTitle(R.string.appName);
67
         actionBar.setDisplayShowTitleEnabled(true);
38
         actionBar.setDisplayShowTitleEnabled(true);
68
 
39
 
69
 
40
 
102
     }
73
     }
103
 
74
 
104
 }
75
 }
105
-
106
-
107
-
108
-
109
-
110
-
111
-
112
-
113
-
114
-
115
-

+ 168
- 90
app/src/main/java/uprrp/tania/fragments/AssessmentsFragment.java View File

12
 import android.widget.Button;
12
 import android.widget.Button;
13
 import android.widget.TextView;
13
 import android.widget.TextView;
14
 import android.widget.Toast;
14
 import android.widget.Toast;
15
+
15
 import androidx.annotation.Nullable;
16
 import androidx.annotation.Nullable;
16
 import androidx.appcompat.app.AlertDialog;
17
 import androidx.appcompat.app.AlertDialog;
17
 import androidx.fragment.app.Fragment;
18
 import androidx.fragment.app.Fragment;
18
 
19
 
19
-import com.google.android.gms.tasks.OnSuccessListener;
20
-import com.google.firebase.iid.FirebaseInstanceId;
21
-import com.google.firebase.iid.InstanceIdResult;
22
-
23
 import org.researchstack.backbone.StorageAccess;
20
 import org.researchstack.backbone.StorageAccess;
24
 import org.researchstack.backbone.answerformat.AnswerFormat;
21
 import org.researchstack.backbone.answerformat.AnswerFormat;
25
 import org.researchstack.backbone.answerformat.ChoiceAnswerFormat;
22
 import org.researchstack.backbone.answerformat.ChoiceAnswerFormat;
36
 import java.util.ArrayList;
33
 import java.util.ArrayList;
37
 import java.util.List;
34
 import java.util.List;
38
 import java.util.Objects;
35
 import java.util.Objects;
36
+import java.util.Observable;
37
+import java.util.Observer;
39
 
38
 
40
-import uprrp.tania.networking.SendAnswers;
41
-import uprrp.tania.models.AnsweredQuestionModel;
39
+import uprrp.tania.GlobalValues;
40
+import uprrp.tania.R;
41
+import uprrp.tania.URLEventListener;
42
 import uprrp.tania.models.AnsweredAssessmentModel;
42
 import uprrp.tania.models.AnsweredAssessmentModel;
43
-import uprrp.tania.networking.FetchAssessment;
44
-import uprrp.tania.networking.FetchUserStatus;
43
+import uprrp.tania.models.AnsweredQuestionModel;
45
 import uprrp.tania.models.AssessmentModel;
44
 import uprrp.tania.models.AssessmentModel;
46
 import uprrp.tania.models.QuestionModel;
45
 import uprrp.tania.models.QuestionModel;
47
-import uprrp.tania.R;
48
-import uprrp.tania.URLEventListener;
49
 import uprrp.tania.models.UserStatusModel;
46
 import uprrp.tania.models.UserStatusModel;
47
+import uprrp.tania.networking.FetchAssessment;
48
+import uprrp.tania.networking.FetchUserStatus;
49
+import uprrp.tania.networking.SendAnswers;
50
 
50
 
51
-public class AssessmentsFragment extends Fragment {
51
+public class AssessmentsFragment extends Fragment implements Observer {
52
 
52
 
53
     // These variables came from the sample app provided to explain the use of Research Stack
53
     // These variables came from the sample app provided to explain the use of Research Stack
54
     private static final int REQUEST_SURVEY = 1;
54
     private static final int REQUEST_SURVEY = 1;
57
 
57
 
58
     // Our variables
58
     // Our variables
59
     private static final String TAG = "AssessmentsFragment";
59
     private static final String TAG = "AssessmentsFragment";
60
-    private String DEVICE_TOKEN;
61
     private String ASSESSMENT_ID;
60
     private String ASSESSMENT_ID;
62
     private View thisFragment;
61
     private View thisFragment;
63
 
62
 
65
     @Override
64
     @Override
66
     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
65
     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
67
 
66
 
68
-        // Get reference for this fragment and other components
69
-        this.thisFragment = inflater.inflate(R.layout.fragment_assessments, container, false);
70
-        final Button surveyButton = thisFragment.findViewById(R.id.surveyButton);
71
-        final Button refreshButton = thisFragment.findViewById(R.id.refreshButton);
67
+        // Constructor
68
+        thisFragment = inflater.inflate(R.layout.fragment_assessments, container, false);
72
 
69
 
73
-        // Change all caps text to normal capitalization
74
-        // TODO: this is a workaround I found, any other acceptable solution is welcome
75
-        surveyButton.setTransformationMethod(null);
76
-        refreshButton.setTransformationMethod(null);
70
+        // Listen for device token changes
71
+        this.startObservingGlobals();
77
 
72
 
78
-        // Request to Firebase...
79
-        // TODO: Should we implement retry logic in onFailureListener?
80
-        FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
81
-            @Override
82
-            public void onSuccess(InstanceIdResult instanceIdResult) {
83
-
84
-                // Get device's token
85
-                // IMPORTANT: must come first before calling
86
-                // another function that uses the token
87
-                DEVICE_TOKEN = instanceIdResult.getToken();
88
-
89
-                // Add onClick listener to "Answer Survey" button
90
-                surveyButton.setOnClickListener(new View.OnClickListener() {
91
-                    @Override
92
-                    public void onClick(View v) {
93
-                        fetchAssessment();
94
-                    }
95
-                });
73
+        // Disable interaction initially while token is being fetched
74
+        if(GlobalValues.getInstance().getDeviceToken() == null) {
75
+            disableInteractionTemporarily();
76
+        } else {
77
+            enableInteraction();
78
+        }
96
 
79
 
97
-                // Add onClick listener to "Refresh Status" button
98
-                refreshButton.setOnClickListener(new View.OnClickListener() {
99
-                    @Override
100
-                    public void onClick(View v) {
101
-                        fetchUserStatus();
102
-                    }
103
-                });
80
+        // Display user status if available
81
+        UserStatusModel userStatus = GlobalValues.getInstance().getUserStatus();
82
+        if(userStatus != null) {
83
+            positiveUserStatus(userStatus);
84
+        }
104
 
85
 
105
-                // Fetch user status and assessment, if any
86
+        // Change all caps text to normal capitalization and add onClick listener
87
+        final Button surveyButton = thisFragment.findViewById(R.id.surveyButton);
88
+        final Button refreshButton = thisFragment.findViewById(R.id.refreshButton);
89
+        surveyButton.setTransformationMethod(null); // TODO: this is a workaround I found, any other acceptable solution is welcome
90
+        refreshButton.setTransformationMethod(null); // TODO: this is a workaround I found, any other acceptable solution is welcome
91
+        surveyButton.setOnClickListener(new View.OnClickListener() {
92
+            @Override
93
+            public void onClick(View v) {
94
+                fetchAssessment();
95
+            }
96
+        });
97
+        refreshButton.setOnClickListener(new View.OnClickListener() {
98
+            @Override
99
+            public void onClick(View v) {
106
                 fetchUserStatus();
100
                 fetchUserStatus();
107
-//            fetchAssessment();
108
-
109
             }
101
             }
110
         });
102
         });
111
 
103
 
113
 
105
 
114
     }
106
     }
115
 
107
 
116
-    private void fetchUserStatus() {
117
-
118
-        // Get text fields and initialize other stuff
119
-        final TextView statusTextView = this.thisFragment.findViewById(R.id.statusTextView);
120
-        final TextView nextSurveyTextView = this.thisFragment.findViewById(R.id.nextSurveyTextView);
121
-        final Button surveyButton = this.thisFragment.findViewById(R.id.surveyButton);
122
-        final Button refreshButton = this.thisFragment.findViewById(R.id.refreshButton);
108
+    private void disableInteractionTemporarily() {
109
+        final Button surveyButton = thisFragment.findViewById(R.id.surveyButton);
110
+        final Button refreshButton = thisFragment.findViewById(R.id.refreshButton);
111
+        final TextView statusTextView = thisFragment.findViewById(R.id.statusTextView);
112
+        final TextView nextSurveyTextView = thisFragment.findViewById(R.id.nextSurveyTextView);
123
 
113
 
124
-        // Change UI to indicate loading is happening
114
+        surveyButton.setEnabled(false);
115
+        refreshButton.setEnabled(false);
125
         statusTextView.setText(R.string.loadingText);
116
         statusTextView.setText(R.string.loadingText);
126
-        nextSurveyTextView.setVisibility(View.GONE);
117
+        nextSurveyTextView.setVisibility(View.INVISIBLE);
118
+    }
127
 
119
 
128
-        // Define task
129
-        FetchUserStatus userStatusTask = new FetchUserStatus(new URLEventListener() {
120
+    private void disableInteraction() {
121
+        final Button surveyButton = thisFragment.findViewById(R.id.surveyButton);
122
+        final Button refreshButton = thisFragment.findViewById(R.id.refreshButton);
123
+        final TextView statusTextView = thisFragment.findViewById(R.id.statusTextView);
124
+        final TextView nextSurveyTextView = thisFragment.findViewById(R.id.nextSurveyTextView);
130
 
125
 
131
-            @Override
132
-            public void onSuccess(UserStatusModel userStatus) {
133
-                if(userStatus.isEnrolled()) {
126
+        surveyButton.setEnabled(false);
127
+        refreshButton.setEnabled(false);
128
+        statusTextView.setText(R.string.tokenErrorText);
129
+        nextSurveyTextView.setVisibility(View.INVISIBLE);
130
+    }
134
 
131
 
135
-                    // Change next survey date text (as well as status text)
136
-                    statusTextView.setText(userStatus.toString());
137
-                    nextSurveyTextView.setText(userStatus.getTimeToNext());
138
-                    nextSurveyTextView.setVisibility(View.VISIBLE);
132
+    private void enableInteraction() {
133
+        final Button surveyButton = thisFragment.findViewById(R.id.surveyButton);
134
+        final Button refreshButton = thisFragment.findViewById(R.id.refreshButton);
139
 
135
 
140
-                    // Hide refresh button (it only refreshes user status, anyways so...)
141
-                    refreshButton.setVisibility(View.GONE);
136
+        surveyButton.setEnabled(true);
137
+        refreshButton.setEnabled(true);
138
+        if(GlobalValues.getInstance().getUserStatus() == null) {
139
+            fetchUserStatus(); // refresh user status
140
+        }
141
+    }
142
 
142
 
143
-                    // Toggle "Answer" button visibility depending on survey availability
144
-                    if(userStatus.surveyAvailable()) {
145
-                        surveyButton.setVisibility(View.VISIBLE);
146
-                    } else {
147
-                        surveyButton.setVisibility(View.GONE);
148
-                    }
143
+    // TAKEN FROM https://stackoverflow.com/questions/21886768/is-there-any-method-i-can-listen-for-changes-to-global-variable-to-trigger-an-ev
144
+    private void startObservingGlobals() {
145
+        GlobalValues.getInstance().addObserver(this);
146
+    }
149
 
147
 
150
-                } else {
151
-                    // Prompt user to refresh status if user doesn't have an experience
152
-//                    statusTextView.setText("You are not enrolled in any experience.\nIf you think this is a mistake, contact your supervisors."); // for debugging/testing
153
-                    statusTextView.setText(userStatus.toString());
154
-                    nextSurveyTextView.setVisibility(View.GONE);
155
-                    surveyButton.setVisibility(View.GONE);
156
-                    refreshButton.setVisibility(View.VISIBLE);
148
+    // TAKEN FROM https://stackoverflow.com/questions/21886768/is-there-any-method-i-can-listen-for-changes-to-global-variable-to-trigger-an-ev
149
+    @Override
150
+    public void update(Observable observable, Object o) {
151
+        if(observable instanceof GlobalValues) {
152
+            if(o instanceof GlobalValues.ValueKey) {
153
+                switch(((GlobalValues.ValueKey) o).getKey()) {
154
+                    case DEVICE_TOKEN:
155
+                        if(GlobalValues.getInstance().getDeviceToken() == null) {
156
+                            disableInteraction();
157
+                        } else {
158
+                            enableInteraction();
159
+                        }
160
+                        break;
161
+                    case USER_STATUS:
162
+                        UserStatusModel userStatus = GlobalValues.getInstance().getUserStatus();
163
+                        if(userStatus == null) {
164
+                            negativeUserStatus();
165
+                        } else {
166
+                            positiveUserStatus(userStatus);
167
+                        }
168
+                        break;
157
                 }
169
                 }
158
             }
170
             }
171
+        }
172
+    }
173
+
174
+    private void negativeUserStatus() {
175
+        Toast.makeText(getContext(), "Can't verify identity!", Toast.LENGTH_LONG).show();
176
+
177
+        final TextView statusTextView = thisFragment.findViewById(R.id.statusTextView);
178
+        final TextView nextSurveyTextView = thisFragment.findViewById(R.id.nextSurveyTextView);
179
+        final Button surveyButton = thisFragment.findViewById(R.id.surveyButton);
180
+        final Button refreshButton = thisFragment.findViewById(R.id.refreshButton);
181
+
182
+        statusTextView.setText(R.string.userStatusErrorText);
183
+        nextSurveyTextView.setVisibility(View.INVISIBLE);
184
+        surveyButton.setVisibility(View.INVISIBLE);
185
+        surveyButton.setEnabled(false);
186
+        refreshButton.setVisibility(View.VISIBLE);
187
+    }
188
+
189
+    private void positiveUserStatus(UserStatusModel userStatus) {
190
+
191
+        final TextView statusTextView = thisFragment.findViewById(R.id.statusTextView);
192
+        final TextView nextSurveyTextView = thisFragment.findViewById(R.id.nextSurveyTextView);
193
+        final Button surveyButton = thisFragment.findViewById(R.id.surveyButton);
194
+        final Button refreshButton = thisFragment.findViewById(R.id.refreshButton);
195
+
196
+        statusTextView.setText(userStatus.toString());
197
+
198
+        if(userStatus.isEnrolled()) {
159
 
199
 
200
+            nextSurveyTextView.setText(userStatus.getTimeToNext());
201
+            nextSurveyTextView.setVisibility(View.VISIBLE);
202
+
203
+            if(userStatus.surveyAvailable()) {
204
+                refreshButton.setVisibility(View.INVISIBLE);
205
+                refreshButton.setEnabled(false);
206
+                surveyButton.setVisibility(View.VISIBLE);
207
+                surveyButton.setEnabled(true);
208
+            } else {
209
+                surveyButton.setVisibility(View.INVISIBLE);
210
+                surveyButton.setEnabled(false);
211
+                refreshButton.setVisibility(View.VISIBLE);
212
+                refreshButton.setEnabled(true);
213
+            }
214
+
215
+        } else {
216
+
217
+            nextSurveyTextView.setText("");
218
+            nextSurveyTextView.setVisibility(View.INVISIBLE);
219
+
220
+            surveyButton.setVisibility(View.INVISIBLE);
221
+            surveyButton.setEnabled(false);
222
+            refreshButton.setVisibility(View.VISIBLE);
223
+            refreshButton.setEnabled(true);
224
+
225
+        }
226
+
227
+    }
228
+
229
+    private void fetchUserStatus() {
230
+
231
+        disableInteractionTemporarily();
232
+
233
+        // Define task
234
+        FetchUserStatus userStatusTask = new FetchUserStatus(new URLEventListener() {
235
+            @Override
236
+            public void onSuccess(UserStatusModel userStatus) {
237
+                GlobalValues.getInstance().setUserStatus(userStatus);
238
+                enableInteraction();
239
+            }
160
             @Override
240
             @Override
161
             public void onFailure(Exception e) {
241
             public void onFailure(Exception e) {
162
-                statusTextView.setText(R.string.userStatusErrorText);
163
-                Toast.makeText(getContext(), "Can't verify identity!", Toast.LENGTH_LONG).show();
164
-                Log.e("ERROR WHILE FETCHING USER STATUS", e.toString());
242
+                GlobalValues.getInstance().setUserStatus(null);
243
+                Log.e(TAG, "Error while fetching user status: " + e.toString());
165
             }
244
             }
166
-
167
         });
245
         });
168
 
246
 
169
         // Start task
247
         // Start task
170
-        userStatusTask.execute(this.DEVICE_TOKEN);
248
+        userStatusTask.execute(GlobalValues.getInstance().getDeviceToken());
171
 
249
 
172
     }
250
     }
173
 
251
 
204
         });
282
         });
205
 
283
 
206
         // Start task
284
         // Start task
207
-        assessmentTask.execute(this.DEVICE_TOKEN);
285
+        assessmentTask.execute(GlobalValues.getInstance().getDeviceToken());
208
 
286
 
209
     }
287
     }
210
 
288
 
259
 
337
 
260
            @Override
338
            @Override
261
            public void onFailure(Exception e) {
339
            public void onFailure(Exception e) {
262
-               Log.e("ERROR WHILE SENDING ANSWERS", e.toString());
340
+               Log.e(TAG, "Error whilte sending answers: " + e.toString());
263
                e.printStackTrace();
341
                e.printStackTrace();
264
                progressDialog.dismiss();
342
                progressDialog.dismiss();
265
                promptRetrySend(answeredAssessment);
343
                promptRetrySend(answeredAssessment);
311
         }
389
         }
312
 
390
 
313
         // Return answered assessment
391
         // Return answered assessment
314
-        return new AnsweredAssessmentModel(this.ASSESSMENT_ID, this.DEVICE_TOKEN, answeredQuestions);
392
+        return new AnsweredAssessmentModel(this.ASSESSMENT_ID, GlobalValues.getInstance().getDeviceToken(), answeredQuestions);
315
 
393
 
316
     }
394
     }
317
 
395
 
322
 
400
 
323
         // Create instruction screen (add it to total steps)
401
         // Create instruction screen (add it to total steps)
324
         InstructionStep instructionStep = new InstructionStep(INSTRUCTION,
402
         InstructionStep instructionStep = new InstructionStep(INSTRUCTION,
325
-                getString(R.string.app_name),
403
+                getString(R.string.appName),
326
                 assessment.getDescription());
404
                 assessment.getDescription());
327
         instructionStep.setStepTitle(R.string.surveyToolbarText);
405
         instructionStep.setStepTitle(R.string.surveyToolbarText);
328
         steps.add(0, instructionStep);
406
         steps.add(0, instructionStep);

+ 71
- 26
app/src/main/java/uprrp/tania/fragments/WithdrawFragment.java View File

11
 import android.view.View;
11
 import android.view.View;
12
 import android.view.ViewGroup;
12
 import android.view.ViewGroup;
13
 import android.widget.Button;
13
 import android.widget.Button;
14
+import android.widget.TextView;
14
 import android.widget.Toast;
15
 import android.widget.Toast;
15
 
16
 
16
 import androidx.annotation.NonNull;
17
 import androidx.annotation.NonNull;
18
 import androidx.appcompat.app.AlertDialog;
19
 import androidx.appcompat.app.AlertDialog;
19
 import androidx.fragment.app.Fragment;
20
 import androidx.fragment.app.Fragment;
20
 
21
 
21
-import com.google.android.gms.tasks.OnSuccessListener;
22
-import com.google.firebase.iid.FirebaseInstanceId;
23
-import com.google.firebase.iid.InstanceIdResult;
24
-
25
 import java.util.Objects;
22
 import java.util.Objects;
23
+import java.util.Observable;
24
+import java.util.Observer;
26
 
25
 
26
+import uprrp.tania.GlobalValues;
27
 import uprrp.tania.R;
27
 import uprrp.tania.R;
28
 import uprrp.tania.URLEventListener;
28
 import uprrp.tania.URLEventListener;
29
 import uprrp.tania.activities.GettingStartedActivity;
29
 import uprrp.tania.activities.GettingStartedActivity;
30
 import uprrp.tania.networking.SendWithdrawal;
30
 import uprrp.tania.networking.SendWithdrawal;
31
 
31
 
32
-public class WithdrawFragment extends Fragment {
32
+public class WithdrawFragment extends Fragment implements Observer {
33
 
33
 
34
     private static final String TAG = "WithdrawFragment";
34
     private static final String TAG = "WithdrawFragment";
35
-    private String DEVICE_TOKEN;
35
+    private View thisFragment;
36
 
36
 
37
     @Nullable
37
     @Nullable
38
     @Override
38
     @Override
39
     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
39
     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
40
 
40
 
41
-        // Get reference for this fragment and other components
42
-        View view = inflater.inflate(R.layout.fragment_withdrawal, container, false);
43
-        final Button withdrawButton = view.findViewById(R.id.withdrawButton);
41
+        // Constructor
42
+        thisFragment = inflater.inflate(R.layout.fragment_withdrawal, container, false);
43
+
44
+        // Listen for device token changes
45
+        this.startObservingGlobals();
44
 
46
 
45
-        // Change all caps text to normal capitalization
46
-        // TODO: this is a workaround I found, any other acceptable solution is welcome
47
-        withdrawButton.setTransformationMethod(null);
48
-        withdrawButton.setText(R.string.loadingText);
47
+        // Disable interaction initially while token is being fetched
48
+        if(GlobalValues.getInstance().getDeviceToken() == null) {
49
+            disableInteractionTemporarily();
50
+        } else {
51
+            enableInteraction();
52
+        }
49
 
53
 
50
-        // Get device's token and attach click listener once we have it
51
-        FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
54
+        // Change all caps text to normal capitalization and add onClick listener
55
+        final Button withdrawButton = thisFragment.findViewById(R.id.withdrawButton);
56
+        withdrawButton.setTransformationMethod(null); // TODO: this is a workaround I found, any other acceptable solution is welcome
57
+        withdrawButton.setOnClickListener(new View.OnClickListener() {
52
             @Override
58
             @Override
53
-            public void onSuccess(InstanceIdResult instanceIdResult) {
54
-                DEVICE_TOKEN = instanceIdResult.getToken();
55
-                withdrawButton.setOnClickListener(new View.OnClickListener() {
56
-                    @Override
57
-                    public void onClick(View v) {
58
-                        promptConfirmation();
59
-                    }
60
-                });
61
-                withdrawButton.setText(R.string.withdrawButtonText);
59
+            public void onClick(View v) {
60
+                promptConfirmation();
62
             }
61
             }
63
         });
62
         });
64
 
63
 
65
-        return view;
64
+        return thisFragment;
65
+
66
+    }
67
+
68
+    private void disableInteractionTemporarily() {
69
+        final Button withdrawButton = thisFragment.findViewById(R.id.withdrawButton);
70
+        final TextView withdrawTextView = thisFragment.findViewById(R.id.withdrawText);
71
+
72
+        withdrawButton.setEnabled(false);
73
+        withdrawTextView.setText(R.string.loadingText);
74
+    }
75
+
76
+    private void disableInteraction() {
77
+        final Button withdrawButton = thisFragment.findViewById(R.id.withdrawButton);
78
+        final TextView withdrawTextView = thisFragment.findViewById(R.id.withdrawText);
79
+
80
+        withdrawButton.setEnabled(false);
81
+        withdrawTextView.setText(R.string.tokenErrorText);
82
+    }
83
+
84
+    private void enableInteraction() {
85
+        final Button withdrawButton = thisFragment.findViewById(R.id.withdrawButton);
86
+        final TextView withdrawTextView = thisFragment.findViewById(R.id.withdrawText);
87
+
88
+        withdrawButton.setEnabled(true);
89
+        withdrawTextView.setText(R.string.withdrawDescriptionText);
90
+    }
91
+
92
+    // TAKEN FROM https://stackoverflow.com/questions/21886768/is-there-any-method-i-can-listen-for-changes-to-global-variable-to-trigger-an-ev
93
+    private void startObservingGlobals() {
94
+        GlobalValues.getInstance().addObserver(this);
95
+    }
96
+
97
+    // TAKEN FROM https://stackoverflow.com/questions/21886768/is-there-any-method-i-can-listen-for-changes-to-global-variable-to-trigger-an-ev
98
+    @Override
99
+    public void update(Observable observable, Object o) {
100
+        if(observable instanceof GlobalValues) {
101
+            if(o instanceof GlobalValues.ValueKey) {
102
+                if(((GlobalValues.ValueKey) o).getKey() == GlobalValues.ValueName.DEVICE_TOKEN) {
103
+                    if(GlobalValues.getInstance().getDeviceToken() == null) {
104
+                        disableInteraction();
105
+                    } else {
106
+                        enableInteraction();
107
+                    }
108
+                }
109
+            }
110
+        }
66
     }
111
     }
67
 
112
 
68
     private void promptConfirmation() {
113
     private void promptConfirmation() {
127
         });
172
         });
128
 
173
 
129
         // Start task
174
         // Start task
130
-        sendWithdrawalTask.execute(DEVICE_TOKEN);
175
+        sendWithdrawalTask.execute(GlobalValues.getInstance().getDeviceToken());
131
 
176
 
132
         // UNCOMMENT THIS FOR TESTING (REMEMBER TO COMMENT .execute() LINE)
177
         // UNCOMMENT THIS FOR TESTING (REMEMBER TO COMMENT .execute() LINE)
133
         /*
178
         /*

+ 19
- 3
app/src/main/java/uprrp/tania/models/UserStatusModel.java View File

37
         }
37
         }
38
     }
38
     }
39
 
39
 
40
-    private String formatTimeToNext() {
40
+    private boolean isInteger(String s) {
41
+        return s.matches("-?\\d+");
42
+    }
41
 
43
 
44
+    private boolean validTimeToNext() {
42
         // Format is DD:HH:MM (can be negative if survey can be answered)
45
         // Format is DD:HH:MM (can be negative if survey can be answered)
43
         String[] parts = this.time_to_next.split(":");
46
         String[] parts = this.time_to_next.split(":");
44
 
47
 
45
-        // Input validation
46
-        if(parts[0].equals("") || parts[1].equals("") || parts[2].equals("")) {
48
+        if(parts.length != 3) {
49
+            return false;
50
+        } else if(!isInteger(parts[0]) || !isInteger(parts[1]) || !isInteger(parts[2])) {
51
+            return false;
52
+        } else {
53
+            return true;
54
+        }
55
+    }
56
+
57
+    private String formatTimeToNext() {
58
+
59
+        // Validation
60
+        if(!this.validTimeToNext()) {
47
             Log.wtf(TAG, "Backend gave an invalid time_to_next: " + this.time_to_next);
61
             Log.wtf(TAG, "Backend gave an invalid time_to_next: " + this.time_to_next);
48
             return ".."; // forms ellipsis
62
             return ".."; // forms ellipsis
49
         }
63
         }
50
 
64
 
65
+        // Format is DD:HH:MM (can be negative if survey can be answered)
66
+        String[] parts = this.time_to_next.split(":");
51
         int days = Integer.parseInt(parts[0]);
67
         int days = Integer.parseInt(parts[0]);
52
         int hours = Integer.parseInt(parts[1]);
68
         int hours = Integer.parseInt(parts[1]);
53
         int minutes = Integer.parseInt(parts[2]);
69
         int minutes = Integer.parseInt(parts[2]);

+ 3
- 5
app/src/main/java/uprrp/tania/networking/FetchAssessment.java View File

1
 package uprrp.tania.networking;
1
 package uprrp.tania.networking;
2
 
2
 
3
-import android.content.res.Resources;
4
 import android.os.AsyncTask;
3
 import android.os.AsyncTask;
5
 import android.util.Log;
4
 import android.util.Log;
6
 
5
 
19
 
18
 
20
 import javax.net.ssl.HttpsURLConnection;
19
 import javax.net.ssl.HttpsURLConnection;
21
 
20
 
22
-import uprrp.tania.R;
23
 import uprrp.tania.URLEventListener;
21
 import uprrp.tania.URLEventListener;
24
 import uprrp.tania.models.AssessmentModel;
22
 import uprrp.tania.models.AssessmentModel;
25
 import uprrp.tania.models.EmptyAssessmentModel;
23
 import uprrp.tania.models.EmptyAssessmentModel;
27
 public class FetchAssessment extends AsyncTask<String, Void, JSONObject> {
25
 public class FetchAssessment extends AsyncTask<String, Void, JSONObject> {
28
 
26
 
29
     private static final String TAG = "FetchAssessment";
27
     private static final String TAG = "FetchAssessment";
28
+    private static final String assessmentBaseURL = "https://tania.uprrp.edu/getSubQ2.php?tk=";
30
     private final URLEventListener myCallBack;
29
     private final URLEventListener myCallBack;
31
 
30
 
32
     public FetchAssessment(URLEventListener callback) {
31
     public FetchAssessment(URLEventListener callback) {
39
 
38
 
40
         try {
39
         try {
41
 
40
 
42
-            String getMomentsBaseURL = Resources.getSystem().getString(R.string.assessmentsBaseURL);
43
-            URL url = new URL(getMomentsBaseURL + deviceToken);
41
+            URL url = new URL(assessmentBaseURL + deviceToken);
44
             Log.d(TAG, "token:" + deviceToken); // log
42
             Log.d(TAG, "token:" + deviceToken); // log
45
             Log.d(TAG, "url:" + url.toString()); // log
43
             Log.d(TAG, "url:" + url.toString()); // log
46
             HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();
44
             HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();
82
     protected void onPostExecute(JSONObject obj) {
80
     protected void onPostExecute(JSONObject obj) {
83
 
81
 
84
         if(this.myCallBack == null) {
82
         if(this.myCallBack == null) {
85
-            this.myCallBack.onFailure(new Exception("Callback wasn't initialized first!"));
83
+            Log.e(TAG, "Callback wasn't initialized first!");
86
             return;
84
             return;
87
         }
85
         }
88
 
86
 

+ 2
- 4
app/src/main/java/uprrp/tania/networking/FetchUserStatus.java View File

1
 package uprrp.tania.networking;
1
 package uprrp.tania.networking;
2
 
2
 
3
-import android.content.res.Resources;
4
 import android.os.AsyncTask;
3
 import android.os.AsyncTask;
5
 import android.util.Log;
4
 import android.util.Log;
6
 
5
 
20
 
19
 
21
 import javax.net.ssl.HttpsURLConnection;
20
 import javax.net.ssl.HttpsURLConnection;
22
 
21
 
23
-import uprrp.tania.R;
24
 import uprrp.tania.URLEventListener;
22
 import uprrp.tania.URLEventListener;
25
 import uprrp.tania.models.EmptyUserStatusModel;
23
 import uprrp.tania.models.EmptyUserStatusModel;
26
 import uprrp.tania.models.UserStatusModel;
24
 import uprrp.tania.models.UserStatusModel;
28
 public class FetchUserStatus extends AsyncTask<String, Void, JSONArray> {
26
 public class FetchUserStatus extends AsyncTask<String, Void, JSONArray> {
29
 
27
 
30
     private static final String TAG = "FetchUserStatus";
28
     private static final String TAG = "FetchUserStatus";
29
+    private static final String userStatusBaseURL = "https://tania.uprrp.edu/status.php?tk=";
31
     private final URLEventListener myCallBack;
30
     private final URLEventListener myCallBack;
32
 
31
 
33
     public FetchUserStatus(URLEventListener callback) {
32
     public FetchUserStatus(URLEventListener callback) {
40
 
39
 
41
         try {
40
         try {
42
 
41
 
43
-            String userStatusBaseURL = Resources.getSystem().getString(R.string.userStatusBaseURL);
44
             URL url = new URL(userStatusBaseURL + deviceToken);
42
             URL url = new URL(userStatusBaseURL + deviceToken);
45
             Log.d(TAG, "token:" + deviceToken); // log
43
             Log.d(TAG, "token:" + deviceToken); // log
46
             Log.d(TAG, "url:" + url.toString()); // log
44
             Log.d(TAG, "url:" + url.toString()); // log
84
         super.onPostExecute(arr);
82
         super.onPostExecute(arr);
85
 
83
 
86
         if(this.myCallBack == null) {
84
         if(this.myCallBack == null) {
87
-            this.myCallBack.onFailure(new Exception("Callback wasn't initialized first!"));
85
+            Log.e(TAG, "Callback wasn't initialized first!");
88
             return;
86
             return;
89
         }
87
         }
90
 
88
 

+ 3
- 4
app/src/main/java/uprrp/tania/networking/SendAnswers.java View File

1
 package uprrp.tania.networking;
1
 package uprrp.tania.networking;
2
 
2
 
3
-import android.content.res.Resources;
4
 import android.os.AsyncTask;
3
 import android.os.AsyncTask;
5
 import android.util.Log;
4
 import android.util.Log;
6
 
5
 
19
 
18
 
20
 import javax.net.ssl.HttpsURLConnection;
19
 import javax.net.ssl.HttpsURLConnection;
21
 
20
 
22
-import uprrp.tania.R;
23
 import uprrp.tania.URLEventListener;
21
 import uprrp.tania.URLEventListener;
24
 import uprrp.tania.models.AnsweredAssessmentModel;
22
 import uprrp.tania.models.AnsweredAssessmentModel;
25
 
23
 
26
 public class SendAnswers extends AsyncTask<AnsweredAssessmentModel, Void, String> {
24
 public class SendAnswers extends AsyncTask<AnsweredAssessmentModel, Void, String> {
27
 
25
 
28
     private static final String TAG = "SendAnswers";
26
     private static final String TAG = "SendAnswers";
27
+    private static final String sendAnswersURL = "https://tania.uprrp.edu/parseAnswers.php";
29
     private final URLEventListener myCallback;
28
     private final URLEventListener myCallback;
30
 
29
 
31
     public SendAnswers(URLEventListener callback) {
30
     public SendAnswers(URLEventListener callback) {
97
             String encodedRequestBody = URLEncoder.encode("data", "UTF-8") + "=" + URLEncoder.encode(surveyResults.toString(), "UTF-8");
96
             String encodedRequestBody = URLEncoder.encode("data", "UTF-8") + "=" + URLEncoder.encode(surveyResults.toString(), "UTF-8");
98
 
97
 
99
             // Send POST data request
98
             // Send POST data request
100
-            URL url = new URL(Resources.getSystem().getString(R.string.sendAnswersURL));
99
+            URL url = new URL(sendAnswersURL);
101
             HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
100
             HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
102
             conn.setDoOutput(true);
101
             conn.setDoOutput(true);
103
             OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
102
             OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
147
     protected void onPostExecute(String response) {
146
     protected void onPostExecute(String response) {
148
 
147
 
149
         if(this.myCallback == null) {
148
         if(this.myCallback == null) {
150
-            this.myCallback.onFailure(new Exception("Callback wasn't initialized first!"));
149
+            Log.e(TAG, "Callback wasn't initialized first!");
151
             return;
150
             return;
152
         }
151
         }
153
 
152
 

+ 3
- 4
app/src/main/java/uprrp/tania/networking/SendExperienceRegistration.java View File

1
 package uprrp.tania.networking;
1
 package uprrp.tania.networking;
2
 
2
 
3
-import android.content.res.Resources;
4
 import android.os.AsyncTask;
3
 import android.os.AsyncTask;
5
 import android.util.Log;
4
 import android.util.Log;
6
 
5
 
16
 
15
 
17
 import javax.net.ssl.HttpsURLConnection;
16
 import javax.net.ssl.HttpsURLConnection;
18
 
17
 
19
-import uprrp.tania.R;
20
 import uprrp.tania.URLEventListener;
18
 import uprrp.tania.URLEventListener;
21
 
19
 
22
 public class SendExperienceRegistration extends AsyncTask<String, String, String> {
20
 public class SendExperienceRegistration extends AsyncTask<String, String, String> {
23
 
21
 
24
     private static final String TAG = "SendActivateExperience";
22
     private static final String TAG = "SendActivateExperience";
23
+    private static final String activateExperienceURL = "https://tania.uprrp.edu/inscripcionExperiencia.php";
25
     private final URLEventListener myCallback;
24
     private final URLEventListener myCallback;
26
 
25
 
27
     public SendExperienceRegistration(URLEventListener callback) {
26
     public SendExperienceRegistration(URLEventListener callback) {
64
             String encodedRequestBody = URLEncoder.encode("data", "UTF-8") + "=" + URLEncoder.encode(experienceRegistrationJSON.toString(), "UTF-8");
63
             String encodedRequestBody = URLEncoder.encode("data", "UTF-8") + "=" + URLEncoder.encode(experienceRegistrationJSON.toString(), "UTF-8");
65
 
64
 
66
             // Send POST data request
65
             // Send POST data request
67
-            URL url = new URL(Resources.getSystem().getString(R.string.activateExperienceURL));
66
+            URL url = new URL(activateExperienceURL);
68
             HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
67
             HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
69
             conn.setDoOutput(true);
68
             conn.setDoOutput(true);
70
             OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
69
             OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
110
     protected void onPostExecute(String response) {
109
     protected void onPostExecute(String response) {
111
 
110
 
112
         if(this.myCallback == null) {
111
         if(this.myCallback == null) {
113
-            this.myCallback.onFailure(new Exception("Callback wasn't initialized first!"));
112
+            Log.e(TAG, "Callback wasn't initialized first!");
114
             return;
113
             return;
115
         }
114
         }
116
 
115
 

+ 3
- 4
app/src/main/java/uprrp/tania/networking/SendWithdrawal.java View File

1
 package uprrp.tania.networking;
1
 package uprrp.tania.networking;
2
 
2
 
3
-import android.content.res.Resources;
4
 import android.os.AsyncTask;
3
 import android.os.AsyncTask;
5
 import android.util.Log;
4
 import android.util.Log;
6
 
5
 
19
 
18
 
20
 import javax.net.ssl.HttpsURLConnection;
19
 import javax.net.ssl.HttpsURLConnection;
21
 
20
 
22
-import uprrp.tania.R;
23
 import uprrp.tania.URLEventListener;
21
 import uprrp.tania.URLEventListener;
24
 
22
 
25
 public class SendWithdrawal extends AsyncTask<String, String, String> {
23
 public class SendWithdrawal extends AsyncTask<String, String, String> {
26
 
24
 
27
     private static final String TAG = "SendWithdrawal";
25
     private static final String TAG = "SendWithdrawal";
26
+    private static final String withdrawalURL = "https://tania.uprrp.edu/withdrawal.php";
28
     private final URLEventListener myCallback;
27
     private final URLEventListener myCallback;
29
 
28
 
30
     public SendWithdrawal(URLEventListener callback) {
29
     public SendWithdrawal(URLEventListener callback) {
56
             String encodedRequestBody = URLEncoder.encode("data", "UTF-8") + "=" + URLEncoder.encode(withdrawJSON.toString(), "UTF-8");
55
             String encodedRequestBody = URLEncoder.encode("data", "UTF-8") + "=" + URLEncoder.encode(withdrawJSON.toString(), "UTF-8");
57
 
56
 
58
             // Send POST data request
57
             // Send POST data request
59
-            URL url = new URL(Resources.getSystem().getString(R.string.withdrawalURL));
58
+            URL url = new URL(withdrawalURL);
60
             HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
59
             HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
61
             conn.setDoOutput(true);
60
             conn.setDoOutput(true);
62
             Writer writer = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8));
61
             Writer writer = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8));
101
     protected void onPostExecute(String response) {
100
     protected void onPostExecute(String response) {
102
 
101
 
103
         if(this.myCallback == null) {
102
         if(this.myCallback == null) {
104
-            this.myCallback.onFailure(new Exception("Callback wasn't initialized first!"));
103
+            Log.e(TAG, "Callback wasn't initialized first!");
105
             return;
104
             return;
106
         }
105
         }
107
 
106
 

app/src/main/java/uprrp/tania/AppPrefs.java → app/src/main/java/uprrp/tania/unused/AppPrefs.java View File

1
-package uprrp.tania;
1
+package uprrp.tania.unused;
2
 
2
 
3
 import android.content.Context;
3
 import android.content.Context;
4
 import android.content.SharedPreferences;
4
 import android.content.SharedPreferences;

app/src/main/java/uprrp/tania/CognitoSettings.java → app/src/main/java/uprrp/tania/unused/CognitoSettings.java View File

1
-package uprrp.tania;
1
+package uprrp.tania.unused;
2
 
2
 
3
 import android.content.Context;
3
 import android.content.Context;
4
 
4
 

+ 7
- 4
app/src/main/res/drawable/button_background.xml View File

1
 <?xml version="1.0" encoding="utf-8" ?>
1
 <?xml version="1.0" encoding="utf-8" ?>
2
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
2
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
3
-    <!--  Non focused states  -->
4
-    <item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/button_unfocused" />
5
-    <item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/button_unfocused" />
6
-    <!--  Focused states  -->
3
+    <!--  Disabled  -->
4
+    <item android:state_enabled="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/button_disabled" />
5
+    <item android:state_enabled="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/button_disabled" />
6
+    <!--  Enabled  -->
7
+    <item android:state_enabled="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/button_unfocused" />
8
+    <item android:state_enabled="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/button_unfocused" />
9
+    <!--  Focused  -->
7
 <!--    <item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/button_focus" />-->
10
 <!--    <item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/button_focus" />-->
8
 <!--    <item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/button_focus" />-->
11
 <!--    <item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/button_focus" />-->
9
     <!--  Pressed  -->
12
     <!--  Pressed  -->

+ 12
- 0
app/src/main/res/drawable/button_disabled.xml View File

1
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
2
+<!--  Border  -->
3
+<!--    <stroke android:width="1dp" android:color="@color/colorPrimary" />-->
4
+<!--  Radius  -->
5
+<corners android:radius="@dimen/cornerRadius" />
6
+<!--  Gradient  -->
7
+<!--    FF6800 -> FF8000 -> FF9700    -->
8
+<gradient android:startColor="@color/colorPrimaryDisabled"
9
+    android:centerColor="@color/colorPrimaryDisabled"
10
+    android:endColor="@color/colorPrimaryDisabled"
11
+    android:angle="90" />
12
+</shape>

+ 4
- 3
app/src/main/res/layout/activity_experience_registration.xml View File

25
         app:layout_constraintTop_toTopOf="parent" />
25
         app:layout_constraintTop_toTopOf="parent" />
26
 
26
 
27
     <TextView
27
     <TextView
28
-        android:id="@+id/textViewConfirmMessage"
28
+        android:id="@+id/experienceRegistrationText"
29
         android:layout_width="0dp"
29
         android:layout_width="0dp"
30
         android:layout_height="wrap_content"
30
         android:layout_height="wrap_content"
31
         android:layout_marginStart="@dimen/horizontalMargin"
31
         android:layout_marginStart="@dimen/horizontalMargin"
33
         android:layout_marginEnd="@dimen/horizontalMargin"
33
         android:layout_marginEnd="@dimen/horizontalMargin"
34
         android:fontFamily="sans-serif"
34
         android:fontFamily="sans-serif"
35
         android:gravity="center"
35
         android:gravity="center"
36
-        android:text="@string/experienceRegistrationDescriptionText"
36
+        android:text="@string/loadingText"
37
         android:textAlignment="center"
37
         android:textAlignment="center"
38
         android:textSize="18sp"
38
         android:textSize="18sp"
39
         app:layout_constraintEnd_toEndOf="parent"
39
         app:layout_constraintEnd_toEndOf="parent"
40
         app:layout_constraintStart_toStartOf="parent"
40
         app:layout_constraintStart_toStartOf="parent"
41
-        app:layout_constraintTop_toBottomOf="@+id/textViewActivateExperience" />
41
+        app:layout_constraintTop_toBottomOf="@+id/textViewActivateExperience"
42
+        tools:text="@string/experienceRegistrationDescriptionText" />
42
 
43
 
43
     <Button
44
     <Button
44
         android:id="@+id/buttonEnterExperience"
45
         android:id="@+id/buttonEnterExperience"

+ 4
- 5
app/src/main/res/layout/fragment_assessments.xml View File

21
         android:textColor="@android:color/white"
21
         android:textColor="@android:color/white"
22
         android:textSize="@dimen/buttonTextSize"
22
         android:textSize="@dimen/buttonTextSize"
23
         android:textStyle="bold"
23
         android:textStyle="bold"
24
+        android:visibility="visible"
24
         app:layout_constraintBottom_toBottomOf="parent"
25
         app:layout_constraintBottom_toBottomOf="parent"
25
         app:layout_constraintEnd_toEndOf="parent"
26
         app:layout_constraintEnd_toEndOf="parent"
26
         app:layout_constraintHeight_max="@dimen/buttonMaxHeight"
27
         app:layout_constraintHeight_max="@dimen/buttonMaxHeight"
27
         app:layout_constraintStart_toStartOf="parent"
28
         app:layout_constraintStart_toStartOf="parent"
28
         app:layout_constraintTop_toBottomOf="@id/statusTextView"
29
         app:layout_constraintTop_toBottomOf="@id/statusTextView"
29
-        tools:visibility="gone" />
30
+        tools:visibility="invisible" />
30
 
31
 
31
     <androidx.appcompat.widget.AppCompatButton
32
     <androidx.appcompat.widget.AppCompatButton
32
         android:id="@+id/surveyButton"
33
         android:id="@+id/surveyButton"
44
         android:textColor="@android:color/white"
45
         android:textColor="@android:color/white"
45
         android:textSize="@dimen/buttonTextSize"
46
         android:textSize="@dimen/buttonTextSize"
46
         android:textStyle="bold"
47
         android:textStyle="bold"
47
-        android:visibility="gone"
48
+        android:visibility="invisible"
48
         app:layout_constraintBottom_toBottomOf="parent"
49
         app:layout_constraintBottom_toBottomOf="parent"
49
         app:layout_constraintEnd_toEndOf="parent"
50
         app:layout_constraintEnd_toEndOf="parent"
50
         app:layout_constraintHeight_max="@dimen/buttonMaxHeight"
51
         app:layout_constraintHeight_max="@dimen/buttonMaxHeight"
76
         android:textAlignment="center"
77
         android:textAlignment="center"
77
         android:textSize="18sp"
78
         android:textSize="18sp"
78
         android:textStyle="bold"
79
         android:textStyle="bold"
79
-        android:visibility="gone"
80
         app:layout_constraintBottom_toTopOf="@+id/surveyButton"
80
         app:layout_constraintBottom_toTopOf="@+id/surveyButton"
81
         app:layout_constraintEnd_toEndOf="parent"
81
         app:layout_constraintEnd_toEndOf="parent"
82
         app:layout_constraintHorizontal_bias="0.5"
82
         app:layout_constraintHorizontal_bias="0.5"
83
         app:layout_constraintStart_toStartOf="parent"
83
         app:layout_constraintStart_toStartOf="parent"
84
-        tools:text="Next survey in 2 days, 6 hours."
85
-        tools:visibility="visible" />
84
+        tools:text="Next survey in 2 days, 6 hours." />
86
 
85
 
87
     <TextView
86
     <TextView
88
         android:id="@+id/assessmentTitle"
87
         android:id="@+id/assessmentTitle"

+ 3
- 2
app/src/main/res/layout/fragment_withdrawal.xml View File

30
         android:layout_marginStart="@dimen/horizontalMargin"
30
         android:layout_marginStart="@dimen/horizontalMargin"
31
         android:layout_marginTop="16dp"
31
         android:layout_marginTop="16dp"
32
         android:layout_marginEnd="@dimen/horizontalMargin"
32
         android:layout_marginEnd="@dimen/horizontalMargin"
33
-        android:text="@string/withdrawing_text"
33
+        android:text="@string/loadingText"
34
         android:textAlignment="textStart"
34
         android:textAlignment="textStart"
35
         android:textSize="@dimen/sectionDescriptionTextSize"
35
         android:textSize="@dimen/sectionDescriptionTextSize"
36
         app:layout_constraintEnd_toEndOf="parent"
36
         app:layout_constraintEnd_toEndOf="parent"
37
         app:layout_constraintStart_toStartOf="parent"
37
         app:layout_constraintStart_toStartOf="parent"
38
-        app:layout_constraintTop_toBottomOf="@+id/withdrawTitle" />
38
+        app:layout_constraintTop_toBottomOf="@+id/withdrawTitle"
39
+        tools:text="@string/withdrawDescriptionText" />
39
 
40
 
40
     <Button
41
     <Button
41
         android:id="@+id/withdrawButton"
42
         android:id="@+id/withdrawButton"

+ 1
- 1
app/src/main/res/values/colors.xml View File

2
 <resources>
2
 <resources>
3
     <color name="colorPrimary">#397af3</color>
3
     <color name="colorPrimary">#397af3</color>
4
     <color name="colorPrimaryDark">#174396</color>
4
     <color name="colorPrimaryDark">#174396</color>
5
+    <color name="colorPrimaryDisabled">#7ea5ed</color>
5
     <color name="colorAccent">#174396</color>
6
     <color name="colorAccent">#174396</color>
6
     <color name="dark_gray">#cccccc</color>
7
     <color name="dark_gray">#cccccc</color>
7
     <color name="textColor1">#FFFCEFD3</color>
8
     <color name="textColor1">#FFFCEFD3</color>
8
     <color name="textColor2">#423E3E</color>
9
     <color name="textColor2">#423E3E</color>
9
-
10
 </resources>
10
 </resources>
11
 
11
 
12
 
12
 

+ 9
- 8
app/src/main/res/values/strings.xml View File

1
 <resources>
1
 <resources>
2
-    <string name="app_name">TANIA</string>
3
     <string name="menu_data_cleared">La información ha sido borrada</string>
2
     <string name="menu_data_cleared">La información ha sido borrada</string>
4
     <string name="user_name">Nombre de usuario:</string>
3
     <string name="user_name">Nombre de usuario:</string>
5
     <string name="date_consented">Fecha de consentimiento:</string>
4
     <string name="date_consented">Fecha de consentimiento:</string>
22
     <string name="title_activity_consent_pdf_viewer">Consent TANIA</string>
21
     <string name="title_activity_consent_pdf_viewer">Consent TANIA</string>
23
 
22
 
24
     <!-- !!!!! POST-Víctor !!!!! -->
23
     <!-- !!!!! POST-Víctor !!!!! -->
25
-
26
     <!--  AmazonCognito Details  -->
24
     <!--  AmazonCognito Details  -->
27
     <string name="identityPoolID">us-east-1:574094cd-0784-4e26-bd14-4fa72ae63579</string>
25
     <string name="identityPoolID">us-east-1:574094cd-0784-4e26-bd14-4fa72ae63579</string>
28
     <!--  API Endpoints  -->
26
     <!--  API Endpoints  -->
29
-    <string name="sendAnswersURL">https://tania.uprrp.edu/parseAnswers.php</string>
30
-    <string name="activateExperienceURL">https://tania.uprrp.edu/inscripcionExperiencia.php</string>
31
-    <string name="withdrawalURL">https://tania.uprrp.edu/withdrawal.php</string>
32
-    <string name="userStatusBaseURL">https://tania.uprrp.edu/status.php?tk=</string>
33
-    <string name="assessmentsBaseURL">https://tania.uprrp.edu/getSubQ2.php?tk=</string>
27
+<!--    <string name="sendAnswersURL">https://tania.uprrp.edu/parseAnswers.php</string>-->
28
+<!--    <string name="activateExperienceURL">https://tania.uprrp.edu/inscripcionExperiencia.php</string>-->
29
+<!--    <string name="withdrawalURL">https://tania.uprrp.edu/withdrawal.php</string>-->
30
+<!--    <string name="userStatusBaseURL">https://tania.uprrp.edu/status.php?tk=</string>-->
31
+<!--    <string name="assessmentsBaseURL">https://tania.uprrp.edu/getSubQ2.php?tk=</string>-->
32
+<!--    <string name="loginBaseURL">https://tania.uprrp.edu/recoverAccount.php</string>-->
34
     <!--  General App Configurations  -->
33
     <!--  General App Configurations  -->
34
+    <string name="appName">TANIA</string>
35
     <string name="surveyToolbarText">Assessment</string>
35
     <string name="surveyToolbarText">Assessment</string>
36
+    <string name="tokenErrorText">There was an error…\nPlease come back later!</string>
36
     <!--  Assessment Fragment  -->
37
     <!--  Assessment Fragment  -->
37
     <string name="mainGreetingText">Hello! 👋</string>
38
     <string name="mainGreetingText">Hello! 👋</string>
38
     <string name="loadingText">Please wait a moment…</string>
39
     <string name="loadingText">Please wait a moment…</string>
42
     <!-- Withdraw Fragment -->
43
     <!-- Withdraw Fragment -->
43
     <string name="withdrawTitleText">Withdraw from Study</string>
44
     <string name="withdrawTitleText">Withdraw from Study</string>
44
     <string name="withdrawButtonText">Withdraw</string>
45
     <string name="withdrawButtonText">Withdraw</string>
45
-    <string name="withdrawing_text">If you no longer want to participate in this research study, you can choose to withdraw. By withdrawing, you understand that your decision is final and your account on TANIA will be removed without any chance of recovery.</string>
46
+    <string name="withdrawDescriptionText">If you no longer want to participate in this research study, you can choose to withdraw. By withdrawing, you understand that your decision is final and your account on TANIA will be removed without any chance of recovery.</string>
46
     <!--  Experience Registration Activity  -->
47
     <!--  Experience Registration Activity  -->
47
     <string name="experienceRegistrationTitleText">Activate Experience</string>
48
     <string name="experienceRegistrationTitleText">Activate Experience</string>
48
     <string name="experienceRegistrationDescriptionText">Click the button below to enter the research experience you are participating in.</string>
49
     <string name="experienceRegistrationDescriptionText">Click the button below to enter the research experience you are participating in.</string>