dataSet) {
}
}
- tabLayout.setOnTabSelectedListener(new IconTabLayout.OnTabSelectedListenerAdapter() {
+ tabLayout.addOnTabSelectedListener(new IconTabLayout.OnTabSelectedListenerAdapter() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
PieData data = dataSet.get(tab.getPosition());
@@ -187,6 +187,7 @@ public void onTabReselected(TabLayout.Tab tab) {
onTabSelected(tab);
}
});
+
}
public PieChart getChart() {
diff --git a/backbone/src/main/res/layout/rsb_item_chart_pie.xml b/chart/src/main/res/layout/rsfch_item_chart_pie.xml
similarity index 100%
rename from backbone/src/main/res/layout/rsb_item_chart_pie.xml
rename to chart/src/main/res/layout/rsfch_item_chart_pie.xml
diff --git a/backbone/src/main/res/layout/rsb_view_chart_bar.xml b/chart/src/main/res/layout/rsfch_view_chart_bar.xml
similarity index 88%
rename from backbone/src/main/res/layout/rsb_view_chart_bar.xml
rename to chart/src/main/res/layout/rsfch_view_chart_bar.xml
index e4d54686f..d65fa5e24 100644
--- a/backbone/src/main/res/layout/rsb_view_chart_bar.xml
+++ b/chart/src/main/res/layout/rsfch_view_chart_bar.xml
@@ -10,19 +10,19 @@
-
diff --git a/backbone/src/main/res/layout/rsb_view_chart_line.xml b/chart/src/main/res/layout/rsfch_view_chart_line.xml
similarity index 88%
rename from backbone/src/main/res/layout/rsb_view_chart_line.xml
rename to chart/src/main/res/layout/rsfch_view_chart_line.xml
index b587ad4dc..53890f152 100644
--- a/backbone/src/main/res/layout/rsb_view_chart_line.xml
+++ b/chart/src/main/res/layout/rsfch_view_chart_line.xml
@@ -11,19 +11,19 @@
-
diff --git a/backbone/src/main/res/layout/rsb_view_chart_pie.xml b/chart/src/main/res/layout/rsfch_view_chart_pie.xml
similarity index 95%
rename from backbone/src/main/res/layout/rsb_view_chart_pie.xml
rename to chart/src/main/res/layout/rsfch_view_chart_pie.xml
index cbb60ecdb..0235bbc5a 100644
--- a/backbone/src/main/res/layout/rsb_view_chart_pie.xml
+++ b/chart/src/main/res/layout/rsfch_view_chart_pie.xml
@@ -11,7 +11,7 @@
diff --git a/backbone/src/main/res/layout/rsb_view_chart_progress.xml b/chart/src/main/res/layout/rsfch_view_chart_progress.xml
similarity index 88%
rename from backbone/src/main/res/layout/rsb_view_chart_progress.xml
rename to chart/src/main/res/layout/rsfch_view_chart_progress.xml
index 9d97fe998..065a58dec 100644
--- a/backbone/src/main/res/layout/rsb_view_chart_progress.xml
+++ b/chart/src/main/res/layout/rsfch_view_chart_progress.xml
@@ -10,12 +10,12 @@
-
-
diff --git a/chart/src/main/res/values/attrs.xml b/chart/src/main/res/values/attrs.xml
new file mode 100644
index 000000000..7e97b251b
--- /dev/null
+++ b/chart/src/main/res/values/attrs.xml
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chart/src/main/res/values/strings.xml b/chart/src/main/res/values/strings.xml
new file mode 100644
index 000000000..854200555
--- /dev/null
+++ b/chart/src/main/res/values/strings.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/chart/src/main/res/values/styles.xml b/chart/src/main/res/values/styles.xml
new file mode 100644
index 000000000..1a0906c1e
--- /dev/null
+++ b/chart/src/main/res/values/styles.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chart/src/main/res/values/themes.xml b/chart/src/main/res/values/themes.xml
new file mode 100644
index 000000000..b879397f6
--- /dev/null
+++ b/chart/src/main/res/values/themes.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/chart/src/test/java/org/researchstack/feature/chart/ExampleUnitTest.java b/chart/src/test/java/org/researchstack/feature/chart/ExampleUnitTest.java
new file mode 100644
index 000000000..4ca3c32e3
--- /dev/null
+++ b/chart/src/test/java/org/researchstack/feature/chart/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package org.researchstack.feature.chart;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/consent/.gitignore b/consent/.gitignore
new file mode 100644
index 000000000..796b96d1c
--- /dev/null
+++ b/consent/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/consent/build.gradle b/consent/build.gradle
new file mode 100644
index 000000000..6ad7ed4c4
--- /dev/null
+++ b/consent/build.gradle
@@ -0,0 +1,167 @@
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+
+apply plugin: 'com.github.dcendents.android-maven'
+apply plugin: 'com.jfrog.bintray'
+
+version = research_stack_version
+
+android {
+ compileSdkVersion 28
+ defaultConfig {
+ minSdkVersion 19
+ targetSdkVersion 28
+ versionCode 1
+ versionName version
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+ resourcePrefix 'rsfc_'
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+Properties properties = new Properties()
+properties.load(project.rootProject.file('local.properties').newDataInputStream())
+
+ext {
+ bintrayRepo = 'ResearchStack'
+ bintrayName = 'Authentication'
+
+ publishedGroupId = 'org.researchstack'
+ libraryName = 'Consent'
+ artifact = 'consent'
+
+ libraryDescription = 'Consent'
+
+ siteUrl = 'https://researchstack.org'
+ gitUrl = 'https://github.com/ResearchStack/ResearchStack.git'
+
+ libraryVersion = version
+
+ userOrgName = 'researchstack'
+ developerId = properties.getProperty("bintray.user")
+ developerName = properties.getProperty("bintray.developerName")
+ developerEmail = properties.getProperty("bintray.developerEmail")
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+dependencies {
+ implementation fileTree(include: ['*.jar'], dir: 'libs')
+ implementation 'androidx.appcompat:appcompat:1.0.2'
+ implementation 'androidx.cardview:cardview:1.0.0'
+ implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
+ implementation 'com.google.android.material:material:1.0.0'
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+
+ implementation project(':foundation')
+ implementation "com.google.code.gson:gson:$gson_version"
+
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'androidx.test:runner:1.1.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
+}
+
+group = publishedGroupId // Maven Group ID for the artifact
+
+install {
+ repositories.mavenInstaller {
+ // This generates POM.xml with proper parameters
+ pom {
+ project {
+ packaging 'aar'
+ groupId publishedGroupId
+ artifactId artifact
+
+ // Add your description here
+ name libraryName
+ description libraryDescription
+ url siteUrl
+
+ // Set your license
+ licenses {
+ license {
+ name licenseName
+ url licenseUrl
+ }
+ }
+ developers {
+ developer {
+ id developerId
+ name developerName
+ email developerEmail
+ }
+ }
+ scm {
+ connection gitUrl
+ developerConnection gitUrl
+ url siteUrl
+ }
+ }
+ }
+ }
+}
+
+if (project.hasProperty("android")) { // Android libraries
+ task sourcesJar(type: Jar) {
+ classifier = 'sources'
+ from android.sourceSets.main.java.srcDirs
+ }
+
+ task javadoc(type: Javadoc) {
+ failOnError false
+ source = android.sourceSets.main.java.srcDirs
+ }
+
+ afterEvaluate {
+ javadoc.classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
+ javadoc.classpath += files(android.libraryVariants.collect { variant ->
+ variant.javaCompile.classpath.files
+ })
+ }
+} else { // Java libraries
+ task sourcesJar(type: Jar, dependsOn: classes) {
+ classifier = 'sources'
+ from sourceSets.main.allSource
+ }
+}
+
+task javadocJar(type: Jar, dependsOn: javadoc) {
+ classifier = 'javadoc'
+ from javadoc.destinationDir
+}
+
+artifacts {
+ archives javadocJar
+ archives sourcesJar
+}
+
+bintray {
+ user = properties.getProperty("bintray.user")
+ key = properties.getProperty("bintray.apikey")
+
+ configurations = ['archives']
+ pkg {
+ repo = bintrayRepo
+ name = bintrayName
+ userOrg = userOrgName
+ desc = libraryDescription
+ websiteUrl = siteUrl
+ vcsUrl = gitUrl
+ licenses = allLicenses
+ publish = true
+ }
+}
diff --git a/consent/proguard-rules.pro b/consent/proguard-rules.pro
new file mode 100644
index 000000000..f1b424510
--- /dev/null
+++ b/consent/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/consent/src/androidTest/java/org/researchstack/feature/consent/ExampleInstrumentedTest.java b/consent/src/androidTest/java/org/researchstack/feature/consent/ExampleInstrumentedTest.java
new file mode 100644
index 000000000..d5490dc3b
--- /dev/null
+++ b/consent/src/androidTest/java/org/researchstack/feature/consent/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package org.researchstack.feature.consent;
+
+import android.content.Context;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("org.researchstack.feature.consent.test", appContext.getPackageName());
+ }
+}
diff --git a/consent/src/main/AndroidManifest.xml b/consent/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..181af0c26
--- /dev/null
+++ b/consent/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
diff --git a/backbone/src/main/java/org/researchstack/backbone/model/ConsentDocument.java b/consent/src/main/java/org/researchstack/feature/consent/model/ConsentDocument.java
similarity index 97%
rename from backbone/src/main/java/org/researchstack/backbone/model/ConsentDocument.java
rename to consent/src/main/java/org/researchstack/feature/consent/model/ConsentDocument.java
index c83f713dc..fd0533227 100644
--- a/backbone/src/main/java/org/researchstack/backbone/model/ConsentDocument.java
+++ b/consent/src/main/java/org/researchstack/feature/consent/model/ConsentDocument.java
@@ -1,6 +1,6 @@
-package org.researchstack.backbone.model;
+package org.researchstack.feature.consent.model;
-import android.support.annotation.StringRes;
+import androidx.annotation.StringRes;
import java.io.Serializable;
import java.util.ArrayList;
diff --git a/backbone/src/main/java/org/researchstack/backbone/model/ConsentSection.java b/consent/src/main/java/org/researchstack/feature/consent/model/ConsentSection.java
similarity index 83%
rename from backbone/src/main/java/org/researchstack/backbone/model/ConsentSection.java
rename to consent/src/main/java/org/researchstack/feature/consent/model/ConsentSection.java
index 13f232117..976e34b2b 100644
--- a/backbone/src/main/java/org/researchstack/backbone/model/ConsentSection.java
+++ b/consent/src/main/java/org/researchstack/feature/consent/model/ConsentSection.java
@@ -1,9 +1,9 @@
-package org.researchstack.backbone.model;
+package org.researchstack.feature.consent.model;
import com.google.gson.annotations.SerializedName;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.utils.TextUtils;
+import org.researchstack.feature.consent.R;
+import org.researchstack.foundation.components.utils.TextUtils;
import java.io.Serializable;
@@ -73,7 +73,7 @@ public class ConsentSection implements Serializable {
* A custom illustration for the consent.
*
* The custom image can override the image associated with any of the predefined section types
- * for an {@link org.researchstack.backbone.step.ConsentVisualStep} object. It is ignored for a
+ * for an {@link org.researchstack.foundation.step.ConsentVisualStep} object. It is ignored for a
* consent review step and for PDF generation.
*
* The image is used in template rendering mode, and is tinted using the tint color.
@@ -267,21 +267,21 @@ public enum Type implements Serializable {
public int getTitleResId() {
switch (this) {
case Overview:
- return R.string.rsb_consent_section_welcome;
+ return R.string.rsfc_consent_section_welcome;
case DataGathering:
- return R.string.rsb_consent_section_data_gathering;
+ return R.string.rsfc_consent_section_data_gathering;
case Privacy:
- return R.string.rsb_consent_section_privacy;
+ return R.string.rsfc_consent_section_privacy;
case DataUse:
- return R.string.rsb_consent_section_data_use;
+ return R.string.rsfc_consent_section_data_use;
case TimeCommitment:
- return R.string.rsb_consent_section_time_commitment;
+ return R.string.rsfc_consent_section_time_commitment;
case StudySurvey:
- return R.string.rsb_consent_section_study_survey;
+ return R.string.rsfc_consent_section_study_survey;
case StudyTasks:
- return R.string.rsb_consent_section_study_tasks;
+ return R.string.rsfc_consent_section_study_tasks;
case Withdrawing:
- return R.string.rsb_consent_section_withdrawing;
+ return R.string.rsfc_consent_section_withdrawing;
default:
return -1;
}
@@ -290,19 +290,19 @@ public int getTitleResId() {
public String getImageName() {
switch (this) {
case DataGathering:
- return "rsb_consent_section_data_gathering";
+ return "rsfc_consent_section_data_gathering";
case Privacy:
- return "rsb_consent_section_privacy";
+ return "rsfc_consent_section_privacy";
case DataUse:
- return "rsb_consent_section_data_use";
+ return "rsfc_consent_section_data_use";
case TimeCommitment:
- return "rsb_consent_section_time_commitment";
+ return "rsfc_consent_section_time_commitment";
case StudySurvey:
- return "rsb_consent_section_study_survey";
+ return "rsfc_consent_section_study_survey";
case StudyTasks:
- return "rsb_consent_section_study_tasks";
+ return "rsfc_consent_section_study_tasks";
case Withdrawing:
- return "rsb_consent_section_withdrawing";
+ return "rsfc_consent_section_withdrawing";
default:
return null;
}
@@ -311,23 +311,23 @@ public String getImageName() {
public int getMoreInfoResId() {
switch (this) {
case Overview:
- return R.string.rsb_consent_section_more_info_welcome;
+ return R.string.rsfc_consent_section_more_info_welcome;
case DataGathering:
- return R.string.rsb_consent_section_more_info_data_gathering;
+ return R.string.rsfc_consent_section_more_info_data_gathering;
case Privacy:
- return R.string.rsb_consent_section_more_info_privacy;
+ return R.string.rsfc_consent_section_more_info_privacy;
case DataUse:
- return R.string.rsb_consent_section_more_info_data_use;
+ return R.string.rsfc_consent_section_more_info_data_use;
case TimeCommitment:
- return R.string.rsb_consent_section_more_info_time_commitment;
+ return R.string.rsfc_consent_section_more_info_time_commitment;
case StudySurvey:
- return R.string.rsb_consent_section_more_info_study_survey;
+ return R.string.rsfc_consent_section_more_info_study_survey;
case StudyTasks:
- return R.string.rsb_consent_section_more_info_study_tasks;
+ return R.string.rsfc_consent_section_more_info_study_tasks;
case Withdrawing:
- return R.string.rsb_consent_section_more_info_withdrawing;
+ return R.string.rsfc_consent_section_more_info_withdrawing;
default:
- return R.string.rsb_consent_section_more_info;
+ return R.string.rsfc_consent_section_more_info;
}
}
diff --git a/backbone/src/main/java/org/researchstack/backbone/model/ConsentSignature.java b/consent/src/main/java/org/researchstack/feature/consent/model/ConsentSignature.java
similarity index 98%
rename from backbone/src/main/java/org/researchstack/backbone/model/ConsentSignature.java
rename to consent/src/main/java/org/researchstack/feature/consent/model/ConsentSignature.java
index 1a27e7ea3..dc840a45b 100644
--- a/backbone/src/main/java/org/researchstack/backbone/model/ConsentSignature.java
+++ b/consent/src/main/java/org/researchstack/feature/consent/model/ConsentSignature.java
@@ -1,6 +1,6 @@
-package org.researchstack.backbone.model;
+package org.researchstack.feature.consent.model;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
import java.io.Serializable;
import java.util.UUID;
diff --git a/backbone/src/main/java/org/researchstack/backbone/step/ConsentDocumentStep.java b/consent/src/main/java/org/researchstack/feature/consent/step/ConsentDocumentStep.java
similarity index 85%
rename from backbone/src/main/java/org/researchstack/backbone/step/ConsentDocumentStep.java
rename to consent/src/main/java/org/researchstack/feature/consent/step/ConsentDocumentStep.java
index a587fe68b..b444b5e72 100644
--- a/backbone/src/main/java/org/researchstack/backbone/step/ConsentDocumentStep.java
+++ b/consent/src/main/java/org/researchstack/feature/consent/step/ConsentDocumentStep.java
@@ -1,7 +1,8 @@
-package org.researchstack.backbone.step;
+package org.researchstack.feature.consent.step;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.ui.step.layout.ConsentDocumentStepLayout;
+import org.researchstack.feature.consent.R;
+import org.researchstack.feature.consent.ui.layout.ConsentDocumentStepLayout;
+import org.researchstack.foundation.core.models.step.Step;
/**
* This step shows an HTML version of your consent document to the user and allows them to indicate
@@ -18,7 +19,7 @@ public ConsentDocumentStep(String identifier) {
@Override
public int getStepTitle() {
- return R.string.rsb_consent;
+ return R.string.rsfc_consent;
}
@Override
diff --git a/backbone/src/main/java/org/researchstack/backbone/step/ConsentSharingStep.java b/consent/src/main/java/org/researchstack/feature/consent/step/ConsentSharingStep.java
similarity index 68%
rename from backbone/src/main/java/org/researchstack/backbone/step/ConsentSharingStep.java
rename to consent/src/main/java/org/researchstack/feature/consent/step/ConsentSharingStep.java
index ca27ec0d1..00c051ad8 100644
--- a/backbone/src/main/java/org/researchstack/backbone/step/ConsentSharingStep.java
+++ b/consent/src/main/java/org/researchstack/feature/consent/step/ConsentSharingStep.java
@@ -1,6 +1,7 @@
-package org.researchstack.backbone.step;
+package org.researchstack.feature.consent.step;
-import org.researchstack.backbone.ui.step.body.SingleChoiceQuestionBody;
+import org.researchstack.foundation.components.survey.step.QuestionStep;
+import org.researchstack.foundation.components.survey.ui.body.SingleChoiceQuestionBody;
/**
* This class represents a question step that includes prepopulated content that asks users about
diff --git a/backbone/src/main/java/org/researchstack/backbone/step/ConsentSignatureStep.java b/consent/src/main/java/org/researchstack/feature/consent/step/ConsentSignatureStep.java
similarity index 92%
rename from backbone/src/main/java/org/researchstack/backbone/step/ConsentSignatureStep.java
rename to consent/src/main/java/org/researchstack/feature/consent/step/ConsentSignatureStep.java
index 3cf36e23e..cd30f3581 100644
--- a/backbone/src/main/java/org/researchstack/backbone/step/ConsentSignatureStep.java
+++ b/consent/src/main/java/org/researchstack/feature/consent/step/ConsentSignatureStep.java
@@ -1,4 +1,6 @@
-package org.researchstack.backbone.step;
+package org.researchstack.feature.consent.step;
+
+import org.researchstack.foundation.core.models.step.Step;
/**
* This class represents the final step in the consent process, collecting the signature from the
diff --git a/backbone/src/main/java/org/researchstack/backbone/step/ConsentVisualStep.java b/consent/src/main/java/org/researchstack/feature/consent/step/ConsentVisualStep.java
similarity index 81%
rename from backbone/src/main/java/org/researchstack/backbone/step/ConsentVisualStep.java
rename to consent/src/main/java/org/researchstack/feature/consent/step/ConsentVisualStep.java
index 00ca0d6df..8e9f35440 100644
--- a/backbone/src/main/java/org/researchstack/backbone/step/ConsentVisualStep.java
+++ b/consent/src/main/java/org/researchstack/feature/consent/step/ConsentVisualStep.java
@@ -1,7 +1,9 @@
-package org.researchstack.backbone.step;
+package org.researchstack.feature.consent.step;
-import org.researchstack.backbone.model.ConsentSection;
-import org.researchstack.backbone.ui.step.layout.ConsentVisualStepLayout;
+import org.researchstack.feature.consent.R;
+import org.researchstack.feature.consent.model.ConsentSection;
+import org.researchstack.feature.consent.ui.layout.ConsentVisualStepLayout;
+import org.researchstack.foundation.core.models.step.Step;
/**
* The {@link ConsentVisualStep} class represents a step in the visual consent sequence.
@@ -21,7 +23,7 @@ public ConsentVisualStep(String identifier) {
@Override
public int getStepTitle() {
- return org.researchstack.backbone.R.string.rsb_consent;
+ return R.string.rsfc_consent;
}
@Override
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/callbacks/SignatureCallbacks.java b/consent/src/main/java/org/researchstack/feature/consent/ui/callbacks/SignatureCallbacks.java
similarity index 65%
rename from backbone/src/main/java/org/researchstack/backbone/ui/callbacks/SignatureCallbacks.java
rename to consent/src/main/java/org/researchstack/feature/consent/ui/callbacks/SignatureCallbacks.java
index 096857845..e46fd1c76 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/callbacks/SignatureCallbacks.java
+++ b/consent/src/main/java/org/researchstack/feature/consent/ui/callbacks/SignatureCallbacks.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.ui.callbacks;
+package org.researchstack.feature.consent.ui.callbacks;
public interface SignatureCallbacks {
void onSignatureStarted();
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/step/layout/ConsentDocumentStepLayout.java b/consent/src/main/java/org/researchstack/feature/consent/ui/layout/ConsentDocumentStepLayout.java
similarity index 75%
rename from backbone/src/main/java/org/researchstack/backbone/ui/step/layout/ConsentDocumentStepLayout.java
rename to consent/src/main/java/org/researchstack/feature/consent/ui/layout/ConsentDocumentStepLayout.java
index fd1a297b1..34730d814 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/step/layout/ConsentDocumentStepLayout.java
+++ b/consent/src/main/java/org/researchstack/feature/consent/ui/layout/ConsentDocumentStepLayout.java
@@ -1,19 +1,20 @@
-package org.researchstack.backbone.ui.step.layout;
+package org.researchstack.feature.consent.ui.layout;
import android.content.Context;
-import android.support.v7.app.AlertDialog;
+import androidx.appcompat.app.AlertDialog;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.webkit.WebView;
import android.widget.LinearLayout;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.ConsentDocumentStep;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.ui.callbacks.StepCallbacks;
-import org.researchstack.backbone.ui.views.SubmitBar;
+import org.researchstack.feature.consent.R;
+import org.researchstack.foundation.components.common.ui.callbacks.StepCallbacks;
+import org.researchstack.foundation.components.common.ui.layout.StepLayout;
+import org.researchstack.foundation.components.common.ui.views.SubmitBar;
+import org.researchstack.feature.consent.step.ConsentDocumentStep;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
/**
* Implement saved state for the following objects:
@@ -75,7 +76,7 @@ public void setCallbacks(StepCallbacks callbacks) {
private void initializeStep() {
setOrientation(VERTICAL);
- LayoutInflater.from(getContext()).inflate(R.layout.rsb_step_layout_consent_doc, this, true);
+ LayoutInflater.from(getContext()).inflate(R.layout.rsfc_step_layout_consent_doc, this, true);
WebView pdfView = (WebView) findViewById(R.id.webview);
pdfView.loadData(htmlContent, "text/html; charset=UTF-8", null);
@@ -86,14 +87,14 @@ private void initializeStep() {
}
private void showDialog() {
- new AlertDialog.Builder(getContext()).setTitle(R.string.rsb_consent_review_alert_title)
+ new AlertDialog.Builder(getContext()).setTitle(R.string.rsfc_consent_review_alert_title)
.setMessage(confirmationDialogBody)
.setCancelable(false)
- .setPositiveButton(R.string.rsb_agree, (dialog, which) -> {
+ .setPositiveButton(R.string.rsf_agree, (dialog, which) -> {
stepResult.setResult(true);
callbacks.onSaveStep(StepCallbacks.ACTION_NEXT, step, stepResult);
})
- .setNegativeButton(R.string.rsb_consent_review_cancel, (dialog, which) -> {
+ .setNegativeButton(R.string.rsfc_consent_review_cancel, (dialog, which) -> {
// Gives them a chance to read it again
})
.show();
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/step/layout/ConsentSignatureStepLayout.java b/consent/src/main/java/org/researchstack/feature/consent/ui/layout/ConsentSignatureStepLayout.java
similarity index 81%
rename from backbone/src/main/java/org/researchstack/backbone/ui/step/layout/ConsentSignatureStepLayout.java
rename to consent/src/main/java/org/researchstack/feature/consent/ui/layout/ConsentSignatureStepLayout.java
index 2c7ba7734..5c3300c1f 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/step/layout/ConsentSignatureStepLayout.java
+++ b/consent/src/main/java/org/researchstack/feature/consent/ui/layout/ConsentSignatureStepLayout.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.ui.step.layout;
+package org.researchstack.feature.consent.ui.layout;
import android.content.Context;
import android.graphics.Bitmap;
@@ -10,18 +10,17 @@
import android.widget.TextView;
import android.widget.Toast;
-import com.jakewharton.rxbinding.view.RxView;
-
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.ConsentSignatureStep;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.ui.callbacks.SignatureCallbacks;
-import org.researchstack.backbone.ui.callbacks.StepCallbacks;
-import org.researchstack.backbone.ui.views.SignatureView;
-import org.researchstack.backbone.ui.views.SubmitBar;
-import org.researchstack.backbone.utils.FormatHelper;
-import org.researchstack.backbone.utils.TextUtils;
+import org.researchstack.feature.consent.R;
+import org.researchstack.foundation.components.common.ui.callbacks.StepCallbacks;
+import org.researchstack.foundation.components.common.ui.layout.StepLayout;
+import org.researchstack.foundation.components.common.ui.views.SubmitBar;
+import org.researchstack.feature.consent.step.ConsentSignatureStep;
+import org.researchstack.feature.consent.ui.callbacks.SignatureCallbacks;
+import org.researchstack.feature.consent.ui.views.SignatureView;
+import org.researchstack.foundation.components.utils.FormatHelper;
+import org.researchstack.foundation.components.utils.TextUtils;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
import java.io.ByteArrayOutputStream;
import java.text.DateFormat;
@@ -76,7 +75,7 @@ public void setCallbacks(StepCallbacks callbacks) {
private void initializeStep() {
LayoutInflater.from(getContext())
- .inflate(R.layout.rsb_step_layout_consent_signature, this, true);
+ .inflate(R.layout.rsfc_step_layout_consent_signature, this, true);
TextView title = (TextView) findViewById(R.id.title);
title.setText(step.getTitle());
@@ -101,7 +100,7 @@ public void onSignatureCleared() {
}
});
- RxView.clicks(clear).subscribe(v -> {
+ clear.setOnClickListener(v -> {
signatureView.clearSignature();
});
@@ -117,7 +116,7 @@ public void onSignatureCleared() {
setDataToResult();
callbacks.onSaveStep(StepCallbacks.ACTION_NEXT, step, result);
} else {
- Toast.makeText(getContext(), R.string.rsb_error_invalid_signature, Toast.LENGTH_SHORT).show();
+ Toast.makeText(getContext(), R.string.rsf_error_invalid_signature, Toast.LENGTH_SHORT).show();
}
});
}
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/step/layout/ConsentVisualStepLayout.java b/consent/src/main/java/org/researchstack/feature/consent/ui/layout/ConsentVisualStepLayout.java
similarity index 77%
rename from backbone/src/main/java/org/researchstack/backbone/ui/step/layout/ConsentVisualStepLayout.java
rename to consent/src/main/java/org/researchstack/feature/consent/ui/layout/ConsentVisualStepLayout.java
index 815c13095..cfa39cd6e 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/step/layout/ConsentVisualStepLayout.java
+++ b/consent/src/main/java/org/researchstack/feature/consent/ui/layout/ConsentVisualStepLayout.java
@@ -1,29 +1,28 @@
-package org.researchstack.backbone.ui.step.layout;
+package org.researchstack.feature.consent.ui.layout;
import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
-import android.support.v4.graphics.drawable.DrawableCompat;
+import androidx.core.graphics.drawable.DrawableCompat;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
-import com.jakewharton.rxbinding.view.RxView;
-
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.model.ConsentSection;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.ConsentVisualStep;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.ui.ViewWebDocumentActivity;
-import org.researchstack.backbone.ui.callbacks.StepCallbacks;
-import org.researchstack.backbone.ui.views.FixedSubmitBarLayout;
-import org.researchstack.backbone.ui.views.SubmitBar;
-import org.researchstack.backbone.utils.ResUtils;
-import org.researchstack.backbone.utils.TextUtils;
+import org.researchstack.feature.consent.R;
+import org.researchstack.foundation.components.common.ui.callbacks.StepCallbacks;
+import org.researchstack.foundation.components.common.ui.layout.FixedSubmitBarLayout;
+import org.researchstack.foundation.components.common.ui.layout.StepLayout;
+import org.researchstack.foundation.components.common.ui.views.SubmitBar;
+import org.researchstack.feature.consent.model.ConsentSection;
+import org.researchstack.feature.consent.step.ConsentVisualStep;
+import org.researchstack.foundation.components.utils.ResUtils;
+import org.researchstack.foundation.components.utils.TextUtils;
+import org.researchstack.foundation.components.web.ui.activities.ViewWebDocumentActivity;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
public class ConsentVisualStepLayout extends FixedSubmitBarLayout implements StepLayout {
@@ -66,7 +65,7 @@ public void setCallbacks(StepCallbacks callbacks) {
@Override
public int getContentResourceId() {
- return R.layout.rsb_step_layout_consent_visual;
+ return R.layout.rsfc_step_layout_consent_visual;
}
private void initializeStep() {
@@ -117,8 +116,8 @@ private void initializeStep() {
moreInfoView.setText(data.getType().getMoreInfoResId());
}
- RxView.clicks(moreInfoView).subscribe(v -> {
- String webTitle = getResources().getString(R.string.rsb_consent_section_more_info);
+ moreInfoView.setOnClickListener(v -> {
+ String webTitle = getResources().getString(R.string.rsfc_consent_section_more_info);
Intent webDoc = ViewWebDocumentActivity.newIntentForContent(getContext(), webTitle,
TextUtils.isEmpty(data.getContent()) ? data.getHtmlContent() : data.getContent());
getContext().startActivity(webDoc);
@@ -127,7 +126,7 @@ private void initializeStep() {
moreInfoView.setVisibility(View.GONE);
}
- SubmitBar submitBar = (SubmitBar) findViewById(R.id.rsb_submit_bar);
+ SubmitBar submitBar = (SubmitBar) findViewById(R.id.rsf_submit_bar);
submitBar.setPositiveTitle(step.getNextButtonString());
submitBar.setPositiveAction(v -> callbacks.onSaveStep(StepCallbacks.ACTION_NEXT,
step,
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/views/SignatureView.java b/consent/src/main/java/org/researchstack/feature/consent/ui/views/SignatureView.java
similarity index 97%
rename from backbone/src/main/java/org/researchstack/backbone/ui/views/SignatureView.java
rename to consent/src/main/java/org/researchstack/feature/consent/ui/views/SignatureView.java
index c06faa3d1..fe4b4ab22 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/views/SignatureView.java
+++ b/consent/src/main/java/org/researchstack/feature/consent/ui/views/SignatureView.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.ui.views;
+package org.researchstack.feature.consent.ui.views;
import android.content.Context;
import android.content.res.TypedArray;
@@ -14,13 +14,13 @@
import android.graphics.drawable.shapes.PathShape;
import android.os.Parcel;
import android.os.Parcelable;
-import android.support.v4.view.ViewCompat;
+import androidx.core.view.ViewCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.ui.callbacks.SignatureCallbacks;
+import org.researchstack.feature.consent.R;
+import org.researchstack.feature.consent.ui.callbacks.SignatureCallbacks;
import java.util.ArrayList;
import java.util.List;
@@ -78,7 +78,7 @@ private void init(Context context, AttributeSet attrs, int defStyleAttr) {
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.SignatureView,
defStyleAttr,
- R.style.Widget_Backbone_SignatureView);
+ R.style.Widget_Feature_Consent_SignatureView);
int signatureColor = a.getColor(R.styleable.SignatureView_signatureColor, Color.BLACK);
diff --git a/backbone/src/main/res/drawable-hdpi/rsb_consent_section_data_gathering.png b/consent/src/main/res/drawable-hdpi/rsfc_consent_section_data_gathering.png
similarity index 100%
rename from backbone/src/main/res/drawable-hdpi/rsb_consent_section_data_gathering.png
rename to consent/src/main/res/drawable-hdpi/rsfc_consent_section_data_gathering.png
diff --git a/backbone/src/main/res/drawable-hdpi/rsb_consent_section_data_use.png b/consent/src/main/res/drawable-hdpi/rsfc_consent_section_data_use.png
similarity index 100%
rename from backbone/src/main/res/drawable-hdpi/rsb_consent_section_data_use.png
rename to consent/src/main/res/drawable-hdpi/rsfc_consent_section_data_use.png
diff --git a/backbone/src/main/res/drawable-hdpi/rsb_consent_section_potential_benefits_alt.png b/consent/src/main/res/drawable-hdpi/rsfc_consent_section_potential_benefits_alt.png
similarity index 100%
rename from backbone/src/main/res/drawable-hdpi/rsb_consent_section_potential_benefits_alt.png
rename to consent/src/main/res/drawable-hdpi/rsfc_consent_section_potential_benefits_alt.png
diff --git a/backbone/src/main/res/drawable-hdpi/rsb_consent_section_privacy.png b/consent/src/main/res/drawable-hdpi/rsfc_consent_section_privacy.png
similarity index 100%
rename from backbone/src/main/res/drawable-hdpi/rsb_consent_section_privacy.png
rename to consent/src/main/res/drawable-hdpi/rsfc_consent_section_privacy.png
diff --git a/backbone/src/main/res/drawable-hdpi/rsb_consent_section_recontact.png b/consent/src/main/res/drawable-hdpi/rsfc_consent_section_recontact.png
similarity index 100%
rename from backbone/src/main/res/drawable-hdpi/rsb_consent_section_recontact.png
rename to consent/src/main/res/drawable-hdpi/rsfc_consent_section_recontact.png
diff --git a/backbone/src/main/res/drawable-hdpi/rsb_consent_section_study_survey.png b/consent/src/main/res/drawable-hdpi/rsfc_consent_section_study_survey.png
similarity index 100%
rename from backbone/src/main/res/drawable-hdpi/rsb_consent_section_study_survey.png
rename to consent/src/main/res/drawable-hdpi/rsfc_consent_section_study_survey.png
diff --git a/backbone/src/main/res/drawable-hdpi/rsb_consent_section_study_tasks.png b/consent/src/main/res/drawable-hdpi/rsfc_consent_section_study_tasks.png
similarity index 100%
rename from backbone/src/main/res/drawable-hdpi/rsb_consent_section_study_tasks.png
rename to consent/src/main/res/drawable-hdpi/rsfc_consent_section_study_tasks.png
diff --git a/backbone/src/main/res/drawable-hdpi/rsb_consent_section_time_commitment.png b/consent/src/main/res/drawable-hdpi/rsfc_consent_section_time_commitment.png
similarity index 100%
rename from backbone/src/main/res/drawable-hdpi/rsb_consent_section_time_commitment.png
rename to consent/src/main/res/drawable-hdpi/rsfc_consent_section_time_commitment.png
diff --git a/backbone/src/main/res/drawable-hdpi/rsb_consent_section_visiting_doctor.png b/consent/src/main/res/drawable-hdpi/rsfc_consent_section_visiting_doctor.png
similarity index 100%
rename from backbone/src/main/res/drawable-hdpi/rsb_consent_section_visiting_doctor.png
rename to consent/src/main/res/drawable-hdpi/rsfc_consent_section_visiting_doctor.png
diff --git a/backbone/src/main/res/drawable-hdpi/rsb_consent_section_withdrawing.png b/consent/src/main/res/drawable-hdpi/rsfc_consent_section_withdrawing.png
similarity index 100%
rename from backbone/src/main/res/drawable-hdpi/rsb_consent_section_withdrawing.png
rename to consent/src/main/res/drawable-hdpi/rsfc_consent_section_withdrawing.png
diff --git a/backbone/src/main/res/drawable-mdpi/rsb_consent_section_data_gathering.png b/consent/src/main/res/drawable-mdpi/rsfc_consent_section_data_gathering.png
similarity index 100%
rename from backbone/src/main/res/drawable-mdpi/rsb_consent_section_data_gathering.png
rename to consent/src/main/res/drawable-mdpi/rsfc_consent_section_data_gathering.png
diff --git a/backbone/src/main/res/drawable-mdpi/rsb_consent_section_data_use.png b/consent/src/main/res/drawable-mdpi/rsfc_consent_section_data_use.png
similarity index 100%
rename from backbone/src/main/res/drawable-mdpi/rsb_consent_section_data_use.png
rename to consent/src/main/res/drawable-mdpi/rsfc_consent_section_data_use.png
diff --git a/backbone/src/main/res/drawable-mdpi/rsb_consent_section_potential_benefits_alt.png b/consent/src/main/res/drawable-mdpi/rsfc_consent_section_potential_benefits_alt.png
similarity index 100%
rename from backbone/src/main/res/drawable-mdpi/rsb_consent_section_potential_benefits_alt.png
rename to consent/src/main/res/drawable-mdpi/rsfc_consent_section_potential_benefits_alt.png
diff --git a/backbone/src/main/res/drawable-mdpi/rsb_consent_section_privacy.png b/consent/src/main/res/drawable-mdpi/rsfc_consent_section_privacy.png
similarity index 100%
rename from backbone/src/main/res/drawable-mdpi/rsb_consent_section_privacy.png
rename to consent/src/main/res/drawable-mdpi/rsfc_consent_section_privacy.png
diff --git a/backbone/src/main/res/drawable-mdpi/rsb_consent_section_recontact.png b/consent/src/main/res/drawable-mdpi/rsfc_consent_section_recontact.png
similarity index 100%
rename from backbone/src/main/res/drawable-mdpi/rsb_consent_section_recontact.png
rename to consent/src/main/res/drawable-mdpi/rsfc_consent_section_recontact.png
diff --git a/backbone/src/main/res/drawable-mdpi/rsb_consent_section_study_survey.png b/consent/src/main/res/drawable-mdpi/rsfc_consent_section_study_survey.png
similarity index 100%
rename from backbone/src/main/res/drawable-mdpi/rsb_consent_section_study_survey.png
rename to consent/src/main/res/drawable-mdpi/rsfc_consent_section_study_survey.png
diff --git a/backbone/src/main/res/drawable-mdpi/rsb_consent_section_study_tasks.png b/consent/src/main/res/drawable-mdpi/rsfc_consent_section_study_tasks.png
similarity index 100%
rename from backbone/src/main/res/drawable-mdpi/rsb_consent_section_study_tasks.png
rename to consent/src/main/res/drawable-mdpi/rsfc_consent_section_study_tasks.png
diff --git a/backbone/src/main/res/drawable-mdpi/rsb_consent_section_time_commitment.png b/consent/src/main/res/drawable-mdpi/rsfc_consent_section_time_commitment.png
similarity index 100%
rename from backbone/src/main/res/drawable-mdpi/rsb_consent_section_time_commitment.png
rename to consent/src/main/res/drawable-mdpi/rsfc_consent_section_time_commitment.png
diff --git a/backbone/src/main/res/drawable-mdpi/rsb_consent_section_visiting_doctor.png b/consent/src/main/res/drawable-mdpi/rsfc_consent_section_visiting_doctor.png
similarity index 100%
rename from backbone/src/main/res/drawable-mdpi/rsb_consent_section_visiting_doctor.png
rename to consent/src/main/res/drawable-mdpi/rsfc_consent_section_visiting_doctor.png
diff --git a/backbone/src/main/res/drawable-mdpi/rsb_consent_section_withdrawing.png b/consent/src/main/res/drawable-mdpi/rsfc_consent_section_withdrawing.png
similarity index 100%
rename from backbone/src/main/res/drawable-mdpi/rsb_consent_section_withdrawing.png
rename to consent/src/main/res/drawable-mdpi/rsfc_consent_section_withdrawing.png
diff --git a/backbone/src/main/res/drawable-xhdpi/rsb_consent_section_data_gathering.png b/consent/src/main/res/drawable-xhdpi/rsfc_consent_section_data_gathering.png
similarity index 100%
rename from backbone/src/main/res/drawable-xhdpi/rsb_consent_section_data_gathering.png
rename to consent/src/main/res/drawable-xhdpi/rsfc_consent_section_data_gathering.png
diff --git a/backbone/src/main/res/drawable-xhdpi/rsb_consent_section_data_use.png b/consent/src/main/res/drawable-xhdpi/rsfc_consent_section_data_use.png
similarity index 100%
rename from backbone/src/main/res/drawable-xhdpi/rsb_consent_section_data_use.png
rename to consent/src/main/res/drawable-xhdpi/rsfc_consent_section_data_use.png
diff --git a/backbone/src/main/res/drawable-xhdpi/rsb_consent_section_potential_benefits_alt.png b/consent/src/main/res/drawable-xhdpi/rsfc_consent_section_potential_benefits_alt.png
similarity index 100%
rename from backbone/src/main/res/drawable-xhdpi/rsb_consent_section_potential_benefits_alt.png
rename to consent/src/main/res/drawable-xhdpi/rsfc_consent_section_potential_benefits_alt.png
diff --git a/backbone/src/main/res/drawable-xhdpi/rsb_consent_section_privacy.png b/consent/src/main/res/drawable-xhdpi/rsfc_consent_section_privacy.png
similarity index 100%
rename from backbone/src/main/res/drawable-xhdpi/rsb_consent_section_privacy.png
rename to consent/src/main/res/drawable-xhdpi/rsfc_consent_section_privacy.png
diff --git a/backbone/src/main/res/drawable-xhdpi/rsb_consent_section_recontact.png b/consent/src/main/res/drawable-xhdpi/rsfc_consent_section_recontact.png
similarity index 100%
rename from backbone/src/main/res/drawable-xhdpi/rsb_consent_section_recontact.png
rename to consent/src/main/res/drawable-xhdpi/rsfc_consent_section_recontact.png
diff --git a/backbone/src/main/res/drawable-xhdpi/rsb_consent_section_study_survey.png b/consent/src/main/res/drawable-xhdpi/rsfc_consent_section_study_survey.png
similarity index 100%
rename from backbone/src/main/res/drawable-xhdpi/rsb_consent_section_study_survey.png
rename to consent/src/main/res/drawable-xhdpi/rsfc_consent_section_study_survey.png
diff --git a/backbone/src/main/res/drawable-xhdpi/rsb_consent_section_study_tasks.png b/consent/src/main/res/drawable-xhdpi/rsfc_consent_section_study_tasks.png
similarity index 100%
rename from backbone/src/main/res/drawable-xhdpi/rsb_consent_section_study_tasks.png
rename to consent/src/main/res/drawable-xhdpi/rsfc_consent_section_study_tasks.png
diff --git a/backbone/src/main/res/drawable-xhdpi/rsb_consent_section_time_commitment.png b/consent/src/main/res/drawable-xhdpi/rsfc_consent_section_time_commitment.png
similarity index 100%
rename from backbone/src/main/res/drawable-xhdpi/rsb_consent_section_time_commitment.png
rename to consent/src/main/res/drawable-xhdpi/rsfc_consent_section_time_commitment.png
diff --git a/backbone/src/main/res/drawable-xhdpi/rsb_consent_section_visiting_doctor.png b/consent/src/main/res/drawable-xhdpi/rsfc_consent_section_visiting_doctor.png
similarity index 100%
rename from backbone/src/main/res/drawable-xhdpi/rsb_consent_section_visiting_doctor.png
rename to consent/src/main/res/drawable-xhdpi/rsfc_consent_section_visiting_doctor.png
diff --git a/backbone/src/main/res/drawable-xhdpi/rsb_consent_section_withdrawing.png b/consent/src/main/res/drawable-xhdpi/rsfc_consent_section_withdrawing.png
similarity index 100%
rename from backbone/src/main/res/drawable-xhdpi/rsb_consent_section_withdrawing.png
rename to consent/src/main/res/drawable-xhdpi/rsfc_consent_section_withdrawing.png
diff --git a/backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_data_gathering.png b/consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_data_gathering.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_data_gathering.png
rename to consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_data_gathering.png
diff --git a/backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_data_use.png b/consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_data_use.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_data_use.png
rename to consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_data_use.png
diff --git a/backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_potential_benefits_alt.png b/consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_potential_benefits_alt.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_potential_benefits_alt.png
rename to consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_potential_benefits_alt.png
diff --git a/backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_privacy.png b/consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_privacy.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_privacy.png
rename to consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_privacy.png
diff --git a/backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_recontact.png b/consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_recontact.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_recontact.png
rename to consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_recontact.png
diff --git a/backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_study_survey.png b/consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_study_survey.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_study_survey.png
rename to consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_study_survey.png
diff --git a/backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_study_tasks.png b/consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_study_tasks.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_study_tasks.png
rename to consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_study_tasks.png
diff --git a/backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_time_commitment.png b/consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_time_commitment.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_time_commitment.png
rename to consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_time_commitment.png
diff --git a/backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_visiting_doctor.png b/consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_visiting_doctor.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_visiting_doctor.png
rename to consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_visiting_doctor.png
diff --git a/backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_withdrawing.png b/consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_withdrawing.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxhdpi/rsb_consent_section_withdrawing.png
rename to consent/src/main/res/drawable-xxhdpi/rsfc_consent_section_withdrawing.png
diff --git a/backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_data_gathering.png b/consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_data_gathering.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_data_gathering.png
rename to consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_data_gathering.png
diff --git a/backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_data_use.png b/consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_data_use.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_data_use.png
rename to consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_data_use.png
diff --git a/backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_potential_benefits_alt.png b/consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_potential_benefits_alt.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_potential_benefits_alt.png
rename to consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_potential_benefits_alt.png
diff --git a/backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_privacy.png b/consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_privacy.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_privacy.png
rename to consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_privacy.png
diff --git a/backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_recontact.png b/consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_recontact.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_recontact.png
rename to consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_recontact.png
diff --git a/backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_study_survey.png b/consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_study_survey.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_study_survey.png
rename to consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_study_survey.png
diff --git a/backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_study_tasks.png b/consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_study_tasks.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_study_tasks.png
rename to consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_study_tasks.png
diff --git a/backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_time_commitment.png b/consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_time_commitment.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_time_commitment.png
rename to consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_time_commitment.png
diff --git a/backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_visiting_doctor.png b/consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_visiting_doctor.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_visiting_doctor.png
rename to consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_visiting_doctor.png
diff --git a/backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_withdrawing.png b/consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_withdrawing.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxxhdpi/rsb_consent_section_withdrawing.png
rename to consent/src/main/res/drawable-xxxhdpi/rsfc_consent_section_withdrawing.png
diff --git a/backbone/src/main/res/layout/rsb_step_layout_consent_doc.xml b/consent/src/main/res/layout/rsfc_step_layout_consent_doc.xml
similarity index 77%
rename from backbone/src/main/res/layout/rsb_step_layout_consent_doc.xml
rename to consent/src/main/res/layout/rsfc_step_layout_consent_doc.xml
index fbba22e12..85102ad1b 100644
--- a/backbone/src/main/res/layout/rsb_step_layout_consent_doc.xml
+++ b/consent/src/main/res/layout/rsfc_step_layout_consent_doc.xml
@@ -11,11 +11,11 @@
android:layout_height="0dp"
android:layout_weight="1" />
-
+ app:negativeActionTitle="@string/rsf_disagree"
+ app:positiveActionTitle="@string/rsf_agree" />
\ No newline at end of file
diff --git a/backbone/src/main/res/layout/rsb_step_layout_consent_signature.xml b/consent/src/main/res/layout/rsfc_step_layout_consent_signature.xml
similarity index 74%
rename from backbone/src/main/res/layout/rsb_step_layout_consent_signature.xml
rename to consent/src/main/res/layout/rsfc_step_layout_consent_signature.xml
index 8cd2c3a5f..9f47175a2 100644
--- a/backbone/src/main/res/layout/rsb_step_layout_consent_signature.xml
+++ b/consent/src/main/res/layout/rsfc_step_layout_consent_signature.xml
@@ -10,8 +10,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/image"
- android:layout_marginLeft="@dimen/rsb_margin_left"
- android:layout_marginRight="@dimen/rsb_margin_right"
+ android:layout_marginLeft="@dimen/rsf_margin_left"
+ android:layout_marginRight="@dimen/rsf_margin_right"
android:layout_marginTop="20dp"
android:textColor="?attr/colorAccent"
@@ -25,32 +25,32 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/title"
- android:layout_marginLeft="@dimen/rsb_margin_left"
- android:layout_marginRight="@dimen/rsb_margin_right"
+ android:layout_marginLeft="@dimen/rsf_margin_left"
+ android:layout_marginRight="@dimen/rsf_margin_right"
android:layout_marginTop="36dp"
tools:text="@string/lorem_medium" />
-
-
-
+ android:text="@string/rsfc_consent_signature_clear"
+ android:textColor="@color/rsf_submit_bar_negative" />
diff --git a/backbone/src/main/res/layout/rsb_step_layout_consent_visual.xml b/consent/src/main/res/layout/rsfc_step_layout_consent_visual.xml
similarity index 75%
rename from backbone/src/main/res/layout/rsb_step_layout_consent_visual.xml
rename to consent/src/main/res/layout/rsfc_step_layout_consent_visual.xml
index 5a4dcf88f..c5f33512a 100644
--- a/backbone/src/main/res/layout/rsb_step_layout_consent_visual.xml
+++ b/consent/src/main/res/layout/rsfc_step_layout_consent_visual.xml
@@ -11,15 +11,15 @@
android:layout_height="180dp"
android:layout_centerHorizontal="true"
android:scaleType="centerInside"
- tools:src="@drawable/rsb_debug_gray" />
+ tools:src="@drawable/rsf_debug_gray" />
@@ -45,10 +45,10 @@
android:layout_height="wrap_content"
android:layout_below="@+id/summary"
android:layout_marginLeft="48dp"
- android:layout_marginRight="@dimen/rsb_margin_right"
- android:paddingBottom="@dimen/rsb_padding_medium"
- android:paddingRight="@dimen/rsb_padding_medium"
- android:paddingTop="@dimen/rsb_padding_medium"
+ android:layout_marginRight="@dimen/rsf_margin_right"
+ android:paddingBottom="@dimen/rsf_padding_medium"
+ android:paddingRight="@dimen/rsf_padding_medium"
+ android:paddingTop="@dimen/rsf_padding_medium"
android:textColor="?attr/colorAccent"
tools:text="More Info" />
diff --git a/consent/src/main/res/values/attrs.xml b/consent/src/main/res/values/attrs.xml
new file mode 100644
index 000000000..7c32f3f3b
--- /dev/null
+++ b/consent/src/main/res/values/attrs.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/consent/src/main/res/values/strings.xml b/consent/src/main/res/values/strings.xml
new file mode 100644
index 000000000..b44d202d9
--- /dev/null
+++ b/consent/src/main/res/values/strings.xml
@@ -0,0 +1,83 @@
+
+
+
+ Consent
+ Welcome
+ Data Gathering
+ Privacy
+ Data Use
+ Time Commitment
+ Study Survey
+ Study Tasks
+ Withdrawing
+ Learn More
+
+
+ Learn more
+ Learn more about how data is
+ gathered
+
+ Learn more about how data is used
+ Learn more about how your privacy and
+ identity are protected
+
+ Learn more about the study first
+ Learn more about the study survey
+
+ Learn more about the study\'s
+ impact on your time
+
+ Learn more about the tasks involved
+
+ Learn more about withdrawing
+
+
+ Sharing Options
+ Share my data with %1$s and qualified researchers
+ worldwide
+
+ Not sharing your data
+ Only share my data with %1$s
+
+ Learn more about data sharing]]>
+
+
+
+ Review
+ Review
+ By agreeing you confirm that you read the information
+ and that you wish to take part in this research study.
+
+ Review the form below, and tap Agree if you\'re
+ ready to continue.
+
+ Cancel
+
+
+ Consent
+ Full Name
+ Date of Birth
+ Required
+
+
+ Signature
+ By agreeing you confirm that you read the consent
+ and that you wish to take part in this research study.
+
+ Please sign using your finger on the line
+ below.
+
+ Sign Here
+ Clear
+
+
+ Quiz
+ Quiz Evaluation
+ Try Again
+ Review Consent
+ Retake Quiz
+ Great Job!
+
+
diff --git a/consent/src/main/res/values/styles.xml b/consent/src/main/res/values/styles.xml
new file mode 100644
index 000000000..2e0460f14
--- /dev/null
+++ b/consent/src/main/res/values/styles.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
diff --git a/consent/src/test/java/org/researchstack/feature/consent/ExampleUnitTest.java b/consent/src/test/java/org/researchstack/feature/consent/ExampleUnitTest.java
new file mode 100644
index 000000000..bcdf8f5dd
--- /dev/null
+++ b/consent/src/test/java/org/researchstack/feature/consent/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package org.researchstack.feature.consent;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/foundation/.gitignore b/foundation/.gitignore
new file mode 100644
index 000000000..796b96d1c
--- /dev/null
+++ b/foundation/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/foundation/build.gradle b/foundation/build.gradle
new file mode 100644
index 000000000..428d564a4
--- /dev/null
+++ b/foundation/build.gradle
@@ -0,0 +1,170 @@
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+
+apply plugin: 'com.github.dcendents.android-maven'
+apply plugin: 'com.jfrog.bintray'
+
+version = research_stack_version
+
+android {
+ compileSdkVersion 28
+ defaultConfig {
+ minSdkVersion 19
+ targetSdkVersion 28
+ versionCode 1
+ versionName version
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+ resourcePrefix 'rsf_'
+ compileOptions {
+ sourceCompatibility = '1.8'
+ targetCompatibility = '1.8'
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ buildToolsVersion '28.0.3'
+}
+
+Properties properties = new Properties()
+properties.load(project.rootProject.file('local.properties').newDataInputStream())
+
+ext {
+ bintrayRepo = 'ResearchStack'
+ bintrayName = 'Foundation'
+
+ publishedGroupId = 'org.researchstack'
+ libraryName = 'Foundation'
+ artifact = 'foundation'
+
+ libraryDescription = 'Foundation'
+
+ siteUrl = 'https://researchstack.org'
+ gitUrl = 'https://github.com/ResearchStack/ResearchStack.git'
+
+ libraryVersion = version
+
+ userOrgName = 'researchstack'
+ developerId = properties.getProperty("bintray.user")
+ developerName = properties.getProperty("bintray.developerName")
+ developerEmail = properties.getProperty("bintray.developerEmail")
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+dependencies {
+ implementation fileTree(include: ['*.jar'], dir: 'libs')
+ implementation 'androidx.appcompat:appcompat:1.0.2'
+ implementation 'androidx.cardview:cardview:1.0.0'
+ implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
+ implementation 'com.google.android.material:material:1.0.0'
+ implementation 'androidx.core:core:1.0.1'
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'androidx.test:runner:1.1.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+
+ implementation "com.google.code.gson:gson:$gson_version"
+
+}
+
+group = publishedGroupId // Maven Group ID for the artifact
+
+install {
+ repositories.mavenInstaller {
+ // This generates POM.xml with proper parameters
+ pom {
+ project {
+ packaging 'aar'
+ groupId publishedGroupId
+ artifactId artifact
+
+ // Add your description here
+ name libraryName
+ description libraryDescription
+ url siteUrl
+
+ // Set your license
+ licenses {
+ license {
+ name licenseName
+ url licenseUrl
+ }
+ }
+ developers {
+ developer {
+ id developerId
+ name developerName
+ email developerEmail
+ }
+ }
+ scm {
+ connection gitUrl
+ developerConnection gitUrl
+ url siteUrl
+ }
+ }
+ }
+ }
+}
+
+if (project.hasProperty("android")) { // Android libraries
+ task sourcesJar(type: Jar) {
+ classifier = 'sources'
+ from android.sourceSets.main.java.srcDirs
+ }
+
+ task javadoc(type: Javadoc) {
+ failOnError false
+ source = android.sourceSets.main.java.srcDirs
+ }
+
+ afterEvaluate {
+ javadoc.classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
+ javadoc.classpath += files(android.libraryVariants.collect { variant ->
+ variant.javaCompile.classpath.files
+ })
+ }
+} else { // Java libraries
+ task sourcesJar(type: Jar, dependsOn: classes) {
+ classifier = 'sources'
+ from sourceSets.main.allSource
+ }
+}
+
+task javadocJar(type: Jar, dependsOn: javadoc) {
+ classifier = 'javadoc'
+ from javadoc.destinationDir
+}
+
+artifacts {
+ archives javadocJar
+ archives sourcesJar
+}
+
+bintray {
+ user = properties.getProperty("bintray.user")
+ key = properties.getProperty("bintray.apikey")
+
+ configurations = ['archives']
+ pkg {
+ repo = bintrayRepo
+ name = bintrayName
+ userOrg = userOrgName
+ desc = libraryDescription
+ websiteUrl = siteUrl
+ vcsUrl = gitUrl
+ licenses = allLicenses
+ publish = true
+ }
+}
diff --git a/foundation/proguard-rules.pro b/foundation/proguard-rules.pro
new file mode 100644
index 000000000..f1b424510
--- /dev/null
+++ b/foundation/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/foundation/src/androidTest/java/org/researchstack/foundation/ExampleInstrumentedTest.java b/foundation/src/androidTest/java/org/researchstack/foundation/ExampleInstrumentedTest.java
new file mode 100644
index 000000000..797eabc7f
--- /dev/null
+++ b/foundation/src/androidTest/java/org/researchstack/foundation/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package org.researchstack.foundation;
+
+import android.content.Context;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("org.researchstack.foundation.test", appContext.getPackageName());
+ }
+}
diff --git a/foundation/src/main/AndroidManifest.xml b/foundation/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..8c59fe33a
--- /dev/null
+++ b/foundation/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
diff --git a/backbone/src/main/java/org/researchstack/backbone/task/OrderedTask.java b/foundation/src/main/java/org/researchstack/foundation/components/common/task/OrderedTask.java
similarity index 90%
rename from backbone/src/main/java/org/researchstack/backbone/task/OrderedTask.java
rename to foundation/src/main/java/org/researchstack/foundation/components/common/task/OrderedTask.java
index b2850676a..d3e094206 100644
--- a/backbone/src/main/java/org/researchstack/backbone/task/OrderedTask.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/common/task/OrderedTask.java
@@ -1,11 +1,12 @@
-package org.researchstack.backbone.task;
+package org.researchstack.foundation.components.common.task;
import android.content.Context;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.result.TaskResult;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.utils.TextUtils;
+import org.researchstack.foundation.R;
+import org.researchstack.foundation.components.utils.TextUtils;
+import org.researchstack.foundation.core.models.result.TaskResult;
+import org.researchstack.foundation.core.models.step.Step;
+import org.researchstack.foundation.core.models.task.Task;
import java.io.Serializable;
import java.util.ArrayList;
@@ -122,7 +123,7 @@ public String getTitleForStep(Context context, Step step) {
String title = super.getTitleForStep(context, step);
if (TextUtils.isEmpty(title)) {
int currentIndex = steps.indexOf(step);
- title = context.getString(R.string.rsb_format_step_title,
+ title = context.getString(R.string.rsf_format_step_title,
currentIndex + 1,
steps.size());
}
@@ -132,7 +133,7 @@ public String getTitleForStep(Context context, Step step) {
/**
* Validates that there are no duplicate identifiers in the list of steps
*
- * @throws org.researchstack.backbone.task.Task.InvalidTaskException
+ * @throws org.researchstack.foundation.task.Task.InvalidTaskException
*/
@Override
public void validateParameters() {
diff --git a/foundation/src/main/java/org/researchstack/foundation/components/common/ui/callbacks/StepCallbacks.java b/foundation/src/main/java/org/researchstack/foundation/components/common/ui/callbacks/StepCallbacks.java
new file mode 100644
index 000000000..b62c76447
--- /dev/null
+++ b/foundation/src/main/java/org/researchstack/foundation/components/common/ui/callbacks/StepCallbacks.java
@@ -0,0 +1,17 @@
+package org.researchstack.foundation.components.common.ui.callbacks;
+
+import org.jetbrains.annotations.Nullable;
+import org.researchstack.foundation.core.interfaces.IResult;
+import org.researchstack.foundation.core.interfaces.IStep;
+
+public interface StepCallbacks {
+ int ACTION_PREV = -1;
+ int ACTION_NONE = 0;
+ int ACTION_NEXT = 1;
+ int ACTION_END = 2;
+
+ void onSaveStep(int action, IStep step, @Nullable IResult result);
+
+ @Deprecated
+ void onCancelStep();
+}
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/views/FixedSubmitBarLayout.java b/foundation/src/main/java/org/researchstack/foundation/components/common/ui/layout/FixedSubmitBarLayout.java
similarity index 83%
rename from backbone/src/main/java/org/researchstack/backbone/ui/views/FixedSubmitBarLayout.java
rename to foundation/src/main/java/org/researchstack/foundation/components/common/ui/layout/FixedSubmitBarLayout.java
index bc5125378..762b7aa34 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/views/FixedSubmitBarLayout.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/common/ui/layout/FixedSubmitBarLayout.java
@@ -1,8 +1,8 @@
-package org.researchstack.backbone.ui.views;
+package org.researchstack.foundation.components.common.ui.layout;
import android.annotation.TargetApi;
import android.content.Context;
-import android.support.v4.view.ViewCompat;
+import androidx.core.view.ViewCompat;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -11,8 +11,9 @@
import android.widget.FrameLayout;
import android.widget.ScrollView;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.ui.step.layout.StepLayout;
+import org.researchstack.foundation.R;
+import org.researchstack.foundation.components.common.ui.views.SubmitBar;
+import org.researchstack.foundation.components.common.ui.views.ObservableScrollView;
public abstract class FixedSubmitBarLayout extends FrameLayout implements StepLayout {
public FixedSubmitBarLayout(Context context) {
@@ -41,17 +42,17 @@ public FixedSubmitBarLayout(Context context, AttributeSet attrs, int defStyleAtt
private void init() {
// Init root
LayoutInflater inflater = LayoutInflater.from(getContext());
- inflater.inflate(R.layout.rsb_layout_fixed_submit_bar, this, true);
+ inflater.inflate(R.layout.rsf_layout_fixed_submit_bar, this, true);
// Add contentContainer to the layout
- ViewGroup contentContainer = (ViewGroup) findViewById(R.id.rsb_content_container);
+ ViewGroup contentContainer = (ViewGroup) findViewById(R.id.rsf_content_container);
View content = inflater.inflate(getContentResourceId(), contentContainer, false);
contentContainer.addView(content, 0);
// Init scrollview and submit bar guide positioning
- final View submitBarGuide = findViewById(R.id.rsb_submit_bar_guide);
- final SubmitBar submitBar = (SubmitBar) findViewById(R.id.rsb_submit_bar);
- ObservableScrollView scrollView = (ObservableScrollView) findViewById(R.id.rsb_content_container_scrollview);
+ final View submitBarGuide = findViewById(R.id.rsf_submit_bar_guide);
+ final SubmitBar submitBar = (SubmitBar) findViewById(R.id.rsf_submit_bar);
+ final ObservableScrollView scrollView = (ObservableScrollView) findViewById(R.id.rsf_content_container_scrollview);
scrollView.setScrollListener(scrollY -> onScrollChanged(scrollView, submitBarGuide, submitBar));
scrollView.getViewTreeObserver()
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/step/layout/StepLayout.java b/foundation/src/main/java/org/researchstack/foundation/components/common/ui/layout/StepLayout.java
similarity index 53%
rename from backbone/src/main/java/org/researchstack/backbone/ui/step/layout/StepLayout.java
rename to foundation/src/main/java/org/researchstack/foundation/components/common/ui/layout/StepLayout.java
index 49f87245a..66936bd94 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/step/layout/StepLayout.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/common/ui/layout/StepLayout.java
@@ -1,10 +1,10 @@
-package org.researchstack.backbone.ui.step.layout;
+package org.researchstack.foundation.components.common.ui.layout;
import android.view.View;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.ui.callbacks.StepCallbacks;
+import org.researchstack.foundation.components.common.ui.callbacks.StepCallbacks;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
public interface StepLayout {
void initialize(Step step, StepResult result);
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/views/IconTab.java b/foundation/src/main/java/org/researchstack/foundation/components/common/ui/views/IconTab.java
similarity index 94%
rename from backbone/src/main/java/org/researchstack/backbone/ui/views/IconTab.java
rename to foundation/src/main/java/org/researchstack/foundation/components/common/ui/views/IconTab.java
index 772edb7d0..312fc5b7b 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/views/IconTab.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/common/ui/views/IconTab.java
@@ -1,11 +1,11 @@
-package org.researchstack.backbone.ui.views;
+package org.researchstack.foundation.components.common.ui.views;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.drawable.Drawable;
-import android.support.annotation.DrawableRes;
-import android.support.annotation.StringRes;
-import android.support.v4.graphics.drawable.DrawableCompat;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.StringRes;
+import androidx.core.graphics.drawable.DrawableCompat;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -17,8 +17,7 @@
import android.widget.TextView;
import android.widget.Toast;
-import org.researchstack.backbone.R;
-
+import org.researchstack.foundation.R;
public class IconTab extends RelativeLayout implements View.OnLongClickListener {
private TextView title;
@@ -47,7 +46,7 @@ public IconTab(Context context, AttributeSet attrs, int defStyleAttr, int defSty
}
private void init() {
- LayoutInflater.from(getContext()).inflate(R.layout.rsb_view_icon_tab, this, true);
+ LayoutInflater.from(getContext()).inflate(R.layout.rsf_view_icon_tab, this, true);
title = (TextView) findViewById(R.id.title);
icon = (ImageView) findViewById(R.id.icon);
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/views/IconTabLayout.java b/foundation/src/main/java/org/researchstack/foundation/components/common/ui/views/IconTabLayout.java
similarity index 90%
rename from backbone/src/main/java/org/researchstack/backbone/ui/views/IconTabLayout.java
rename to foundation/src/main/java/org/researchstack/foundation/components/common/ui/views/IconTabLayout.java
index 65f598a09..10bdeb195 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/views/IconTabLayout.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/common/ui/views/IconTabLayout.java
@@ -1,14 +1,14 @@
-package org.researchstack.backbone.ui.views;
+package org.researchstack.foundation.components.common.ui.views;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
-import android.support.annotation.Nullable;
-import android.support.design.widget.TabLayout;
+import androidx.annotation.Nullable;
+import com.google.android.material.tabs.TabLayout;
import android.util.AttributeSet;
-import org.researchstack.backbone.R;
+import org.researchstack.foundation.R;
public class IconTabLayout extends TabLayout {
private int tabIconColor = Color.WHITE;
@@ -29,7 +29,7 @@ public IconTabLayout(Context context, @Nullable AttributeSet attrs, int defStyle
final TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.IconTabLayout,
defStyleAttr,
- R.style.Widget_Backbone_IconTabLayout);
+ R.style.Widget_Foundation_IconTabLayout);
Drawable background = a.getDrawable(R.styleable.IconTabLayout_android_background);
setBackground(background);
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/views/ObservableScrollView.java b/foundation/src/main/java/org/researchstack/foundation/components/common/ui/views/ObservableScrollView.java
similarity index 94%
rename from backbone/src/main/java/org/researchstack/backbone/ui/views/ObservableScrollView.java
rename to foundation/src/main/java/org/researchstack/foundation/components/common/ui/views/ObservableScrollView.java
index 02065466a..04b689814 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/views/ObservableScrollView.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/common/ui/views/ObservableScrollView.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.ui.views;
+package org.researchstack.foundation.components.common.ui.views;
import android.annotation.TargetApi;
import android.content.Context;
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/views/SubmitBar.java b/foundation/src/main/java/org/researchstack/foundation/components/common/ui/views/SubmitBar.java
similarity index 78%
rename from backbone/src/main/java/org/researchstack/backbone/ui/views/SubmitBar.java
rename to foundation/src/main/java/org/researchstack/foundation/components/common/ui/views/SubmitBar.java
index a927b53f9..2553a9a04 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/views/SubmitBar.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/common/ui/views/SubmitBar.java
@@ -1,21 +1,17 @@
-package org.researchstack.backbone.ui.views;
+package org.researchstack.foundation.components.common.ui.views;
import android.content.Context;
import android.content.res.TypedArray;
-import android.support.annotation.Nullable;
-import android.support.v4.content.ContextCompat;
+import androidx.annotation.Nullable;
+import androidx.core.content.ContextCompat;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
-import com.jakewharton.rxbinding.view.RxView;
-
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.utils.ThemeUtils;
-
-import rx.functions.Action1;
+import org.researchstack.foundation.R;
+import org.researchstack.foundation.components.utils.ThemeUtils;
public class SubmitBar extends LinearLayout {
private TextView positiveView;
@@ -32,12 +28,12 @@ public SubmitBar(Context context, @Nullable AttributeSet attrs) {
public SubmitBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- LayoutInflater.from(getContext()).inflate(R.layout.rsb_view_submitbar, this, true);
+ LayoutInflater.from(getContext()).inflate(R.layout.rsf_view_submitbar, this, true);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.SubmitBar,
defStyleAttr,
- R.style.Widget_Backbone_SubmitBar);
+ R.style.Widget_Foundation_SubmitBar);
setBackground(a.getDrawable(R.styleable.SubmitBar_android_background));
@@ -49,7 +45,7 @@ public SubmitBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr
negativeView = (TextView) findViewById(R.id.bar_submit_negative);
negativeView.setText(a.getString(R.styleable.SubmitBar_negativeActionTitle));
negativeView.setTextColor(a.getColor(R.styleable.SubmitBar_negativeActionColor,
- ContextCompat.getColor(context, R.color.rsb_submit_bar_negative)));
+ ContextCompat.getColor(context, R.color.rsf_submit_bar_negative)));
a.recycle();
}
@@ -66,8 +62,8 @@ public void setPositiveTitle(String title) {
positiveView.setText(title);
}
- public void setPositiveAction(Action1 submit) {
- RxView.clicks(this.positiveView).subscribe(submit);
+ public void setPositiveAction(OnClickListener listener) {
+ this.positiveView.setOnClickListener(listener);
}
public View getPositiveActionView() {
@@ -87,8 +83,8 @@ public void setNegativeTitle(String title) {
negativeView.setText(title);
}
- public void setNegativeAction(Action1 submit) {
- RxView.clicks(this.negativeView).subscribe(submit);
+ public void setNegativeAction(OnClickListener listener) {
+ this.negativeView.setOnClickListener(listener);
}
public View getNegativeActionView() {
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/step/layout/TextViewLinkHandler.java b/foundation/src/main/java/org/researchstack/foundation/components/common/ui/views/TextViewLinkHandler.java
similarity index 94%
rename from backbone/src/main/java/org/researchstack/backbone/ui/step/layout/TextViewLinkHandler.java
rename to foundation/src/main/java/org/researchstack/foundation/components/common/ui/views/TextViewLinkHandler.java
index 725e103af..ca334daa9 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/step/layout/TextViewLinkHandler.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/common/ui/views/TextViewLinkHandler.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.ui.step.layout;
+package org.researchstack.foundation.components.common.ui.views;
import android.text.Layout;
import android.text.Spannable;
diff --git a/foundation/src/main/java/org/researchstack/foundation/components/presentation/ITaskProvider.kt b/foundation/src/main/java/org/researchstack/foundation/components/presentation/ITaskProvider.kt
new file mode 100644
index 000000000..56c950349
--- /dev/null
+++ b/foundation/src/main/java/org/researchstack/foundation/components/presentation/ITaskProvider.kt
@@ -0,0 +1,7 @@
+package org.researchstack.foundation.components.presentation
+
+import org.researchstack.foundation.core.interfaces.ITask
+
+interface ITaskProvider {
+ fun task(identifier: String): ITask?
+}
\ No newline at end of file
diff --git a/foundation/src/main/java/org/researchstack/foundation/components/presentation/TaskPresentationCallback.kt b/foundation/src/main/java/org/researchstack/foundation/components/presentation/TaskPresentationCallback.kt
new file mode 100644
index 000000000..ecad3e41c
--- /dev/null
+++ b/foundation/src/main/java/org/researchstack/foundation/components/presentation/TaskPresentationCallback.kt
@@ -0,0 +1,8 @@
+package org.researchstack.foundation.components.presentation
+
+import org.researchstack.foundation.core.interfaces.IResult
+import org.researchstack.foundation.core.interfaces.ITask
+
+abstract class TaskPresentationCallback {
+ abstract fun onTaskPresentationFinished(task: TaskType, result: ResultType?)
+}
\ No newline at end of file
diff --git a/foundation/src/main/java/org/researchstack/foundation/components/presentation/TaskPresentationFragment.kt b/foundation/src/main/java/org/researchstack/foundation/components/presentation/TaskPresentationFragment.kt
new file mode 100644
index 000000000..f51726462
--- /dev/null
+++ b/foundation/src/main/java/org/researchstack/foundation/components/presentation/TaskPresentationFragment.kt
@@ -0,0 +1,237 @@
+package org.researchstack.foundation.components.presentation
+
+import android.content.Context
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import androidx.appcompat.app.AlertDialog
+import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.widget.Toolbar
+import android.util.Log
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import org.researchstack.foundation.R
+import org.researchstack.foundation.components.common.ui.callbacks.StepCallbacks
+import org.researchstack.foundation.components.presentation.interfaces.IStepFragment
+import org.researchstack.foundation.components.presentation.interfaces.IStepFragmentProvider
+import org.researchstack.foundation.components.presentation.interfaces.ITaskNavigator
+import org.researchstack.foundation.core.interfaces.IResult
+import org.researchstack.foundation.core.interfaces.IStep
+import org.researchstack.foundation.core.interfaces.ITask
+import java.lang.RuntimeException
+import java.util.*
+
+abstract class TaskPresentationFragment(): androidx.fragment.app.Fragment(), StepCallbacks {
+
+ public var taskProvider: ITaskProvider? = null
+ public var stepFragmentProvider: IStepFragmentProvider? = null
+
+ protected var _task: TaskType? = null
+ public val task: TaskType
+ get() = this._task!!
+
+ protected var _taskNavigator: ITaskNavigator? = null
+ public val taskNavigator: ITaskNavigator
+ get() = this._taskNavigator!!
+
+ public var callback: TaskPresentationCallback? = null
+
+ var _currentStep: StepType? = null
+ var _currentFragment: IStepFragment? = null
+
+ val currentStep: StepType?
+ get() = this._currentStep
+
+ var _result: ResultType? = null
+ val result: ResultType
+ get() = this._result!!
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+
+ val view = inflater.inflate(R.layout.rsf_fragment_task_presentation, container, false);
+
+ val toolbar = view.findViewById(R.id.toolbar) as Toolbar?
+
+ val appCompatActivity: AppCompatActivity = this.activity as AppCompatActivity
+ appCompatActivity.setSupportActionBar(toolbar)
+ appCompatActivity.supportActionBar!!.setDisplayHomeAsUpEnabled(true)
+
+ this.initialize(savedInstanceState)
+
+ return view
+ }
+
+ abstract fun initialize(savedInstanceState: Bundle?)
+
+ override fun onResume() {
+
+ val currentStep = this.currentStep
+
+ if (currentStep == null) {
+ this.taskNavigator.getStepAfterStep(null, this.result)?.let { firstStep ->
+ showStep(firstStep)
+ }
+ }
+ else {
+ showStep(currentStep)
+ }
+
+ super.onResume()
+ }
+
+ protected fun showNextStep() {
+ val nextStep = this.taskNavigator.getStepAfterStep(this.currentStep, this.result)
+ if (nextStep == null) {
+ this.saveAndFinish(false)
+ } else {
+ showStep(nextStep)
+ }
+ }
+
+ protected fun showPreviousStep() {
+ val previousStep = this.taskNavigator.getStepBeforeStep(this.currentStep, this.result)
+ if (previousStep == null) {
+ saveAndFinish(true)
+ } else {
+ showStep(previousStep)
+ }
+ }
+
+ private fun showStep(step: StepType) {
+ val currentStepPosition = this.currentStep?.let {
+ this.taskNavigator.getProgressOfCurrentStep(it, this.result).current
+ }
+
+ val newStepPosition = this.taskNavigator.getProgressOfCurrentStep(step, this.result).current
+
+ val stepFragment = this.getFragmentForStep(step)
+ this._currentFragment = stepFragment
+
+ val transaction = childFragmentManager.beginTransaction()
+
+ if (currentStepPosition != null) {
+ if (newStepPosition > currentStepPosition) {
+ transaction.setCustomAnimations(R.anim.rsf_slide_in_right, R.anim.rsf_slide_out_left)
+ }
+ else {
+ transaction.setCustomAnimations(R.anim.rsf_slide_in_left, R.anim.rsf_slide_out_right)
+ }
+
+ transaction
+ .replace(R.id.rsf_content_step, stepFragment.fragment)
+ .commit()
+ }
+ else {
+ transaction
+ .add(R.id.rsf_content_step, stepFragment.fragment)
+ .commit()
+ }
+
+ childFragmentManager.executePendingTransactions()
+
+ Log.d("DEBUG", ""+childFragmentManager.fragments.size)
+
+ this._currentStep = step
+ }
+
+ abstract fun getStepResult(taskResult: ResultType, stepIdentifier: String): IResult?
+ abstract fun setStepResult(taskResult: ResultType, stepIdentifier: String, stepResult: IResult)
+
+ protected fun getFragmentForStep(step: StepType): IStepFragment {
+
+ val hostFragment = this
+
+ // Change the title on the activity
+ val title: String = {
+ val title = this.taskNavigator.getTitleForStep(step)
+ if (title != "") {
+ title
+ }
+ else {
+ this.taskNavigator.getTitleForStep(this.activity!!, step)
+ }
+
+ }()
+
+ setActionBarTitle(title)
+
+ // Get result from the TaskResult, can be null
+
+ val stepResult: IResult? = this.getStepResult(this.result, step.identifier)
+
+ val fragment = createFragmentFromStep(step)
+ if (fragment == null) {
+ throw RuntimeException("Cannot create fragment for step ${step.identifier}")
+ }
+
+ val stepFragment: IStepFragment = fragment.apply {
+ this.initialize(step, stepResult)
+ this.setCallbacks(hostFragment)
+ }
+
+ return stepFragment
+ }
+
+ private fun createFragmentFromStep(step: IStep): IStepFragment? {
+ return this.stepFragmentProvider?.stepFragment(this.activity!! as Context, step)
+ }
+
+ protected abstract fun saveAndFinish(clearResult: Boolean)
+
+ fun setActionBarTitle(title: String) {
+
+ val appCompatActivity: AppCompatActivity = this.activity as AppCompatActivity
+
+ val actionBar = appCompatActivity.supportActionBar
+ if (actionBar != null) {
+ actionBar.setTitle(title)
+ }
+ }
+
+ //JDK - 4/16/19 - as part of future work, we will be removing conformance to StepCallbacks
+ //This means that onSaveStep, onCancelStep, onExecuteStepAction and showConfirmExitDialog will
+ //probably all go away
+ protected fun onExecuteStepAction(action: Int) {
+ if (action == StepCallbacks.ACTION_NEXT) {
+ showNextStep()
+ } else if (action == StepCallbacks.ACTION_PREV) {
+ showPreviousStep()
+ } else if (action == StepCallbacks.ACTION_END) {
+ showConfirmExitDialog()
+ } else if (action == StepCallbacks.ACTION_NONE) {
+ // Used when onSaveInstanceState is called of a view. No action is taken.
+ } else {
+ throw IllegalArgumentException("Action with value " + action + " is invalid. " +
+ "See StepCallbacks for allowable arguments")
+ }
+ }
+
+ private fun showConfirmExitDialog() {
+ val alertDialog = AlertDialog.Builder(this.activity!!).setTitle(
+ "Are you sure you want to exit?")
+ .setMessage(R.string.lorem_medium)
+ .setPositiveButton("End Task") { dialog, which -> saveAndFinish(true) }
+ .setNegativeButton("Cancel", null)
+ .create()
+ alertDialog.show()
+ }
+
+ public fun onBackPressed() {
+ notifyStepOfBackPress()
+ }
+
+ private fun notifyStepOfBackPress() {
+ this._currentFragment?.onBackPressed()
+ }
+
+
+ override fun onSaveStep(action: Int, step: IStep, result: IResult?) {
+ result?.let { setStepResult(this.result, step.identifier, it) }
+ onExecuteStepAction(action)
+ }
+
+ override fun onCancelStep() {
+ TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+ }
+
+}
\ No newline at end of file
diff --git a/foundation/src/main/java/org/researchstack/foundation/components/presentation/compatibility/BackwardsCompatibleStepFragment.kt b/foundation/src/main/java/org/researchstack/foundation/components/presentation/compatibility/BackwardsCompatibleStepFragment.kt
new file mode 100644
index 000000000..2bf52f60c
--- /dev/null
+++ b/foundation/src/main/java/org/researchstack/foundation/components/presentation/compatibility/BackwardsCompatibleStepFragment.kt
@@ -0,0 +1,69 @@
+package org.researchstack.foundation.components.presentation.compatibility
+
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import org.researchstack.foundation.R
+import org.researchstack.foundation.components.common.ui.callbacks.StepCallbacks
+import org.researchstack.foundation.components.common.ui.layout.StepLayout
+import org.researchstack.foundation.components.presentation.interfaces.IStepFragment
+import org.researchstack.foundation.core.interfaces.IResult
+import org.researchstack.foundation.core.interfaces.IStep
+import org.researchstack.foundation.core.models.result.StepResult
+import org.researchstack.foundation.core.models.step.Step
+
+public class BackwardsCompatibleStepFragment(): androidx.fragment.app.Fragment(), IStepFragment {
+
+ companion object {
+
+ fun newInstance(stepLayout: StepLayout): BackwardsCompatibleStepFragment {
+ val fragment = BackwardsCompatibleStepFragment()
+ fragment.stepLayout = stepLayout
+ return fragment
+ }
+ }
+
+ //this will implement the traditional step layout
+ var stepLayout: StepLayout? = null
+
+ override val fragment: androidx.fragment.app.Fragment
+ get() = this
+
+ private fun getLayoutParams(stepLayout: StepLayout): FrameLayout.LayoutParams {
+ var lp: FrameLayout.LayoutParams? = stepLayout.layout.layoutParams?.let {
+ it as? FrameLayout.LayoutParams
+ }
+ if (lp == null) {
+ lp = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)
+ }
+ return lp
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+
+ val layout = this.stepLayout!!
+ val view = inflater.inflate(R.layout.rsf_fragment_step_compat, container, false)
+ val containerView: FrameLayout = view.findViewById(R.id.rsf_content_layout) as FrameLayout
+
+ val lp = getLayoutParams(layout)
+ containerView.addView(layout.layout, 0, lp)
+
+ return view
+ }
+
+ override fun onBackPressed() {
+ this.stepLayout!!.isBackEventConsumed
+ }
+
+ override fun initialize(step: IStep, result: IResult?) {
+ this.stepLayout!!.initialize(step as Step, result?.let { it as? StepResult<*> })
+ }
+
+ override fun setCallbacks(callbacks: StepCallbacks) {
+ this.stepLayout!!.setCallbacks(callbacks)
+ }
+
+}
\ No newline at end of file
diff --git a/foundation/src/main/java/org/researchstack/foundation/components/presentation/compatibility/BackwardsCompatibleStepFragmentProvider.kt b/foundation/src/main/java/org/researchstack/foundation/components/presentation/compatibility/BackwardsCompatibleStepFragmentProvider.kt
new file mode 100644
index 000000000..fab849d94
--- /dev/null
+++ b/foundation/src/main/java/org/researchstack/foundation/components/presentation/compatibility/BackwardsCompatibleStepFragmentProvider.kt
@@ -0,0 +1,34 @@
+package org.researchstack.foundation.components.presentation.compatibility
+
+import android.content.Context
+import org.researchstack.foundation.components.common.ui.layout.StepLayout
+import org.researchstack.foundation.components.presentation.interfaces.IStepFragment
+import org.researchstack.foundation.components.presentation.interfaces.IStepFragmentProvider
+import org.researchstack.foundation.core.interfaces.IStep
+
+
+public class BackwardsCompatibleStepFragmentProvider(val stepLayoutProvider: IStepLayoutProvider): IStepFragmentProvider {
+
+ override fun stepFragment(context: Context, step: IStep): IStepFragment? {
+
+ try {
+
+ val stepLayout = this.stepLayoutProvider.stepLayout(step)?.let {
+ val constructor = it.getConstructor(Context::class.java)
+ constructor.newInstance(context)
+ } as? StepLayout
+
+ if (stepLayout != null) {
+ val fragment = BackwardsCompatibleStepFragment.newInstance(stepLayout)
+ return fragment
+ }
+ else {
+ throw RuntimeException("Could not instantiate Step Layout")
+ }
+
+ } catch (e: Exception) {
+ throw RuntimeException(e)
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/foundation/src/main/java/org/researchstack/foundation/components/presentation/compatibility/BackwardsCompatibleStepLayoutProvider.kt b/foundation/src/main/java/org/researchstack/foundation/components/presentation/compatibility/BackwardsCompatibleStepLayoutProvider.kt
new file mode 100644
index 000000000..0fccb89f7
--- /dev/null
+++ b/foundation/src/main/java/org/researchstack/foundation/components/presentation/compatibility/BackwardsCompatibleStepLayoutProvider.kt
@@ -0,0 +1,10 @@
+package org.researchstack.foundation.components.presentation.compatibility
+
+import org.researchstack.foundation.core.interfaces.IStep
+import org.researchstack.foundation.core.models.step.Step
+
+public class BackwardsCompatibleStepLayoutProvider(): IStepLayoutProvider {
+ override fun stepLayout(step: IStep): Class<*>? {
+ return (step as? Step)?.stepLayoutClass
+ }
+}
\ No newline at end of file
diff --git a/foundation/src/main/java/org/researchstack/foundation/components/presentation/compatibility/BackwardsCompatibleTaskPresentationFragment.kt b/foundation/src/main/java/org/researchstack/foundation/components/presentation/compatibility/BackwardsCompatibleTaskPresentationFragment.kt
new file mode 100644
index 000000000..4205cca85
--- /dev/null
+++ b/foundation/src/main/java/org/researchstack/foundation/components/presentation/compatibility/BackwardsCompatibleTaskPresentationFragment.kt
@@ -0,0 +1,74 @@
+package org.researchstack.foundation.components.presentation.compatibility
+
+import android.os.Bundle
+import org.researchstack.foundation.components.common.ui.callbacks.StepCallbacks
+import org.researchstack.foundation.components.presentation.TaskPresentationCallback
+import org.researchstack.foundation.components.presentation.TaskPresentationFragment
+import org.researchstack.foundation.components.presentation.interfaces.IStepFragmentProvider
+import org.researchstack.foundation.core.interfaces.IResult
+import org.researchstack.foundation.core.models.result.StepResult
+import org.researchstack.foundation.core.models.result.TaskResult
+import org.researchstack.foundation.core.models.step.Step
+import org.researchstack.foundation.core.models.task.Task
+import java.util.*
+
+open class BackwardsCompatibleTaskPresentationFragment: TaskPresentationFragment(), StepCallbacks {
+
+ companion object {
+ val EXTRA_TASK_IDENTIFIER = "BackwardsCompatibleTaskPresentationFragment.ExtraTaskIdentifier"
+ val EXTRA_TASK_RESULT = "BackwardsCompatibleTaskPresentationFragment.ExtraTaskResult"
+ val EXTRA_STEP = "BackwardsCompatibleTaskPresentationFragment.ExtraStep"
+
+ fun newInstance(
+ taskIdentifier: String,
+ stepFragmentProvider: IStepFragmentProvider,
+ callback: TaskPresentationCallback
+ ): BackwardsCompatibleTaskPresentationFragment {
+ val fragment = BackwardsCompatibleTaskPresentationFragment()
+ val args = Bundle()
+ args.putString(EXTRA_TASK_IDENTIFIER, taskIdentifier)
+ fragment.setArguments(args)
+ fragment.stepFragmentProvider = stepFragmentProvider
+ fragment.callback = callback
+ return fragment
+ }
+
+ }
+
+ override fun initialize(savedInstanceState: Bundle?) {
+
+ if (savedInstanceState == null) {
+ val taskIdentifier: String = this.arguments!!.getString(BackwardsCompatibleTaskPresentationFragment.EXTRA_TASK_IDENTIFIER)!!
+ this._task = this.taskProvider!!.task(taskIdentifier) as Task
+ this._taskNavigator = this.task
+ this._result = TaskResult(this.task.identifier)
+ this.result.setStartDate(Date())
+ } else {
+ val taskIdentifier: String = savedInstanceState.getString(BackwardsCompatibleTaskPresentationFragment.EXTRA_TASK_IDENTIFIER)!!
+ this._task = this.taskProvider!!.task(taskIdentifier) as Task
+ this._taskNavigator = this.task
+ this._result = savedInstanceState.getSerializable(BackwardsCompatibleTaskPresentationFragment.EXTRA_TASK_RESULT) as TaskResult
+ this._currentStep = savedInstanceState.getSerializable(BackwardsCompatibleTaskPresentationFragment.EXTRA_STEP) as Step
+ }
+
+ this.task.validateParameters()
+ }
+
+ override fun getStepResult(taskResult: TaskResult, stepIdentifier: String): IResult? {
+ return taskResult.getStepResult(stepIdentifier)
+ }
+
+ override fun setStepResult(taskResult: TaskResult, stepIdentifier: String, stepResult: IResult) {
+ taskResult.setStepResultForStepIdentifier(stepIdentifier, stepResult as StepResult<*>)
+ }
+
+ override fun saveAndFinish(clearResult: Boolean) {
+ if (clearResult) {
+ this.callback!!.onTaskPresentationFinished(this.task, null)
+ }
+ else {
+ this.result.setEndDate(Date())
+ this.callback!!.onTaskPresentationFinished(this.task, this.result)
+ }
+ }
+}
\ No newline at end of file
diff --git a/foundation/src/main/java/org/researchstack/foundation/components/presentation/compatibility/IStepLayoutProvider.kt b/foundation/src/main/java/org/researchstack/foundation/components/presentation/compatibility/IStepLayoutProvider.kt
new file mode 100644
index 000000000..497192c92
--- /dev/null
+++ b/foundation/src/main/java/org/researchstack/foundation/components/presentation/compatibility/IStepLayoutProvider.kt
@@ -0,0 +1,7 @@
+package org.researchstack.foundation.components.presentation.compatibility
+
+import org.researchstack.foundation.core.interfaces.IStep
+
+interface IStepLayoutProvider {
+ fun stepLayout(step: IStep): Class<*>?
+}
\ No newline at end of file
diff --git a/foundation/src/main/java/org/researchstack/foundation/components/presentation/interfaces/IStepFragment.kt b/foundation/src/main/java/org/researchstack/foundation/components/presentation/interfaces/IStepFragment.kt
new file mode 100644
index 000000000..1bacb507c
--- /dev/null
+++ b/foundation/src/main/java/org/researchstack/foundation/components/presentation/interfaces/IStepFragment.kt
@@ -0,0 +1,15 @@
+package org.researchstack.foundation.components.presentation.interfaces
+
+import androidx.fragment.app.Fragment
+import org.researchstack.foundation.components.common.ui.callbacks.StepCallbacks
+import org.researchstack.foundation.core.interfaces.IResult
+import org.researchstack.foundation.core.interfaces.IStep
+
+interface IStepFragment {
+ fun initialize(step: IStep, result: IResult?)
+ //TODO: JDK - 4/13/19 - Understand if we need to change StepCallbacks
+ //This interface may change depending on work on Actions
+ fun setCallbacks(callbacks: StepCallbacks)
+ fun onBackPressed()
+ val fragment: androidx.fragment.app.Fragment
+}
\ No newline at end of file
diff --git a/foundation/src/main/java/org/researchstack/foundation/components/presentation/interfaces/IStepFragmentProvider.kt b/foundation/src/main/java/org/researchstack/foundation/components/presentation/interfaces/IStepFragmentProvider.kt
new file mode 100644
index 000000000..6cdcde6d3
--- /dev/null
+++ b/foundation/src/main/java/org/researchstack/foundation/components/presentation/interfaces/IStepFragmentProvider.kt
@@ -0,0 +1,8 @@
+package org.researchstack.foundation.components.presentation.interfaces
+
+import android.content.Context
+import org.researchstack.foundation.core.interfaces.IStep
+
+interface IStepFragmentProvider {
+ fun stepFragment(context: Context, step: IStep): IStepFragment?
+}
\ No newline at end of file
diff --git a/foundation/src/main/java/org/researchstack/foundation/components/presentation/interfaces/ITaskNavigator.kt b/foundation/src/main/java/org/researchstack/foundation/components/presentation/interfaces/ITaskNavigator.kt
new file mode 100644
index 000000000..dff1fa42f
--- /dev/null
+++ b/foundation/src/main/java/org/researchstack/foundation/components/presentation/interfaces/ITaskNavigator.kt
@@ -0,0 +1,17 @@
+package org.researchstack.foundation.components.presentation.interfaces
+
+import android.content.Context
+import org.researchstack.foundation.core.interfaces.IResult
+import org.researchstack.foundation.core.interfaces.IStep
+import org.researchstack.foundation.core.models.task.Task
+
+interface ITaskNavigator {
+ @Deprecated("Only here for backwards compatibilty. Will be removed soon")
+ fun getTitleForStep(context: Context, step: StepType): String
+ fun getTitleForStep(step: StepType): String
+ fun getStepWithIdentifier(identifier: String): StepType?
+ fun getStepAfterStep(step: StepType?, result: ResultType): StepType?
+ fun getStepBeforeStep(step: StepType?, result: ResultType): StepType?
+ fun getProgressOfCurrentStep(step: StepType, result: ResultType): Task.TaskProgress
+ fun validateParameters()
+}
\ No newline at end of file
diff --git a/backbone/src/main/java/org/researchstack/backbone/ResourcePathManager.java b/foundation/src/main/java/org/researchstack/foundation/components/singletons/ResourcePathManager.java
similarity index 98%
rename from backbone/src/main/java/org/researchstack/backbone/ResourcePathManager.java
rename to foundation/src/main/java/org/researchstack/foundation/components/singletons/ResourcePathManager.java
index 3943deef6..0a7d60aca 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ResourcePathManager.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/singletons/ResourcePathManager.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone;
+package org.researchstack.foundation.components.singletons;
import android.app.Application;
import android.content.Context;
@@ -8,7 +8,7 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
-import org.researchstack.backbone.utils.LogExt;
+import org.researchstack.foundation.components.utils.LogExt;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
diff --git a/foundation/src/main/java/org/researchstack/foundation/components/singletons/TextViewLinkManager.kt b/foundation/src/main/java/org/researchstack/foundation/components/singletons/TextViewLinkManager.kt
new file mode 100644
index 000000000..a3497fadd
--- /dev/null
+++ b/foundation/src/main/java/org/researchstack/foundation/components/singletons/TextViewLinkManager.kt
@@ -0,0 +1,48 @@
+package org.researchstack.foundation.components.singletons
+
+import android.content.Context
+import org.researchstack.foundation.components.common.ui.views.TextViewLinkHandler
+import org.researchstack.foundation.components.web.ui.activities.ViewWebDocumentActivity
+import java.lang.RuntimeException
+
+public abstract class TextViewLinkManager {
+
+ companion object {
+
+ private var _sharedManager: TextViewLinkManager? = LegacyTextViewLinkManager()
+
+ fun setSharedManager(manager: TextViewLinkManager) {
+ this._sharedManager = manager
+ }
+
+ fun getSharedManager(): TextViewLinkManager {
+ val manager = this._sharedManager
+ if (manager == null) {
+ throw RuntimeException("Shared Manager instance is null. Make sure you configure this by calling TextViewLinkManager.init()")
+ }
+ return manager
+ }
+
+ }
+
+ abstract fun getHandler(context: Context, title: String): TextViewLinkHandler
+
+}
+
+public class LegacyTextViewLinkManager: TextViewLinkManager() {
+
+ public class LegacyTextViewLinkHandler(val context: Context, val title: String): TextViewLinkHandler() {
+ override fun onLinkClick(url: String?) {
+ val path = ResourcePathManager.getInstance().generateAbsolutePath(ResourcePathManager.Resource.TYPE_HTML, url)
+ val intent = ViewWebDocumentActivity.newIntentForPath(
+ context,
+ title,
+ path)
+ context.startActivity(intent)
+ }
+ }
+
+ override fun getHandler(context: Context, title: String): TextViewLinkHandler {
+ return LegacyTextViewLinkHandler(context, title)
+ }
+}
\ No newline at end of file
diff --git a/backbone/src/main/java/org/researchstack/backbone/answerformat/AnswerFormat.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/AnswerFormat.java
similarity index 72%
rename from backbone/src/main/java/org/researchstack/backbone/answerformat/AnswerFormat.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/AnswerFormat.java
index d489242bd..7b96f0163 100644
--- a/backbone/src/main/java/org/researchstack/backbone/answerformat/AnswerFormat.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/AnswerFormat.java
@@ -1,26 +1,26 @@
-package org.researchstack.backbone.answerformat;
+package org.researchstack.foundation.components.survey.answerformat;
-import org.researchstack.backbone.ui.step.body.DateQuestionBody;
-import org.researchstack.backbone.ui.step.body.DecimalQuestionBody;
-import org.researchstack.backbone.ui.step.body.DurationQuestionBody;
-import org.researchstack.backbone.ui.step.body.FormBody;
-import org.researchstack.backbone.ui.step.body.IntegerQuestionBody;
-import org.researchstack.backbone.ui.step.body.MultiChoiceQuestionBody;
-import org.researchstack.backbone.ui.step.body.NotImplementedStepBody;
-import org.researchstack.backbone.ui.step.body.SingleChoiceQuestionBody;
-import org.researchstack.backbone.ui.step.body.TextQuestionBody;
+import org.researchstack.foundation.components.survey.ui.body.DateQuestionBody;
+import org.researchstack.foundation.components.survey.ui.body.DecimalQuestionBody;
+import org.researchstack.foundation.components.survey.ui.body.DurationQuestionBody;
+import org.researchstack.foundation.components.survey.ui.body.FormBody;
+import org.researchstack.foundation.components.survey.ui.body.IntegerQuestionBody;
+import org.researchstack.foundation.components.survey.ui.body.MultiChoiceQuestionBody;
+import org.researchstack.foundation.components.survey.ui.body.NotImplementedStepBody;
+import org.researchstack.foundation.components.survey.ui.body.SingleChoiceQuestionBody;
+import org.researchstack.foundation.components.survey.ui.body.TextQuestionBody;
import java.io.Serializable;
/**
* The AnswerFormat class is the abstract base class for classes that describe the format in which a
* survey question should be answered. The ResearchStack framework uses {@link
- * org.researchstack.backbone.step.QuestionStep} to represent questions to ask the user. Each
+ * org.researchstack.foundation.step.QuestionStep} to represent questions to ask the user. Each
* question must have an associated answer format.
*
* To use an answer format, instantiate the appropriate answer format subclass and attach it to a
* question step or form item. Incorporate the resulting step into a task, and present the task with
- * a {@link org.researchstack.backbone.ui.ViewTaskActivity}.
+ * a {@link org.researchstack.foundation.ui.ViewTaskActivity}.
*/
public abstract class AnswerFormat implements Serializable {
/**
@@ -42,7 +42,7 @@ public QuestionType getQuestionType() {
/**
* The type of question. (read-only)
*
- * The type provides a default {@link org.researchstack.backbone.ui.step.body.StepBody} for that
+ * The type provides a default {@link org.researchstack.foundation.ui.step.body.StepBody} for that
* type of question. A custom StepLayout implementation may provide it's own StepBody rather
* than using the default provided by this AnswerFormat.
*/
@@ -105,7 +105,7 @@ public enum DateAnswerStyle {
/**
* Interface that {@link Type} implements. Since you cannot add a value to an existing enum, you
* may implement this interface instead to provide your own QuestionType that provides a {@link
- * org.researchstack.backbone.ui.step.body.StepBody} class.
+ * org.researchstack.foundation.ui.step.body.StepBody} class.
*/
public interface QuestionType {
Class> getStepBodyClass();
diff --git a/backbone/src/main/java/org/researchstack/backbone/answerformat/BirthDateAnswerFormat.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/BirthDateAnswerFormat.java
similarity index 83%
rename from backbone/src/main/java/org/researchstack/backbone/answerformat/BirthDateAnswerFormat.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/BirthDateAnswerFormat.java
index a7c3a55f0..5a5dc9f59 100644
--- a/backbone/src/main/java/org/researchstack/backbone/answerformat/BirthDateAnswerFormat.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/BirthDateAnswerFormat.java
@@ -1,7 +1,7 @@
-package org.researchstack.backbone.answerformat;
+package org.researchstack.foundation.components.survey.answerformat;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.ui.step.body.BodyAnswer;
+import org.researchstack.foundation.R;
+import org.researchstack.foundation.components.survey.ui.body.BodyAnswer;
import java.util.Calendar;
import java.util.Date;
@@ -32,11 +32,11 @@ public BodyAnswer validateAnswer(Date resultDate) {
Date maxDate = getMaximumDate();
if (minDate != null && isOnOrBefore(resultDate, minDate)) {
- return new BodyAnswer(false, R.string.rsb_birth_date_too_old, String.valueOf(maxAge));
+ return new BodyAnswer(false, R.string.rsf_birth_date_too_old, String.valueOf(maxAge));
}
if (maxDate != null && !isOnOrBefore(resultDate, maxDate)) {
- return new BodyAnswer(false, R.string.rsb_birth_date_too_young, String.valueOf(minAge));
+ return new BodyAnswer(false, R.string.rsf_birth_date_too_young, String.valueOf(minAge));
}
return BodyAnswer.VALID;
diff --git a/backbone/src/main/java/org/researchstack/backbone/answerformat/BooleanAnswerFormat.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/BooleanAnswerFormat.java
similarity index 87%
rename from backbone/src/main/java/org/researchstack/backbone/answerformat/BooleanAnswerFormat.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/BooleanAnswerFormat.java
index d4d40eae9..f8c67d2ef 100644
--- a/backbone/src/main/java/org/researchstack/backbone/answerformat/BooleanAnswerFormat.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/BooleanAnswerFormat.java
@@ -1,7 +1,7 @@
-package org.researchstack.backbone.answerformat;
+package org.researchstack.foundation.components.survey.answerformat;
-import org.researchstack.backbone.model.Choice;
+import org.researchstack.foundation.components.survey.model.Choice;
/**
* A convenience subclass of {@link ChoiceAnswerFormat} that provides a simple true/false single
diff --git a/backbone/src/main/java/org/researchstack/backbone/answerformat/ChoiceAnswerFormat.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/ChoiceAnswerFormat.java
similarity index 85%
rename from backbone/src/main/java/org/researchstack/backbone/answerformat/ChoiceAnswerFormat.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/ChoiceAnswerFormat.java
index d87ae7296..450d51fab 100644
--- a/backbone/src/main/java/org/researchstack/backbone/answerformat/ChoiceAnswerFormat.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/ChoiceAnswerFormat.java
@@ -1,7 +1,6 @@
-package org.researchstack.backbone.answerformat;
+package org.researchstack.foundation.components.survey.answerformat;
-
-import org.researchstack.backbone.model.Choice;
+import org.researchstack.foundation.components.survey.model.Choice;
/**
* The ChoiceAnswerFormat class represents an answer format that lets participants choose from a
@@ -25,7 +24,7 @@ public ChoiceAnswerFormat(AnswerFormat.ChoiceAnswerStyle answerStyle, Choice...
/**
* Returns a multiple choice or single choice question type, which will decide which {@link
- * org.researchstack.backbone.ui.step.body.StepBody} to use to display this question.
+ * org.researchstack.foundation.ui.step.body.StepBody} to use to display this question.
*
* @return the question type for this answer format
*/
diff --git a/backbone/src/main/java/org/researchstack/backbone/answerformat/DateAnswerFormat.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/DateAnswerFormat.java
similarity index 87%
rename from backbone/src/main/java/org/researchstack/backbone/answerformat/DateAnswerFormat.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/DateAnswerFormat.java
index f4c06047c..e8a05c180 100644
--- a/backbone/src/main/java/org/researchstack/backbone/answerformat/DateAnswerFormat.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/DateAnswerFormat.java
@@ -1,8 +1,8 @@
-package org.researchstack.backbone.answerformat;
+package org.researchstack.foundation.components.survey.answerformat;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.ui.step.body.BodyAnswer;
-import org.researchstack.backbone.utils.FormatHelper;
+import org.researchstack.foundation.R;
+import org.researchstack.foundation.components.survey.ui.body.BodyAnswer;
+import org.researchstack.foundation.components.utils.FormatHelper;
import java.util.Date;
@@ -86,13 +86,13 @@ public QuestionType getQuestionType() {
public BodyAnswer validateAnswer(Date resultDate) {
if (minimumDate != null && resultDate.getTime() < minimumDate.getTime()) {
return new BodyAnswer(false,
- R.string.rsb_invalid_answer_date_under,
+ R.string.rsf_invalid_answer_date_under,
FormatHelper.SIMPLE_FORMAT_DATE.format(minimumDate));
}
if (maximumDate != null && resultDate.getTime() > maximumDate.getTime()) {
return new BodyAnswer(false,
- R.string.rsb_invalid_answer_date_over,
+ R.string.rsf_invalid_answer_date_over,
FormatHelper.SIMPLE_FORMAT_DATE.format(maximumDate));
}
diff --git a/backbone/src/main/java/org/researchstack/backbone/answerformat/DecimalAnswerFormat.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/DecimalAnswerFormat.java
similarity index 83%
rename from backbone/src/main/java/org/researchstack/backbone/answerformat/DecimalAnswerFormat.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/DecimalAnswerFormat.java
index 5c7714f50..c425d2eb6 100644
--- a/backbone/src/main/java/org/researchstack/backbone/answerformat/DecimalAnswerFormat.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/DecimalAnswerFormat.java
@@ -1,8 +1,9 @@
-package org.researchstack.backbone.answerformat;
+package org.researchstack.foundation.components.survey.answerformat;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.ui.step.body.BodyAnswer;
-import org.researchstack.backbone.utils.TextUtils;
+
+import org.researchstack.foundation.R;
+import org.researchstack.foundation.components.survey.ui.body.BodyAnswer;
+import org.researchstack.foundation.components.utils.TextUtils;
/**
* This class defines the attributes for a decimal answer format that participants enter using a
@@ -59,10 +60,10 @@ public BodyAnswer validateAnswer(String inputString) {
Float floatAnswer = Float.valueOf(inputString);
if (floatAnswer < minValue) {
return new BodyAnswer(false,
- R.string.rsb_invalid_answer_integer_under, String.valueOf(getMinValue()));
+ R.string.rsf_invalid_answer_integer_under, String.valueOf(getMinValue()));
} else if (floatAnswer > maxValue) {
return new BodyAnswer(false,
- R.string.rsb_invalid_answer_integer_over, String.valueOf(getMaxValue()));
+ R.string.rsf_invalid_answer_integer_over, String.valueOf(getMaxValue()));
}
}
diff --git a/backbone/src/main/java/org/researchstack/backbone/answerformat/DurationAnswerFormat.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/DurationAnswerFormat.java
similarity index 90%
rename from backbone/src/main/java/org/researchstack/backbone/answerformat/DurationAnswerFormat.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/DurationAnswerFormat.java
index 94a6c3fd5..8da181ea4 100644
--- a/backbone/src/main/java/org/researchstack/backbone/answerformat/DurationAnswerFormat.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/DurationAnswerFormat.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.answerformat;
+package org.researchstack.foundation.components.survey.answerformat;
/**
* Created by Dario Salvi on 29/04/2016.
diff --git a/backbone/src/main/java/org/researchstack/backbone/answerformat/EmailAnswerFormat.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/EmailAnswerFormat.java
similarity index 71%
rename from backbone/src/main/java/org/researchstack/backbone/answerformat/EmailAnswerFormat.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/EmailAnswerFormat.java
index 5b7585b33..f15eead49 100644
--- a/backbone/src/main/java/org/researchstack/backbone/answerformat/EmailAnswerFormat.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/EmailAnswerFormat.java
@@ -1,7 +1,6 @@
-package org.researchstack.backbone.answerformat;
+package org.researchstack.foundation.components.survey.answerformat;
-
-import org.researchstack.backbone.utils.TextUtils;
+import org.researchstack.foundation.components.utils.TextUtils;
public class EmailAnswerFormat extends TextAnswerFormat {
private static final int MAX_EMAIL_LENGTH = 255;
diff --git a/backbone/src/main/java/org/researchstack/backbone/answerformat/FormAnswerFormat.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/FormAnswerFormat.java
similarity index 86%
rename from backbone/src/main/java/org/researchstack/backbone/answerformat/FormAnswerFormat.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/FormAnswerFormat.java
index dcd6fb85d..a0a0191b9 100644
--- a/backbone/src/main/java/org/researchstack/backbone/answerformat/FormAnswerFormat.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/FormAnswerFormat.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.answerformat;
+package org.researchstack.foundation.components.survey.answerformat;
/**
* AnswerFormat indicating that the QuestionStep is a form step. This lets the layout know that it
diff --git a/backbone/src/main/java/org/researchstack/backbone/answerformat/IntegerAnswerFormat.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/IntegerAnswerFormat.java
similarity index 80%
rename from backbone/src/main/java/org/researchstack/backbone/answerformat/IntegerAnswerFormat.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/IntegerAnswerFormat.java
index 7ccaae7dd..1a5205989 100644
--- a/backbone/src/main/java/org/researchstack/backbone/answerformat/IntegerAnswerFormat.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/IntegerAnswerFormat.java
@@ -1,15 +1,15 @@
-package org.researchstack.backbone.answerformat;
+package org.researchstack.foundation.components.survey.answerformat;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.ui.step.body.BodyAnswer;
-import org.researchstack.backbone.utils.TextUtils;
+import org.researchstack.foundation.R;
+import org.researchstack.foundation.components.survey.ui.body.BodyAnswer;
+import org.researchstack.foundation.components.utils.TextUtils;
/**
* This class defines the attributes for an integer answer format that participants enter using a
* numeric keyboard.
*
* If you specify maximum or minimum values and the user enters a value outside the specified range,
- * the {@link org.researchstack.backbone.ui.step.body.IntegerQuestionBody} does not allow navigation
+ * the {@link org.researchstack.foundation.ui.step.body.IntegerQuestionBody} does not allow navigation
* until the participant provides a value that is within the valid range.
*/
public class IntegerAnswerFormat extends AnswerFormat {
@@ -60,11 +60,11 @@ public BodyAnswer validateAnswer(String inputString) {
Integer intAnswer = Integer.valueOf(inputString);
if (intAnswer < getMinValue()) {
return new BodyAnswer(false,
- R.string.rsb_invalid_answer_integer_under,
+ R.string.rsf_invalid_answer_integer_under,
String.valueOf(getMinValue()));
} else if (intAnswer > getMaxValue()) {
return new BodyAnswer(false,
- R.string.rsb_invalid_answer_integer_over,
+ R.string.rsf_invalid_answer_integer_over,
String.valueOf(getMaxValue()));
}
diff --git a/backbone/src/main/java/org/researchstack/backbone/answerformat/TextAnswerFormat.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/TextAnswerFormat.java
similarity index 96%
rename from backbone/src/main/java/org/researchstack/backbone/answerformat/TextAnswerFormat.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/TextAnswerFormat.java
index 3cdda7726..2a29e3543 100644
--- a/backbone/src/main/java/org/researchstack/backbone/answerformat/TextAnswerFormat.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/TextAnswerFormat.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.answerformat;
+package org.researchstack.foundation.components.survey.answerformat;
/**
diff --git a/backbone/src/main/java/org/researchstack/backbone/answerformat/UnknownAnswerFormat.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/UnknownAnswerFormat.java
similarity index 74%
rename from backbone/src/main/java/org/researchstack/backbone/answerformat/UnknownAnswerFormat.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/UnknownAnswerFormat.java
index 299dea72e..eac000ec3 100644
--- a/backbone/src/main/java/org/researchstack/backbone/answerformat/UnknownAnswerFormat.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/answerformat/UnknownAnswerFormat.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.answerformat;
+package org.researchstack.foundation.components.survey.answerformat;
@Deprecated
diff --git a/backbone/src/main/java/org/researchstack/backbone/model/Choice.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/model/Choice.java
similarity index 93%
rename from backbone/src/main/java/org/researchstack/backbone/model/Choice.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/model/Choice.java
index e4c820e9b..361820b1f 100644
--- a/backbone/src/main/java/org/researchstack/backbone/model/Choice.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/model/Choice.java
@@ -1,9 +1,9 @@
-package org.researchstack.backbone.model;
+package org.researchstack.foundation.components.survey.model;
import java.io.Serializable;
/**
- * Choice objects for use in {@link org.researchstack.backbone.answerformat.ChoiceAnswerFormat}.
+ * Choice objects for use in {@link org.researchstack.foundation.answerformat.ChoiceAnswerFormat}.
* They typically have an integer or string value, always with a string text representation of the
* choice for the user.
*
diff --git a/backbone/src/main/java/org/researchstack/backbone/step/FormStep.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/step/FormStep.java
similarity index 80%
rename from backbone/src/main/java/org/researchstack/backbone/step/FormStep.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/step/FormStep.java
index 94db97656..5af2d5bd7 100644
--- a/backbone/src/main/java/org/researchstack/backbone/step/FormStep.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/step/FormStep.java
@@ -1,6 +1,6 @@
-package org.researchstack.backbone.step;
+package org.researchstack.foundation.components.survey.step;
-import org.researchstack.backbone.answerformat.FormAnswerFormat;
+import org.researchstack.foundation.components.survey.answerformat.FormAnswerFormat;
import java.util.Arrays;
import java.util.List;
@@ -12,7 +12,7 @@
* To use FormStep, instantiate the object, give it a list of {@link QuestionStep}s, and include it
* in a task.
*
- * The result of a form step is an {@link org.researchstack.backbone.result.StepResult} object that
+ * The result of a form step is an {@link org.researchstack.foundation.result.StepResult} object that
* includes a child StepResult object for each form item.
*/
public class FormStep extends QuestionStep {
diff --git a/backbone/src/main/java/org/researchstack/backbone/step/InstructionStep.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/step/InstructionStep.java
similarity index 75%
rename from backbone/src/main/java/org/researchstack/backbone/step/InstructionStep.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/step/InstructionStep.java
index 8efbec31f..22bf1b98a 100644
--- a/backbone/src/main/java/org/researchstack/backbone/step/InstructionStep.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/step/InstructionStep.java
@@ -1,6 +1,7 @@
-package org.researchstack.backbone.step;
+package org.researchstack.foundation.components.survey.step;
-import org.researchstack.backbone.ui.step.layout.InstructionStepLayout;
+import org.researchstack.foundation.components.survey.ui.layout.InstructionStepLayout;
+import org.researchstack.foundation.core.models.step.Step;
/**
* An InstructionStep object gives the participant instructions for a task.
diff --git a/backbone/src/main/java/org/researchstack/backbone/step/QuestionStep.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/step/QuestionStep.java
similarity index 87%
rename from backbone/src/main/java/org/researchstack/backbone/step/QuestionStep.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/step/QuestionStep.java
index 014541465..bdb859fb3 100644
--- a/backbone/src/main/java/org/researchstack/backbone/step/QuestionStep.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/step/QuestionStep.java
@@ -1,7 +1,8 @@
-package org.researchstack.backbone.step;
+package org.researchstack.foundation.components.survey.step;
-import org.researchstack.backbone.answerformat.AnswerFormat;
-import org.researchstack.backbone.ui.step.layout.SurveyStepLayout;
+import org.researchstack.foundation.components.survey.answerformat.AnswerFormat;
+import org.researchstack.foundation.components.survey.ui.layout.SurveyStepLayout;
+import org.researchstack.foundation.core.models.step.Step;
/**
* The {@link QuestionStep} class is a concrete subclass of {@link Step} that represents a step in
@@ -9,16 +10,16 @@
*
* To use a question step, instantiate an QuestionStep object, fill in its properties, and include
* it in a task. When the task completes, the user's answer is encoded in the result hierarchy
- * returned from the {@link org.researchstack.backbone.ui.ViewTaskActivity}.
+ * returned from the {@link org.researchstack.foundation.ui.ViewTaskActivity}.
*
* When the ViewTaskActivity presents a QuestionStep object, it instantiates a {@link
* SurveyStepLayout} object to present the step. The actual visual presentation depends on the
- * answer format and its {@link org.researchstack.backbone.ui.step.body.StepBody}.
+ * answer format and its {@link org.researchstack.foundation.ui.step.body.StepBody}.
*
* When you need to present more than one question at the same time, it can be appropriate to use
* {@link FormStep} instead of QuestionStep.
*
- * The result of a question step is an {@link org.researchstack.backbone.result.StepResult} object.
+ * The result of a question step is an {@link org.researchstack.foundation.result.StepResult} object.
*/
public class QuestionStep extends Step {
private AnswerFormat answerFormat;
@@ -61,7 +62,7 @@ public QuestionStep(String identifier, String title, AnswerFormat format) {
}
/**
- * Returns a special {@link org.researchstack.backbone.ui.step.layout.StepLayout} that is used
+ * Returns a special {@link org.researchstack.foundation.ui.step.layout.StepLayout} that is used
* for all question steps.
*
* This step layout uses the {@link #getStepBodyClass()} to fill in the user interaction portion
@@ -75,7 +76,7 @@ public Class getStepLayoutClass() {
}
/**
- * Returns a subclass of {@link org.researchstack.backbone.ui.step.body.StepBody} responsible
+ * Returns a subclass of {@link org.researchstack.foundation.ui.step.body.StepBody} responsible
* for creating the ui for answering the question, base on the AnswerFormat.
*
* This class is used by {@link SurveyStepLayout} to create the part of the layout where the
@@ -96,7 +97,7 @@ public Class> getStepBodyClass() {
*
* For example, the answer format might include the type of data to collect, the constraints to
* place on the answer, or a list of available choices (in the case of single or multiple select
- * questions). It also provides the default {@link org.researchstack.backbone.ui.step.body.StepBody}
+ * questions). It also provides the default {@link org.researchstack.foundation.ui.step.body.StepBody}
* for questions of its type.
*
* @return the answer format for this question step
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/BodyAnswer.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/BodyAnswer.java
similarity index 82%
rename from backbone/src/main/java/org/researchstack/backbone/ui/step/body/BodyAnswer.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/BodyAnswer.java
index 08c14361d..db71d35e9 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/BodyAnswer.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/BodyAnswer.java
@@ -1,14 +1,14 @@
-package org.researchstack.backbone.ui.step.body;
+package org.researchstack.foundation.components.survey.ui.body;
import android.content.Context;
-import android.support.annotation.StringRes;
+import androidx.annotation.StringRes;
-import org.researchstack.backbone.R;
+import org.researchstack.foundation.R;
public class BodyAnswer {
public static final BodyAnswer VALID = new BodyAnswer(true, 0);
public static final BodyAnswer INVALID = new BodyAnswer(false,
- R.string.rsb_invalid_answer_default);
+ R.string.rsf_invalid_answer_default);
private boolean isValid;
private int reason;
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/DateQuestionBody.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/DateQuestionBody.java
similarity index 88%
rename from backbone/src/main/java/org/researchstack/backbone/ui/step/body/DateQuestionBody.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/DateQuestionBody.java
index fcdb5fd73..195d60cf2 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/DateQuestionBody.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/DateQuestionBody.java
@@ -1,22 +1,23 @@
-package org.researchstack.backbone.ui.step.body;
+package org.researchstack.foundation.components.survey.ui.body;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.content.res.Resources;
-import android.support.v7.view.ContextThemeWrapper;
+import androidx.appcompat.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.answerformat.AnswerFormat;
-import org.researchstack.backbone.answerformat.DateAnswerFormat;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.QuestionStep;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.utils.FormatHelper;
+
+import org.researchstack.foundation.R;
+import org.researchstack.foundation.components.survey.answerformat.AnswerFormat;
+import org.researchstack.foundation.components.survey.answerformat.DateAnswerFormat;
+import org.researchstack.foundation.components.survey.step.QuestionStep;
+import org.researchstack.foundation.components.utils.FormatHelper;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
import java.text.DateFormat;
import java.util.Calendar;
@@ -73,7 +74,7 @@ else if (format.getDefaultDate() != null) {
@Override
public View getBodyView(int viewType, LayoutInflater inflater, ViewGroup parent) {
- View view = inflater.inflate(R.layout.rsb_item_date_view, parent, false);
+ View view = inflater.inflate(R.layout.rsf_item_date_view, parent, false);
TextView title = (TextView) view.findViewById(R.id.label);
if (viewType == VIEW_TYPE_COMPACT) {
@@ -88,11 +89,11 @@ public View getBodyView(int viewType, LayoutInflater inflater, ViewGroup parent)
textView.setHint(step.getPlaceholder());
} else {
if (format.getStyle() == AnswerFormat.DateAnswerStyle.Date) {
- textView.setHint(R.string.rsb_hint_step_body_date);
+ textView.setHint(R.string.rsf_hint_step_body_date);
} else if (format.getStyle() == AnswerFormat.DateAnswerStyle.TimeOfDay) {
- textView.setHint(R.string.rsb_hint_step_body_time);
+ textView.setHint(R.string.rsf_hint_step_body_time);
} else if (format.getStyle() == AnswerFormat.DateAnswerStyle.DateAndTime) {
- textView.setHint(R.string.rsb_hint_step_body_datetime);
+ textView.setHint(R.string.rsf_hint_step_body_datetime);
}
}
@@ -115,8 +116,8 @@ public View getBodyView(int viewType, LayoutInflater inflater, ViewGroup parent)
Resources res = parent.getResources();
LinearLayout.MarginLayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
- layoutParams.leftMargin = res.getDimensionPixelSize(R.dimen.rsb_margin_left);
- layoutParams.rightMargin = res.getDimensionPixelSize(R.dimen.rsb_margin_right);
+ layoutParams.leftMargin = res.getDimensionPixelSize(R.dimen.rsf_margin_left);
+ layoutParams.rightMargin = res.getDimensionPixelSize(R.dimen.rsf_margin_right);
view.setLayoutParams(layoutParams);
return view;
@@ -140,7 +141,7 @@ public StepResult getStepResult(boolean skipped) {
@Override
public BodyAnswer getBodyAnswerState() {
if (!hasChosenDate) {
- return new BodyAnswer(false, R.string.rsb_invalid_answer_date_none);
+ return new BodyAnswer(false, R.string.rsf_invalid_answer_date_none);
}
return format.validateAnswer(calendar.getTime());
@@ -149,7 +150,7 @@ public BodyAnswer getBodyAnswerState() {
private void showDialog(TextView tv) {
// need to find a material date picker, since it's not in the support library
ContextThemeWrapper contextWrapper = new ContextThemeWrapper(tv.getContext(),
- R.style.Theme_Backbone);
+ R.style.Theme_Foundation);
if (format.getStyle() == AnswerFormat.DateAnswerStyle.Date) {
new DatePickerDialog(contextWrapper,
(view, year, monthOfYear, dayOfMonth) -> {
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/DecimalQuestionBody.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/DecimalQuestionBody.java
similarity index 85%
rename from backbone/src/main/java/org/researchstack/backbone/ui/step/body/DecimalQuestionBody.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/DecimalQuestionBody.java
index c88bea5ba..16e305693 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/DecimalQuestionBody.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/DecimalQuestionBody.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.ui.step.body;
+package org.researchstack.foundation.components.survey.ui.body;
import android.content.Context;
import android.content.res.Resources;
@@ -11,13 +11,13 @@
import android.widget.LinearLayout;
import android.widget.TextView;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.answerformat.DecimalAnswerFormat;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.QuestionStep;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.utils.TextUtils;
-import org.researchstack.backbone.utils.ViewUtils;
+import org.researchstack.foundation.R;
+import org.researchstack.foundation.components.survey.answerformat.DecimalAnswerFormat;
+import org.researchstack.foundation.components.survey.step.QuestionStep;
+import org.researchstack.foundation.components.utils.TextUtils;
+import org.researchstack.foundation.components.utils.ViewUtils;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
public class DecimalQuestionBody implements StepBody {
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
@@ -48,8 +48,8 @@ public View getBodyView(int viewType, LayoutInflater inflater, ViewGroup parent)
Resources res = parent.getResources();
LinearLayout.MarginLayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
- layoutParams.leftMargin = res.getDimensionPixelSize(R.dimen.rsb_margin_left);
- layoutParams.rightMargin = res.getDimensionPixelSize(R.dimen.rsb_margin_right);
+ layoutParams.leftMargin = res.getDimensionPixelSize(R.dimen.rsf_margin_left);
+ layoutParams.rightMargin = res.getDimensionPixelSize(R.dimen.rsf_margin_right);
view.setLayoutParams(layoutParams);
return view;
@@ -66,14 +66,14 @@ private View getViewForType(int viewType, LayoutInflater inflater, ViewGroup par
}
private View initViewDefault(LayoutInflater inflater, ViewGroup parent) {
- editText = (EditText) inflater.inflate(R.layout.rsb_item_edit_text, parent, false);
+ editText = (EditText) inflater.inflate(R.layout.rsf_item_edit_text, parent, false);
setFilters(parent.getContext());
return editText;
}
private View initViewCompact(LayoutInflater inflater, ViewGroup parent) {
- View formItemView = inflater.inflate(R.layout.rsb_item_edit_text_compact, parent, false);
+ View formItemView = inflater.inflate(R.layout.rsf_item_edit_text_compact, parent, false);
TextView title = (TextView) formItemView.findViewById(R.id.label);
title.setText(step.getTitle());
@@ -93,9 +93,9 @@ private void setFilters(Context context) {
if (step.getPlaceholder() != null) {
editText.setHint(step.getPlaceholder());
} else if (maxValue == Integer.MAX_VALUE) {
- editText.setHint(context.getString(R.string.rsb_hint_step_body_int_no_max));
+ editText.setHint(context.getString(R.string.rsf_hint_step_body_int_no_max));
} else {
- editText.setHint(context.getString(R.string.rsb_hint_step_body_dec,
+ editText.setHint(context.getString(R.string.rsf_hint_step_body_dec,
minValue,
maxValue));
}
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/DurationQuestionBody.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/DurationQuestionBody.java
similarity index 89%
rename from backbone/src/main/java/org/researchstack/backbone/ui/step/body/DurationQuestionBody.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/DurationQuestionBody.java
index 73a1e3bed..fd6ea5c45 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/DurationQuestionBody.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/DurationQuestionBody.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.ui.step.body;
+package org.researchstack.foundation.components.survey.ui.body;
import android.content.res.Resources;
import android.view.LayoutInflater;
@@ -8,11 +8,11 @@
import android.widget.LinearLayout;
import android.widget.Spinner;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.answerformat.DurationAnswerFormat;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.QuestionStep;
-import org.researchstack.backbone.step.Step;
+import org.researchstack.foundation.R;
+import org.researchstack.foundation.components.survey.answerformat.DurationAnswerFormat;
+import org.researchstack.foundation.components.survey.step.QuestionStep;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
/**
* Implementation of the question type "duration".
@@ -59,8 +59,8 @@ public View getBodyView(int viewType, LayoutInflater inflater, ViewGroup parent)
Resources res = parent.getResources();
LinearLayout.MarginLayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
- layoutParams.leftMargin = res.getDimensionPixelSize(R.dimen.rsb_margin_left);
- layoutParams.rightMargin = res.getDimensionPixelSize(R.dimen.rsb_margin_right);
+ layoutParams.leftMargin = res.getDimensionPixelSize(R.dimen.rsf_margin_left);
+ layoutParams.rightMargin = res.getDimensionPixelSize(R.dimen.rsf_margin_right);
view.setLayoutParams(layoutParams);
return view;
@@ -75,7 +75,7 @@ private View getViewForType(int viewType, LayoutInflater inflater, ViewGroup par
}
private View initView(LayoutInflater inflater, ViewGroup parent) {
- View v = inflater.inflate(R.layout.rsb_item_edit_duration, parent, false);
+ View v = inflater.inflate(R.layout.rsf_item_edit_duration, parent, false);
String[] hoursStrs = new String[24];
for (int i = 0; i < 24; i++) hoursStrs[i] = String.valueOf(i);
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/FormBody.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/FormBody.java
similarity index 86%
rename from backbone/src/main/java/org/researchstack/backbone/ui/step/body/FormBody.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/FormBody.java
index d6c85f7e5..96fffaff9 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/FormBody.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/FormBody.java
@@ -1,17 +1,18 @@
-package org.researchstack.backbone.ui.step.body;
+package org.researchstack.foundation.components.survey.ui.body;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.FormStep;
-import org.researchstack.backbone.step.QuestionStep;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.utils.LogExt;
+
+import org.researchstack.foundation.R;
+import org.researchstack.foundation.components.survey.step.FormStep;
+import org.researchstack.foundation.components.survey.step.QuestionStep;
+import org.researchstack.foundation.components.utils.LogExt;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
@@ -37,7 +38,7 @@ public FormBody(Step step, StepResult result) {
@Override
public View getBodyView(int viewType, LayoutInflater inflater, ViewGroup parent) {
// Inflate our container for each compact child StepBody
- LinearLayout body = (LinearLayout) inflater.inflate(R.layout.rsb_step_layout_form_body,
+ LinearLayout body = (LinearLayout) inflater.inflate(R.layout.rsf_step_layout_form_body,
parent,
false);
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/IntegerQuestionBody.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/IntegerQuestionBody.java
similarity index 85%
rename from backbone/src/main/java/org/researchstack/backbone/ui/step/body/IntegerQuestionBody.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/IntegerQuestionBody.java
index d06575237..112f0272b 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/IntegerQuestionBody.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/IntegerQuestionBody.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.ui.step.body;
+package org.researchstack.foundation.components.survey.ui.body;
import android.content.Context;
import android.content.res.Resources;
@@ -11,13 +11,13 @@
import android.widget.LinearLayout;
import android.widget.TextView;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.answerformat.IntegerAnswerFormat;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.QuestionStep;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.utils.TextUtils;
-import org.researchstack.backbone.utils.ViewUtils;
+import org.researchstack.foundation.R;
+import org.researchstack.foundation.components.survey.answerformat.IntegerAnswerFormat;
+import org.researchstack.foundation.components.survey.step.QuestionStep;
+import org.researchstack.foundation.components.utils.TextUtils;
+import org.researchstack.foundation.components.utils.ViewUtils;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
public class IntegerQuestionBody implements StepBody {
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
@@ -48,8 +48,8 @@ public View getBodyView(int viewType, LayoutInflater inflater, ViewGroup parent)
Resources res = parent.getResources();
LinearLayout.MarginLayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
- layoutParams.leftMargin = res.getDimensionPixelSize(R.dimen.rsb_margin_left);
- layoutParams.rightMargin = res.getDimensionPixelSize(R.dimen.rsb_margin_right);
+ layoutParams.leftMargin = res.getDimensionPixelSize(R.dimen.rsf_margin_left);
+ layoutParams.rightMargin = res.getDimensionPixelSize(R.dimen.rsf_margin_right);
view.setLayoutParams(layoutParams);
return view;
@@ -66,14 +66,14 @@ private View getViewForType(int viewType, LayoutInflater inflater, ViewGroup par
}
private View initViewDefault(LayoutInflater inflater, ViewGroup parent) {
- editText = (EditText) inflater.inflate(R.layout.rsb_item_edit_text, parent, false);
+ editText = (EditText) inflater.inflate(R.layout.rsf_item_edit_text, parent, false);
setFilters(parent.getContext());
return editText;
}
private View initViewCompact(LayoutInflater inflater, ViewGroup parent) {
- View formItemView = inflater.inflate(R.layout.rsb_item_edit_text_compact, parent, false);
+ View formItemView = inflater.inflate(R.layout.rsf_item_edit_text_compact, parent, false);
TextView title = (TextView) formItemView.findViewById(R.id.label);
title.setText(step.getTitle());
@@ -93,9 +93,9 @@ private void setFilters(Context context) {
if (step.getPlaceholder() != null) {
editText.setHint(step.getPlaceholder());
} else if (maxValue == Integer.MAX_VALUE) {
- editText.setHint(context.getString(R.string.rsb_hint_step_body_int_no_max));
+ editText.setHint(context.getString(R.string.rsf_hint_step_body_int_no_max));
} else {
- editText.setHint(context.getString(R.string.rsb_hint_step_body_int,
+ editText.setHint(context.getString(R.string.rsf_hint_step_body_int,
minValue,
maxValue));
}
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/MultiChoiceQuestionBody.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/MultiChoiceQuestionBody.java
similarity index 85%
rename from backbone/src/main/java/org/researchstack/backbone/ui/step/body/MultiChoiceQuestionBody.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/MultiChoiceQuestionBody.java
index 2499de7aa..99a31dc94 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/MultiChoiceQuestionBody.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/MultiChoiceQuestionBody.java
@@ -1,8 +1,8 @@
-package org.researchstack.backbone.ui.step.body;
+package org.researchstack.foundation.components.survey.ui.body;
import android.content.res.Resources;
-import android.support.v4.content.ContextCompat;
-import android.support.v7.widget.AppCompatCheckBox;
+import androidx.core.content.ContextCompat;
+import androidx.appcompat.widget.AppCompatCheckBox;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -10,12 +10,13 @@
import android.widget.RadioGroup;
import android.widget.TextView;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.answerformat.ChoiceAnswerFormat;
-import org.researchstack.backbone.model.Choice;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.QuestionStep;
-import org.researchstack.backbone.step.Step;
+
+import org.researchstack.foundation.R;
+import org.researchstack.foundation.components.survey.answerformat.ChoiceAnswerFormat;
+import org.researchstack.foundation.components.survey.model.Choice;
+import org.researchstack.foundation.components.survey.step.QuestionStep;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
import java.util.Arrays;
import java.util.HashSet;
@@ -53,8 +54,8 @@ public View getBodyView(int viewType, LayoutInflater inflater, ViewGroup parent)
Resources res = parent.getResources();
LinearLayout.MarginLayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
- layoutParams.leftMargin = res.getDimensionPixelSize(R.dimen.rsb_margin_left);
- layoutParams.rightMargin = res.getDimensionPixelSize(R.dimen.rsb_margin_right);
+ layoutParams.leftMargin = res.getDimensionPixelSize(R.dimen.rsf_margin_left);
+ layoutParams.rightMargin = res.getDimensionPixelSize(R.dimen.rsf_margin_right);
view.setLayoutParams(layoutParams);
return view;
@@ -74,13 +75,13 @@ private View initViewDefault(LayoutInflater inflater, ViewGroup parent) {
RadioGroup radioGroup = new RadioGroup(inflater.getContext());
radioGroup.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
radioGroup.setDividerDrawable(ContextCompat.getDrawable(parent.getContext(),
- R.drawable.rsb_divider_empty_8dp));
+ R.drawable.rsf_divider_empty_8dp));
for (int i = 0; i < choices.length; i++) {
Choice item = choices[i];
// Create & add the View to our body-view
- AppCompatCheckBox checkBox = (AppCompatCheckBox) inflater.inflate(R.layout.rsb_item_checkbox,
+ AppCompatCheckBox checkBox = (AppCompatCheckBox) inflater.inflate(R.layout.rsf_item_checkbox,
radioGroup,
false);
checkBox.setText(item.getText());
@@ -109,7 +110,7 @@ private View initViewDefault(LayoutInflater inflater, ViewGroup parent) {
private View initViewCompact(LayoutInflater inflater, ViewGroup parent) {
ViewGroup compactView = (ViewGroup) initViewDefault(inflater, parent);
- TextView label = (TextView) inflater.inflate(R.layout.rsb_item_text_view_title_compact,
+ TextView label = (TextView) inflater.inflate(R.layout.rsf_item_text_view_title_compact,
compactView,
false);
label.setText(step.getTitle());
@@ -133,7 +134,7 @@ public StepResult getStepResult(boolean skipped) {
@Override
public BodyAnswer getBodyAnswerState() {
if (currentSelected.isEmpty()) {
- return new BodyAnswer(false, R.string.rsb_invalid_answer_choice);
+ return new BodyAnswer(false, R.string.rsf_invalid_answer_choice);
} else {
return BodyAnswer.VALID;
}
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/NotImplementedStepBody.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/NotImplementedStepBody.java
similarity index 85%
rename from backbone/src/main/java/org/researchstack/backbone/ui/step/body/NotImplementedStepBody.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/NotImplementedStepBody.java
index 3d59fb387..70b0f261b 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/NotImplementedStepBody.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/NotImplementedStepBody.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.ui.step.body;
+package org.researchstack.foundation.components.survey.ui.body;
import android.content.Context;
import android.view.LayoutInflater;
@@ -6,8 +6,9 @@
import android.view.ViewGroup;
import android.widget.TextView;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.QuestionStep;
+import org.researchstack.foundation.components.survey.step.QuestionStep;
+import org.researchstack.foundation.core.models.result.StepResult;
+
@Deprecated
public class NotImplementedStepBody implements StepBody {
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/SingleChoiceQuestionBody.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/SingleChoiceQuestionBody.java
similarity index 85%
rename from backbone/src/main/java/org/researchstack/backbone/ui/step/body/SingleChoiceQuestionBody.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/SingleChoiceQuestionBody.java
index d7a2ced1c..bd6212eaf 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/SingleChoiceQuestionBody.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/SingleChoiceQuestionBody.java
@@ -1,7 +1,7 @@
-package org.researchstack.backbone.ui.step.body;
+package org.researchstack.foundation.components.survey.ui.body;
import android.content.res.Resources;
-import android.support.v4.content.ContextCompat;
+import androidx.core.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -10,12 +10,13 @@
import android.widget.RadioGroup;
import android.widget.TextView;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.answerformat.ChoiceAnswerFormat;
-import org.researchstack.backbone.model.Choice;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.QuestionStep;
-import org.researchstack.backbone.step.Step;
+import org.researchstack.foundation.R;
+import org.researchstack.foundation.components.survey.answerformat.ChoiceAnswerFormat;
+import org.researchstack.foundation.components.survey.model.Choice;
+import org.researchstack.foundation.components.survey.step.QuestionStep;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
+
public class SingleChoiceQuestionBody implements StepBody {
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
@@ -51,8 +52,8 @@ public View getBodyView(int viewType, LayoutInflater inflater, ViewGroup parent)
Resources res = parent.getResources();
LinearLayout.MarginLayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
- layoutParams.leftMargin = res.getDimensionPixelSize(R.dimen.rsb_margin_left);
- layoutParams.rightMargin = res.getDimensionPixelSize(R.dimen.rsb_margin_right);
+ layoutParams.leftMargin = res.getDimensionPixelSize(R.dimen.rsf_margin_left);
+ layoutParams.rightMargin = res.getDimensionPixelSize(R.dimen.rsf_margin_right);
view.setLayoutParams(layoutParams);
return view;
@@ -72,11 +73,11 @@ private View initViewDefault(LayoutInflater inflater, ViewGroup parent) {
RadioGroup radioGroup = new RadioGroup(parent.getContext());
radioGroup.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
radioGroup.setDividerDrawable(ContextCompat.getDrawable(parent.getContext(),
- R.drawable.rsb_divider_empty_8dp));
+ R.drawable.rsf_divider_empty_8dp));
for (int i = 0; i < choices.length; i++) {
Choice choice = choices[i];
- RadioButton radioButton = (RadioButton) inflater.inflate(R.layout.rsb_item_radio,
+ RadioButton radioButton = (RadioButton) inflater.inflate(R.layout.rsf_item_radio,
radioGroup,
false);
radioButton.setText(choice.getText());
@@ -100,7 +101,7 @@ private View initViewDefault(LayoutInflater inflater, ViewGroup parent) {
private View initViewCompact(LayoutInflater inflater, ViewGroup parent) {
ViewGroup compactView = (ViewGroup) initViewDefault(inflater, parent);
- TextView label = (TextView) inflater.inflate(R.layout.rsb_item_text_view_title_compact,
+ TextView label = (TextView) inflater.inflate(R.layout.rsf_item_text_view_title_compact,
compactView,
false);
label.setText(step.getTitle());
@@ -124,7 +125,7 @@ public StepResult getStepResult(boolean skipped) {
@Override
public BodyAnswer getBodyAnswerState() {
if (currentSelected == null) {
- return new BodyAnswer(false, R.string.rsb_invalid_answer_choice);
+ return new BodyAnswer(false, R.string.rsf_invalid_answer_choice);
} else {
return BodyAnswer.VALID;
}
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/StepBody.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/StepBody.java
similarity index 73%
rename from backbone/src/main/java/org/researchstack/backbone/ui/step/body/StepBody.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/StepBody.java
index d1658a7cd..e42b2afe3 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/StepBody.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/StepBody.java
@@ -1,10 +1,10 @@
-package org.researchstack.backbone.ui.step.body;
+package org.researchstack.foundation.components.survey.ui.body;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import org.researchstack.backbone.result.StepResult;
+import org.researchstack.foundation.core.models.result.StepResult;
public interface StepBody {
int VIEW_TYPE_DEFAULT = 0;
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/TextQuestionBody.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/TextQuestionBody.java
similarity index 72%
rename from backbone/src/main/java/org/researchstack/backbone/ui/step/body/TextQuestionBody.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/TextQuestionBody.java
index ad4a83505..2188a6b0d 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/step/body/TextQuestionBody.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/body/TextQuestionBody.java
@@ -1,7 +1,9 @@
-package org.researchstack.backbone.ui.step.body;
+package org.researchstack.foundation.components.survey.ui.body;
import android.content.res.Resources;
+import android.text.Editable;
import android.text.InputFilter;
+import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -9,15 +11,14 @@
import android.widget.LinearLayout;
import android.widget.TextView;
-import com.jakewharton.rxbinding.widget.RxTextView;
+import org.researchstack.foundation.R;
+import org.researchstack.foundation.components.survey.answerformat.TextAnswerFormat;
+import org.researchstack.foundation.components.survey.step.QuestionStep;
+import org.researchstack.foundation.components.utils.TextUtils;
+import org.researchstack.foundation.components.utils.ViewUtils;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.answerformat.TextAnswerFormat;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.QuestionStep;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.utils.TextUtils;
-import org.researchstack.backbone.utils.ViewUtils;
public class TextQuestionBody implements StepBody {
//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
@@ -38,13 +39,13 @@ public TextQuestionBody(Step step, StepResult result) {
@Override
public View getBodyView(int viewType, LayoutInflater inflater, ViewGroup parent) {
- View body = inflater.inflate(R.layout.rsb_item_edit_text_compact, parent, false);
+ View body = inflater.inflate(R.layout.rsf_item_edit_text_compact, parent, false);
editText = (EditText) body.findViewById(R.id.value);
if (step.getPlaceholder() != null) {
editText.setHint(step.getPlaceholder());
} else {
- editText.setHint(R.string.rsb_hint_step_body_text);
+ editText.setHint(R.string.rsf_hint_step_body_text);
}
TextView title = (TextView) body.findViewById(R.id.label);
@@ -62,8 +63,21 @@ public View getBodyView(int viewType, LayoutInflater inflater, ViewGroup parent)
}
// Set result on text change
- RxTextView.textChanges(editText).subscribe(text -> {
- result.setResult(text.toString());
+ editText.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ result.setResult(s.toString());
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+
+ }
});
// Format EditText from TextAnswerFormat
@@ -80,8 +94,8 @@ public View getBodyView(int viewType, LayoutInflater inflater, ViewGroup parent)
Resources res = parent.getResources();
LinearLayout.MarginLayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
- layoutParams.leftMargin = res.getDimensionPixelSize(R.dimen.rsb_margin_left);
- layoutParams.rightMargin = res.getDimensionPixelSize(R.dimen.rsb_margin_right);
+ layoutParams.leftMargin = res.getDimensionPixelSize(R.dimen.rsf_margin_left);
+ layoutParams.rightMargin = res.getDimensionPixelSize(R.dimen.rsf_margin_right);
body.setLayoutParams(layoutParams);
return body;
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/step/layout/InstructionStepLayout.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/layout/InstructionStepLayout.java
similarity index 63%
rename from backbone/src/main/java/org/researchstack/backbone/ui/step/layout/InstructionStepLayout.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/ui/layout/InstructionStepLayout.java
index 6e967df95..63526ef82 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/step/layout/InstructionStepLayout.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/layout/InstructionStepLayout.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.ui.step.layout;
+package org.researchstack.foundation.components.survey.ui.layout;
import android.content.Context;
import android.content.Intent;
@@ -7,15 +7,15 @@
import android.view.View;
import android.widget.TextView;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.ResourcePathManager;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.ui.ViewWebDocumentActivity;
-import org.researchstack.backbone.ui.callbacks.StepCallbacks;
-import org.researchstack.backbone.ui.views.FixedSubmitBarLayout;
-import org.researchstack.backbone.ui.views.SubmitBar;
-import org.researchstack.backbone.utils.TextUtils;
+import org.researchstack.foundation.R;
+import org.researchstack.foundation.components.common.ui.callbacks.StepCallbacks;
+import org.researchstack.foundation.components.common.ui.layout.FixedSubmitBarLayout;
+import org.researchstack.foundation.components.common.ui.layout.StepLayout;
+import org.researchstack.foundation.components.common.ui.views.SubmitBar;
+import org.researchstack.foundation.components.singletons.TextViewLinkManager;
+import org.researchstack.foundation.components.utils.TextUtils;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
public class InstructionStepLayout extends FixedSubmitBarLayout implements StepLayout {
private StepCallbacks callbacks;
@@ -57,7 +57,7 @@ public void setCallbacks(StepCallbacks callbacks) {
@Override
public int getContentResourceId() {
- return R.layout.rsb_step_layout_instruction;
+ return R.layout.rsf_step_layout_instruction;
}
private void initializeStep() {
@@ -65,38 +65,30 @@ private void initializeStep() {
// Set Title
if (!TextUtils.isEmpty(step.getTitle())) {
- TextView title = (TextView) findViewById(R.id.rsb_intruction_title);
+ TextView title = (TextView) findViewById(R.id.rsf_intruction_title);
title.setVisibility(View.VISIBLE);
title.setText(step.getTitle());
}
// Set Summary
if (!TextUtils.isEmpty(step.getText())) {
- TextView summary = (TextView) findViewById(R.id.rsb_intruction_text);
+ TextView summary = (TextView) findViewById(R.id.rsf_intruction_text);
summary.setVisibility(View.VISIBLE);
summary.setText(Html.fromHtml(step.getText()));
- summary.setMovementMethod(new TextViewLinkHandler() {
- @Override
- public void onLinkClick(String url) {
- String path = ResourcePathManager.getInstance().
- generateAbsolutePath(ResourcePathManager.Resource.TYPE_HTML, url);
- Intent intent = ViewWebDocumentActivity.newIntentForPath(getContext(),
- step.getTitle(),
- path);
- getContext().startActivity(intent);
- }
- });
+ summary.setMovementMethod(
+ TextViewLinkManager.Companion.getSharedManager().getHandler(getContext(), step.getTitle())
+ );
}
// Set Next / Skip
- SubmitBar submitBar = (SubmitBar) findViewById(R.id.rsb_submit_bar);
- submitBar.setPositiveTitle(R.string.rsb_next);
+ SubmitBar submitBar = (SubmitBar) findViewById(R.id.rsf_submit_bar);
+ submitBar.setPositiveTitle(R.string.rsf_next);
submitBar.setPositiveAction(v -> callbacks.onSaveStep(StepCallbacks.ACTION_NEXT,
step,
null));
if (step.isOptional()) {
- submitBar.setNegativeTitle(R.string.rsb_step_skip);
+ submitBar.setNegativeTitle(R.string.rsf_step_skip);
submitBar.setNegativeAction(v -> {
if (callbacks != null) {
callbacks.onSaveStep(StepCallbacks.ACTION_NEXT, step, null);
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/step/layout/SurveyStepLayout.java b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/layout/SurveyStepLayout.java
similarity index 74%
rename from backbone/src/main/java/org/researchstack/backbone/ui/step/layout/SurveyStepLayout.java
rename to foundation/src/main/java/org/researchstack/foundation/components/survey/ui/layout/SurveyStepLayout.java
index 4d27c1b4b..95849ecda 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/step/layout/SurveyStepLayout.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/survey/ui/layout/SurveyStepLayout.java
@@ -1,10 +1,9 @@
-package org.researchstack.backbone.ui.step.layout;
+package org.researchstack.foundation.components.survey.ui.layout;
import android.content.Context;
-import android.content.Intent;
import android.os.Parcelable;
-import android.support.annotation.NonNull;
-import android.support.annotation.StringRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.StringRes;
import android.text.Html;
import android.util.AttributeSet;
import android.view.LayoutInflater;
@@ -13,19 +12,19 @@
import android.widget.TextView;
import android.widget.Toast;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.ResourcePathManager;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.QuestionStep;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.ui.ViewWebDocumentActivity;
-import org.researchstack.backbone.ui.callbacks.StepCallbacks;
-import org.researchstack.backbone.ui.step.body.BodyAnswer;
-import org.researchstack.backbone.ui.step.body.StepBody;
-import org.researchstack.backbone.ui.views.FixedSubmitBarLayout;
-import org.researchstack.backbone.ui.views.SubmitBar;
-import org.researchstack.backbone.utils.LogExt;
-import org.researchstack.backbone.utils.TextUtils;
+import org.researchstack.foundation.R;
+import org.researchstack.foundation.components.common.ui.callbacks.StepCallbacks;
+import org.researchstack.foundation.components.common.ui.layout.StepLayout;
+import org.researchstack.foundation.components.common.ui.views.SubmitBar;
+import org.researchstack.foundation.components.singletons.TextViewLinkManager;
+import org.researchstack.foundation.components.survey.ui.body.BodyAnswer;
+import org.researchstack.foundation.components.common.ui.layout.FixedSubmitBarLayout;
+import org.researchstack.foundation.components.survey.step.QuestionStep;
+import org.researchstack.foundation.components.survey.ui.body.StepBody;
+import org.researchstack.foundation.components.utils.LogExt;
+import org.researchstack.foundation.components.utils.TextUtils;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
import java.lang.reflect.Constructor;
@@ -100,7 +99,7 @@ public void setCallbacks(StepCallbacks callbacks) {
@Override
public int getContentResourceId() {
- return R.layout.rsb_step_layout;
+ return R.layout.rsf_step_layout;
}
public void initializeStep() {
@@ -111,10 +110,10 @@ public void initializeStep() {
public void initStepLayout() {
LogExt.i(getClass(), "initStepLayout()");
- container = (LinearLayout) findViewById(R.id.rsb_survey_content_container);
- TextView title = (TextView) findViewById(R.id.rsb_survey_title);
- TextView summary = (TextView) findViewById(R.id.rsb_survey_text);
- SubmitBar submitBar = (SubmitBar) findViewById(R.id.rsb_submit_bar);
+ container = (LinearLayout) findViewById(R.id.rsf_survey_content_container);
+ TextView title = (TextView) findViewById(R.id.rsf_survey_title);
+ TextView summary = (TextView) findViewById(R.id.rsf_survey_text);
+ SubmitBar submitBar = (SubmitBar) findViewById(R.id.rsf_submit_bar);
submitBar.setPositiveAction(v -> onNextClicked());
if (questionStep != null) {
@@ -126,21 +125,13 @@ public void initStepLayout() {
if (!TextUtils.isEmpty(questionStep.getText())) {
summary.setVisibility(View.VISIBLE);
summary.setText(Html.fromHtml(questionStep.getText()));
- summary.setMovementMethod(new TextViewLinkHandler() {
- @Override
- public void onLinkClick(String url) {
- String path = ResourcePathManager.getInstance().
- generateAbsolutePath(ResourcePathManager.Resource.TYPE_HTML, url);
- Intent intent = ViewWebDocumentActivity.newIntentForPath(getContext(),
- questionStep.getTitle(),
- path);
- getContext().startActivity(intent);
- }
- });
+ summary.setMovementMethod(
+ TextViewLinkManager.Companion.getSharedManager().getHandler(getContext(), questionStep.getTitle())
+ );
}
if (questionStep.isOptional()) {
- submitBar.setNegativeTitle(R.string.rsb_step_skip);
+ submitBar.setNegativeTitle(R.string.rsf_step_skip);
submitBar.setNegativeAction(v -> onSkipClicked());
} else {
submitBar.getNegativeActionView().setVisibility(View.GONE);
@@ -156,11 +147,11 @@ public void initStepBody() {
View body = stepBody.getBodyView(StepBody.VIEW_TYPE_DEFAULT, inflater, this);
if (body != null) {
- View oldView = container.findViewById(R.id.rsb_survey_step_body);
+ View oldView = container.findViewById(R.id.rsf_survey_step_body);
int bodyIndex = container.indexOfChild(oldView);
container.removeView(oldView);
container.addView(body, bodyIndex);
- body.setId(R.id.rsb_survey_step_body);
+ body.setId(R.id.rsf_survey_step_body);
}
}
diff --git a/backbone/src/main/java/org/researchstack/backbone/utils/FormatHelper.java b/foundation/src/main/java/org/researchstack/foundation/components/utils/FormatHelper.java
similarity index 94%
rename from backbone/src/main/java/org/researchstack/backbone/utils/FormatHelper.java
rename to foundation/src/main/java/org/researchstack/foundation/components/utils/FormatHelper.java
index 721cdfbdc..f0d07bd7d 100644
--- a/backbone/src/main/java/org/researchstack/backbone/utils/FormatHelper.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/utils/FormatHelper.java
@@ -1,6 +1,4 @@
-package org.researchstack.backbone.utils;
-
-import org.researchstack.backbone.ui.step.layout.ConsentSignatureStepLayout;
+package org.researchstack.foundation.components.utils;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
diff --git a/backbone/src/main/java/org/researchstack/backbone/utils/LogExt.java b/foundation/src/main/java/org/researchstack/foundation/components/utils/LogExt.java
similarity index 98%
rename from backbone/src/main/java/org/researchstack/backbone/utils/LogExt.java
rename to foundation/src/main/java/org/researchstack/foundation/components/utils/LogExt.java
index 991adcc8c..bafc04e26 100644
--- a/backbone/src/main/java/org/researchstack/backbone/utils/LogExt.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/utils/LogExt.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.utils;
+package org.researchstack.foundation.components.utils;
import android.util.Log;
diff --git a/backbone/src/main/java/org/researchstack/backbone/utils/ResUtils.java b/foundation/src/main/java/org/researchstack/foundation/components/utils/ResUtils.java
similarity index 94%
rename from backbone/src/main/java/org/researchstack/backbone/utils/ResUtils.java
rename to foundation/src/main/java/org/researchstack/foundation/components/utils/ResUtils.java
index 07010fae8..7436e76f9 100644
--- a/backbone/src/main/java/org/researchstack/backbone/utils/ResUtils.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/utils/ResUtils.java
@@ -1,10 +1,7 @@
-package org.researchstack.backbone.utils;
+package org.researchstack.foundation.components.utils;
import android.content.Context;
-import org.researchstack.backbone.StorageAccess;
-
-
public class ResUtils {
private ResUtils() {
diff --git a/backbone/src/main/java/org/researchstack/backbone/utils/TextUtils.java b/foundation/src/main/java/org/researchstack/foundation/components/utils/TextUtils.java
similarity index 97%
rename from backbone/src/main/java/org/researchstack/backbone/utils/TextUtils.java
rename to foundation/src/main/java/org/researchstack/foundation/components/utils/TextUtils.java
index c658096cf..987dfd0f0 100644
--- a/backbone/src/main/java/org/researchstack/backbone/utils/TextUtils.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/utils/TextUtils.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.utils;
+package org.researchstack.foundation.components.utils;
import android.text.InputFilter;
import android.text.Spanned;
diff --git a/backbone/src/main/java/org/researchstack/backbone/utils/ThemeUtils.java b/foundation/src/main/java/org/researchstack/foundation/components/utils/ThemeUtils.java
similarity index 92%
rename from backbone/src/main/java/org/researchstack/backbone/utils/ThemeUtils.java
rename to foundation/src/main/java/org/researchstack/foundation/components/utils/ThemeUtils.java
index b9df9c894..d2a93e329 100644
--- a/backbone/src/main/java/org/researchstack/backbone/utils/ThemeUtils.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/utils/ThemeUtils.java
@@ -1,11 +1,11 @@
-package org.researchstack.backbone.utils;
+package org.researchstack.foundation.components.utils;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.TypedValue;
-import org.researchstack.backbone.R;
+import org.researchstack.foundation.R;
import java.lang.reflect.Method;
@@ -38,7 +38,7 @@ public static int getPassCodeTheme(Context context) {
new int[]{R.attr.passcodeTheme});
int themeResId = a.getResourceId(0, 0);
if (themeResId == 0) {
- throw new RuntimeException("Theme must define attribute passCodeTheme or extend from @style/Base.Theme.Backbone");
+ throw new RuntimeException("Theme must define attribute passCodeTheme or extend from @style/Base.Theme.Foundation");
}
a.recycle();
diff --git a/backbone/src/main/java/org/researchstack/backbone/utils/UiThreadContext.java b/foundation/src/main/java/org/researchstack/foundation/components/utils/UiThreadContext.java
similarity index 93%
rename from backbone/src/main/java/org/researchstack/backbone/utils/UiThreadContext.java
rename to foundation/src/main/java/org/researchstack/foundation/components/utils/UiThreadContext.java
index 918d6453e..90e0dda15 100644
--- a/backbone/src/main/java/org/researchstack/backbone/utils/UiThreadContext.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/utils/UiThreadContext.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.utils;
+package org.researchstack.foundation.components.utils;
import android.os.Looper;
diff --git a/backbone/src/main/java/org/researchstack/backbone/utils/ViewUtils.java b/foundation/src/main/java/org/researchstack/foundation/components/utils/ViewUtils.java
similarity index 97%
rename from backbone/src/main/java/org/researchstack/backbone/utils/ViewUtils.java
rename to foundation/src/main/java/org/researchstack/foundation/components/utils/ViewUtils.java
index 2eb753cd3..744a15315 100644
--- a/backbone/src/main/java/org/researchstack/backbone/utils/ViewUtils.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/utils/ViewUtils.java
@@ -1,9 +1,9 @@
-package org.researchstack.backbone.utils;
+package org.researchstack.foundation.components.utils;
import android.app.Activity;
import android.content.Context;
import android.os.Build;
-import android.support.v4.app.Fragment;
+import androidx.fragment.app.Fragment;
import android.text.InputFilter;
import android.text.InputType;
import android.view.View;
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/ViewVideoActivity.java b/foundation/src/main/java/org/researchstack/foundation/components/web/ui/activities/ViewVideoActivity.java
similarity index 83%
rename from backbone/src/main/java/org/researchstack/backbone/ui/ViewVideoActivity.java
rename to foundation/src/main/java/org/researchstack/foundation/components/web/ui/activities/ViewVideoActivity.java
index a5db40bee..00ad23486 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/ViewVideoActivity.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/web/ui/activities/ViewVideoActivity.java
@@ -1,14 +1,14 @@
-package org.researchstack.backbone.ui;
+package org.researchstack.foundation.components.web.ui.activities;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
+import androidx.appcompat.app.AppCompatActivity;
import android.widget.MediaController;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.ui.views.AssetVideoView;
+import org.researchstack.foundation.R;
+import org.researchstack.foundation.components.web.ui.views.AssetVideoView;
import java.io.IOException;
@@ -27,7 +27,7 @@ public static Intent newIntent(Context context, String relativeVideoPath) {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- super.setContentView(R.layout.rsb_activity_video_viewer);
+ super.setContentView(R.layout.rsf_activity_video_viewer);
videoView = (AssetVideoView) findViewById(R.id.videoView);
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/ViewWebDocumentActivity.java b/foundation/src/main/java/org/researchstack/foundation/components/web/ui/activities/ViewWebDocumentActivity.java
similarity index 89%
rename from backbone/src/main/java/org/researchstack/backbone/ui/ViewWebDocumentActivity.java
rename to foundation/src/main/java/org/researchstack/foundation/components/web/ui/activities/ViewWebDocumentActivity.java
index 8c9bbaffe..0236a2884 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/ViewWebDocumentActivity.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/web/ui/activities/ViewWebDocumentActivity.java
@@ -1,16 +1,16 @@
-package org.researchstack.backbone.ui;
+package org.researchstack.foundation.components.web.ui.activities;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
import android.view.MenuItem;
-import org.researchstack.backbone.R;
-import org.researchstack.backbone.ui.views.LocalWebView;
-import org.researchstack.backbone.utils.ThemeUtils;
+import org.researchstack.foundation.R;
+import org.researchstack.foundation.components.utils.ThemeUtils;
+import org.researchstack.foundation.components.web.ui.views.LocalWebView;
/**
* The ViewWebDocumentActivity is used for viewing both local and network HTML docs. This activity
@@ -62,7 +62,7 @@ protected void onCreate(Bundle savedInstanceState) {
setTheme(getIntent().getIntExtra(KEY_THEME, 0));
}
super.onCreate(savedInstanceState);
- super.setContentView(R.layout.rsb_activity_web_document);
+ super.setContentView(R.layout.rsf_activity_web_document);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/views/AssetVideoView.java b/foundation/src/main/java/org/researchstack/foundation/components/web/ui/views/AssetVideoView.java
similarity index 98%
rename from backbone/src/main/java/org/researchstack/backbone/ui/views/AssetVideoView.java
rename to foundation/src/main/java/org/researchstack/foundation/components/web/ui/views/AssetVideoView.java
index 65c5777a7..d718d388d 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/views/AssetVideoView.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/web/ui/views/AssetVideoView.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.researchstack.backbone.ui.views;
+package org.researchstack.foundation.components.web.ui.views;
import android.annotation.TargetApi;
import android.app.AlertDialog;
@@ -33,7 +33,7 @@
import android.widget.MediaController;
import android.widget.VideoView;
-import org.researchstack.backbone.R;
+import org.researchstack.foundation.R;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -192,13 +192,13 @@ public boolean onError(MediaPlayer mp, int framework_err, int impl_err) {
int messageId;
if (framework_err == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {
- messageId = R.string.rsb_error_assetvideoview_invalid_progressive_playback;
+ messageId = R.string.rsf_error_assetvideoview_invalid_progressive_playback;
} else {
- messageId = R.string.rsb_error_assetvideoview_unknown;
+ messageId = R.string.rsf_error_assetvideoview_unknown;
}
new AlertDialog.Builder(getContext()).setMessage(messageId)
- .setPositiveButton(R.string.rsb_error_assetvideoview_button,
+ .setPositiveButton(R.string.rsf_error_assetvideoview_button,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
/* If we get here, there is no onError listener, so
diff --git a/backbone/src/main/java/org/researchstack/backbone/ui/views/LocalWebView.java b/foundation/src/main/java/org/researchstack/foundation/components/web/ui/views/LocalWebView.java
similarity index 89%
rename from backbone/src/main/java/org/researchstack/backbone/ui/views/LocalWebView.java
rename to foundation/src/main/java/org/researchstack/foundation/components/web/ui/views/LocalWebView.java
index 80574090d..a9e7f6018 100644
--- a/backbone/src/main/java/org/researchstack/backbone/ui/views/LocalWebView.java
+++ b/foundation/src/main/java/org/researchstack/foundation/components/web/ui/views/LocalWebView.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.ui.views;
+package org.researchstack.foundation.components.web.ui.views;
import android.content.Context;
import android.content.Intent;
@@ -9,10 +9,10 @@
import android.webkit.WebView;
import android.webkit.WebViewClient;
-import org.researchstack.backbone.ResourcePathManager;
-import org.researchstack.backbone.ui.ViewVideoActivity;
-import org.researchstack.backbone.ui.ViewWebDocumentActivity;
-import org.researchstack.backbone.utils.LogExt;
+import org.researchstack.foundation.components.singletons.ResourcePathManager;
+import org.researchstack.foundation.components.utils.LogExt;
+import org.researchstack.foundation.components.web.ui.activities.ViewVideoActivity;
+import org.researchstack.foundation.components.web.ui.activities.ViewWebDocumentActivity;
import java.io.File;
diff --git a/foundation/src/main/java/org/researchstack/foundation/core/interfaces/IResult.kt b/foundation/src/main/java/org/researchstack/foundation/core/interfaces/IResult.kt
new file mode 100644
index 000000000..1d27e84b1
--- /dev/null
+++ b/foundation/src/main/java/org/researchstack/foundation/core/interfaces/IResult.kt
@@ -0,0 +1,5 @@
+package org.researchstack.foundation.core.interfaces
+
+interface IResult {
+ val identifier: String
+}
\ No newline at end of file
diff --git a/foundation/src/main/java/org/researchstack/foundation/core/interfaces/IStep.kt b/foundation/src/main/java/org/researchstack/foundation/core/interfaces/IStep.kt
new file mode 100644
index 000000000..73b80619a
--- /dev/null
+++ b/foundation/src/main/java/org/researchstack/foundation/core/interfaces/IStep.kt
@@ -0,0 +1,5 @@
+package org.researchstack.foundation.core.interfaces
+
+interface IStep {
+ val identifier: String
+}
\ No newline at end of file
diff --git a/foundation/src/main/java/org/researchstack/foundation/core/interfaces/ITask.kt b/foundation/src/main/java/org/researchstack/foundation/core/interfaces/ITask.kt
new file mode 100644
index 000000000..a99d6498a
--- /dev/null
+++ b/foundation/src/main/java/org/researchstack/foundation/core/interfaces/ITask.kt
@@ -0,0 +1,5 @@
+package org.researchstack.foundation.core.interfaces
+
+interface ITask {
+ val identifier: String
+}
\ No newline at end of file
diff --git a/backbone/src/main/java/org/researchstack/backbone/result/Result.java b/foundation/src/main/java/org/researchstack/foundation/core/models/result/Result.java
similarity index 84%
rename from backbone/src/main/java/org/researchstack/backbone/result/Result.java
rename to foundation/src/main/java/org/researchstack/foundation/core/models/result/Result.java
index b64ff5571..97e8e9274 100644
--- a/backbone/src/main/java/org/researchstack/backbone/result/Result.java
+++ b/foundation/src/main/java/org/researchstack/foundation/core/models/result/Result.java
@@ -1,4 +1,6 @@
-package org.researchstack.backbone.result;
+package org.researchstack.foundation.core.models.result;
+
+import org.researchstack.foundation.core.interfaces.IResult;
import java.io.Serializable;
import java.util.Date;
@@ -6,8 +8,8 @@
/**
* The Result class defines the attributes of a result from one step or a group of steps. When you
* use the ResearchStack framework APIs, you typically get a result from the Result property of
- * either {@link org.researchstack.backbone.ui.ViewTaskActivity} or {@link
- * org.researchstack.backbone.ui.step.layout.StepLayout}. Certain types of results can contain other
+ * either {@link org.researchstack.foundation.ui.ViewTaskActivity} or {@link
+ * org.researchstack.foundation.ui.step.layout.StepLayout}. Certain types of results can contain other
* results, which together express a hierarchy; examples of these types of results are {@link
* StepResult} and {@link TaskResult}.
*
@@ -21,7 +23,7 @@
* hold the type of result data the step can generate, unless it makes sense to use an existing
* subclass.
*/
-public class Result implements Serializable {
+public class Result implements Serializable, IResult {
private String identifier;
private Date startDate;
@@ -34,8 +36,8 @@ public class Result implements Serializable {
/**
* Returns an initialized result using the specified identifier.
*
- * Typically, objects such as {@link org.researchstack.backbone.ui.ViewTaskActivity} and {@link
- * org.researchstack.backbone.ui.step.layout.StepLayout} instantiate result (and Result
+ * Typically, objects such as {@link org.researchstack.foundation.ui.ViewTaskActivity} and {@link
+ * org.researchstack.foundation.ui.step.layout.StepLayout} instantiate result (and Result
* subclass) objects; you seldom need to instantiate a result object in your code.
*
* @param identifier The unique identifier of the result.
diff --git a/backbone/src/main/java/org/researchstack/backbone/result/StepResult.java b/foundation/src/main/java/org/researchstack/foundation/core/models/result/StepResult.java
similarity index 82%
rename from backbone/src/main/java/org/researchstack/backbone/result/StepResult.java
rename to foundation/src/main/java/org/researchstack/foundation/core/models/result/StepResult.java
index 603beb1db..a2dad1984 100644
--- a/backbone/src/main/java/org/researchstack/backbone/result/StepResult.java
+++ b/foundation/src/main/java/org/researchstack/foundation/core/models/result/StepResult.java
@@ -1,15 +1,17 @@
-package org.researchstack.backbone.result;
+package org.researchstack.foundation.core.models.result;
-import org.researchstack.backbone.answerformat.AnswerFormat;
-import org.researchstack.backbone.step.QuestionStep;
-import org.researchstack.backbone.step.Step;
+import androidx.annotation.Nullable;
+
+import org.researchstack.foundation.components.survey.answerformat.AnswerFormat;
+import org.researchstack.foundation.components.survey.step.QuestionStep;
+import org.researchstack.foundation.core.models.step.Step;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
- * The StepResult class represents a result produced by a {@link org.researchstack.backbone.ui.step.layout.StepLayout}
+ * The StepResult class represents a result produced by a {@link org.researchstack.foundation.ui.step.layout.StepLayout}
* to hold all child results of type T produced by the step.
*
* A step result is typically generated by the framework as the task proceeds. When the task
@@ -27,7 +29,7 @@ public class StepResult extends Result {
private Map results;
- private AnswerFormat answerFormat;
+ private Step step;
/**
* Creates a StepResult from a {@link Step}.
@@ -40,10 +42,8 @@ public class StepResult extends Result {
public StepResult(Step step) {
super(step.getIdentifier());
this.results = new HashMap<>();
+ this.step = step;
- if (step instanceof QuestionStep) {
- answerFormat = ((QuestionStep) step).getAnswerFormat();
- }
setStartDate(new Date());
// this will be updated when the result is set
setEndDate(new Date());
@@ -105,7 +105,21 @@ public void setResultForIdentifier(String identifier, T result) {
*
* @return the answer format associated with the step
*/
+
+ @Deprecated
+ @Nullable
public AnswerFormat getAnswerFormat() {
- return answerFormat;
+ if (step instanceof QuestionStep) {
+ AnswerFormat answerFormat = ((QuestionStep) step).getAnswerFormat();
+ return answerFormat;
+ }
+ else {
+ return null;
+ }
+ }
+
+ public Step getStep() {
+ return this.step;
}
}
+
diff --git a/backbone/src/main/java/org/researchstack/backbone/result/TaskResult.java b/foundation/src/main/java/org/researchstack/foundation/core/models/result/TaskResult.java
similarity index 88%
rename from backbone/src/main/java/org/researchstack/backbone/result/TaskResult.java
rename to foundation/src/main/java/org/researchstack/foundation/core/models/result/TaskResult.java
index f7abc5249..4b33f7cac 100644
--- a/backbone/src/main/java/org/researchstack/backbone/result/TaskResult.java
+++ b/foundation/src/main/java/org/researchstack/foundation/core/models/result/TaskResult.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.result;
+package org.researchstack.foundation.core.models.result;
import android.net.Uri;
@@ -8,8 +8,8 @@
/**
* An TaskResult object is a result that contains all the step results generated from one run of a
- * task or ordered task (that is, {@link org.researchstack.backbone.task.Task} or {@link
- * org.researchstack.backbone.task.OrderedTask}).
+ * task or ordered task (that is, {@link org.researchstack.foundation.task.Task} or {@link
+ * org.researchstack.foundation.task.OrderedTask}).
*
* A task result is typically generated by the framework as the task proceeds. When the task
* completes, it may be appropriate to serialize it for transmission to a server, or to immediately
@@ -20,6 +20,7 @@
public class TaskResult extends Result {
private Map results;
+ //TODO: JDK - 4/13/19 add support for this
// unimplemented but exists in RK, implement or delete if not needed
private UUID uuidTask;
diff --git a/backbone/src/main/java/org/researchstack/backbone/step/Step.java b/foundation/src/main/java/org/researchstack/foundation/core/models/step/Step.java
similarity index 78%
rename from backbone/src/main/java/org/researchstack/backbone/step/Step.java
rename to foundation/src/main/java/org/researchstack/foundation/core/models/step/Step.java
index af059ab52..899aa08d6 100644
--- a/backbone/src/main/java/org/researchstack/backbone/step/Step.java
+++ b/foundation/src/main/java/org/researchstack/foundation/core/models/step/Step.java
@@ -1,31 +1,34 @@
-package org.researchstack.backbone.step;
+package org.researchstack.foundation.core.models.step;
-import org.researchstack.backbone.task.Task;
+import org.researchstack.foundation.core.interfaces.IStep;
+import org.researchstack.foundation.core.models.task.Task;
import java.io.Serializable;
/**
* Step is the base class for the steps that can compose a task for presentation in an {@link
- * org.researchstack.backbone.ui.ViewTaskActivity} object. Each Step object represents one logical
+ * org.researchstack.foundation.ui.ViewTaskActivity} object. Each Step object represents one logical
* piece of data entry or activity in a larger task.
*
* A step can be a question, an active test, or a simple instruction. An Step subclass is usually
- * paired with an {@link org.researchstack.backbone.ui.step.layout.StepLayout} subclass that
+ * paired with an {@link org.researchstack.foundation.ui.step.layout.StepLayout} subclass that
* displays the step.
*
* To use a step, instantiate an Step object and populate its properties. Add the step to a task,
- * such as an {@link org.researchstack.backbone.task.OrderedTask} object, and then present the task
+ * such as an {@link org.researchstack.foundation.task.OrderedTask} object, and then present the task
* using a ViewTaskActivity.
*
* To implement a new type of step, subclass Step and add your additional properties. Separately,
* subclass StepLayout and implement your user interface.
*/
-public class Step implements Serializable {
+public class Step implements Serializable, IStep {
private String identifier;
private Class stepLayoutClass;
+ @Deprecated()
private int stepTitle;
+ private String stepTitleString;
private boolean optional = true;
@@ -66,7 +69,7 @@ public Step(String identifier, String title) {
* A short string that uniquely identifies the step within the task.
*
* The identifier is reproduced in the results of a step. In fact, the only way to link a result
- * (a {@link org.researchstack.backbone.result.StepResult} object) to the step that generated it
+ * (a {@link org.researchstack.foundation.result.StepResult} object) to the step that generated it
* is to look at the value of identifier. To accurately identify step results, you
* need to ensure that step identifiers are unique within each task.
*
@@ -152,6 +155,7 @@ public void setText(String text) {
*
* @return the id for the title to display in the action bar
*/
+ @Deprecated
public int getStepTitle() {
return stepTitle;
}
@@ -161,12 +165,31 @@ public int getStepTitle() {
*
* @param stepTitle the Android resource id for the title
*/
+ @Deprecated
public void setStepTitle(int stepTitle) {
this.stepTitle = stepTitle;
}
/**
- * Returns the class that the {@link org.researchstack.backbone.ui.ViewTaskActivity} should
+ * Gets the string the title to display in the action bar (optional).
+ *
+ * @return the string for the title to display in the action bar
+ */
+ public String getStepTitleString() {
+ return stepTitleString;
+ }
+
+ /**
+ * Gets the string for the title to display in the action bar (optional).
+ *
+ * @param stepTitle the string for the title
+ */
+ public void setStepTitle(String stepTitle) {
+ this.stepTitleString = stepTitle;
+ }
+
+ /**
+ * Returns the class that the {@link org.researchstack.foundation.ui.ViewTaskActivity} should
* instantiate to display this step.
*
* This method is used within the framework so that steps can define their step view controller
@@ -175,7 +198,7 @@ public void setStepTitle(int stepTitle) {
* Outside the framework, developers should instantiate the required view controller in their
* ViewTaskActivity delegate to override the ViewTaskActivity's default.
*
- * @return the class of the {@link org.researchstack.backbone.ui.step.layout.StepLayout} for
+ * @return the class of the {@link org.researchstack.foundation.ui.step.layout.StepLayout} for
* this step
*/
public Class getStepLayoutClass() {
@@ -185,7 +208,7 @@ public Class getStepLayoutClass() {
/**
* Sets the class that should be used to display this step
*
- * @param stepLayoutClass the {@link org.researchstack.backbone.ui.step.layout.StepLayout} class
+ * @param stepLayoutClass the {@link org.researchstack.foundation.ui.step.layout.StepLayout} class
* to be used to display this step
*/
public void setStepLayoutClass(Class stepLayoutClass) {
diff --git a/backbone/src/main/java/org/researchstack/backbone/task/Task.java b/foundation/src/main/java/org/researchstack/foundation/core/models/task/Task.java
similarity index 77%
rename from backbone/src/main/java/org/researchstack/backbone/task/Task.java
rename to foundation/src/main/java/org/researchstack/foundation/core/models/task/Task.java
index ea21b3e5a..4c8d57912 100644
--- a/backbone/src/main/java/org/researchstack/backbone/task/Task.java
+++ b/foundation/src/main/java/org/researchstack/foundation/core/models/task/Task.java
@@ -1,10 +1,12 @@
-package org.researchstack.backbone.task;
+package org.researchstack.foundation.core.models.task;
import android.content.Context;
-import org.researchstack.backbone.result.TaskResult;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.ui.ViewTaskActivity;
+import org.jetbrains.annotations.NotNull;
+import org.researchstack.foundation.components.presentation.interfaces.ITaskNavigator;
+import org.researchstack.foundation.core.interfaces.ITask;
+import org.researchstack.foundation.core.models.result.TaskResult;
+import org.researchstack.foundation.core.models.step.Step;
import java.io.Serializable;
@@ -13,19 +15,24 @@
*
* To present the ResearchStack framework UI in your app, instantiate an object that extends the
* Task class (such as {@link OrderedTask}) and provide it to a {@link
- * org.researchstack.backbone.ui.ViewTaskActivity}.
+ * org.researchstack.foundation.ui.ViewTaskActivity}.
*
* Implement this protocol to enable dynamic selection of the steps for a given task. By default,
* OrderedTask implements this protocol for simple sequential tasks.
*
* Each {@link Step} in a task roughly corresponds to one screen, and represents the primary unit of
- * work in any task. For example, a {@link org.researchstack.backbone.step.QuestionStep} object
+ * work in any task. For example, a {@link org.researchstack.foundation.step.QuestionStep} object
* corresponds to a single question presented on screen, together with controls the participant uses
- * to answer the question. Another example is {@link org.researchstack.backbone.step.FormStep},
+ * to answer the question. Another example is {@link org.researchstack.foundation.step.FormStep},
* which corresponds to a single screen that displays multiple questions or items for which
* participants provide information, such as first name, last name, and birth date.
*/
-public abstract class Task implements Serializable {
+public abstract class Task implements Serializable, ITask, ITaskNavigator {
+
+ public interface TaskLifecycleObserver {
+
+ }
+
private String identifier;
/**
@@ -69,16 +76,22 @@ public String getIdentifier() {
* @param step the current step
* @return the title to display
*/
+ @Deprecated
public String getTitleForStep(Context context, Step step) {
return step.getStepTitle() != 0 ? context.getString(step.getStepTitle()) : "";
}
+ public String getTitleForStep(Step step) {
+ String titleString = step.getStepTitleString();
+ return titleString != null ? titleString : "";
+ }
+
/**
* Returns the step after the specified step, if there is one.
*
* This method lets you use a result to determine the next step.
*
- * The {@link org.researchstack.backbone.ui.ViewTaskActivity} calls this method to determine
+ * The {@link org.researchstack.foundation.ui.ViewTaskActivity} calls this method to determine
* the step to display after the specified step. The ViewTaskActivity can also call this
* method every time the result updates, to determine if the new result changes which steps are
* available.
@@ -95,7 +108,7 @@ public String getTitleForStep(Context context, Step step) {
/**
* Returns the step that precedes the specified step, if there is one.
*
- * The {@link org.researchstack.backbone.ui.ViewTaskActivity} calls this method to determine the
+ * The {@link org.researchstack.foundation.ui.ViewTaskActivity} calls this method to determine the
* step to display before the specified step. The ViewTaskActivity
* can also call this method every time the result changes, to determine if the new result
* changes which steps are available.
@@ -121,7 +134,7 @@ public String getTitleForStep(Context context, Step step) {
/**
* Returns the progress of the current step.
*
- * During a task, the {@link org.researchstack.backbone.ui.ViewTaskActivity} can display the
+ * During a task, the {@link org.researchstack.foundation.ui.ViewTaskActivity} can display the
* progress (that is, the current step number out of the total number of steps) in the
* navigation bar. Implement this method to control what is displayed; if you don't implement
* this method, the progress label does not appear.
@@ -144,23 +157,30 @@ public String getTitleForStep(Context context, Step step) {
* implementation makes sure that all its step identifiers are unique, throwing an exception
* otherwise.
*
- * This method is usually called by {@link org.researchstack.backbone.ui.ViewTaskActivity} when
+ * This method is usually called by {@link org.researchstack.foundation.ui.ViewTaskActivity} when
* its task is set.
*
* @throws InvalidTaskException
*/
public abstract void validateParameters();
- /**
- * Function that can be overridden in order to access the low level changes in the view.
- * The function is called at Activity lifecycle events (creation, pause, resume, stop and whenever
- * the content of the activity is changed, according to the step.
- *
- * @param type lifecycle event
- * @param activity current activity
- * @param currentStep the current step being shown
- */
- public void onViewChange(ViewChangeType type, ViewTaskActivity activity, Step currentStep) {
+ //JDK - 4/13/19 - changed this interface from
+ //onViewChange(ViewChangeType type, ViewTaskActivity activity, Step currentStep)
+ //to
+ //onViewChange(ViewChangeType type, TaskLifecycleObserver observer, Step currentStep)
+ //this was done to remove the circular dependency on ViewTaskActivity
+ //Note that this method is invoked by ViewTaskActivity, which was modified to implement TaskLifecycleObserver
+ //This is not (yet) invoked by TaskPresentationFragment, but this potentially change at some point
+// /**
+// * Function that can be overridden in order to access the low level changes in the view.
+// * The function is called at Activity lifecycle events (creation, pause, resume, stop and whenever
+// * the content of the activity is changed, according to the step.
+// *
+// * @param type lifecycle event
+// * @param observer current activity
+// * @param currentStep the current step being shown
+// */
+ public void onViewChange(ViewChangeType type, TaskLifecycleObserver observer, Step currentStep) {
}
@@ -176,7 +196,7 @@ public static enum ViewChangeType {
* A structure that represents how far a task has progressed.
*
* Objects that extend Task return the task progress structure to indicate to the {@link
- * org.researchstack.backbone.ui.ViewTaskActivity} how far the task has progressed.
+ * org.researchstack.foundation.ui.ViewTaskActivity} how far the task has progressed.
*
* Note that the values in an {@link TaskProgress} structure are used only for display; you
* don't use the values to access the steps in a task.
diff --git a/backbone/src/main/res/anim/rsb_interpolator_step_layout.xml b/foundation/src/main/res/anim/rsf_interpolator_step_layout.xml
similarity index 100%
rename from backbone/src/main/res/anim/rsb_interpolator_step_layout.xml
rename to foundation/src/main/res/anim/rsf_interpolator_step_layout.xml
diff --git a/backbone/src/main/res/anim/rsb_slide_in_left.xml b/foundation/src/main/res/anim/rsf_slide_in_left.xml
similarity index 87%
rename from backbone/src/main/res/anim/rsb_slide_in_left.xml
rename to foundation/src/main/res/anim/rsf_slide_in_left.xml
index a3239933b..c70afe17a 100644
--- a/backbone/src/main/res/anim/rsb_slide_in_left.xml
+++ b/foundation/src/main/res/anim/rsf_slide_in_left.xml
@@ -18,7 +18,7 @@
-->
diff --git a/backbone/src/main/res/anim/rsb_slide_in_right.xml b/foundation/src/main/res/anim/rsf_slide_in_right.xml
similarity index 87%
rename from backbone/src/main/res/anim/rsb_slide_in_right.xml
rename to foundation/src/main/res/anim/rsf_slide_in_right.xml
index d42bf20c3..725324da8 100644
--- a/backbone/src/main/res/anim/rsb_slide_in_right.xml
+++ b/foundation/src/main/res/anim/rsf_slide_in_right.xml
@@ -18,7 +18,7 @@
-->
diff --git a/backbone/src/main/res/anim/rsb_slide_in_up.xml b/foundation/src/main/res/anim/rsf_slide_in_up.xml
similarity index 89%
rename from backbone/src/main/res/anim/rsb_slide_in_up.xml
rename to foundation/src/main/res/anim/rsf_slide_in_up.xml
index 309e7c884..e2a1435d6 100644
--- a/backbone/src/main/res/anim/rsb_slide_in_up.xml
+++ b/foundation/src/main/res/anim/rsf_slide_in_up.xml
@@ -21,11 +21,11 @@
android:interpolator="@android:interpolator/decelerate_cubic">
diff --git a/backbone/src/main/res/anim/rsb_slide_out_down.xml b/foundation/src/main/res/anim/rsf_slide_out_down.xml
similarity index 89%
rename from backbone/src/main/res/anim/rsb_slide_out_down.xml
rename to foundation/src/main/res/anim/rsf_slide_out_down.xml
index 7b5382c6e..16d4feb50 100644
--- a/backbone/src/main/res/anim/rsb_slide_out_down.xml
+++ b/foundation/src/main/res/anim/rsf_slide_out_down.xml
@@ -20,11 +20,11 @@
diff --git a/backbone/src/main/res/anim/rsb_slide_out_left.xml b/foundation/src/main/res/anim/rsf_slide_out_left.xml
similarity index 87%
rename from backbone/src/main/res/anim/rsb_slide_out_left.xml
rename to foundation/src/main/res/anim/rsf_slide_out_left.xml
index 961697cfe..11b5c53c3 100644
--- a/backbone/src/main/res/anim/rsb_slide_out_left.xml
+++ b/foundation/src/main/res/anim/rsf_slide_out_left.xml
@@ -18,7 +18,7 @@
-->
diff --git a/backbone/src/main/res/anim/rsb_slide_out_right.xml b/foundation/src/main/res/anim/rsf_slide_out_right.xml
similarity index 87%
rename from backbone/src/main/res/anim/rsb_slide_out_right.xml
rename to foundation/src/main/res/anim/rsf_slide_out_right.xml
index 7692f5a45..7c545a366 100644
--- a/backbone/src/main/res/anim/rsb_slide_out_right.xml
+++ b/foundation/src/main/res/anim/rsf_slide_out_right.xml
@@ -18,7 +18,7 @@
-->
diff --git a/backbone/src/main/res/drawable-hdpi/rsb_ic_check.png b/foundation/src/main/res/drawable-hdpi/rsf_ic_check.png
similarity index 100%
rename from backbone/src/main/res/drawable-hdpi/rsb_ic_check.png
rename to foundation/src/main/res/drawable-hdpi/rsf_ic_check.png
diff --git a/backbone/src/main/res/drawable-hdpi/rsb_ic_fullscreen.png b/foundation/src/main/res/drawable-hdpi/rsf_ic_fullscreen.png
similarity index 100%
rename from backbone/src/main/res/drawable-hdpi/rsb_ic_fullscreen.png
rename to foundation/src/main/res/drawable-hdpi/rsf_ic_fullscreen.png
diff --git a/backbone/src/main/res/drawable-hdpi/rsb_ic_x.png b/foundation/src/main/res/drawable-hdpi/rsf_ic_x.png
similarity index 100%
rename from backbone/src/main/res/drawable-hdpi/rsb_ic_x.png
rename to foundation/src/main/res/drawable-hdpi/rsf_ic_x.png
diff --git a/backbone/src/main/res/drawable-hdpi/rsb_illo_dashboard_empty.png b/foundation/src/main/res/drawable-hdpi/rsf_illo_dashboard_empty.png
similarity index 100%
rename from backbone/src/main/res/drawable-hdpi/rsb_illo_dashboard_empty.png
rename to foundation/src/main/res/drawable-hdpi/rsf_illo_dashboard_empty.png
diff --git a/backbone/src/main/res/drawable-mdpi/rsb_ic_check.png b/foundation/src/main/res/drawable-mdpi/rsf_ic_check.png
similarity index 100%
rename from backbone/src/main/res/drawable-mdpi/rsb_ic_check.png
rename to foundation/src/main/res/drawable-mdpi/rsf_ic_check.png
diff --git a/backbone/src/main/res/drawable-mdpi/rsb_ic_fullscreen.png b/foundation/src/main/res/drawable-mdpi/rsf_ic_fullscreen.png
similarity index 100%
rename from backbone/src/main/res/drawable-mdpi/rsb_ic_fullscreen.png
rename to foundation/src/main/res/drawable-mdpi/rsf_ic_fullscreen.png
diff --git a/backbone/src/main/res/drawable-mdpi/rsb_ic_x.png b/foundation/src/main/res/drawable-mdpi/rsf_ic_x.png
similarity index 100%
rename from backbone/src/main/res/drawable-mdpi/rsb_ic_x.png
rename to foundation/src/main/res/drawable-mdpi/rsf_ic_x.png
diff --git a/backbone/src/main/res/drawable-mdpi/rsb_illo_dashboard_empty.png b/foundation/src/main/res/drawable-mdpi/rsf_illo_dashboard_empty.png
similarity index 100%
rename from backbone/src/main/res/drawable-mdpi/rsb_illo_dashboard_empty.png
rename to foundation/src/main/res/drawable-mdpi/rsf_illo_dashboard_empty.png
diff --git a/backbone/src/main/res/drawable-xhdpi/rsb_ic_check.png b/foundation/src/main/res/drawable-xhdpi/rsf_ic_check.png
similarity index 100%
rename from backbone/src/main/res/drawable-xhdpi/rsb_ic_check.png
rename to foundation/src/main/res/drawable-xhdpi/rsf_ic_check.png
diff --git a/backbone/src/main/res/drawable-xhdpi/rsb_ic_fullscreen.png b/foundation/src/main/res/drawable-xhdpi/rsf_ic_fullscreen.png
similarity index 100%
rename from backbone/src/main/res/drawable-xhdpi/rsb_ic_fullscreen.png
rename to foundation/src/main/res/drawable-xhdpi/rsf_ic_fullscreen.png
diff --git a/backbone/src/main/res/drawable-xhdpi/rsb_ic_x.png b/foundation/src/main/res/drawable-xhdpi/rsf_ic_x.png
similarity index 100%
rename from backbone/src/main/res/drawable-xhdpi/rsb_ic_x.png
rename to foundation/src/main/res/drawable-xhdpi/rsf_ic_x.png
diff --git a/backbone/src/main/res/drawable-xhdpi/rsb_illo_dashboard_empty.png b/foundation/src/main/res/drawable-xhdpi/rsf_illo_dashboard_empty.png
similarity index 100%
rename from backbone/src/main/res/drawable-xhdpi/rsb_illo_dashboard_empty.png
rename to foundation/src/main/res/drawable-xhdpi/rsf_illo_dashboard_empty.png
diff --git a/backbone/src/main/res/drawable-xxhdpi/rsb_ic_check.png b/foundation/src/main/res/drawable-xxhdpi/rsf_ic_check.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxhdpi/rsb_ic_check.png
rename to foundation/src/main/res/drawable-xxhdpi/rsf_ic_check.png
diff --git a/backbone/src/main/res/drawable-xxhdpi/rsb_ic_fullscreen.png b/foundation/src/main/res/drawable-xxhdpi/rsf_ic_fullscreen.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxhdpi/rsb_ic_fullscreen.png
rename to foundation/src/main/res/drawable-xxhdpi/rsf_ic_fullscreen.png
diff --git a/backbone/src/main/res/drawable-xxhdpi/rsb_ic_x.png b/foundation/src/main/res/drawable-xxhdpi/rsf_ic_x.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxhdpi/rsb_ic_x.png
rename to foundation/src/main/res/drawable-xxhdpi/rsf_ic_x.png
diff --git a/backbone/src/main/res/drawable-xxhdpi/rsb_illo_dashboard_empty.png b/foundation/src/main/res/drawable-xxhdpi/rsf_illo_dashboard_empty.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxhdpi/rsb_illo_dashboard_empty.png
rename to foundation/src/main/res/drawable-xxhdpi/rsf_illo_dashboard_empty.png
diff --git a/backbone/src/main/res/drawable-xxxhdpi/rsb_ic_check.png b/foundation/src/main/res/drawable-xxxhdpi/rsf_ic_check.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxxhdpi/rsb_ic_check.png
rename to foundation/src/main/res/drawable-xxxhdpi/rsf_ic_check.png
diff --git a/backbone/src/main/res/drawable-xxxhdpi/rsb_ic_fullscreen.png b/foundation/src/main/res/drawable-xxxhdpi/rsf_ic_fullscreen.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxxhdpi/rsb_ic_fullscreen.png
rename to foundation/src/main/res/drawable-xxxhdpi/rsf_ic_fullscreen.png
diff --git a/backbone/src/main/res/drawable-xxxhdpi/rsb_ic_x.png b/foundation/src/main/res/drawable-xxxhdpi/rsf_ic_x.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxxhdpi/rsb_ic_x.png
rename to foundation/src/main/res/drawable-xxxhdpi/rsf_ic_x.png
diff --git a/backbone/src/main/res/drawable-xxxhdpi/rsb_illo_dashboard_empty.png b/foundation/src/main/res/drawable-xxxhdpi/rsf_illo_dashboard_empty.png
similarity index 100%
rename from backbone/src/main/res/drawable-xxxhdpi/rsb_illo_dashboard_empty.png
rename to foundation/src/main/res/drawable-xxxhdpi/rsf_illo_dashboard_empty.png
diff --git a/backbone/src/main/res/drawable/rsb_debug_gray.xml b/foundation/src/main/res/drawable/rsf_debug_gray.xml
similarity index 100%
rename from backbone/src/main/res/drawable/rsb_debug_gray.xml
rename to foundation/src/main/res/drawable/rsf_debug_gray.xml
diff --git a/backbone/src/main/res/drawable/rsb_divider_empty_16dp.xml b/foundation/src/main/res/drawable/rsf_divider_empty_16dp.xml
similarity index 100%
rename from backbone/src/main/res/drawable/rsb_divider_empty_16dp.xml
rename to foundation/src/main/res/drawable/rsf_divider_empty_16dp.xml
diff --git a/backbone/src/main/res/drawable/rsb_divider_empty_8dp.xml b/foundation/src/main/res/drawable/rsf_divider_empty_8dp.xml
similarity index 100%
rename from backbone/src/main/res/drawable/rsb_divider_empty_8dp.xml
rename to foundation/src/main/res/drawable/rsf_divider_empty_8dp.xml
diff --git a/backbone/src/main/res/drawable/rsb_ic_circle_8dp.xml b/foundation/src/main/res/drawable/rsf_ic_circle_8dp.xml
similarity index 81%
rename from backbone/src/main/res/drawable/rsb_ic_circle_8dp.xml
rename to foundation/src/main/res/drawable/rsf_ic_circle_8dp.xml
index a8500cdb3..ed7548e86 100644
--- a/backbone/src/main/res/drawable/rsb_ic_circle_8dp.xml
+++ b/foundation/src/main/res/drawable/rsf_ic_circle_8dp.xml
@@ -6,6 +6,6 @@
android:width="8dp"
android:height="8dp" />
-
+
\ No newline at end of file
diff --git a/backbone/src/main/res/layout/rsb_activity_video_viewer.xml b/foundation/src/main/res/layout/rsf_activity_video_viewer.xml
similarity index 83%
rename from backbone/src/main/res/layout/rsb_activity_video_viewer.xml
rename to foundation/src/main/res/layout/rsf_activity_video_viewer.xml
index 84c6707cd..31546d464 100644
--- a/backbone/src/main/res/layout/rsb_activity_video_viewer.xml
+++ b/foundation/src/main/res/layout/rsf_activity_video_viewer.xml
@@ -3,7 +3,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
-
+
-
+
+
+
+
+
\ No newline at end of file
diff --git a/foundation/src/main/res/layout/rsf_fragment_task_presentation.xml b/foundation/src/main/res/layout/rsf_fragment_task_presentation.xml
new file mode 100644
index 000000000..26e62852a
--- /dev/null
+++ b/foundation/src/main/res/layout/rsf_fragment_task_presentation.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/backbone/src/main/res/layout/rsb_item_checkbox.xml b/foundation/src/main/res/layout/rsf_item_checkbox.xml
similarity index 72%
rename from backbone/src/main/res/layout/rsb_item_checkbox.xml
rename to foundation/src/main/res/layout/rsf_item_checkbox.xml
index eab13322f..231aa349f 100644
--- a/backbone/src/main/res/layout/rsb_item_checkbox.xml
+++ b/foundation/src/main/res/layout/rsf_item_checkbox.xml
@@ -1,9 +1,9 @@
-
diff --git a/backbone/src/main/res/layout/rsb_item_date_view.xml b/foundation/src/main/res/layout/rsf_item_date_view.xml
similarity index 80%
rename from backbone/src/main/res/layout/rsb_item_date_view.xml
rename to foundation/src/main/res/layout/rsf_item_date_view.xml
index c223e3748..358737762 100644
--- a/backbone/src/main/res/layout/rsb_item_date_view.xml
+++ b/foundation/src/main/res/layout/rsf_item_date_view.xml
@@ -5,22 +5,22 @@
android:layout_height="wrap_content"
android:orientation="vertical">
-
-
@@ -43,7 +43,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_weight="0.6"
- android:text="@string/rsb_minutes"
+ android:text="@string/rsf_minutes"
android:textAppearance="?android:attr/textAppearanceMedium" />
diff --git a/backbone/src/main/res/layout/rsb_item_edit_text.xml b/foundation/src/main/res/layout/rsf_item_edit_text.xml
similarity index 89%
rename from backbone/src/main/res/layout/rsb_item_edit_text.xml
rename to foundation/src/main/res/layout/rsf_item_edit_text.xml
index b4dee8384..cf2777f32 100644
--- a/backbone/src/main/res/layout/rsb_item_edit_text.xml
+++ b/foundation/src/main/res/layout/rsf_item_edit_text.xml
@@ -6,7 +6,7 @@
android:layout_height="wrap_content"
android:imeOptions="actionNext"
android:inputType="text"
- android:minHeight="@dimen/rsb_item_size_default"
+ android:minHeight="@dimen/rsf_item_size_default"
android:singleLine="true"
android:textColor="?android:attr/textColorPrimary"
android:textSize="14sp"
diff --git a/backbone/src/main/res/layout/rsb_item_edit_text_compact.xml b/foundation/src/main/res/layout/rsf_item_edit_text_compact.xml
similarity index 89%
rename from backbone/src/main/res/layout/rsb_item_edit_text_compact.xml
rename to foundation/src/main/res/layout/rsf_item_edit_text_compact.xml
index 557882298..96ac24d81 100644
--- a/backbone/src/main/res/layout/rsb_item_edit_text_compact.xml
+++ b/foundation/src/main/res/layout/rsf_item_edit_text_compact.xml
@@ -11,7 +11,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
- android:minHeight="@dimen/rsb_item_size_default"
+ android:minHeight="@dimen/rsf_item_size_default"
android:textColor="?attr/colorAccent"
android:textSize="16sp"
tools:text="title" />
@@ -22,7 +22,7 @@
android:layout_height="wrap_content"
android:imeOptions="actionNext"
android:inputType="text"
- android:minHeight="@dimen/rsb_item_size_default"
+ android:minHeight="@dimen/rsf_item_size_default"
android:singleLine="true"
android:textColor="?android:attr/textColorPrimary"
android:textSize="14sp"
diff --git a/backbone/src/main/res/layout/rsb_item_radio.xml b/foundation/src/main/res/layout/rsf_item_radio.xml
similarity index 73%
rename from backbone/src/main/res/layout/rsb_item_radio.xml
rename to foundation/src/main/res/layout/rsf_item_radio.xml
index 6631b9b00..9a44b4d79 100644
--- a/backbone/src/main/res/layout/rsb_item_radio.xml
+++ b/foundation/src/main/res/layout/rsf_item_radio.xml
@@ -1,9 +1,9 @@
-
diff --git a/backbone/src/main/res/layout/rsb_item_text_view_title_compact.xml b/foundation/src/main/res/layout/rsf_item_text_view_title_compact.xml
similarity index 100%
rename from backbone/src/main/res/layout/rsb_item_text_view_title_compact.xml
rename to foundation/src/main/res/layout/rsf_item_text_view_title_compact.xml
diff --git a/backbone/src/main/res/layout/rsb_layout_fixed_submit_bar.xml b/foundation/src/main/res/layout/rsf_layout_fixed_submit_bar.xml
similarity index 63%
rename from backbone/src/main/res/layout/rsb_layout_fixed_submit_bar.xml
rename to foundation/src/main/res/layout/rsf_layout_fixed_submit_bar.xml
index 22a398722..588c36538 100644
--- a/backbone/src/main/res/layout/rsb_layout_fixed_submit_bar.xml
+++ b/foundation/src/main/res/layout/rsf_layout_fixed_submit_bar.xml
@@ -1,19 +1,19 @@
-
-
+
-
diff --git a/backbone/src/main/res/layout/rsb_layout_toolbar.xml b/foundation/src/main/res/layout/rsf_layout_toolbar.xml
similarity index 81%
rename from backbone/src/main/res/layout/rsb_layout_toolbar.xml
rename to foundation/src/main/res/layout/rsf_layout_toolbar.xml
index 3493d8f39..68e769205 100644
--- a/backbone/src/main/res/layout/rsb_layout_toolbar.xml
+++ b/foundation/src/main/res/layout/rsf_layout_toolbar.xml
@@ -1,5 +1,5 @@
-
diff --git a/backbone/src/main/res/layout/rsb_step_layout_form_body.xml b/foundation/src/main/res/layout/rsf_step_layout_form_body.xml
similarity index 82%
rename from backbone/src/main/res/layout/rsb_step_layout_form_body.xml
rename to foundation/src/main/res/layout/rsf_step_layout_form_body.xml
index 993d22a51..cb6a1cac0 100644
--- a/backbone/src/main/res/layout/rsb_step_layout_form_body.xml
+++ b/foundation/src/main/res/layout/rsf_step_layout_form_body.xml
@@ -2,6 +2,6 @@
\ No newline at end of file
diff --git a/backbone/src/main/res/layout/rsb_step_layout_instruction.xml b/foundation/src/main/res/layout/rsf_step_layout_instruction.xml
similarity index 81%
rename from backbone/src/main/res/layout/rsb_step_layout_instruction.xml
rename to foundation/src/main/res/layout/rsf_step_layout_instruction.xml
index 0bd6e2e90..c49a000bf 100644
--- a/backbone/src/main/res/layout/rsb_step_layout_instruction.xml
+++ b/foundation/src/main/res/layout/rsf_step_layout_instruction.xml
@@ -6,8 +6,8 @@
android:orientation="vertical">
-
-
-
+ android:src="@drawable/rsf_ic_circle_8dp" />
\ No newline at end of file
diff --git a/backbone/src/main/res/layout/rsb_view_submitbar.xml b/foundation/src/main/res/layout/rsf_view_submitbar.xml
similarity index 90%
rename from backbone/src/main/res/layout/rsb_view_submitbar.xml
rename to foundation/src/main/res/layout/rsf_view_submitbar.xml
index 8e3386312..bba385e8e 100644
--- a/backbone/src/main/res/layout/rsb_view_submitbar.xml
+++ b/foundation/src/main/res/layout/rsf_view_submitbar.xml
@@ -11,14 +11,14 @@
android:layout_height="wrap_content"
android:layout_weight="1" />
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/foundation/src/main/res/values/attrs.xml b/foundation/src/main/res/values/attrs.xml
new file mode 100644
index 000000000..0597c0016
--- /dev/null
+++ b/foundation/src/main/res/values/attrs.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/foundation/src/main/res/values/colors.xml b/foundation/src/main/res/values/colors.xml
new file mode 100644
index 000000000..38faea889
--- /dev/null
+++ b/foundation/src/main/res/values/colors.xml
@@ -0,0 +1,20 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+ #cc3367
+ #000
+ #33000000
+ #66000000
+ #CCFFFFFF
+ #FF757575
+ #33757575
+ #EEEEEE
+ #979797
+ #e5e5e5
+ #ffff5722
+
+ #2196f3
+ #662196f3
+
diff --git a/foundation/src/main/res/values/dimens.xml b/foundation/src/main/res/values/dimens.xml
new file mode 100644
index 000000000..aba39ca3c
--- /dev/null
+++ b/foundation/src/main/res/values/dimens.xml
@@ -0,0 +1,23 @@
+
+
+
+
+ 8dp
+ 12dp
+ 16dp
+ 24dp
+
+
+ 48dp
+ 56dp
+ @dimen/rsf_item_size_small
+ 1dp
+
+
+ 48dp
+ 16dp
+
+
+ 20sp
+
+
\ No newline at end of file
diff --git a/foundation/src/main/res/values/ids.xml b/foundation/src/main/res/values/ids.xml
new file mode 100644
index 000000000..0d2c4cc40
--- /dev/null
+++ b/foundation/src/main/res/values/ids.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/foundation/src/main/res/values/integers.xml b/foundation/src/main/res/values/integers.xml
new file mode 100644
index 000000000..865ea8487
--- /dev/null
+++ b/foundation/src/main/res/values/integers.xml
@@ -0,0 +1,4 @@
+
+
+ 300
+
\ No newline at end of file
diff --git a/foundation/src/main/res/values/strings.xml b/foundation/src/main/res/values/strings.xml
new file mode 100644
index 000000000..77d9ae9a6
--- /dev/null
+++ b/foundation/src/main/res/values/strings.xml
@@ -0,0 +1,76 @@
+
+
+ Lorem Ipsum
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit.
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit sed do
+ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim.
+
+ Lorem ipsum dolor sit amet, consectetur
+ adipiscing elit, sed do
+ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
+ nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute
+ irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
+ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit
+ anim id est laborum.
+
+
+
+ Submit
+ Exit
+ Get Started
+ Done
+ Skip
+ next
+ What to Expect
+ Name
+ Email
+ Disagree
+ Agree
+ OK
+ Cancel
+ Yes
+ No
+ Step %1$d of %2$d
+ Hours
+ Minutes
+
+
+ Failed to load encrypted data, try again!
+ Signature Invalid
+ Invalid answer, try again!
+ Invalid answer, date must be before %1$s
+ Invalid answer, date must be after %1$s
+ Invalid answer, your value must be %1$s or lower
+ Invalid answer, your value must be %1$s or higher
+ Please select a value!
+ Please choose a date.
+ You must be %1$s years or younger
+ You must be at least %1$s years old
+
+
+ Enter a number %1$d-%2$d
+ Enter a number %1$.2f-%2$.2f
+ Enter a number
+ Enter a date
+ Enter a time
+ Enter a date and a time
+ Answer
+
+
+ %1$s of %2$s
+ %1$s%
+
+
+
+ Video problem
+
+ This video isn\'t valid for streaming to this device.
+
+ Can\'t play this video.
+
+ OK
+
+
diff --git a/foundation/src/main/res/values/styles.xml b/foundation/src/main/res/values/styles.xml
new file mode 100644
index 000000000..4b85840c4
--- /dev/null
+++ b/foundation/src/main/res/values/styles.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/foundation/src/main/res/values/themes.xml b/foundation/src/main/res/values/themes.xml
new file mode 100644
index 000000000..69724d63c
--- /dev/null
+++ b/foundation/src/main/res/values/themes.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/foundation/src/test/java/org/researchstack/foundation/ExampleUnitTest.java b/foundation/src/test/java/org/researchstack/foundation/ExampleUnitTest.java
new file mode 100644
index 000000000..a4687af1d
--- /dev/null
+++ b/foundation/src/test/java/org/researchstack/foundation/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package org.researchstack.foundation;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index 7791533f8..9d24db0b8 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -11,4 +11,7 @@
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true
\ No newline at end of file
+# org.gradle.parallel=true
+android.enableJetifier=true
+android.useAndroidX=true
+systemProp.snapshot=true
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 5653266a8..2be106237 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Tue Aug 30 13:10:33 EDT 2016
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
+#Wed Feb 27 13:45:12 PST 2019
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
diff --git a/sample_backbone_app/.gitignore b/sample_backbone_app/.gitignore
new file mode 100644
index 000000000..796b96d1c
--- /dev/null
+++ b/sample_backbone_app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/sample_backbone_app/build.gradle b/sample_backbone_app/build.gradle
new file mode 100644
index 000000000..f87f61fee
--- /dev/null
+++ b/sample_backbone_app/build.gradle
@@ -0,0 +1,40 @@
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+
+android {
+ compileSdkVersion 28
+
+ defaultConfig {
+ applicationId "org.researchstack.backboneapp"
+ minSdkVersion 16
+ targetSdkVersion 28
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.appcompat:appcompat:1.0.2'
+ implementation 'org.researchstack:backbone:1.1.2'
+
+ testImplementation 'junit:junit:4.12'
+
+ androidTestImplementation "androidx.core:core-ktx:1.0.0"
+ androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+ androidTestImplementation "androidx.test.espresso:espresso-contrib:3.1.1"
+
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-beta01'
+ androidTestImplementation 'androidx.test:rules:1.2.0-beta01'
+}
+repositories {
+ mavenCentral()
+}
diff --git a/sample_backbone_app/proguard-rules.pro b/sample_backbone_app/proguard-rules.pro
new file mode 100644
index 000000000..2b8673663
--- /dev/null
+++ b/sample_backbone_app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/bradleymcdermott/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/sample_backbone_app/src/androidTest/java/org/researchstack/backboneapp/MainActivityTest.kt b/sample_backbone_app/src/androidTest/java/org/researchstack/backboneapp/MainActivityTest.kt
new file mode 100644
index 000000000..b44b910e7
--- /dev/null
+++ b/sample_backbone_app/src/androidTest/java/org/researchstack/backboneapp/MainActivityTest.kt
@@ -0,0 +1,292 @@
+package org.researchstack.backboneapp
+
+import android.view.View
+import android.view.ViewGroup
+import android.widget.DatePicker
+import android.widget.LinearLayout
+import androidx.test.espresso.Espresso.onView
+import androidx.test.espresso.action.ViewActions.click
+import androidx.test.espresso.action.ViewActions.closeSoftKeyboard
+import androidx.test.espresso.action.ViewActions.replaceText
+import androidx.test.espresso.action.ViewActions.scrollTo
+import androidx.test.espresso.action.ViewActions.swipeDown
+import androidx.test.espresso.action.ViewActions.swipeRight
+import androidx.test.espresso.assertion.ViewAssertions.matches
+import androidx.test.espresso.contrib.PickerActions.setDate
+import androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom
+import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
+import androidx.test.espresso.matcher.ViewMatchers.withClassName
+import androidx.test.espresso.matcher.ViewMatchers.withId
+import androidx.test.espresso.matcher.ViewMatchers.withSubstring
+import androidx.test.espresso.matcher.ViewMatchers.withText
+import androidx.test.filters.LargeTest
+import androidx.test.rule.ActivityTestRule
+import org.hamcrest.*
+import org.hamcrest.Matchers.*
+import org.hamcrest.core.*
+import org.junit.*
+import org.researchstack.backboneapp.R.id
+
+@LargeTest
+class MainActivityTest {
+
+ @Rule
+ @JvmField
+ var mActivityTestRule = ActivityTestRule(MainActivity::class.java)
+
+ @Test
+ fun mainActivityTest() {
+
+ // reset state, TODO: better way to setup/cleanup
+ onView(withId(R.id.menu_clear)).perform(click())
+
+ // Launch consent task
+ onView(withId(R.id.consent_button)).perform(click())
+
+ testConsentTask()
+
+ // Launch survey task
+ onView(withId(R.id.survey_button)).perform(click())
+
+ testSurvey()
+ }
+
+ private fun testSurvey() {
+ val appCompatTextView5 = onView(
+ allOf(withId(id.bar_submit_postitive), withText("next"),
+ childAtPosition(
+ allOf(withId(id.rsb_submit_bar),
+ childAtPosition(
+ withId(id.rsb_current_step),
+ 1)),
+ 2),
+ isDisplayed()))
+ appCompatTextView5.perform(click())
+
+ val appCompatEditText2 = onView(
+ allOf(withId(id.value),
+ childAtPosition(
+ allOf(withId(id.rsb_survey_step_body),
+ childAtPosition(
+ withId(id.rsb_survey_content_container),
+ 2)),
+ 1),
+ isDisplayed()))
+ appCompatEditText2.perform(replaceText("test"), closeSoftKeyboard())
+
+ val appCompatTextView6 = onView(
+ allOf(withId(id.bar_submit_postitive), withText("next"),
+ childAtPosition(
+ allOf(withId(id.rsb_submit_bar),
+ childAtPosition(
+ withId(id.rsb_current_step),
+ 1)),
+ 2),
+ isDisplayed()))
+ appCompatTextView6.perform(click())
+
+
+ onView(withId(id.value))
+ .perform(click())
+
+ onView(isAssignableFrom(DatePicker::class.java))
+ .perform(setDate(2017, 6, 30));
+
+ val appCompatButton4 = onView(
+ allOf(withId(android.R.id.button1), withText("OK"),
+ childAtPosition(
+ childAtPosition(
+ withClassName(`is`("android.widget.ScrollView")),
+ 0),
+ 3)))
+ appCompatButton4.perform(scrollTo(), click())
+
+ val appCompatTextView7 = onView(
+ allOf(withId(id.bar_submit_postitive), withText("next"),
+ childAtPosition(
+ allOf(withId(id.rsb_submit_bar),
+ childAtPosition(
+ withId(id.rsb_current_step),
+ 1)),
+ 2),
+ isDisplayed()))
+ appCompatTextView7.perform(click())
+
+ val appCompatRadioButton = onView(
+ allOf(withText("Yes"),
+ childAtPosition(
+ allOf(withId(id.rsb_survey_step_body),
+ childAtPosition(
+ withId(id.rsb_survey_content_container),
+ 2)),
+ 0),
+ isDisplayed()))
+ appCompatRadioButton.perform(click())
+
+ val appCompatTextView8 = onView(
+ allOf(withId(id.bar_submit_postitive), withText("next"),
+ childAtPosition(
+ allOf(withId(id.rsb_submit_bar),
+ childAtPosition(
+ withId(id.rsb_current_step),
+ 1)),
+ 2),
+ isDisplayed()))
+ appCompatTextView8.perform(click())
+
+ val appCompatCheckBox = onView(
+ allOf(withText("One"),
+ childAtPosition(
+ allOf(withId(id.rsb_survey_step_body),
+ childAtPosition(
+ withId(id.rsb_survey_content_container),
+ 2)),
+ 1),
+ isDisplayed()))
+ appCompatCheckBox.perform(click())
+
+ val appCompatCheckBox2 = onView(
+ allOf(withText("Two"),
+ childAtPosition(
+ allOf(withId(id.rsb_survey_step_body),
+ childAtPosition(
+ withId(id.rsb_survey_content_container),
+ 2)),
+ 2),
+ isDisplayed()))
+ appCompatCheckBox2.perform(click())
+
+ val appCompatTextView9 = onView(
+ allOf(withId(id.bar_submit_postitive), withText("next"),
+ childAtPosition(
+ allOf(withId(id.rsb_submit_bar),
+ childAtPosition(
+ withId(id.rsb_current_step),
+ 1)),
+ 2),
+ isDisplayed()))
+ appCompatTextView9.perform(click())
+
+ val textView = onView(
+ allOf(withId(id.survey_results),
+ childAtPosition(
+ childAtPosition(
+ IsInstanceOf.instanceOf(LinearLayout::class.java),
+ 3),
+ 1),
+ isDisplayed()))
+ textView.check(
+ matches(allOf(
+ withSubstring("multi_step: [1.0, 2.0]"),
+ withSubstring("nutrition: true"),
+ withSubstring("date: 1.49"),
+ withSubstring("name: test")))
+
+ )
+ }
+
+ private fun testConsentTask() {
+ // ConsentVisualStep
+
+ onView(withId(id.title))
+ .check(matches(allOf(
+ withText("The title of the section goes here ..."),
+ isDisplayed())))
+
+ onView(withId(id.summary))
+ .check(matches(allOf(
+ withText("The summary about the section goes here ..."),
+ isDisplayed())))
+
+ onView(withId(id.bar_submit_negative))
+ .check(matches(not(isDisplayed())))
+
+ onView(withId(id.bar_submit_postitive))
+ .check(matches(allOf(withText("next"), isDisplayed())))
+ .perform(click())
+
+ // ConsentDocumentStep
+
+ onView(withId(id.bar_submit_negative))
+ .check(matches(allOf(
+ isDisplayed(),
+ withText("DISAGREE")
+ )))
+
+ onView(withId(id.bar_submit_postitive))
+ .check(matches(allOf(
+ withText("Agree"),
+ isDisplayed())))
+ .perform(click())
+
+
+ onView(withId(android.R.id.button2))
+ .check(matches(allOf(
+ withText("CANCEL"),
+ isDisplayed()
+ )))
+
+ onView(withId(android.R.id.button1))
+ .check(matches(allOf(
+ withText("Agree"),
+ isDisplayed())))
+ .perform(scrollTo(), click())
+
+ // FormStep (for signature)
+
+ val appCompatEditText = onView(
+ allOf(withId(id.value),
+ childAtPosition(
+ childAtPosition(
+ withId(id.rsb_survey_step_body),
+ 0),
+ 1),
+ isDisplayed()))
+ appCompatEditText.perform(replaceText("test"), closeSoftKeyboard())
+
+ val appCompatTextView3 = onView(
+ allOf(withId(id.bar_submit_postitive), withText("next"),
+ childAtPosition(
+ allOf(withId(id.rsb_submit_bar),
+ childAtPosition(
+ withId(id.rsb_current_step),
+ 1)),
+ 2),
+ isDisplayed()))
+ appCompatTextView3.perform(click())
+
+ val appCompatTextView4 = onView(
+ allOf(withId(id.bar_submit_postitive), withText("next"),
+ childAtPosition(
+ allOf(withId(id.submit_bar),
+ childAtPosition(
+ withId(id.rsb_current_step),
+ 3)),
+ 2),
+ isDisplayed()))
+
+ // ConsentSignatureStep
+ onView(withId(id.layout_consent_review_signature))
+ .perform(swipeRight())
+ .perform(swipeDown())
+
+ appCompatTextView4.perform(click())
+ }
+
+ private fun childAtPosition(
+ parentMatcher: Matcher, position: Int): Matcher {
+
+ return object : TypeSafeMatcher() {
+ override fun describeTo(description: Description) {
+ description.appendText("Child at position $position in parent ")
+ parentMatcher.describeTo(description)
+ }
+
+ public override fun matchesSafely(view: View): Boolean {
+ val parent = view.parent
+ return parent is ViewGroup && parentMatcher.matches(parent)
+ && view == parent.getChildAt(position)
+ }
+ }
+ }
+}
diff --git a/sample_backbone_app/src/main/AndroidManifest.xml b/sample_backbone_app/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..0c72435bc
--- /dev/null
+++ b/sample_backbone_app/src/main/AndroidManifest.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sample_backbone_app/src/main/java/org/researchstack/backboneapp/AppPrefs.java b/sample_backbone_app/src/main/java/org/researchstack/backboneapp/AppPrefs.java
new file mode 100644
index 000000000..921009c87
--- /dev/null
+++ b/sample_backbone_app/src/main/java/org/researchstack/backboneapp/AppPrefs.java
@@ -0,0 +1,58 @@
+package org.researchstack.backboneapp;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+
+public class AppPrefs
+{
+ public static final String HAS_CONSENTED = "HAS_CONSENTED";
+ public static final String CONSENT_NAME = "CONSENT_NAME";
+ public static final String CONSENT_SIGNATURE = "CONSENT_SIGNATURE";
+ public static final String HAS_SURVEYED = "HAS_SURVEYED";
+ public static final String SURVEY_RESULT = "SURVEY_RESULT";
+
+ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ // Statics
+ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ private static AppPrefs instance;
+
+ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ // Field Vars
+ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ private final SharedPreferences prefs;
+
+ AppPrefs(Context context)
+ {
+ prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ }
+
+ public static synchronized AppPrefs getInstance(Context context)
+ {
+ if(instance == null)
+ {
+ instance = new AppPrefs(context);
+ }
+ return instance;
+ }
+
+ public boolean hasConsented()
+ {
+ return prefs.getBoolean(HAS_CONSENTED, false);
+ }
+
+ public void setHasConsented(boolean consented)
+ {
+ prefs.edit().putBoolean(HAS_CONSENTED, consented).apply();
+ }
+
+ public boolean hasSurveyed()
+ {
+ return prefs.getBoolean(HAS_SURVEYED, false);
+ }
+
+ public void setHasSurveyed(boolean surveyed)
+ {
+ prefs.edit().putBoolean(HAS_SURVEYED, surveyed).apply();
+ }
+}
\ No newline at end of file
diff --git a/sample_backbone_app/src/main/java/org/researchstack/backboneapp/BackboneApplication.java b/sample_backbone_app/src/main/java/org/researchstack/backboneapp/BackboneApplication.java
new file mode 100644
index 000000000..89803d86e
--- /dev/null
+++ b/sample_backbone_app/src/main/java/org/researchstack/backboneapp/BackboneApplication.java
@@ -0,0 +1,39 @@
+package org.researchstack.backboneapp;
+
+import android.app.Application;
+
+import org.researchstack.backbone.StorageAccess;
+import org.researchstack.backbone.storage.database.AppDatabase;
+import org.researchstack.backbone.storage.database.sqlite.DatabaseHelper;
+import org.researchstack.backbone.storage.file.EncryptionProvider;
+import org.researchstack.backbone.storage.file.FileAccess;
+import org.researchstack.backbone.storage.file.PinCodeConfig;
+import org.researchstack.backbone.storage.file.SimpleFileAccess;
+import org.researchstack.backbone.storage.file.UnencryptedProvider;
+
+
+public class BackboneApplication extends Application
+{
+ @Override
+ public void onCreate()
+ {
+ super.onCreate();
+
+ // Customize your pin code preferences
+ PinCodeConfig pinCodeConfig = new PinCodeConfig(); // default pin config (4-digit, 1 min lockout)
+
+ // Customize encryption preferences
+ EncryptionProvider encryptionProvider = new UnencryptedProvider(); // No pin, no encryption
+
+ // If you have special file handling needs, implement FileAccess
+ FileAccess fileAccess = new SimpleFileAccess();
+
+ // If you have your own custom database, implement AppDatabase
+ AppDatabase database = new DatabaseHelper(this,
+ DatabaseHelper.DEFAULT_NAME,
+ null,
+ DatabaseHelper.DEFAULT_VERSION);
+
+ StorageAccess.getInstance().init(pinCodeConfig, encryptionProvider, fileAccess, database);
+ }
+}
diff --git a/sample_backbone_app/src/main/java/org/researchstack/backboneapp/MainActivity.java b/sample_backbone_app/src/main/java/org/researchstack/backboneapp/MainActivity.java
new file mode 100644
index 000000000..315cf95d1
--- /dev/null
+++ b/sample_backbone_app/src/main/java/org/researchstack/backboneapp/MainActivity.java
@@ -0,0 +1,432 @@
+package org.researchstack.backboneapp;
+
+import android.content.Intent;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.widget.AppCompatButton;
+import androidx.appcompat.widget.Toolbar;
+import android.util.Base64;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import org.researchstack.backbone.StorageAccess;
+import org.researchstack.backbone.answerformat.AnswerFormat;
+import org.researchstack.backbone.answerformat.BooleanAnswerFormat;
+import org.researchstack.backbone.answerformat.ChoiceAnswerFormat;
+import org.researchstack.backbone.answerformat.DateAnswerFormat;
+import org.researchstack.backbone.answerformat.IntegerAnswerFormat;
+import org.researchstack.backbone.answerformat.TextAnswerFormat;
+import org.researchstack.backbone.answerformat.UnknownAnswerFormat;
+import org.researchstack.backbone.model.Choice;
+import org.researchstack.backbone.model.ConsentDocument;
+import org.researchstack.backbone.model.ConsentSection;
+import org.researchstack.backbone.model.ConsentSignature;
+import org.researchstack.backbone.result.StepResult;
+import org.researchstack.backbone.result.TaskResult;
+import org.researchstack.backbone.step.ConsentDocumentStep;
+import org.researchstack.backbone.step.ConsentSignatureStep;
+import org.researchstack.backbone.step.ConsentVisualStep;
+import org.researchstack.backbone.step.FormStep;
+import org.researchstack.backbone.step.InstructionStep;
+import org.researchstack.backbone.step.QuestionStep;
+import org.researchstack.backbone.task.OrderedTask;
+import org.researchstack.backbone.task.Task;
+import org.researchstack.backbone.ui.PinCodeActivity;
+import org.researchstack.backbone.ui.ViewTaskActivity;
+import org.researchstack.backbone.ui.step.layout.ConsentSignatureStepLayout;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+public class MainActivity extends PinCodeActivity
+{
+ // Activity Request Codes
+ private static final int REQUEST_CONSENT = 0;
+ private static final int REQUEST_SURVEY = 1;
+
+ // Task/Step Identifiers
+ public static final String FORM_STEP = "form_step";
+ public static final String AGE = "age";
+ public static final String INSTRUCTION = "identifier";
+ public static final String BASIC_INFO_HEADER = "basic_info_header";
+ public static final String FORM_AGE = "form_age";
+ public static final String FORM_GENDER = "gender";
+ public static final String FORM_MULTI_CHOICE = "multi_choice";
+ public static final String FORM_DATE_OF_BIRTH = "date_of_birth";
+ public static final String NUTRITION = "nutrition";
+ public static final String SIGNATURE = "signature";
+ public static final String SIGNATURE_DATE = "signature_date";
+ public static final String VISUAL_CONSENT_IDENTIFIER = "visual_consent_identifier";
+ public static final String CONSENT_DOC = "consent_doc";
+ public static final String SIGNATURE_FORM_STEP = "form_step";
+ public static final String NAME = "name";
+ public static final String CONSENT = "consent";
+ public static final String MULTI_STEP = "multi_step";
+ public static final String DATE = "date";
+ public static final String DECIMAL = "decimal";
+ private static final String FORM_NAME = "form_name";
+ public static final String SAMPLE_SURVEY = "sample_survey";
+
+ // Views
+ private AppCompatButton consentButton;
+ private AppCompatButton surveyButton;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+ ActionBar actionBar = getSupportActionBar();
+ actionBar.setDisplayShowTitleEnabled(true);
+
+ consentButton = (AppCompatButton) findViewById(R.id.consent_button);
+ consentButton.setOnClickListener(new View.OnClickListener()
+ {
+ @Override
+ public void onClick(View v)
+ {
+ launchConsent();
+ }
+ });
+
+ surveyButton = (AppCompatButton) findViewById(R.id.survey_button);
+ surveyButton.setOnClickListener(new View.OnClickListener()
+ {
+ @Override
+ public void onClick(View v)
+ {
+ launchSurvey();
+ }
+ });
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu)
+ {
+ getMenuInflater().inflate(R.menu.activity_main, menu);
+ return super.onCreateOptionsMenu(menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item)
+ {
+ if (item.getItemId() == R.id.menu_clear)
+ {
+ clearData();
+ Toast.makeText(this, R.string.menu_data_cleared, Toast.LENGTH_SHORT).show();
+ return true;
+ }
+ else
+ {
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ void clearData()
+ {
+ AppPrefs appPrefs = AppPrefs.getInstance(this);
+ appPrefs.setHasSurveyed(false);
+ appPrefs.setHasConsented(false);
+
+ initViews();
+ }
+
+ @Override
+ public void onDataReady()
+ {
+ super.onDataReady();
+ initViews();
+ }
+
+ private void initViews()
+ {
+ AppPrefs prefs = AppPrefs.getInstance(this);
+
+ View lblConsentedDate = findViewById(R.id.consented_date_lbl);
+ TextView consentedDate = (TextView)findViewById(R.id.consented_date);
+ ImageView consentedSig = (ImageView) findViewById(R.id.consented_signature);
+
+ if(prefs.hasConsented())
+ {
+ consentButton.setVisibility(View.GONE);
+ surveyButton.setEnabled(true);
+
+ consentedSig.setVisibility(View.VISIBLE);
+ consentedDate.setVisibility(View.VISIBLE);
+ lblConsentedDate.setVisibility(View.VISIBLE);
+
+ printConsentInfo(consentedDate, consentedSig);
+ }
+ else
+ {
+ consentButton.setVisibility(View.VISIBLE);
+ surveyButton.setEnabled(false);
+
+ consentedSig.setVisibility(View.INVISIBLE);
+ consentedSig.setImageBitmap(null);
+ consentedDate.setVisibility(View.INVISIBLE);
+ lblConsentedDate.setVisibility(View.INVISIBLE);
+ }
+
+ TextView surveyAnswer = (TextView) findViewById(R.id.survey_results);
+
+ if(prefs.hasSurveyed())
+ {
+ surveyAnswer.setVisibility(View.VISIBLE);
+ printSurveyInfo(surveyAnswer);
+ }
+ else
+ {
+ surveyAnswer.setVisibility(View.GONE);
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data)
+ {
+ super.onActivityResult(requestCode, resultCode, data);
+
+ if(requestCode == REQUEST_CONSENT && resultCode == RESULT_OK)
+ {
+ processConsentResult((TaskResult) data.getSerializableExtra(ViewTaskActivity.EXTRA_TASK_RESULT));
+ }
+ else if(requestCode == REQUEST_SURVEY && resultCode == RESULT_OK)
+ {
+ processSurveyResult((TaskResult) data.getSerializableExtra(ViewTaskActivity.EXTRA_TASK_RESULT));
+ }
+ }
+
+ // Consent stuff
+
+ private void launchConsent()
+ {
+ ConsentDocument document = new ConsentDocument();
+ document.setTitle("Demo Consent");
+ document.setSignaturePageTitle(R.string.rsb_consent);
+
+ // Create consent visual sections
+ ConsentSection section1 = new ConsentSection(ConsentSection.Type.DataGathering);
+ section1.setTitle("The title of the section goes here ...");
+ section1.setSummary("The summary about the section goes here ...");
+ section1.setContent("The content to show in learn more ...");
+
+ // ...add more sections as needed, then create a visual consent step
+ ConsentVisualStep visualStep = new ConsentVisualStep(VISUAL_CONSENT_IDENTIFIER);
+ visualStep.setStepTitle(R.string.rsb_consent);
+ visualStep.setSection(section1);
+ visualStep.setNextButtonString(getString(R.string.rsb_next));
+
+ // Create consent signature object and set what info is required
+ ConsentSignature signature = new ConsentSignature();
+ signature.setRequiresName(true);
+ signature.setRequiresSignatureImage(true);
+
+ // Create our HTML to show the user and have them accept or decline.
+ StringBuilder docBuilder = new StringBuilder(
+ "");
+ docBuilder.append(" HTML Consent Doc goes here
");
+
+ // Create the Consent doc step, pass in our HTML doc
+ ConsentDocumentStep documentStep = new ConsentDocumentStep(CONSENT_DOC);
+ documentStep.setConsentHTML(docBuilder.toString());
+ documentStep.setConfirmMessage(getString(R.string.rsb_consent_review_reason));
+
+ // Create Consent form step, to get users first & last name
+ FormStep formStep = new FormStep(SIGNATURE_FORM_STEP,
+ "Form Title",
+ "Form step description");
+ formStep.setStepTitle(R.string.rsb_consent);
+
+ TextAnswerFormat format = new TextAnswerFormat();
+ format.setIsMultipleLines(false);
+
+ QuestionStep fullName = new QuestionStep(NAME, "Full name", format);
+ formStep.setFormSteps(Collections.singletonList(fullName));
+
+ // Create Consent signature step, user can sign their name
+ ConsentSignatureStep signatureStep = new ConsentSignatureStep(SIGNATURE);
+ signatureStep.setStepTitle(R.string.rsb_consent);
+ signatureStep.setTitle(getString(R.string.rsb_consent_signature_title));
+ signatureStep.setText(getString(R.string.rsb_consent_signature_instruction));
+ signatureStep.setSignatureDateFormat(signature.getSignatureDateFormatString());
+ signatureStep.setOptional(false);
+ signatureStep.setStepLayoutClass(ConsentSignatureStepLayout.class);
+
+ // Finally, create and present a task including these steps.
+ Task consentTask = new OrderedTask(CONSENT,
+ visualStep,
+ documentStep,
+ formStep,
+ signatureStep);
+
+ // Launch using hte ViewTaskActivity and make sure to listen for the activity result
+ Intent intent = ViewTaskActivity.newIntent(this, consentTask);
+ startActivityForResult(intent, REQUEST_CONSENT);
+ }
+
+ private void processConsentResult(TaskResult result)
+ {
+ boolean consented = (boolean) result.getStepResult(CONSENT_DOC).getResult();
+
+ if(consented)
+ {
+ StorageAccess.getInstance().getAppDatabase().saveTaskResult(result);
+
+ AppPrefs prefs = AppPrefs.getInstance(this);
+ prefs.setHasConsented(true);
+
+ initViews();
+ }
+ }
+
+ private void printConsentInfo(TextView consentedDate, ImageView consentedSig)
+ {
+ TaskResult result = StorageAccess.getInstance()
+ .getAppDatabase()
+ .loadLatestTaskResult(CONSENT);
+
+ String signatureBase64 = (String) result.getStepResult(SIGNATURE)
+ .getResultForIdentifier(ConsentSignatureStepLayout.KEY_SIGNATURE);
+
+ String signatureDate = (String) result.getStepResult(SIGNATURE)
+ .getResultForIdentifier(ConsentSignatureStepLayout.KEY_SIGNATURE_DATE);
+
+ consentedDate.setText(signatureDate);
+
+ byte[] signatureBytes = Base64.decode(signatureBase64, Base64.DEFAULT);
+ consentedSig.setImageBitmap(BitmapFactory.decodeByteArray(
+ signatureBytes,
+ 0,
+ signatureBytes.length));
+ }
+
+
+ // Survey Stuff
+
+ private void launchSurvey()
+ {
+ InstructionStep instructionStep = new InstructionStep(INSTRUCTION,
+ "Selection Survey",
+ "This survey can help us understand your eligibility for the fitness study");
+ instructionStep.setStepTitle(R.string.survey);
+
+ TextAnswerFormat format = new TextAnswerFormat();
+ QuestionStep ageStep = new QuestionStep(NAME, "What is your name?", format);
+ ageStep.setStepTitle(R.string.survey);
+
+ DateAnswerFormat dateFormat = new DateAnswerFormat(AnswerFormat.DateAnswerStyle.Date);
+ QuestionStep dateStep = new QuestionStep(DATE, "Enter a date", dateFormat);
+ dateStep.setStepTitle(R.string.survey);
+
+ // Create a Boolean step to include in the task.
+ QuestionStep booleanStep = new QuestionStep(NUTRITION);
+ booleanStep.setStepTitle(R.string.survey);
+ booleanStep.setTitle("Do you take nutritional supplements?");
+ booleanStep.setAnswerFormat(new BooleanAnswerFormat(getString(R.string.rsb_yes),
+ getString(R.string.rsb_no)));
+ booleanStep.setOptional(false);
+
+ QuestionStep multiStep = new QuestionStep(MULTI_STEP);
+ multiStep.setStepTitle(R.string.survey);
+ AnswerFormat multiFormat = new ChoiceAnswerFormat(AnswerFormat.ChoiceAnswerStyle.MultipleChoice,
+ new Choice<>("Zero", 0),
+ new Choice<>("One", 1),
+ new Choice<>("Two", 2));
+ multiStep.setTitle("Select multiple");
+ multiStep.setAnswerFormat(multiFormat);
+ multiStep.setOptional(false);
+
+ // Create a task wrapping the steps.
+ OrderedTask task = new OrderedTask(SAMPLE_SURVEY, instructionStep, ageStep, dateStep,
+ // formStep,
+ booleanStep, multiStep);
+
+ // Create an activity using the task and set a delegate.
+ Intent intent = ViewTaskActivity.newIntent(this, task);
+ startActivityForResult(intent, REQUEST_SURVEY);
+ }
+
+ @NonNull
+ private FormStep createFormStep()
+ {
+ FormStep formStep = new FormStep(FORM_STEP, "Form", "Form groups multi-entry in one page");
+ ArrayList formItems = new ArrayList<>();
+
+ QuestionStep basicInfoHeader = new QuestionStep(BASIC_INFO_HEADER,
+ "Basic Information",
+ new UnknownAnswerFormat());
+ formItems.add(basicInfoHeader);
+
+ TextAnswerFormat format = new TextAnswerFormat();
+ format.setIsMultipleLines(false);
+ QuestionStep nameItem = new QuestionStep(FORM_NAME, "Name", format);
+ formItems.add(nameItem);
+
+ QuestionStep ageItem = new QuestionStep(FORM_AGE, "Age", new IntegerAnswerFormat(18, 90));
+ formItems.add(ageItem);
+
+ AnswerFormat genderFormat = new ChoiceAnswerFormat(AnswerFormat.ChoiceAnswerStyle.SingleChoice,
+ new Choice<>("Male", 0),
+ new Choice<>("Female", 1));
+ QuestionStep genderFormItem = new QuestionStep(FORM_GENDER, "Gender", genderFormat);
+ formItems.add(genderFormItem);
+
+ AnswerFormat multiFormat = new ChoiceAnswerFormat(AnswerFormat.ChoiceAnswerStyle.MultipleChoice,
+ new Choice<>("Zero", 0),
+ new Choice<>("One", 1),
+ new Choice<>("Two", 2));
+ QuestionStep multiFormItem = new QuestionStep(FORM_MULTI_CHOICE, "Test Multi", multiFormat);
+ formItems.add(multiFormItem);
+
+ AnswerFormat dateOfBirthFormat = new DateAnswerFormat(AnswerFormat.DateAnswerStyle.Date);
+ QuestionStep dateOfBirthFormItem = new QuestionStep(FORM_DATE_OF_BIRTH,
+ "Birthdate",
+ dateOfBirthFormat);
+ formItems.add(dateOfBirthFormItem);
+
+ // ... And so on, adding additional items
+ formStep.setFormSteps(formItems);
+ return formStep;
+ }
+
+ private void processSurveyResult(TaskResult result)
+ {
+ StorageAccess.getInstance().getAppDatabase().saveTaskResult(result);
+
+ AppPrefs prefs = AppPrefs.getInstance(this);
+ prefs.setHasSurveyed(true);
+ initViews();
+ }
+
+ private void printSurveyInfo(TextView surveyAnswer)
+ {
+ TaskResult taskResult = StorageAccess.getInstance()
+ .getAppDatabase()
+ .loadLatestTaskResult(SAMPLE_SURVEY);
+
+ String results = "";
+ for(String id : taskResult.getResults().keySet())
+ {
+ StepResult stepResult = taskResult.getStepResult(id);
+ results += id + ": " + stepResult.getResult().toString() + "\n";
+ }
+
+ surveyAnswer.setText(results);
+ }
+}
diff --git a/sample_backbone_app/src/main/res/layout/activity_main.xml b/sample_backbone_app/src/main/res/layout/activity_main.xml
new file mode 100644
index 000000000..29bd51f79
--- /dev/null
+++ b/sample_backbone_app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sample_backbone_app/src/main/res/menu/activity_main.xml b/sample_backbone_app/src/main/res/menu/activity_main.xml
new file mode 100644
index 000000000..abc9d8bf9
--- /dev/null
+++ b/sample_backbone_app/src/main/res/menu/activity_main.xml
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/sample_backbone_app/src/main/res/mipmap-hdpi/ic_launcher.png b/sample_backbone_app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..aa46eebdc
Binary files /dev/null and b/sample_backbone_app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/sample_backbone_app/src/main/res/mipmap-mdpi/ic_launcher.png b/sample_backbone_app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..cbab2b190
Binary files /dev/null and b/sample_backbone_app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/sample_backbone_app/src/main/res/mipmap-xhdpi/ic_launcher.png b/sample_backbone_app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..82a75e801
Binary files /dev/null and b/sample_backbone_app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/sample_backbone_app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/sample_backbone_app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..dded52e65
Binary files /dev/null and b/sample_backbone_app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/sample_backbone_app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/sample_backbone_app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..4cf21665a
Binary files /dev/null and b/sample_backbone_app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/sample_backbone_app/src/main/res/values-v21/styles.xml b/sample_backbone_app/src/main/res/values-v21/styles.xml
new file mode 100644
index 000000000..2c02b673a
--- /dev/null
+++ b/sample_backbone_app/src/main/res/values-v21/styles.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sample_backbone_app/src/main/res/values-w820dp/dimens.xml b/sample_backbone_app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 000000000..63fc81644
--- /dev/null
+++ b/sample_backbone_app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/sample_backbone_app/src/main/res/values/colors.xml b/sample_backbone_app/src/main/res/values/colors.xml
new file mode 100644
index 000000000..975426a94
--- /dev/null
+++ b/sample_backbone_app/src/main/res/values/colors.xml
@@ -0,0 +1,7 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+ #cccccc
+
diff --git a/sample_backbone_app/src/main/res/values/dimens.xml b/sample_backbone_app/src/main/res/values/dimens.xml
new file mode 100644
index 000000000..47c822467
--- /dev/null
+++ b/sample_backbone_app/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@
+
+
+ 16dp
+ 16dp
+
diff --git a/sample_backbone_app/src/main/res/values/strings.xml b/sample_backbone_app/src/main/res/values/strings.xml
new file mode 100644
index 000000000..b1472a140
--- /dev/null
+++ b/sample_backbone_app/src/main/res/values/strings.xml
@@ -0,0 +1,11 @@
+
+ Backbone App
+ Start Consent
+ Take Survey
+ Consented
+ Clear
+ Survey
+ Data has been cleared
+ User Name:
+ Date Consented:
+
diff --git a/sample_backbone_app/src/main/res/values/styles.xml b/sample_backbone_app/src/main/res/values/styles.xml
new file mode 100644
index 000000000..c0507cc6b
--- /dev/null
+++ b/sample_backbone_app/src/main/res/values/styles.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sample_backbone_app/src/test/java/org/researchstack/backboneapp/ExampleUnitTest.java b/sample_backbone_app/src/test/java/org/researchstack/backboneapp/ExampleUnitTest.java
new file mode 100644
index 000000000..3132a0438
--- /dev/null
+++ b/sample_backbone_app/src/test/java/org/researchstack/backboneapp/ExampleUnitTest.java
@@ -0,0 +1,18 @@
+package org.researchstack.backboneapp;
+
+import org.junit.Test;
+
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * To work on unit tests, switch the Test Artifact in the Build Variants view.
+ */
+public class ExampleUnitTest
+{
+ @Test
+ public void addition_isCorrect() throws Exception
+ {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index 408516fa3..46157c442 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1,2 @@
-include ':backbone', ':skin'
+include ':backbone', ':skin', ':foundation', ':authentication', ':chart', ':consent', ':storage'
+include ':sample_backbone_app'
\ No newline at end of file
diff --git a/skin/build.gradle b/skin/build.gradle
index d828485dc..07c2d932b 100644
--- a/skin/build.gradle
+++ b/skin/build.gradle
@@ -1,25 +1,26 @@
apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
apply plugin: 'com.github.dcendents.android-maven'
-apply plugin: 'me.tatarka.retrolambda'
-apply plugin: 'com.neenbedankt.android-apt'
apply plugin: 'com.jfrog.bintray'
-version = '1.1.2'
+apply plugin: 'kotlin-kapt'
+
+version = research_stack_version
android {
- compileSdkVersion 23
- buildToolsVersion "23.0.2"
+ compileSdkVersion 28
lintOptions {
warning "InvalidPackage"
}
defaultConfig {
- minSdkVersion 16
- targetSdkVersion 23
- versionCode 6
+ minSdkVersion 19
+ targetSdkVersion 28
+ versionCode 7
versionName version
}
+
buildTypes {
release {
minifyEnabled false
@@ -69,16 +70,38 @@ ext {
}
dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar', '*.so'])
- compile 'com.cronutils:cron-utils:3.1.2'
- compile project(':backbone')
- testCompile 'junit:junit:4.12'
- testCompile 'org.robolectric:robolectric:3.0'
- testCompile 'org.mockito:mockito-core:1.10.19'
- compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'
- compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3'
- compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta3'
- compile 'com.squareup.okhttp3:logging-interceptor:3.0.0-RC1'
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.so'])
+ implementation 'com.cronutils:cron-utils:3.1.2'
+ implementation project(':foundation')
+ implementation project(':authentication')
+ implementation project(':storage')
+ implementation project(':consent')
+
+ implementation project(':backbone')
+
+ implementation 'androidx.appcompat:appcompat:1.0.2'
+ implementation 'androidx.cardview:cardview:1.0.0'
+ implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
+ implementation 'com.google.android.material:material:1.0.0'
+
+ implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+
+ implementation 'com.jakewharton.rxbinding:rxbinding:0.4.0'
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+ implementation 'com.jakewharton.rxbinding:rxbinding-support-v4:0.4.0'
+ implementation 'com.jakewharton.rxbinding:rxbinding-appcompat-v7:0.4.0'
+ implementation 'com.jakewharton.rxbinding:rxbinding-design:0.4.0'
+
+ implementation 'co.touchlab.squeaky:squeaky-query:0.4.0.0'
+ kapt 'co.touchlab.squeaky:squeaky-processor:0.4.0.0'
+
+ testImplementation 'junit:junit:4.12'
+ testImplementation 'org.robolectric:robolectric:3.0'
+ testImplementation 'org.mockito:mockito-core:1.10.19'
+ implementation 'com.squareup.retrofit2:retrofit:2.0.0-beta3'
+ implementation 'com.squareup.retrofit2:converter-gson:2.0.0-beta3'
+ implementation 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta3'
+ implementation 'com.squareup.okhttp3:logging-interceptor:3.0.0-RC1'
}
diff --git a/skin/src/main/java/org/researchstack/skin/DataProvider.java b/skin/src/main/java/org/researchstack/skin/DataProvider.java
index 3cbfd5a58..f3e32b8b8 100644
--- a/skin/src/main/java/org/researchstack/skin/DataProvider.java
+++ b/skin/src/main/java/org/researchstack/skin/DataProvider.java
@@ -3,9 +3,8 @@
import android.app.Application;
import android.content.Context;
-import org.researchstack.backbone.result.TaskResult;
-import org.researchstack.backbone.storage.file.FileAccess;
-import org.researchstack.backbone.task.Task;
+import org.researchstack.foundation.core.models.result.TaskResult;
+import org.researchstack.foundation.core.models.task.Task;
import org.researchstack.skin.model.SchedulesAndTasksModel;
import org.researchstack.skin.model.User;
import org.researchstack.skin.ui.EmailVerificationActivity;
diff --git a/skin/src/main/java/org/researchstack/skin/PermissionRequestManager.java b/skin/src/main/java/org/researchstack/skin/PermissionRequestManager.java
index 23c748e4e..175de0a30 100644
--- a/skin/src/main/java/org/researchstack/skin/PermissionRequestManager.java
+++ b/skin/src/main/java/org/researchstack/skin/PermissionRequestManager.java
@@ -5,9 +5,9 @@
import android.app.Application;
import android.content.Context;
import android.content.Intent;
-import android.support.annotation.DrawableRes;
-import android.support.annotation.StringRes;
-import android.support.v4.content.ContextCompat;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.StringRes;
+import androidx.core.content.ContextCompat;
import org.researchstack.skin.ui.layout.PermissionStepLayout;
diff --git a/skin/src/main/java/org/researchstack/skin/ResearchStack.java b/skin/src/main/java/org/researchstack/skin/ResearchStack.java
index 84b3500ea..584580452 100644
--- a/skin/src/main/java/org/researchstack/skin/ResearchStack.java
+++ b/skin/src/main/java/org/researchstack/skin/ResearchStack.java
@@ -3,11 +3,12 @@
import android.app.Application;
import android.content.Context;
-import org.researchstack.backbone.StorageAccess;
-import org.researchstack.backbone.storage.database.AppDatabase;
-import org.researchstack.backbone.storage.file.EncryptionProvider;
-import org.researchstack.backbone.storage.file.FileAccess;
-import org.researchstack.backbone.storage.file.PinCodeConfig;
+import org.researchstack.feature.authentication.pincode.PinCodeConfig;
+import org.researchstack.feature.authentication.pincode.PinCodeConfigProvider;
+import org.researchstack.feature.storage.StorageAccess;
+import org.researchstack.feature.storage.database.AppDatabase;
+import org.researchstack.feature.storage.file.EncryptionProvider;
+import org.researchstack.feature.storage.file.FileAccess;
import org.researchstack.skin.notification.NotificationConfig;
/**
@@ -53,8 +54,10 @@ public static void init(Context context, ResearchStack concreteResearchStack) {
DataProvider.init(concreteResearchStack.createDataProviderImplementation(context));
+ PinCodeConfig pinCodeConfig = concreteResearchStack.getPinCodeConfig(context);
+ PinCodeConfigProvider.Companion.config(pinCodeConfig);
StorageAccess.getInstance()
- .init(concreteResearchStack.getPinCodeConfig(context),
+ .init(pinCodeConfig,
concreteResearchStack.getEncryptionProvider(context),
concreteResearchStack.createFileAccessImplementation(context),
concreteResearchStack.createAppDatabaseImplementation(context));
diff --git a/skin/src/main/java/org/researchstack/skin/ResourceManager.java b/skin/src/main/java/org/researchstack/skin/ResourceManager.java
index e3ded729e..e9cec4e66 100644
--- a/skin/src/main/java/org/researchstack/skin/ResourceManager.java
+++ b/skin/src/main/java/org/researchstack/skin/ResourceManager.java
@@ -1,6 +1,6 @@
package org.researchstack.skin;
-import org.researchstack.backbone.ResourcePathManager;
+import org.researchstack.foundation.components.singletons.ResourcePathManager;
/**
* This class is responsible for returning paths of resources defined in the assets folder. This
diff --git a/skin/src/main/java/org/researchstack/skin/TaskProvider.java b/skin/src/main/java/org/researchstack/skin/TaskProvider.java
index b3b9658ff..a3b6b3d2e 100644
--- a/skin/src/main/java/org/researchstack/skin/TaskProvider.java
+++ b/skin/src/main/java/org/researchstack/skin/TaskProvider.java
@@ -2,13 +2,17 @@
import android.app.Application;
-import org.researchstack.backbone.task.Task;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.researchstack.foundation.components.presentation.ITaskProvider;
+import org.researchstack.foundation.core.interfaces.ITask;
+import org.researchstack.foundation.core.models.task.Task;
/**
* TaskProvider is used as a way for the Framework to get Tasks needed throughout the onboarding
* process. This allows you to implement your own Tasks if needed.
*/
-public abstract class TaskProvider {
+public abstract class TaskProvider implements ITaskProvider {
/**
* Task ID used by the framework for looking up the "initial" task
*/
@@ -64,6 +68,12 @@ public static TaskProvider getInstance() {
*/
public abstract Task get(String taskId);
+ @Nullable
+ @Override
+ public ITask task(@NotNull String identifier) {
+ return this.get(identifier);
+ }
+
/**
* Used to store a task object for reuse
*
diff --git a/skin/src/main/java/org/researchstack/skin/UiManager.java b/skin/src/main/java/org/researchstack/skin/UiManager.java
index c3849d8ff..7f14c8ce4 100644
--- a/skin/src/main/java/org/researchstack/skin/UiManager.java
+++ b/skin/src/main/java/org/researchstack/skin/UiManager.java
@@ -3,8 +3,10 @@
import android.app.Application;
import android.content.Context;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.Step;
+import androidx.fragment.app.Fragment;
+
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
import org.researchstack.skin.notification.TaskNotificationReceiver;
import java.util.List;
@@ -53,7 +55,7 @@ public static UiManager getInstance() {
* All ActionItems returned by this method should define a title, icon, and class. These items
* are used to fill a pager in the MainActivity. The framework uses the class objects from this
* list to create a Fragments for tha pager. It is imperative that the defined classes be of
- * instance {@link android.support.v4.app.Fragment}.
+ * instance {@link Fragment}.
*
* @return a list of ActionItems for display in the MainActivity ActionBar
*/
diff --git a/skin/src/main/java/org/researchstack/skin/model/ConsentQuizModel.java b/skin/src/main/java/org/researchstack/skin/model/ConsentQuizModel.java
index 50b7c107c..6c66d500a 100644
--- a/skin/src/main/java/org/researchstack/skin/model/ConsentQuizModel.java
+++ b/skin/src/main/java/org/researchstack/skin/model/ConsentQuizModel.java
@@ -12,7 +12,7 @@ public class ConsentQuizModel implements Serializable {
private List questions;
// fields with defaults
- private String incorrectIcon = "rsb_quiz_retry";
+ private String incorrectIcon = "rsf_quiz_retry";
private String correctIcon = "rss_ic_quiz_valid";
public String getFailureTitle() {
diff --git a/skin/src/main/java/org/researchstack/skin/model/ConsentSectionModel.java b/skin/src/main/java/org/researchstack/skin/model/ConsentSectionModel.java
index 092a091b7..a933272d1 100644
--- a/skin/src/main/java/org/researchstack/skin/model/ConsentSectionModel.java
+++ b/skin/src/main/java/org/researchstack/skin/model/ConsentSectionModel.java
@@ -2,8 +2,8 @@
import com.google.gson.annotations.SerializedName;
-import org.researchstack.backbone.model.ConsentSection;
import org.researchstack.backbone.model.DocumentProperties;
+import org.researchstack.feature.consent.model.ConsentSection;
import java.util.List;
diff --git a/skin/src/main/java/org/researchstack/skin/notification/NotificationConfig.java b/skin/src/main/java/org/researchstack/skin/notification/NotificationConfig.java
index 0190423eb..59b2b632a 100644
--- a/skin/src/main/java/org/researchstack/skin/notification/NotificationConfig.java
+++ b/skin/src/main/java/org/researchstack/skin/notification/NotificationConfig.java
@@ -2,8 +2,8 @@
import android.app.Application;
import android.content.Context;
-import android.support.annotation.ColorInt;
-import android.support.annotation.DrawableRes;
+import androidx.annotation.ColorInt;
+import androidx.annotation.DrawableRes;
/**
* Configuration class for framework notifciations
diff --git a/skin/src/main/java/org/researchstack/skin/notification/SimpleNotificationConfig.java b/skin/src/main/java/org/researchstack/skin/notification/SimpleNotificationConfig.java
index 9886e8de2..66204538f 100644
--- a/skin/src/main/java/org/researchstack/skin/notification/SimpleNotificationConfig.java
+++ b/skin/src/main/java/org/researchstack/skin/notification/SimpleNotificationConfig.java
@@ -12,7 +12,7 @@ public int getSmallIcon() {
@Override
public int getLargeIconBackgroundColor(Context context) {
- return context.getResources().getColor(R.color.rsb_error);
+ return context.getResources().getColor(R.color.rsf_error);
}
@Override
diff --git a/skin/src/main/java/org/researchstack/skin/notification/TaskAlertReceiver.java b/skin/src/main/java/org/researchstack/skin/notification/TaskAlertReceiver.java
index 425ea40a6..c82c8acc3 100644
--- a/skin/src/main/java/org/researchstack/skin/notification/TaskAlertReceiver.java
+++ b/skin/src/main/java/org/researchstack/skin/notification/TaskAlertReceiver.java
@@ -7,11 +7,11 @@
import android.content.Intent;
import android.util.Log;
-import org.researchstack.backbone.storage.NotificationHelper;
-import org.researchstack.backbone.storage.database.TaskNotification;
-import org.researchstack.backbone.utils.FormatHelper;
-import org.researchstack.backbone.utils.LogExt;
import org.researchstack.backbone.utils.ObservableUtils;
+import org.researchstack.feature.storage.NotificationHelper;
+import org.researchstack.feature.storage.database.TaskNotification;
+import org.researchstack.foundation.components.utils.FormatHelper;
+import org.researchstack.foundation.components.utils.LogExt;
import org.researchstack.skin.UiManager;
import org.researchstack.skin.schedule.ScheduleHelper;
diff --git a/skin/src/main/java/org/researchstack/skin/notification/TaskNotificationReceiver.java b/skin/src/main/java/org/researchstack/skin/notification/TaskNotificationReceiver.java
index 6ae54463c..f07a4528e 100644
--- a/skin/src/main/java/org/researchstack/skin/notification/TaskNotificationReceiver.java
+++ b/skin/src/main/java/org/researchstack/skin/notification/TaskNotificationReceiver.java
@@ -6,7 +6,8 @@
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.support.v7.app.NotificationCompat;
+//import android.support.v7.app.NotificationCompat;
+import androidx.core.app.NotificationCompat;
import android.util.Log;
import org.researchstack.skin.ui.MainActivity;
diff --git a/skin/src/main/java/org/researchstack/skin/step/ConsentQuizEvaluationStep.java b/skin/src/main/java/org/researchstack/skin/step/ConsentQuizEvaluationStep.java
index 778bd071c..5d658f588 100644
--- a/skin/src/main/java/org/researchstack/skin/step/ConsentQuizEvaluationStep.java
+++ b/skin/src/main/java/org/researchstack/skin/step/ConsentQuizEvaluationStep.java
@@ -1,6 +1,6 @@
package org.researchstack.skin.step;
-import org.researchstack.backbone.step.Step;
+import org.researchstack.foundation.core.models.step.Step;
import org.researchstack.skin.R;
import org.researchstack.skin.model.ConsentQuizModel;
import org.researchstack.skin.ui.layout.ConsentQuizEvaluationStepLayout;
@@ -18,7 +18,7 @@ public ConsentQuizEvaluationStep(String identifier, ConsentQuizModel quizModel)
@Override
public int getStepTitle() {
- return R.string.rsb_quiz_evaluation;
+ return R.string.rsfc_quiz_evaluation;
}
@Override
diff --git a/skin/src/main/java/org/researchstack/skin/step/ConsentQuizQuestionStep.java b/skin/src/main/java/org/researchstack/skin/step/ConsentQuizQuestionStep.java
index fb844a464..84992f7a6 100644
--- a/skin/src/main/java/org/researchstack/skin/step/ConsentQuizQuestionStep.java
+++ b/skin/src/main/java/org/researchstack/skin/step/ConsentQuizQuestionStep.java
@@ -1,6 +1,6 @@
package org.researchstack.skin.step;
-import org.researchstack.backbone.step.Step;
+import org.researchstack.foundation.core.models.step.Step;
import org.researchstack.skin.R;
import org.researchstack.skin.model.ConsentQuizModel;
import org.researchstack.skin.ui.layout.ConsentQuizQuestionStepLayout;
@@ -20,7 +20,7 @@ public Class getStepLayoutClass() {
@Override
public int getStepTitle() {
- return R.string.rsb_quiz;
+ return R.string.rsfc_quiz;
}
@Override
diff --git a/skin/src/main/java/org/researchstack/skin/task/ConsentTask.java b/skin/src/main/java/org/researchstack/skin/task/ConsentTask.java
index 34ecb7fbc..8ca9bc340 100644
--- a/skin/src/main/java/org/researchstack/skin/task/ConsentTask.java
+++ b/skin/src/main/java/org/researchstack/skin/task/ConsentTask.java
@@ -3,29 +3,29 @@
import android.content.Context;
import android.content.res.Resources;
-import org.researchstack.backbone.answerformat.AnswerFormat;
-import org.researchstack.backbone.answerformat.BirthDateAnswerFormat;
-import org.researchstack.backbone.answerformat.ChoiceAnswerFormat;
-import org.researchstack.backbone.answerformat.DateAnswerFormat;
-import org.researchstack.backbone.answerformat.TextAnswerFormat;
-import org.researchstack.backbone.model.Choice;
-import org.researchstack.backbone.model.ConsentDocument;
-import org.researchstack.backbone.model.ConsentSection;
-import org.researchstack.backbone.model.ConsentSignature;
import org.researchstack.backbone.model.DocumentProperties;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.result.TaskResult;
-import org.researchstack.backbone.step.ConsentDocumentStep;
-import org.researchstack.backbone.step.ConsentSharingStep;
-import org.researchstack.backbone.step.ConsentSignatureStep;
-import org.researchstack.backbone.step.ConsentVisualStep;
-import org.researchstack.backbone.step.FormStep;
-import org.researchstack.backbone.step.QuestionStep;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.task.OrderedTask;
-import org.researchstack.backbone.ui.step.layout.ConsentSignatureStepLayout;
-import org.researchstack.backbone.utils.LogExt;
-import org.researchstack.backbone.utils.TextUtils;
+import org.researchstack.feature.consent.model.ConsentDocument;
+import org.researchstack.feature.consent.model.ConsentSection;
+import org.researchstack.feature.consent.model.ConsentSignature;
+import org.researchstack.feature.consent.step.ConsentDocumentStep;
+import org.researchstack.feature.consent.step.ConsentSharingStep;
+import org.researchstack.feature.consent.step.ConsentSignatureStep;
+import org.researchstack.feature.consent.step.ConsentVisualStep;
+import org.researchstack.feature.consent.ui.layout.ConsentSignatureStepLayout;
+import org.researchstack.foundation.components.common.task.OrderedTask;
+import org.researchstack.foundation.components.survey.answerformat.AnswerFormat;
+import org.researchstack.foundation.components.survey.answerformat.BirthDateAnswerFormat;
+import org.researchstack.foundation.components.survey.answerformat.ChoiceAnswerFormat;
+import org.researchstack.foundation.components.survey.answerformat.DateAnswerFormat;
+import org.researchstack.foundation.components.survey.answerformat.TextAnswerFormat;
+import org.researchstack.foundation.components.survey.model.Choice;
+import org.researchstack.foundation.components.survey.step.FormStep;
+import org.researchstack.foundation.components.survey.step.QuestionStep;
+import org.researchstack.foundation.components.utils.LogExt;
+import org.researchstack.foundation.components.utils.TextUtils;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.result.TaskResult;
+import org.researchstack.foundation.core.models.step.Step;
import org.researchstack.skin.R;
import org.researchstack.skin.ResourceManager;
import org.researchstack.skin.model.ConsentQuizModel;
@@ -75,9 +75,9 @@ public static ConsentTask create(Context context, String taskId) {
signature.setRequiresBirthDate(properties.requiresBirthdate());
ConsentDocument doc = new ConsentDocument();
- doc.setTitle(r.getString(R.string.rsb_consent_form_title));
- doc.setSignaturePageTitle(R.string.rsb_consent_form_title);
- doc.setSignaturePageContent(r.getString(R.string.rsb_consent_signature_content));
+ doc.setTitle(r.getString(R.string.rsfc_consent_form_title));
+ doc.setSignaturePageTitle(R.string.rsfc_consent_form_title);
+ doc.setSignaturePageContent(r.getString(R.string.rsfc_consent_signature_content));
doc.setSections(sections);
doc.addSignature(signature);
@@ -116,13 +116,13 @@ private static void initConsentSharingStep(Resources r, ConsentSectionModel data
ConsentSharingStep sharingStep = new ConsentSharingStep(ID_SHARING);
sharingStep.setOptional(false);
- sharingStep.setStepTitle(R.string.rsb_consent);
+ sharingStep.setStepTitle(R.string.rsfc_consent);
// sharingStep.setLocalizedLearnMoreHTMLContent(localizedLearnMoreHTMLContent);
- String shareWidely = r.getString(R.string.rsb_consent_share_widely, investigatorLongDesc);
+ String shareWidely = r.getString(R.string.rsfc_consent_share_widely, investigatorLongDesc);
Choice shareWidelyChoice = new Choice<>(shareWidely, "sponsors_and_partners", null);
- String shareRestricted = r.getString(R.string.rsb_consent_share_only,
+ String shareRestricted = r.getString(R.string.rsfc_consent_share_only,
investigatorShortDesc);
Choice shareRestrictedChoice = new Choice<>(shareRestricted,
"all_qualified_researchers",
@@ -132,8 +132,8 @@ private static void initConsentSharingStep(Resources r, ConsentSectionModel data
shareWidelyChoice,
shareRestrictedChoice));
- sharingStep.setTitle(r.getString(R.string.rsb_consent_share_title));
- sharingStep.setText(r.getString(R.string.rsb_consent_share_description,
+ sharingStep.setTitle(r.getString(R.string.rsfc_consent_share_title));
+ sharingStep.setText(r.getString(R.string.rsfc_consent_share_description,
investigatorLongDesc,
localizedLearnMoreHTMLContent));
@@ -153,11 +153,11 @@ private static void initVisualSteps(Context ctx, ConsentDocument doc, List
ConsentVisualStep step = new ConsentVisualStep("consent_" + i);
step.setSection(section);
- String nextString = ctx.getString(R.string.rsb_next);
+ String nextString = ctx.getString(R.string.rsf_next);
if (section.getType() == ConsentSection.Type.Overview) {
- nextString = ctx.getString(R.string.rsb_get_started);
+ nextString = ctx.getString(R.string.rsf_get_started);
} else if (i == size - 1) {
- nextString = ctx.getString(R.string.rsb_done);
+ nextString = ctx.getString(R.string.rsf_done);
}
step.setNextButtonString(nextString);
@@ -193,18 +193,18 @@ private static void initConsentReviewSteps(Context ctx, ConsentDocument doc, Lis
// Add ConsentReviewDocumentStep (view html version of the PDF doc)
StringBuilder docBuilder = new StringBuilder(
"");
docBuilder.append(doc.getHtmlReviewContent());
ConsentDocumentStep step = new ConsentDocumentStep(ID_CONSENT_DOC);
step.setConsentHTML(docBuilder.toString());
- step.setConfirmMessage(ctx.getString(R.string.rsb_consent_review_reason));
+ step.setConfirmMessage(ctx.getString(R.string.rsfc_consent_review_reason));
steps.add(step);
// Add full-name input
@@ -217,8 +217,8 @@ private static void initConsentReviewSteps(Context ctx, ConsentDocument doc, Lis
format.setIsMultipleLines(false);
String placeholder = ctx.getResources()
- .getString(R.string.rsb_consent_name_placeholder);
- String nameText = ctx.getResources().getString(R.string.rsb_consent_name_full);
+ .getString(R.string.rsfc_consent_name_placeholder);
+ String nameText = ctx.getResources().getString(R.string.rsfc_consent_name_full);
formSteps.add(new QuestionStep(ID_FORM_NAME, nameText, format));
}
@@ -226,13 +226,13 @@ private static void initConsentReviewSteps(Context ctx, ConsentDocument doc, Lis
Calendar maxDate = Calendar.getInstance();
maxDate.add(Calendar.YEAR, -18);
DateAnswerFormat dobFormat = new BirthDateAnswerFormat(null, 18, 0);
- String dobText = ctx.getResources().getString(R.string.rsb_consent_dob_full);
+ String dobText = ctx.getResources().getString(R.string.rsfc_consent_dob_full);
formSteps.add(new QuestionStep(ID_FORM_DOB, dobText, dobFormat));
}
- String formTitle = ctx.getString(R.string.rsb_consent_form_title);
+ String formTitle = ctx.getString(R.string.rsfc_consent_form_title);
FormStep formStep = new FormStep(ID_FORM, formTitle, step.getText());
- formStep.setStepTitle(R.string.rsb_consent);
+ formStep.setStepTitle(R.string.rsfc_consent);
formStep.setOptional(false);
formStep.setFormSteps(formSteps);
steps.add(formStep);
@@ -241,9 +241,9 @@ private static void initConsentReviewSteps(Context ctx, ConsentDocument doc, Lis
// Add signature input
if (doc.getSignature(0).requiresSignatureImage()) {
ConsentSignatureStep signatureStep = new ConsentSignatureStep(ID_SIGNATURE);
- signatureStep.setStepTitle(R.string.rsb_consent);
- signatureStep.setTitle(ctx.getString(R.string.rsb_consent_signature_title));
- signatureStep.setText(ctx.getString(R.string.rsb_consent_signature_instruction));
+ signatureStep.setStepTitle(R.string.rsfc_consent);
+ signatureStep.setTitle(ctx.getString(R.string.rsfc_consent_signature_title));
+ signatureStep.setText(ctx.getString(R.string.rsfc_consent_signature_instruction));
signatureStep.setOptional(false);
signatureStep.setSignatureDateFormat(doc.getSignature(0)
.getSignatureDateFormatString());
diff --git a/skin/src/main/java/org/researchstack/skin/task/OnboardingTask.java b/skin/src/main/java/org/researchstack/skin/task/OnboardingTask.java
index 921f67aaf..49a3c092d 100644
--- a/skin/src/main/java/org/researchstack/skin/task/OnboardingTask.java
+++ b/skin/src/main/java/org/researchstack/skin/task/OnboardingTask.java
@@ -1,12 +1,12 @@
package org.researchstack.skin.task;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.result.TaskResult;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.task.Task;
-import org.researchstack.backbone.ui.step.body.NotImplementedStepBody;
+import org.researchstack.feature.authentication.pincode.step.PassCodeCreationStep;
+import org.researchstack.foundation.components.survey.ui.body.NotImplementedStepBody;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.result.TaskResult;
+import org.researchstack.foundation.core.models.step.Step;
+import org.researchstack.foundation.core.models.task.Task;
import org.researchstack.skin.R;
-import org.researchstack.skin.step.PassCodeCreationStep;
import org.researchstack.skin.ui.layout.PermissionStepLayout;
import org.researchstack.skin.ui.layout.SignInStepLayout;
import org.researchstack.skin.ui.layout.SignUpEligibleStepLayout;
diff --git a/skin/src/main/java/org/researchstack/skin/task/SignInTask.java b/skin/src/main/java/org/researchstack/skin/task/SignInTask.java
index 20d1812f5..e238b5929 100644
--- a/skin/src/main/java/org/researchstack/skin/task/SignInTask.java
+++ b/skin/src/main/java/org/researchstack/skin/task/SignInTask.java
@@ -2,8 +2,8 @@
import android.content.Context;
-import org.researchstack.backbone.result.TaskResult;
-import org.researchstack.backbone.step.Step;
+import org.researchstack.foundation.core.models.result.TaskResult;
+import org.researchstack.foundation.core.models.step.Step;
import org.researchstack.skin.PermissionRequestManager;
import org.researchstack.skin.TaskProvider;
diff --git a/skin/src/main/java/org/researchstack/skin/task/SignUpTask.java b/skin/src/main/java/org/researchstack/skin/task/SignUpTask.java
index 8a34ea529..bc787e4f1 100644
--- a/skin/src/main/java/org/researchstack/skin/task/SignUpTask.java
+++ b/skin/src/main/java/org/researchstack/skin/task/SignUpTask.java
@@ -2,8 +2,8 @@
import android.content.Context;
-import org.researchstack.backbone.result.TaskResult;
-import org.researchstack.backbone.step.Step;
+import org.researchstack.foundation.core.models.result.TaskResult;
+import org.researchstack.foundation.core.models.step.Step;
import org.researchstack.skin.PermissionRequestManager;
import org.researchstack.skin.TaskProvider;
import org.researchstack.skin.UiManager;
diff --git a/skin/src/main/java/org/researchstack/skin/task/SmartSurveyTask.java b/skin/src/main/java/org/researchstack/skin/task/SmartSurveyTask.java
index 88896590f..7d8323a0c 100644
--- a/skin/src/main/java/org/researchstack/skin/task/SmartSurveyTask.java
+++ b/skin/src/main/java/org/researchstack/skin/task/SmartSurveyTask.java
@@ -2,22 +2,22 @@
import android.content.Context;
-import org.researchstack.backbone.answerformat.AnswerFormat;
-import org.researchstack.backbone.answerformat.BooleanAnswerFormat;
-import org.researchstack.backbone.answerformat.ChoiceAnswerFormat;
-import org.researchstack.backbone.answerformat.DateAnswerFormat;
-import org.researchstack.backbone.answerformat.DecimalAnswerFormat;
-import org.researchstack.backbone.answerformat.DurationAnswerFormat;
-import org.researchstack.backbone.answerformat.IntegerAnswerFormat;
-import org.researchstack.backbone.answerformat.TextAnswerFormat;
-import org.researchstack.backbone.answerformat.UnknownAnswerFormat;
-import org.researchstack.backbone.model.Choice;
-import org.researchstack.backbone.result.TaskResult;
-import org.researchstack.backbone.step.InstructionStep;
-import org.researchstack.backbone.step.QuestionStep;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.task.Task;
-import org.researchstack.backbone.utils.LogExt;
+import org.researchstack.foundation.components.survey.answerformat.AnswerFormat;
+import org.researchstack.foundation.components.survey.answerformat.BooleanAnswerFormat;
+import org.researchstack.foundation.components.survey.answerformat.ChoiceAnswerFormat;
+import org.researchstack.foundation.components.survey.answerformat.DateAnswerFormat;
+import org.researchstack.foundation.components.survey.answerformat.DecimalAnswerFormat;
+import org.researchstack.foundation.components.survey.answerformat.DurationAnswerFormat;
+import org.researchstack.foundation.components.survey.answerformat.IntegerAnswerFormat;
+import org.researchstack.foundation.components.survey.answerformat.TextAnswerFormat;
+import org.researchstack.foundation.components.survey.answerformat.UnknownAnswerFormat;
+import org.researchstack.foundation.components.survey.model.Choice;
+import org.researchstack.foundation.components.survey.step.InstructionStep;
+import org.researchstack.foundation.components.survey.step.QuestionStep;
+import org.researchstack.foundation.components.utils.LogExt;
+import org.researchstack.foundation.core.models.result.TaskResult;
+import org.researchstack.foundation.core.models.step.Step;
+import org.researchstack.foundation.core.models.task.Task;
import org.researchstack.skin.R;
import org.researchstack.skin.model.TaskModel;
@@ -95,8 +95,8 @@ private AnswerFormat from(Context context, TaskModel.ConstraintsModel constraint
AnswerFormat answerFormat;
String type = constraints.type;
if (type.equals("BooleanConstraints")) {
- answerFormat = new BooleanAnswerFormat(context.getString(R.string.rsb_yes),
- context.getString(R.string.rsb_no));
+ answerFormat = new BooleanAnswerFormat(context.getString(R.string.rsf_yes),
+ context.getString(R.string.rsf_no));
} else if (type.equals("MultiValueConstraints")) {
AnswerFormat.ChoiceAnswerStyle answerStyle = constraints.allowMultiple
? AnswerFormat.ChoiceAnswerStyle.MultipleChoice
@@ -215,7 +215,7 @@ public Step getStepWithIdentifier(String identifier) {
@Override
public String getTitleForStep(Context context, Step step) {
int currentIndex = staticStepIdentifiers.indexOf(step.getIdentifier()) + 1;
- return context.getString(R.string.rsb_format_step_title,
+ return context.getString(R.string.rsf_format_step_title,
currentIndex,
staticStepIdentifiers.size());
}
diff --git a/skin/src/main/java/org/researchstack/skin/ui/BaseActivity.java b/skin/src/main/java/org/researchstack/skin/ui/BaseActivity.java
index 95b662c3a..23eebeb57 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/BaseActivity.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/BaseActivity.java
@@ -5,20 +5,20 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
-import android.support.design.widget.Snackbar;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.content.LocalBroadcastManager;
+import com.google.android.material.snackbar.Snackbar;
+import androidx.core.content.ContextCompat;
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
-import org.researchstack.backbone.StorageAccess;
-import org.researchstack.backbone.result.TaskResult;
-import org.researchstack.backbone.task.Task;
import org.researchstack.backbone.ui.PinCodeActivity;
import org.researchstack.backbone.ui.ViewTaskActivity;
-import org.researchstack.backbone.utils.LogExt;
import org.researchstack.backbone.utils.ObservableUtils;
+import org.researchstack.feature.storage.StorageAccess;
+import org.researchstack.foundation.components.utils.LogExt;
+import org.researchstack.foundation.core.models.result.TaskResult;
+import org.researchstack.foundation.core.models.task.Task;
import org.researchstack.skin.AppPrefs;
import org.researchstack.skin.DataProvider;
import org.researchstack.skin.R;
@@ -124,7 +124,7 @@ private TextView getSnackBarMessageView(Snackbar snackbar) {
}
// Try id for lib level snackbar id
- id = android.support.design.R.id.snackbar_text;
+ id = com.google.android.material.R.id.snackbar_text;
tv = (TextView) snackbar.getView().findViewById(id);
if (tv != null) {
return tv;
diff --git a/skin/src/main/java/org/researchstack/skin/ui/ConsentTaskActivity.java b/skin/src/main/java/org/researchstack/skin/ui/ConsentTaskActivity.java
index 5d7b5970d..180e1fe39 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/ConsentTaskActivity.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/ConsentTaskActivity.java
@@ -3,9 +3,9 @@
import android.content.Context;
import android.content.Intent;
-import org.researchstack.backbone.StorageAccess;
-import org.researchstack.backbone.task.Task;
import org.researchstack.backbone.ui.ViewTaskActivity;
+import org.researchstack.feature.storage.StorageAccess;
+import org.researchstack.foundation.core.models.task.Task;
public class ConsentTaskActivity extends ViewTaskActivity {
public static Intent newIntent(Context context, Task task) {
diff --git a/skin/src/main/java/org/researchstack/skin/ui/EmailVerificationActivity.java b/skin/src/main/java/org/researchstack/skin/ui/EmailVerificationActivity.java
index de49c50a7..18ce888a2 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/EmailVerificationActivity.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/EmailVerificationActivity.java
@@ -3,8 +3,8 @@
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
-import android.support.v7.widget.AppCompatTextView;
-import android.support.v7.widget.Toolbar;
+import androidx.appcompat.widget.AppCompatTextView;
+import androidx.appcompat.widget.Toolbar;
import android.text.Html;
import android.view.MenuItem;
import android.view.View;
@@ -12,15 +12,15 @@
import com.jakewharton.rxbinding.view.RxView;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.result.TaskResult;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.task.OrderedTask;
import org.researchstack.backbone.ui.PinCodeActivity;
import org.researchstack.backbone.ui.ViewTaskActivity;
-import org.researchstack.backbone.ui.views.SubmitBar;
import org.researchstack.backbone.utils.ObservableUtils;
-import org.researchstack.backbone.utils.ThemeUtils;
+import org.researchstack.foundation.components.common.task.OrderedTask;
+import org.researchstack.foundation.components.common.ui.views.SubmitBar;
+import org.researchstack.foundation.components.utils.ThemeUtils;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.result.TaskResult;
+import org.researchstack.foundation.core.models.step.Step;
import org.researchstack.skin.DataProvider;
import org.researchstack.skin.R;
import org.researchstack.skin.task.OnboardingTask;
diff --git a/skin/src/main/java/org/researchstack/skin/ui/LearnActivity.java b/skin/src/main/java/org/researchstack/skin/ui/LearnActivity.java
index 47e186804..e32a19e63 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/LearnActivity.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/LearnActivity.java
@@ -1,7 +1,7 @@
package org.researchstack.skin.ui;
import android.os.Bundle;
-import android.support.v7.widget.Toolbar;
+import androidx.appcompat.widget.Toolbar;
import android.view.MenuItem;
import org.researchstack.backbone.ui.PinCodeActivity;
diff --git a/skin/src/main/java/org/researchstack/skin/ui/MainActivity.java b/skin/src/main/java/org/researchstack/skin/ui/MainActivity.java
index 057894633..bcf803202 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/MainActivity.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/MainActivity.java
@@ -4,20 +4,20 @@
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
-import android.support.design.widget.TabLayout;
-import android.support.v4.view.ViewPager;
-import android.support.v7.widget.Toolbar;
+import com.google.android.material.tabs.TabLayout;
+import androidx.viewpager.widget.ViewPager;
+import androidx.appcompat.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
-import org.researchstack.backbone.StorageAccess;
-import org.researchstack.backbone.result.TaskResult;
-import org.researchstack.backbone.task.Task;
import org.researchstack.backbone.ui.ViewTaskActivity;
-import org.researchstack.backbone.ui.views.IconTabLayout;
-import org.researchstack.backbone.utils.LogExt;
import org.researchstack.backbone.utils.ObservableUtils;
-import org.researchstack.backbone.utils.UiThreadContext;
+import org.researchstack.feature.storage.StorageAccess;
+import org.researchstack.foundation.components.common.ui.views.IconTabLayout;
+import org.researchstack.foundation.components.utils.LogExt;
+import org.researchstack.foundation.components.utils.UiThreadContext;
+import org.researchstack.foundation.core.models.result.TaskResult;
+import org.researchstack.foundation.core.models.task.Task;
import org.researchstack.skin.ActionItem;
import org.researchstack.skin.DataProvider;
import org.researchstack.skin.R;
diff --git a/skin/src/main/java/org/researchstack/skin/ui/OnboardingActivity.java b/skin/src/main/java/org/researchstack/skin/ui/OnboardingActivity.java
index 9a3a1cda1..62e406c6b 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/OnboardingActivity.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/OnboardingActivity.java
@@ -4,10 +4,10 @@
import android.animation.ValueAnimator;
import android.content.Intent;
import android.os.Bundle;
-import android.support.design.widget.TabLayout;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.view.ViewPager;
-import android.support.v7.widget.AppCompatButton;
+import com.google.android.material.tabs.TabLayout;
+import androidx.core.content.ContextCompat;
+import androidx.viewpager.widget.ViewPager;
+import androidx.appcompat.widget.AppCompatButton;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
@@ -15,20 +15,20 @@
import android.widget.LinearLayout;
import android.widget.TextView;
-import org.researchstack.backbone.StorageAccess;
-import org.researchstack.backbone.result.TaskResult;
-import org.researchstack.backbone.task.OrderedTask;
import org.researchstack.backbone.ui.PinCodeActivity;
import org.researchstack.backbone.ui.ViewTaskActivity;
-import org.researchstack.backbone.utils.ResUtils;
-import org.researchstack.backbone.utils.TextUtils;
+import org.researchstack.feature.authentication.pincode.step.PassCodeCreationStep;
+import org.researchstack.feature.storage.StorageAccess;
+import org.researchstack.foundation.components.common.task.OrderedTask;
+import org.researchstack.foundation.components.utils.ResUtils;
+import org.researchstack.foundation.components.utils.TextUtils;
+import org.researchstack.foundation.core.models.result.TaskResult;
import org.researchstack.skin.AppPrefs;
import org.researchstack.skin.R;
import org.researchstack.skin.ResourceManager;
import org.researchstack.skin.TaskProvider;
import org.researchstack.skin.UiManager;
import org.researchstack.skin.model.StudyOverviewModel;
-import org.researchstack.skin.step.PassCodeCreationStep;
import org.researchstack.skin.task.OnboardingTask;
import org.researchstack.skin.task.SignInTask;
import org.researchstack.skin.task.SignUpTask;
diff --git a/skin/src/main/java/org/researchstack/skin/ui/SettingsActivity.java b/skin/src/main/java/org/researchstack/skin/ui/SettingsActivity.java
index 5615f0d10..15a34a964 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/SettingsActivity.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/SettingsActivity.java
@@ -1,7 +1,7 @@
package org.researchstack.skin.ui;
import android.os.Bundle;
-import android.support.v7.widget.Toolbar;
+import androidx.appcompat.widget.Toolbar;
import android.view.MenuItem;
import org.researchstack.skin.R;
diff --git a/skin/src/main/java/org/researchstack/skin/ui/SignUpTaskActivity.java b/skin/src/main/java/org/researchstack/skin/ui/SignUpTaskActivity.java
index 65e21d03c..584ca4084 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/SignUpTaskActivity.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/SignUpTaskActivity.java
@@ -6,16 +6,19 @@
import android.content.Intent;
import android.os.Build;
-import org.researchstack.backbone.StorageAccess;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.result.TaskResult;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.task.Task;
+import org.jetbrains.annotations.Nullable;
import org.researchstack.backbone.ui.ViewTaskActivity;
import org.researchstack.backbone.ui.callbacks.ActivityCallback;
-import org.researchstack.backbone.ui.step.layout.StepLayout;
import org.researchstack.backbone.ui.step.layout.StepPermissionRequest;
-import org.researchstack.backbone.utils.TextUtils;
+import org.researchstack.feature.storage.StorageAccess;
+import org.researchstack.foundation.components.common.ui.layout.StepLayout;
+import org.researchstack.foundation.components.utils.TextUtils;
+import org.researchstack.foundation.core.interfaces.IResult;
+import org.researchstack.foundation.core.interfaces.IStep;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.result.TaskResult;
+import org.researchstack.foundation.core.models.step.Step;
+import org.researchstack.foundation.core.models.task.Task;
import org.researchstack.skin.DataProvider;
import org.researchstack.skin.PermissionRequestManager;
import org.researchstack.skin.R;
@@ -44,20 +47,24 @@ public void onDataAuth() {
}
@Override
- public void onSaveStep(int action, Step step, StepResult result) {
- // Save result to task
- onSaveStepResult(step.getIdentifier(), result);
-
- // Save Pin to disk, then save our consent info
- if (action == ACTION_NEXT &&
- step.getIdentifier().equals(OnboardingTask.SignUpPassCodeCreationStepIdentifier)) {
- String pin = (String) result.getResult();
- if (!TextUtils.isEmpty(pin)) {
- StorageAccess.getInstance().createPinCode(this, pin);
- }
+ public void onSaveStep(int action, IStep step, @Nullable IResult result) {
+
+ if (result instanceof StepResult) {
+ StepResult stepResult = (StepResult) result;
+ // Save result to task
+ onSaveStepResult(step.getIdentifier(), stepResult);
+
+ // Save Pin to disk, then save our consent info
+ if (action == ACTION_NEXT &&
+ step.getIdentifier().equals(OnboardingTask.SignUpPassCodeCreationStepIdentifier)) {
+ String pin = (String) stepResult.getResult();
+ if (!TextUtils.isEmpty(pin)) {
+ StorageAccess.getInstance().createPinCode(this, pin);
+ }
- if (consentResult != null) {
- saveConsentResultInfo();
+ if (consentResult != null) {
+ saveConsentResultInfo();
+ }
}
}
diff --git a/skin/src/main/java/org/researchstack/skin/ui/SplashActivity.java b/skin/src/main/java/org/researchstack/skin/ui/SplashActivity.java
index 9098f1bbe..94cdc8b6e 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/SplashActivity.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/SplashActivity.java
@@ -3,9 +3,9 @@
import android.content.Intent;
import android.os.Bundle;
-import org.researchstack.backbone.StorageAccess;
import org.researchstack.backbone.ui.PinCodeActivity;
import org.researchstack.backbone.utils.ObservableUtils;
+import org.researchstack.feature.storage.StorageAccess;
import org.researchstack.skin.AppPrefs;
import org.researchstack.skin.DataProvider;
import org.researchstack.skin.notification.TaskAlertReceiver;
diff --git a/skin/src/main/java/org/researchstack/skin/ui/adapter/MainPagerAdapter.java b/skin/src/main/java/org/researchstack/skin/ui/adapter/MainPagerAdapter.java
index 852cfc026..11e1e5481 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/adapter/MainPagerAdapter.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/adapter/MainPagerAdapter.java
@@ -1,10 +1,10 @@
package org.researchstack.skin.ui.adapter;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentPagerAdapter;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentPagerAdapter;
-import org.researchstack.backbone.utils.ViewUtils;
+import org.researchstack.foundation.components.utils.ViewUtils;
import org.researchstack.skin.ActionItem;
import java.util.List;
diff --git a/skin/src/main/java/org/researchstack/skin/ui/adapter/OnboardingPagerAdapter.java b/skin/src/main/java/org/researchstack/skin/ui/adapter/OnboardingPagerAdapter.java
index e877604d0..7ea337053 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/adapter/OnboardingPagerAdapter.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/adapter/OnboardingPagerAdapter.java
@@ -2,16 +2,16 @@
import android.content.Context;
import android.content.Intent;
-import android.support.v4.view.PagerAdapter;
+import androidx.viewpager.widget.PagerAdapter;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
-import org.researchstack.backbone.ui.ViewVideoActivity;
-import org.researchstack.backbone.ui.views.LocalWebView;
-import org.researchstack.backbone.utils.TextUtils;
+import org.researchstack.foundation.components.utils.TextUtils;
+import org.researchstack.foundation.components.web.ui.activities.ViewVideoActivity;
+import org.researchstack.foundation.components.web.ui.views.LocalWebView;
import org.researchstack.skin.R;
import org.researchstack.skin.ResourceManager;
import org.researchstack.skin.model.StudyOverviewModel;
diff --git a/skin/src/main/java/org/researchstack/skin/ui/fragment/ActivitiesFragment.java b/skin/src/main/java/org/researchstack/skin/ui/fragment/ActivitiesFragment.java
index 1732c9ad1..cd36cc1d6 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/fragment/ActivitiesFragment.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/fragment/ActivitiesFragment.java
@@ -5,12 +5,12 @@
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
-import android.support.v4.graphics.drawable.DrawableCompat;
-import android.support.v7.widget.AppCompatTextView;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.core.graphics.drawable.DrawableCompat;
+import androidx.appcompat.widget.AppCompatTextView;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
@@ -18,13 +18,13 @@
import android.widget.ImageView;
import android.widget.Toast;
-import org.researchstack.backbone.StorageAccess;
-import org.researchstack.backbone.result.TaskResult;
-import org.researchstack.backbone.storage.file.StorageAccessListener;
-import org.researchstack.backbone.task.Task;
import org.researchstack.backbone.ui.ViewTaskActivity;
-import org.researchstack.backbone.utils.LogExt;
import org.researchstack.backbone.utils.ObservableUtils;
+import org.researchstack.feature.storage.StorageAccess;
+import org.researchstack.feature.storage.file.StorageAccessListener;
+import org.researchstack.foundation.components.utils.LogExt;
+import org.researchstack.foundation.core.models.result.TaskResult;
+import org.researchstack.foundation.core.models.task.Task;
import org.researchstack.skin.DataProvider;
import org.researchstack.skin.R;
import org.researchstack.skin.model.SchedulesAndTasksModel;
diff --git a/skin/src/main/java/org/researchstack/skin/ui/fragment/LearnFragment.java b/skin/src/main/java/org/researchstack/skin/ui/fragment/LearnFragment.java
index 0e78c7d5b..e12bc3f5c 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/fragment/LearnFragment.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/fragment/LearnFragment.java
@@ -3,17 +3,17 @@
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
-import android.support.v7.widget.AppCompatTextView;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.appcompat.widget.AppCompatTextView;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
-import org.researchstack.backbone.ui.ViewWebDocumentActivity;
+import org.researchstack.foundation.components.web.ui.activities.ViewWebDocumentActivity;
import org.researchstack.skin.R;
import org.researchstack.skin.ResourceManager;
import org.researchstack.skin.model.SectionModel;
@@ -63,7 +63,7 @@ public LearnAdapter(Context context, SectionModel sections) {
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_HEADER) {
- View view = inflater.inflate(R.layout.preference_category_material, parent, false);
+ View view = inflater.inflate(R.layout.rss_item_section_learn, parent, false);
return new HeaderViewHolder(view);
} else {
View view = inflater.inflate(R.layout.rss_item_row_learn, parent, false);
@@ -114,7 +114,7 @@ public static class HeaderViewHolder extends RecyclerView.ViewHolder {
public HeaderViewHolder(View itemView) {
super(itemView);
- title = (TextView) itemView;
+ title = (AppCompatTextView) itemView.findViewById(R.id.learn_item_title);
}
}
diff --git a/skin/src/main/java/org/researchstack/skin/ui/fragment/SettingsFragment.java b/skin/src/main/java/org/researchstack/skin/ui/fragment/SettingsFragment.java
index 2ee0e0482..4cbddce0c 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/fragment/SettingsFragment.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/fragment/SettingsFragment.java
@@ -6,41 +6,41 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
-import android.support.v7.app.AlertDialog;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceCategory;
-import android.support.v7.preference.PreferenceFragmentCompat;
-import android.support.v7.preference.PreferenceScreen;
+import androidx.appcompat.app.AlertDialog;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceFragmentCompat;
+import androidx.preference.PreferenceScreen;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.Toast;
-import org.researchstack.backbone.StorageAccess;
-import org.researchstack.backbone.answerformat.AnswerFormat;
-import org.researchstack.backbone.answerformat.ChoiceAnswerFormat;
-import org.researchstack.backbone.model.Choice;
-import org.researchstack.backbone.result.TaskResult;
-import org.researchstack.backbone.step.ConsentSharingStep;
-import org.researchstack.backbone.storage.file.StorageAccessListener;
-import org.researchstack.backbone.task.OrderedTask;
-import org.researchstack.backbone.task.Task;
import org.researchstack.backbone.ui.ViewTaskActivity;
-import org.researchstack.backbone.ui.ViewWebDocumentActivity;
-import org.researchstack.backbone.utils.FormatHelper;
-import org.researchstack.backbone.utils.LogExt;
import org.researchstack.backbone.utils.ObservableUtils;
+import org.researchstack.feature.authentication.pincode.step.PassCodeCreationStep;
+import org.researchstack.feature.authentication.pincode.ui.SignUpPinCodeCreationStepLayout;
+import org.researchstack.feature.consent.step.ConsentSharingStep;
+import org.researchstack.feature.storage.StorageAccess;
+import org.researchstack.feature.storage.file.StorageAccessListener;
+import org.researchstack.foundation.components.common.task.OrderedTask;
+import org.researchstack.foundation.components.survey.answerformat.AnswerFormat;
+import org.researchstack.foundation.components.survey.answerformat.ChoiceAnswerFormat;
+import org.researchstack.foundation.components.survey.model.Choice;
+import org.researchstack.foundation.components.utils.FormatHelper;
+import org.researchstack.foundation.components.utils.LogExt;
+import org.researchstack.foundation.components.web.ui.activities.ViewWebDocumentActivity;
+import org.researchstack.foundation.core.models.result.TaskResult;
+import org.researchstack.foundation.core.models.task.Task;
import org.researchstack.skin.AppPrefs;
import org.researchstack.skin.DataProvider;
import org.researchstack.skin.R;
import org.researchstack.skin.ResourceManager;
import org.researchstack.skin.model.ConsentSectionModel;
import org.researchstack.skin.notification.TaskAlertReceiver;
-import org.researchstack.skin.step.PassCodeCreationStep;
import org.researchstack.skin.task.ConsentTask;
import org.researchstack.skin.ui.OnboardingActivity;
-import org.researchstack.skin.ui.layout.SignUpPinCodeCreationStepLayout;
import org.researchstack.skin.utils.ConsentFormUtils;
import java.text.DateFormat;
@@ -203,7 +203,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
ViewGroup v = (ViewGroup) super.onCreateView(inflater, container, savedInstanceState);
settingsRoot.addView(v);
- progress = inflater.inflate(R.layout.rsb_progress, container, false);
+ progress = inflater.inflate(R.layout.rsf_progress, container, false);
progress.setVisibility(View.GONE);
settingsRoot.addView(progress);
@@ -251,13 +251,13 @@ public boolean onPreferenceTreeClick(Preference preference) {
sharingStep.setOptional(false);
sharingStep.setStepTitle(R.string.rss_settings_privacy_sharing_options);
- String shareWidely = getString(R.string.rsb_consent_share_widely,
+ String shareWidely = getString(R.string.rsfc_consent_share_widely,
investigatorLongDesc);
Choice shareWidelyChoice = new Choice<>(shareWidely,
"sponsors_and_partners",
null);
- String shareRestricted = getString(R.string.rsb_consent_share_only,
+ String shareRestricted = getString(R.string.rsfc_consent_share_only,
investigatorShortDesc);
Choice shareRestrictedChoice = new Choice<>(shareRestricted,
"all_qualified_researchers",
@@ -267,8 +267,8 @@ public boolean onPreferenceTreeClick(Preference preference) {
shareWidelyChoice,
shareRestrictedChoice));
- sharingStep.setTitle(getString(R.string.rsb_consent_share_title));
- sharingStep.setText(getString(R.string.rsb_consent_share_description,
+ sharingStep.setTitle(getString(R.string.rsfc_consent_share_title));
+ sharingStep.setText(getString(R.string.rsfc_consent_share_description,
investigatorLongDesc,
localizedLearnMoreHTMLContent));
@@ -308,7 +308,7 @@ public boolean onPreferenceTreeClick(Preference preference) {
progress.setVisibility(View.GONE);
});
})
- .setNegativeButton(R.string.rsb_cancel, null)
+ .setNegativeButton(R.string.rsf_cancel, null)
.show();
return true;
@@ -387,14 +387,14 @@ public String formatSharingOption(String option) {
String investigatorLongDesc = data.getDocumentProperties()
.getInvestigatorLongDescription();
- return getString(R.string.rsb_consent_share_widely, investigatorLongDesc);
+ return getString(R.string.rsfc_consent_share_widely, investigatorLongDesc);
} else if (option.equals("all_qualified_researchers")) {
String investigatorShortDesc = data.getDocumentProperties()
.getInvestigatorShortDescription();
- return getString(R.string.rsb_consent_share_only, investigatorShortDesc);
+ return getString(R.string.rsfc_consent_share_only, investigatorShortDesc);
} else if (option.equals("no_sharing")) {
- return getString(R.string.rsb_consent_share_no);
+ return getString(R.string.rsfc_consent_share_no);
} else {
// If you want to add another sharing option, feel free, you just need to override this
// method in your SettingsFragment
diff --git a/skin/src/main/java/org/researchstack/skin/ui/layout/ConsentQuizEvaluationStepLayout.java b/skin/src/main/java/org/researchstack/skin/ui/layout/ConsentQuizEvaluationStepLayout.java
index f101095b4..b3348dee9 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/layout/ConsentQuizEvaluationStepLayout.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/layout/ConsentQuizEvaluationStepLayout.java
@@ -6,13 +6,13 @@
import android.widget.ImageView;
import android.widget.TextView;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.ui.callbacks.StepCallbacks;
-import org.researchstack.backbone.ui.step.layout.StepLayout;
-import org.researchstack.backbone.ui.views.FixedSubmitBarLayout;
-import org.researchstack.backbone.ui.views.SubmitBar;
-import org.researchstack.backbone.utils.ResUtils;
+import org.researchstack.foundation.components.common.ui.callbacks.StepCallbacks;
+import org.researchstack.foundation.components.common.ui.layout.FixedSubmitBarLayout;
+import org.researchstack.foundation.components.common.ui.layout.StepLayout;
+import org.researchstack.foundation.components.common.ui.views.SubmitBar;
+import org.researchstack.foundation.components.utils.ResUtils;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
import org.researchstack.skin.R;
import org.researchstack.skin.step.ConsentQuizEvaluationStep;
@@ -52,7 +52,7 @@ private void initializeStep() {
TextView title = (TextView) findViewById(R.id.rss_quiz_eval_title);
TextView summary = (TextView) findViewById(R.id.rss_quiz_eval_summary);
- SubmitBar submitBar = (SubmitBar) findViewById(R.id.rsb_submit_bar);
+ SubmitBar submitBar = (SubmitBar) findViewById(R.id.rsf_submit_bar);
submitBar.getNegativeActionView().setVisibility(View.GONE);
submitBar.setPositiveAction(v -> callbacks.onSaveStep(StepCallbacks.ACTION_NEXT,
step,
@@ -64,14 +64,14 @@ private void initializeStep() {
step.getQuizModel().getIncorrectIcon());
image.setImageResource(iconResId);
- title.setText(R.string.rsb_quiz_evaluation_try_again);
+ title.setText(R.string.rsfc_quiz_evaluation_try_again);
if (!step.isOverMaxAttempts()) {
summary.setText(step.getQuizModel().getFailureMessage());
- submitBar.setPositiveTitle(R.string.rsb_quiz_evaluation_retake);
+ submitBar.setPositiveTitle(R.string.rsfc_quiz_evaluation_retake);
} else {
summary.setText(step.getQuizModel().getFailureMessage());
- submitBar.setPositiveTitle(R.string.rsb_quiz_evaluation_review_consent);
+ submitBar.setPositiveTitle(R.string.rsfc_quiz_evaluation_review_consent);
}
}
@@ -81,7 +81,7 @@ private void initializeStep() {
step.getQuizModel().getCorrectIcon());
image.setImageResource(iconResId);
- title.setText(R.string.rsb_quiz_evaluation_great_job);
+ title.setText(R.string.rsfc_quiz_evaluation_great_job);
if (step.getIncorrect() == 0) {
summary.setText(step.getQuizModel().getSuccessMessage());
@@ -89,7 +89,7 @@ private void initializeStep() {
summary.setText(step.getQuizModel().getSuccessMessage());
}
- submitBar.setPositiveTitle(R.string.rsb_next);
+ submitBar.setPositiveTitle(R.string.rsf_next);
}
}
diff --git a/skin/src/main/java/org/researchstack/skin/ui/layout/ConsentQuizQuestionStepLayout.java b/skin/src/main/java/org/researchstack/skin/ui/layout/ConsentQuizQuestionStepLayout.java
index 48d3831b0..7e9fa0bd0 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/layout/ConsentQuizQuestionStepLayout.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/layout/ConsentQuizQuestionStepLayout.java
@@ -3,10 +3,10 @@
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
-import android.support.annotation.NonNull;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.graphics.drawable.DrawableCompat;
-import android.support.v7.widget.AppCompatRadioButton;
+import androidx.annotation.NonNull;
+import androidx.core.content.ContextCompat;
+import androidx.core.graphics.drawable.DrawableCompat;
+import androidx.appcompat.widget.AppCompatRadioButton;
import android.text.Html;
import android.util.AttributeSet;
import android.view.LayoutInflater;
@@ -18,12 +18,12 @@
import android.widget.TextView;
import android.widget.Toast;
-import org.researchstack.backbone.model.Choice;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.ui.callbacks.StepCallbacks;
-import org.researchstack.backbone.ui.step.layout.StepLayout;
-import org.researchstack.backbone.ui.views.SubmitBar;
+import org.researchstack.foundation.components.common.ui.callbacks.StepCallbacks;
+import org.researchstack.foundation.components.common.ui.layout.StepLayout;
+import org.researchstack.foundation.components.common.ui.views.SubmitBar;
+import org.researchstack.foundation.components.survey.model.Choice;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
import org.researchstack.skin.R;
import org.researchstack.skin.model.ConsentQuizModel;
import org.researchstack.skin.step.ConsentQuizQuestionStep;
@@ -88,10 +88,10 @@ public void initializeStep() {
instructionText.setVisibility(VISIBLE);
// instruction steps don't need submit, also always count as correct answer
- submitBar.setPositiveTitle(R.string.rsb_next);
+ submitBar.setPositiveTitle(R.string.rsf_next);
submitBar.setPositiveAction(v -> onNext(true));
} else {
- submitBar.setPositiveTitle(R.string.rsb_submit);
+ submitBar.setPositiveTitle(R.string.rsf_submit);
submitBar.setPositiveAction(v -> onSubmit());
for (Choice choice : getChoices(question)) {
@@ -148,7 +148,7 @@ public void onSubmit() {
}
// Set the drawable of the current checked button, with correct color tint
- int resId = answerCorrect ? R.drawable.rsb_ic_check : R.drawable.rsb_ic_x;
+ int resId = answerCorrect ? R.drawable.rsf_ic_check : R.drawable.rsf_ic_x;
Drawable drawable = ContextCompat.getDrawable(getContext(), resId);
drawable = DrawableCompat.wrap(drawable);
DrawableCompat.setTint(drawable, resultTextColor);
@@ -211,7 +211,7 @@ private void onNext(boolean answerCorrect) {
private void setSubmitBarNext() {
// Change the submit bar positive-title to "next"
- submitBar.setPositiveTitle(R.string.rsb_next);
+ submitBar.setPositiveTitle(R.string.rsf_next);
}
public boolean isAnswerValid() {
diff --git a/skin/src/main/java/org/researchstack/skin/ui/layout/PermissionStepLayout.java b/skin/src/main/java/org/researchstack/skin/ui/layout/PermissionStepLayout.java
index 5a50e09ab..673f9cc8c 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/layout/PermissionStepLayout.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/layout/PermissionStepLayout.java
@@ -2,8 +2,8 @@
import android.content.Context;
import android.graphics.drawable.Drawable;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.graphics.drawable.DrawableCompat;
+import androidx.core.content.ContextCompat;
+import androidx.core.graphics.drawable.DrawableCompat;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -14,14 +14,14 @@
import com.jakewharton.rxbinding.view.RxView;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.Step;
import org.researchstack.backbone.ui.callbacks.ActivityCallback;
-import org.researchstack.backbone.ui.callbacks.StepCallbacks;
-import org.researchstack.backbone.ui.step.layout.StepLayout;
import org.researchstack.backbone.ui.step.layout.StepPermissionRequest;
-import org.researchstack.backbone.ui.views.SubmitBar;
-import org.researchstack.backbone.utils.ThemeUtils;
+import org.researchstack.foundation.components.common.ui.callbacks.StepCallbacks;
+import org.researchstack.foundation.components.common.ui.layout.StepLayout;
+import org.researchstack.foundation.components.common.ui.views.SubmitBar;
+import org.researchstack.foundation.components.utils.ThemeUtils;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
import org.researchstack.skin.PermissionRequestManager;
import org.researchstack.skin.R;
@@ -122,7 +122,7 @@ public void initializeStep() {
// Set submit bar behavior
submitBar = (SubmitBar) findViewById(R.id.submit_bar);
- submitBar.setPositiveTitle(R.string.rsb_next);
+ submitBar.setPositiveTitle(R.string.rsf_next);
submitBar.setPositiveAction(v -> {
if (isAnswerValid()) {
onNext(true);
diff --git a/skin/src/main/java/org/researchstack/skin/ui/layout/SignInStepLayout.java b/skin/src/main/java/org/researchstack/skin/ui/layout/SignInStepLayout.java
index d76dcae2d..21565c86d 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/layout/SignInStepLayout.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/layout/SignInStepLayout.java
@@ -1,7 +1,7 @@
package org.researchstack.skin.ui.layout;
import android.content.Context;
-import android.support.v7.widget.AppCompatEditText;
+import androidx.appcompat.widget.AppCompatEditText;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -13,13 +13,13 @@
import com.jakewharton.rxbinding.view.RxView;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.ui.callbacks.StepCallbacks;
-import org.researchstack.backbone.ui.step.layout.StepLayout;
-import org.researchstack.backbone.ui.views.SubmitBar;
import org.researchstack.backbone.utils.ObservableUtils;
-import org.researchstack.backbone.utils.TextUtils;
+import org.researchstack.foundation.components.common.ui.callbacks.StepCallbacks;
+import org.researchstack.foundation.components.common.ui.layout.StepLayout;
+import org.researchstack.foundation.components.common.ui.views.SubmitBar;
+import org.researchstack.foundation.components.utils.TextUtils;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
import org.researchstack.skin.DataProvider;
import org.researchstack.skin.R;
import org.researchstack.skin.task.SignInTask;
diff --git a/skin/src/main/java/org/researchstack/skin/ui/layout/SignUpEligibleStepLayout.java b/skin/src/main/java/org/researchstack/skin/ui/layout/SignUpEligibleStepLayout.java
index 80dd361df..1a5bd70c6 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/layout/SignUpEligibleStepLayout.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/layout/SignUpEligibleStepLayout.java
@@ -6,12 +6,12 @@
import android.view.View;
import android.widget.RelativeLayout;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.Step;
import org.researchstack.backbone.ui.callbacks.ActivityCallback;
-import org.researchstack.backbone.ui.callbacks.StepCallbacks;
-import org.researchstack.backbone.ui.step.layout.StepLayout;
-import org.researchstack.backbone.ui.views.SubmitBar;
+import org.researchstack.foundation.components.common.ui.callbacks.StepCallbacks;
+import org.researchstack.foundation.components.common.ui.layout.StepLayout;
+import org.researchstack.foundation.components.common.ui.views.SubmitBar;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
import org.researchstack.skin.R;
public class SignUpEligibleStepLayout extends RelativeLayout implements StepLayout {
diff --git a/skin/src/main/java/org/researchstack/skin/ui/layout/SignUpIneligibleStepLayout.java b/skin/src/main/java/org/researchstack/skin/ui/layout/SignUpIneligibleStepLayout.java
index 0abb6bc18..0de3a462d 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/layout/SignUpIneligibleStepLayout.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/layout/SignUpIneligibleStepLayout.java
@@ -6,10 +6,10 @@
import android.view.View;
import android.widget.LinearLayout;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.ui.callbacks.StepCallbacks;
-import org.researchstack.backbone.ui.step.layout.StepLayout;
+import org.researchstack.foundation.components.common.ui.callbacks.StepCallbacks;
+import org.researchstack.foundation.components.common.ui.layout.StepLayout;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
import org.researchstack.skin.R;
public class SignUpIneligibleStepLayout extends LinearLayout implements StepLayout {
diff --git a/skin/src/main/java/org/researchstack/skin/ui/layout/SignUpStepLayout.java b/skin/src/main/java/org/researchstack/skin/ui/layout/SignUpStepLayout.java
index b2e23c00a..cc217bc71 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/layout/SignUpStepLayout.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/layout/SignUpStepLayout.java
@@ -1,7 +1,7 @@
package org.researchstack.skin.ui.layout;
import android.content.Context;
-import android.support.v7.widget.AppCompatEditText;
+import androidx.appcompat.widget.AppCompatEditText;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -10,13 +10,13 @@
import android.widget.RelativeLayout;
import android.widget.Toast;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.ui.callbacks.StepCallbacks;
-import org.researchstack.backbone.ui.step.layout.StepLayout;
-import org.researchstack.backbone.ui.views.SubmitBar;
import org.researchstack.backbone.utils.ObservableUtils;
-import org.researchstack.backbone.utils.TextUtils;
+import org.researchstack.foundation.components.common.ui.callbacks.StepCallbacks;
+import org.researchstack.foundation.components.common.ui.layout.StepLayout;
+import org.researchstack.foundation.components.common.ui.views.SubmitBar;
+import org.researchstack.foundation.components.utils.TextUtils;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
import org.researchstack.skin.DataProvider;
import org.researchstack.skin.R;
import org.researchstack.skin.task.SignUpTask;
diff --git a/skin/src/main/java/org/researchstack/skin/ui/preference/TextColorPreference.java b/skin/src/main/java/org/researchstack/skin/ui/preference/TextColorPreference.java
index 8f92609f1..d4be03ab6 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/preference/TextColorPreference.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/preference/TextColorPreference.java
@@ -3,8 +3,8 @@
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceViewHolder;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
import android.util.AttributeSet;
import android.widget.TextView;
diff --git a/skin/src/main/java/org/researchstack/skin/ui/views/DividerItemDecoration.java b/skin/src/main/java/org/researchstack/skin/ui/views/DividerItemDecoration.java
index 63afc476f..3b88bd93b 100644
--- a/skin/src/main/java/org/researchstack/skin/ui/views/DividerItemDecoration.java
+++ b/skin/src/main/java/org/researchstack/skin/ui/views/DividerItemDecoration.java
@@ -21,9 +21,9 @@
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.support.v4.view.ViewCompat;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
+import androidx.core.view.ViewCompat;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
diff --git a/skin/src/main/java/org/researchstack/skin/utils/ConsentFormUtils.java b/skin/src/main/java/org/researchstack/skin/utils/ConsentFormUtils.java
index b35056223..c5b6d6a71 100644
--- a/skin/src/main/java/org/researchstack/skin/utils/ConsentFormUtils.java
+++ b/skin/src/main/java/org/researchstack/skin/utils/ConsentFormUtils.java
@@ -4,12 +4,12 @@
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
-import org.researchstack.backbone.ui.ViewWebDocumentActivity;
-import org.researchstack.backbone.utils.LogExt;
import org.researchstack.backbone.utils.ObservableUtils;
-import org.researchstack.backbone.utils.ResUtils;
+import org.researchstack.foundation.components.utils.LogExt;
+import org.researchstack.foundation.components.utils.ResUtils;
+import org.researchstack.foundation.components.web.ui.activities.ViewWebDocumentActivity;
import org.researchstack.skin.R;
import org.researchstack.skin.ResourceManager;
@@ -27,7 +27,7 @@ private ConsentFormUtils() {
public static void viewConsentForm(Context context) {
String path = ResourceManager.getInstance().getConsentHtml().getAbsolutePath();
- String title = context.getString(R.string.rsb_consent);
+ String title = context.getString(R.string.rsfc_consent);
Intent intent = ViewWebDocumentActivity.newIntentForPath(context, title, path);
context.startActivity(intent);
}
diff --git a/skin/src/main/res/drawable/rss_ic_circle_16dp.xml b/skin/src/main/res/drawable/rss_ic_circle_16dp.xml
index 5120fea77..c160d9398 100644
--- a/skin/src/main/res/drawable/rss_ic_circle_16dp.xml
+++ b/skin/src/main/res/drawable/rss_ic_circle_16dp.xml
@@ -6,6 +6,6 @@
android:width="16dp"
android:height="16dp" />
-
+
\ No newline at end of file
diff --git a/skin/src/main/res/drawable/rss_text_color_accent.xml b/skin/src/main/res/drawable/rss_text_color_accent.xml
index b9647e761..ffb387b7c 100644
--- a/skin/src/main/res/drawable/rss_text_color_accent.xml
+++ b/skin/src/main/res/drawable/rss_text_color_accent.xml
@@ -1,6 +1,6 @@
-
-
+
+
\ No newline at end of file
diff --git a/skin/src/main/res/layout-v16/rss_item_row_learn.xml b/skin/src/main/res/layout-v16/rss_item_row_learn.xml
index cceb649f1..05d674717 100644
--- a/skin/src/main/res/layout-v16/rss_item_row_learn.xml
+++ b/skin/src/main/res/layout-v16/rss_item_row_learn.xml
@@ -1,5 +1,5 @@
-
-
-
diff --git a/skin/src/main/res/layout/rss_activity_email_verification.xml b/skin/src/main/res/layout/rss_activity_email_verification.xml
index 7df7401e5..32def5430 100644
--- a/skin/src/main/res/layout/rss_activity_email_verification.xml
+++ b/skin/src/main/res/layout/rss_activity_email_verification.xml
@@ -5,40 +5,40 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
+
-
-
-
@@ -114,7 +114,7 @@
android:layout_height="1dp"
android:layout_marginBottom="12dp"
android:layout_marginTop="12dp"
- android:background="@color/rsb_black"
+ android:background="@color/rsf_black"
/>
@@ -136,10 +136,10 @@
-->
\ No newline at end of file
diff --git a/skin/src/main/res/layout/rss_activity_fragment.xml b/skin/src/main/res/layout/rss_activity_fragment.xml
index 6e2f6f6d4..892998af6 100644
--- a/skin/src/main/res/layout/rss_activity_fragment.xml
+++ b/skin/src/main/res/layout/rss_activity_fragment.xml
@@ -4,7 +4,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
-
+
-
+ android:background="@color/rsf_submit_bar_gray" />
-
-
-
-
+
-
-
-
-
diff --git a/skin/src/main/res/layout/rss_fragment_activities.xml b/skin/src/main/res/layout/rss_fragment_activities.xml
index c9609588b..31e00c4db 100644
--- a/skin/src/main/res/layout/rss_fragment_activities.xml
+++ b/skin/src/main/res/layout/rss_fragment_activities.xml
@@ -1,5 +1,5 @@
-
-
-
-
-
-
@@ -48,7 +48,7 @@
-
-
\ No newline at end of file
diff --git a/skin/src/main/res/layout/rss_item_permission_card.xml b/skin/src/main/res/layout/rss_item_permission_card.xml
index 6b3a111c0..cc578ae9a 100644
--- a/skin/src/main/res/layout/rss_item_permission_card.xml
+++ b/skin/src/main/res/layout/rss_item_permission_card.xml
@@ -1,9 +1,9 @@
-
-
+
diff --git a/skin/src/main/res/layout/rss_item_permission_content.xml b/skin/src/main/res/layout/rss_item_permission_content.xml
index eed09e395..236b06bf4 100644
--- a/skin/src/main/res/layout/rss_item_permission_content.xml
+++ b/skin/src/main/res/layout/rss_item_permission_content.xml
@@ -4,7 +4,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
-
-
-
-
-
diff --git a/skin/src/main/res/layout/rss_item_row_learn.xml b/skin/src/main/res/layout/rss_item_row_learn.xml
index 37e6bb521..cb5ca1ed2 100644
--- a/skin/src/main/res/layout/rss_item_row_learn.xml
+++ b/skin/src/main/res/layout/rss_item_row_learn.xml
@@ -1,5 +1,5 @@
-
-
-
\ No newline at end of file
diff --git a/skin/src/main/res/layout/rss_item_section_learn.xml b/skin/src/main/res/layout/rss_item_section_learn.xml
new file mode 100644
index 000000000..c3dd63eed
--- /dev/null
+++ b/skin/src/main/res/layout/rss_item_section_learn.xml
@@ -0,0 +1,16 @@
+
+
\ No newline at end of file
diff --git a/skin/src/main/res/layout/rss_layout_consent_evaluation.xml b/skin/src/main/res/layout/rss_layout_consent_evaluation.xml
index f37baf4ba..32cc6b59a 100644
--- a/skin/src/main/res/layout/rss_layout_consent_evaluation.xml
+++ b/skin/src/main/res/layout/rss_layout_consent_evaluation.xml
@@ -10,15 +10,15 @@
android:layout_height="180dp"
android:layout_centerHorizontal="true"
android:scaleType="center"
- tools:src="@drawable/rsb_debug_gray" />
+ tools:src="@drawable/rsf_debug_gray" />
diff --git a/skin/src/main/res/layout/rss_layout_eligible.xml b/skin/src/main/res/layout/rss_layout_eligible.xml
index 0e85ebbaf..5914f2424 100644
--- a/skin/src/main/res/layout/rss_layout_eligible.xml
+++ b/skin/src/main/res/layout/rss_layout_eligible.xml
@@ -26,7 +26,7 @@
android:layout_marginTop="24dp"
android:text="@string/rss_eligibility_tap_below" />
-
@@ -34,11 +34,11 @@
-
+ app:negativeActionTitle="@string/rsf_exit"
+ app:positiveActionTitle="@string/rsf_submit" />
\ No newline at end of file
diff --git a/skin/src/main/res/layout/rss_layout_quiz_question.xml b/skin/src/main/res/layout/rss_layout_quiz_question.xml
index 777e6649f..cdb8648b3 100644
--- a/skin/src/main/res/layout/rss_layout_quiz_question.xml
+++ b/skin/src/main/res/layout/rss_layout_quiz_question.xml
@@ -12,7 +12,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
- android:paddingBottom="@dimen/rsb_padding_wedge"
+ android:paddingBottom="@dimen/rsf_padding_wedge"
android:text="@string/rss_quiz_question_disclamer"
android:visibility="visible" />
@@ -38,8 +38,8 @@
style="@style/Backbone.Survey.Title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingBottom="@dimen/rsb_padding_wedge"
- android:paddingTop="@dimen/rsb_padding_wedge"
+ android:paddingBottom="@dimen/rsf_padding_wedge"
+ android:paddingTop="@dimen/rsf_padding_wedge"
tools:text="@string/lorem_short" />
@@ -59,7 +59,7 @@
android:layout_height="wrap_content"
android:layout_alignTop="@+id/radio_group"
android:background="@android:color/holo_red_light"
- android:minHeight="@dimen/rsb_item_size_default"
+ android:minHeight="@dimen/rsf_item_size_default"
android:visibility="gone" />
@@ -88,8 +88,8 @@
android:layout_height="wrap_content"
android:layout_below="@+id/quiz_result_title"
android:layout_marginTop="0dp"
- android:paddingBottom="@dimen/rsb_padding_medium"
- android:paddingTop="@dimen/rsb_padding_small"
+ android:paddingBottom="@dimen/rsf_padding_medium"
+ android:paddingTop="@dimen/rsf_padding_small"
android:text="@string/lorem_long"
android:visibility="gone"
tools:visibility="visible" />
@@ -98,12 +98,12 @@
-
diff --git a/skin/src/main/res/layout/rss_layout_sign_in.xml b/skin/src/main/res/layout/rss_layout_sign_in.xml
index 411a18c50..cdcb48499 100644
--- a/skin/src/main/res/layout/rss_layout_sign_in.xml
+++ b/skin/src/main/res/layout/rss_layout_sign_in.xml
@@ -19,24 +19,24 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/title"
- android:layout_marginLeft="@dimen/rsb_margin_left"
- android:layout_marginRight="@dimen/rsb_margin_right"
- android:layout_marginTop="@dimen/rsb_padding_wedge"
+ android:layout_marginLeft="@dimen/rsf_margin_left"
+ android:layout_marginRight="@dimen/rsf_margin_right"
+ android:layout_marginTop="@dimen/rsf_padding_wedge"
android:stretchColumns="1">
+ android:minHeight="@dimen/rsf_item_size_default">
-
-
+ android:minHeight="@dimen/rsf_item_size_default">
-
-
-
+ app:negativeActionTitle="@string/rsf_exit"
+ app:positiveActionTitle="@string/rsf_submit" />
-
+ android:textColor="@color/rsf_submit_bar_negative" />
diff --git a/skin/src/main/res/layout/rss_layout_sign_up.xml b/skin/src/main/res/layout/rss_layout_sign_up.xml
index 99dfdc745..0d8bcb033 100644
--- a/skin/src/main/res/layout/rss_layout_sign_up.xml
+++ b/skin/src/main/res/layout/rss_layout_sign_up.xml
@@ -30,23 +30,23 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/text"
- android:layout_marginLeft="@dimen/rsb_margin_left"
- android:layout_marginRight="@dimen/rsb_margin_right"
+ android:layout_marginLeft="@dimen/rsf_margin_left"
+ android:layout_marginRight="@dimen/rsf_margin_right"
android:stretchColumns="1">
+ android:minHeight="@dimen/rsf_item_size_default">
-
+ android:text="@string/rsf_email" />
-
+ android:minHeight="@dimen/rsf_item_size_default">
-
-
-
+ app:negativeActionTitle="@string/rsf_exit"
+ app:positiveActionTitle="@string/rsf_submit" />
diff --git a/skin/src/main/res/layout/rss_layout_toolbar_tabs.xml b/skin/src/main/res/layout/rss_layout_toolbar_tabs.xml
index c8a83b5dc..9c05019b8 100644
--- a/skin/src/main/res/layout/rss_layout_toolbar_tabs.xml
+++ b/skin/src/main/res/layout/rss_layout_toolbar_tabs.xml
@@ -6,13 +6,13 @@
android:foreground="?android:attr/windowContentOverlay"
android:orientation="vertical">
-
-
diff --git a/skin/src/main/res/values/strings.xml b/skin/src/main/res/values/strings.xml
index d413d21b5..b1a1b6465 100644
--- a/skin/src/main/res/values/strings.xml
+++ b/skin/src/main/res/values/strings.xml
@@ -113,7 +113,7 @@
Software Notices
Leave Study
Join Study
- Build number %1$s (%2$s)
+ Build number %1$s (%2$d)
Unknown version
Are you sure you want to leave the study? This
action cannot be undone and you will need to provide consent in order to re-enroll.
diff --git a/skin/src/main/res/xml/rss_settings.xml b/skin/src/main/res/xml/rss_settings.xml
index 6f4dc5fce..e679e6700 100644
--- a/skin/src/main/res/xml/rss_settings.xml
+++ b/skin/src/main/res/xml/rss_settings.xml
@@ -88,7 +88,7 @@
android:key="rss_settings_general_leave_study"
android:order="2"
android:title="@string/rss_settings_general_leave_study"
- app:preferenceTextColor="@color/rsb_error" />
+ app:preferenceTextColor="@color/rsf_error" />
diff --git a/storage/.gitignore b/storage/.gitignore
new file mode 100644
index 000000000..796b96d1c
--- /dev/null
+++ b/storage/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/storage/build.gradle b/storage/build.gradle
new file mode 100644
index 000000000..5d5702de5
--- /dev/null
+++ b/storage/build.gradle
@@ -0,0 +1,172 @@
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+
+apply plugin: 'com.github.dcendents.android-maven'
+apply plugin: 'com.jfrog.bintray'
+
+apply plugin: 'kotlin-kapt'
+
+version = research_stack_version
+
+android {
+ compileSdkVersion 28
+ defaultConfig {
+ minSdkVersion 19
+ targetSdkVersion 28
+ versionCode 1
+ versionName version
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+ resourcePrefix 'rsfs_'
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+Properties properties = new Properties()
+properties.load(project.rootProject.file('local.properties').newDataInputStream())
+
+ext {
+ bintrayRepo = 'ResearchStack'
+ bintrayName = 'Storage'
+
+ publishedGroupId = 'org.researchstack'
+ libraryName = 'Storage'
+ artifact = 'storage'
+
+ libraryDescription = 'Storage'
+
+ siteUrl = 'https://researchstack.org'
+ gitUrl = 'https://github.com/ResearchStack/ResearchStack.git'
+
+ libraryVersion = version
+
+ userOrgName = 'researchstack'
+ developerId = properties.getProperty("bintray.user")
+ developerName = properties.getProperty("bintray.developerName")
+ developerEmail = properties.getProperty("bintray.developerEmail")
+
+ licenseName = 'The Apache Software License, Version 2.0'
+ licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ allLicenses = ["Apache-2.0"]
+}
+
+dependencies {
+ implementation fileTree(include: ['*.jar'], dir: 'libs')
+ implementation 'androidx.appcompat:appcompat:1.0.2'
+ implementation 'androidx.cardview:cardview:1.0.0'
+ implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
+ implementation 'com.google.android.material:material:1.0.0'
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+ implementation project(':foundation')
+ implementation project(':authentication')
+ implementation "com.google.code.gson:gson:$gson_version"
+ implementation 'com.scottyab:aes-crypto:0.0.3'
+ implementation 'co.touchlab.squeaky:squeaky-query:0.4.0.0'
+ kapt 'co.touchlab.squeaky:squeaky-processor:0.4.0.0'
+ implementation 'net.zetetic:android-database-sqlcipher:3.5.4@aar'
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'androidx.test:runner:1.1.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
+}
+
+group = publishedGroupId // Maven Group ID for the artifact
+
+install {
+ repositories.mavenInstaller {
+ // This generates POM.xml with proper parameters
+ pom {
+ project {
+ packaging 'aar'
+ groupId publishedGroupId
+ artifactId artifact
+
+ // Add your description here
+ name libraryName
+ description libraryDescription
+ url siteUrl
+
+ // Set your license
+ licenses {
+ license {
+ name licenseName
+ url licenseUrl
+ }
+ }
+ developers {
+ developer {
+ id developerId
+ name developerName
+ email developerEmail
+ }
+ }
+ scm {
+ connection gitUrl
+ developerConnection gitUrl
+ url siteUrl
+ }
+ }
+ }
+ }
+}
+
+if (project.hasProperty("android")) { // Android libraries
+ task sourcesJar(type: Jar) {
+ classifier = 'sources'
+ from android.sourceSets.main.java.srcDirs
+ }
+
+ task javadoc(type: Javadoc) {
+ failOnError false
+ source = android.sourceSets.main.java.srcDirs
+ }
+
+ afterEvaluate {
+ javadoc.classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
+ javadoc.classpath += files(android.libraryVariants.collect { variant ->
+ variant.javaCompile.classpath.files
+ })
+ }
+} else { // Java libraries
+ task sourcesJar(type: Jar, dependsOn: classes) {
+ classifier = 'sources'
+ from sourceSets.main.allSource
+ }
+}
+
+task javadocJar(type: Jar, dependsOn: javadoc) {
+ classifier = 'javadoc'
+ from javadoc.destinationDir
+}
+
+artifacts {
+ archives javadocJar
+ archives sourcesJar
+}
+
+bintray {
+ user = properties.getProperty("bintray.user")
+ key = properties.getProperty("bintray.apikey")
+
+ configurations = ['archives']
+ pkg {
+ repo = bintrayRepo
+ name = bintrayName
+ userOrg = userOrgName
+ desc = libraryDescription
+ websiteUrl = siteUrl
+ vcsUrl = gitUrl
+ licenses = allLicenses
+ publish = true
+ }
+}
\ No newline at end of file
diff --git a/storage/proguard-rules.pro b/storage/proguard-rules.pro
new file mode 100644
index 000000000..f1b424510
--- /dev/null
+++ b/storage/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/storage/src/androidTest/java/org/researchstack/feature/storage/ExampleInstrumentedTest.java b/storage/src/androidTest/java/org/researchstack/feature/storage/ExampleInstrumentedTest.java
new file mode 100644
index 000000000..c87c689af
--- /dev/null
+++ b/storage/src/androidTest/java/org/researchstack/feature/storage/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package org.researchstack.feature.storage;
+
+import android.content.Context;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("org.researchstack.feature.storage.test", appContext.getPackageName());
+ }
+}
diff --git a/storage/src/main/AndroidManifest.xml b/storage/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..b86a31c3e
--- /dev/null
+++ b/storage/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/NotificationHelper.java b/storage/src/main/java/org/researchstack/feature/storage/NotificationHelper.java
similarity index 93%
rename from backbone/src/main/java/org/researchstack/backbone/storage/NotificationHelper.java
rename to storage/src/main/java/org/researchstack/feature/storage/NotificationHelper.java
index f327ffa14..98b1af1f1 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/NotificationHelper.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/NotificationHelper.java
@@ -1,9 +1,9 @@
-package org.researchstack.backbone.storage;
+package org.researchstack.feature.storage;
import android.content.Context;
-import org.researchstack.backbone.storage.database.TaskNotification;
-import org.researchstack.backbone.utils.LogExt;
+import org.researchstack.foundation.components.utils.LogExt;
+import org.researchstack.feature.storage.database.TaskNotification;
import java.sql.SQLException;
import java.util.List;
diff --git a/backbone/src/main/java/org/researchstack/backbone/StorageAccess.java b/storage/src/main/java/org/researchstack/feature/storage/StorageAccess.java
similarity index 94%
rename from backbone/src/main/java/org/researchstack/backbone/StorageAccess.java
rename to storage/src/main/java/org/researchstack/feature/storage/StorageAccess.java
index a810e15c0..ec7e6e795 100644
--- a/backbone/src/main/java/org/researchstack/backbone/StorageAccess.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/StorageAccess.java
@@ -1,19 +1,18 @@
-package org.researchstack.backbone;
+package org.researchstack.feature.storage;
import android.app.Application;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
-import android.support.annotation.MainThread;
+import androidx.annotation.MainThread;
-import org.researchstack.backbone.storage.database.AppDatabase;
-import org.researchstack.backbone.storage.file.EncryptionProvider;
-import org.researchstack.backbone.storage.file.FileAccess;
-import org.researchstack.backbone.storage.file.PinCodeConfig;
-import org.researchstack.backbone.storage.file.StorageAccessException;
-import org.researchstack.backbone.storage.file.StorageAccessListener;
-import org.researchstack.backbone.ui.PinCodeActivity;
-import org.researchstack.backbone.utils.UiThreadContext;
+import org.researchstack.foundation.components.utils.UiThreadContext;
+import org.researchstack.feature.storage.database.AppDatabase;
+import org.researchstack.feature.storage.file.EncryptionProvider;
+import org.researchstack.feature.storage.file.FileAccess;
+import org.researchstack.feature.authentication.pincode.PinCodeConfig;
+import org.researchstack.feature.storage.file.StorageAccessException;
+import org.researchstack.feature.storage.file.StorageAccessListener;
import java.util.ArrayList;
import java.util.Collections;
@@ -28,7 +27,7 @@
* If {@link StorageAccessListener#onDataAuth()} is called, then you must prompt the user for their
* pin and authenticate using {@link #authenticate}.
*
- * {@link org.researchstack.backbone.ui.PinCodeActivity} handles almost all of this for you,
+ * {@link org.researchstack.foundation.ui.PinCodeActivity} handles almost all of this for you,
* including presenting the pin code screen to the user. PinCodeActivity should be used, extended,
* or it's fuctionality copied to your application's own base Activity. Make sure to delay any data
* access until {@link PinCodeActivity#onDataReady()} has been called.
diff --git a/storage/src/main/java/org/researchstack/feature/storage/StorageAccessPasscodeStore.kt b/storage/src/main/java/org/researchstack/feature/storage/StorageAccessPasscodeStore.kt
new file mode 100644
index 000000000..fafb20e8c
--- /dev/null
+++ b/storage/src/main/java/org/researchstack/feature/storage/StorageAccessPasscodeStore.kt
@@ -0,0 +1,28 @@
+package org.researchstack.feature.storage
+
+import android.content.Context
+import org.researchstack.feature.authentication.pincode.PasscodeAuthenticator
+
+class StorageAccessPasscodeStore(val context: Context): PasscodeAuthenticator.PasscodeStore {
+
+ override fun hasPasscode(): Boolean {
+ return StorageAccess.getInstance().hasPinCode(context)
+ }
+
+ override fun registerPasscode(passcode: String) {
+ StorageAccess.getInstance().createPinCode(context, passcode)
+ }
+
+ override fun checkPasscode(passcode: String) {
+ StorageAccess.getInstance().authenticate(context, passcode)
+ }
+
+ override fun removePasscode() {
+ StorageAccess.getInstance().removePinCode(context)
+ }
+
+ override fun changePasscode(oldPasscode: String, newPasscode: String) {
+ StorageAccess.getInstance().changePinCode(context, oldPasscode, newPasscode)
+ }
+
+}
\ No newline at end of file
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/database/AppDatabase.java b/storage/src/main/java/org/researchstack/feature/storage/database/AppDatabase.java
similarity index 90%
rename from backbone/src/main/java/org/researchstack/backbone/storage/database/AppDatabase.java
rename to storage/src/main/java/org/researchstack/feature/storage/database/AppDatabase.java
index 7e1a529a5..46d25e9a1 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/database/AppDatabase.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/database/AppDatabase.java
@@ -1,7 +1,7 @@
-package org.researchstack.backbone.storage.database;
+package org.researchstack.feature.storage.database;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.result.TaskResult;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.result.TaskResult;
import java.util.List;
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/database/StepRecord.java b/storage/src/main/java/org/researchstack/feature/storage/database/StepRecord.java
similarity index 81%
rename from backbone/src/main/java/org/researchstack/backbone/storage/database/StepRecord.java
rename to storage/src/main/java/org/researchstack/feature/storage/database/StepRecord.java
index 196743cd7..45a103124 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/database/StepRecord.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/database/StepRecord.java
@@ -1,12 +1,12 @@
-package org.researchstack.backbone.storage.database;
+package org.researchstack.feature.storage.database;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.step.Step;
-import org.researchstack.backbone.utils.FormatHelper;
-import org.researchstack.backbone.utils.TextUtils;
+import org.researchstack.foundation.components.utils.FormatHelper;
+import org.researchstack.foundation.components.utils.TextUtils;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.step.Step;
import java.util.Date;
import java.util.Map;
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/database/TaskNotification.java b/storage/src/main/java/org/researchstack/feature/storage/database/TaskNotification.java
similarity index 87%
rename from backbone/src/main/java/org/researchstack/backbone/storage/database/TaskNotification.java
rename to storage/src/main/java/org/researchstack/feature/storage/database/TaskNotification.java
index 7ba21945e..8d798d68d 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/database/TaskNotification.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/database/TaskNotification.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.storage.database;
+package org.researchstack.feature.storage.database;
import java.io.Serializable;
import java.util.Date;
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/database/TaskRecord.java b/storage/src/main/java/org/researchstack/feature/storage/database/TaskRecord.java
similarity index 85%
rename from backbone/src/main/java/org/researchstack/backbone/storage/database/TaskRecord.java
rename to storage/src/main/java/org/researchstack/feature/storage/database/TaskRecord.java
index 2c8600a42..3992adf5e 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/database/TaskRecord.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/database/TaskRecord.java
@@ -1,7 +1,7 @@
-package org.researchstack.backbone.storage.database;
+package org.researchstack.feature.storage.database;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.result.TaskResult;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.result.TaskResult;
import java.util.Date;
import java.util.List;
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/database/sqlite/DatabaseHelper.java b/storage/src/main/java/org/researchstack/feature/storage/database/sqlite/DatabaseHelper.java
similarity index 92%
rename from backbone/src/main/java/org/researchstack/backbone/storage/database/sqlite/DatabaseHelper.java
rename to storage/src/main/java/org/researchstack/feature/storage/database/sqlite/DatabaseHelper.java
index 9dae5cead..8063956fa 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/database/sqlite/DatabaseHelper.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/database/sqlite/DatabaseHelper.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.storage.database.sqlite;
+package org.researchstack.feature.storage.database.sqlite;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
@@ -6,13 +6,13 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.result.TaskResult;
-import org.researchstack.backbone.storage.database.AppDatabase;
-import org.researchstack.backbone.storage.database.StepRecord;
-import org.researchstack.backbone.storage.database.TaskRecord;
-import org.researchstack.backbone.utils.FormatHelper;
-import org.researchstack.backbone.utils.LogExt;
+import org.researchstack.foundation.components.utils.FormatHelper;
+import org.researchstack.foundation.components.utils.LogExt;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.result.TaskResult;
+import org.researchstack.feature.storage.database.AppDatabase;
+import org.researchstack.feature.storage.database.StepRecord;
+import org.researchstack.feature.storage.database.TaskRecord;
import java.sql.SQLException;
import java.util.ArrayList;
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/database/sqlite/SqlCipherDatabaseHelper.java b/storage/src/main/java/org/researchstack/feature/storage/database/sqlite/SqlCipherDatabaseHelper.java
similarity index 92%
rename from backbone/src/main/java/org/researchstack/backbone/storage/database/sqlite/SqlCipherDatabaseHelper.java
rename to storage/src/main/java/org/researchstack/feature/storage/database/sqlite/SqlCipherDatabaseHelper.java
index fea741c9d..b36fa44f2 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/database/sqlite/SqlCipherDatabaseHelper.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/database/sqlite/SqlCipherDatabaseHelper.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.storage.database.sqlite;
+package org.researchstack.feature.storage.database.sqlite;
import android.content.Context;
@@ -7,13 +7,13 @@
import net.sqlcipher.database.SQLiteDatabase;
-import org.researchstack.backbone.result.StepResult;
-import org.researchstack.backbone.result.TaskResult;
-import org.researchstack.backbone.storage.database.AppDatabase;
-import org.researchstack.backbone.storage.database.StepRecord;
-import org.researchstack.backbone.storage.database.TaskRecord;
-import org.researchstack.backbone.utils.FormatHelper;
-import org.researchstack.backbone.utils.LogExt;
+import org.researchstack.foundation.components.utils.FormatHelper;
+import org.researchstack.foundation.components.utils.LogExt;
+import org.researchstack.foundation.core.models.result.StepResult;
+import org.researchstack.foundation.core.models.result.TaskResult;
+import org.researchstack.feature.storage.database.AppDatabase;
+import org.researchstack.feature.storage.database.StepRecord;
+import org.researchstack.feature.storage.database.TaskRecord;
import java.sql.SQLException;
import java.util.ArrayList;
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/database/sqlite/UpdatablePassphraseProvider.java b/storage/src/main/java/org/researchstack/feature/storage/database/sqlite/UpdatablePassphraseProvider.java
similarity index 85%
rename from backbone/src/main/java/org/researchstack/backbone/storage/database/sqlite/UpdatablePassphraseProvider.java
rename to storage/src/main/java/org/researchstack/feature/storage/database/sqlite/UpdatablePassphraseProvider.java
index 11b713b10..32de2db5f 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/database/sqlite/UpdatablePassphraseProvider.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/database/sqlite/UpdatablePassphraseProvider.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.storage.database.sqlite;
+package org.researchstack.feature.storage.database.sqlite;
import co.touchlab.squeaky.db.sqlcipher.PassphraseProvider;
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/file/EncryptionProvider.java b/storage/src/main/java/org/researchstack/feature/storage/file/EncryptionProvider.java
similarity index 92%
rename from backbone/src/main/java/org/researchstack/backbone/storage/file/EncryptionProvider.java
rename to storage/src/main/java/org/researchstack/feature/storage/file/EncryptionProvider.java
index 5852f6aae..3399ef985 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/file/EncryptionProvider.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/file/EncryptionProvider.java
@@ -1,8 +1,9 @@
-package org.researchstack.backbone.storage.file;
+package org.researchstack.feature.storage.file;
import android.content.Context;
-import org.researchstack.backbone.storage.file.aes.Encrypter;
+import org.researchstack.feature.storage.file.aes.Encrypter;
+import org.researchstack.feature.authentication.pincode.PinCodeConfig;
/**
* This interface is used to create, change, and authenticate pin codes provided by the user.
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/file/FileAccess.java b/storage/src/main/java/org/researchstack/feature/storage/file/FileAccess.java
similarity index 96%
rename from backbone/src/main/java/org/researchstack/backbone/storage/file/FileAccess.java
rename to storage/src/main/java/org/researchstack/feature/storage/file/FileAccess.java
index 41945cf75..0ed084fb0 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/file/FileAccess.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/file/FileAccess.java
@@ -1,8 +1,8 @@
-package org.researchstack.backbone.storage.file;
+package org.researchstack.feature.storage.file;
import android.content.Context;
-import org.researchstack.backbone.storage.file.aes.Encrypter;
+import org.researchstack.feature.storage.file.aes.Encrypter;
/**
* Generic file access contract for the app. Depending on the type, there may need to be auth
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/file/SimpleFileAccess.java b/storage/src/main/java/org/researchstack/feature/storage/file/SimpleFileAccess.java
similarity index 90%
rename from backbone/src/main/java/org/researchstack/backbone/storage/file/SimpleFileAccess.java
rename to storage/src/main/java/org/researchstack/feature/storage/file/SimpleFileAccess.java
index 550da5e85..f6f1bc3d3 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/file/SimpleFileAccess.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/file/SimpleFileAccess.java
@@ -1,11 +1,11 @@
-package org.researchstack.backbone.storage.file;
+package org.researchstack.feature.storage.file;
import android.content.Context;
-import android.support.annotation.NonNull;
-import android.support.annotation.WorkerThread;
+import androidx.annotation.NonNull;
+import androidx.annotation.WorkerThread;
-import org.researchstack.backbone.storage.file.aes.Encrypter;
-import org.researchstack.backbone.utils.FileUtils;
+import org.researchstack.feature.storage.utils.FileUtils;
+import org.researchstack.feature.storage.file.aes.Encrypter;
import java.io.File;
import java.io.FileInputStream;
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/file/StorageAccessException.java b/storage/src/main/java/org/researchstack/feature/storage/file/StorageAccessException.java
similarity index 89%
rename from backbone/src/main/java/org/researchstack/backbone/storage/file/StorageAccessException.java
rename to storage/src/main/java/org/researchstack/feature/storage/file/StorageAccessException.java
index 1d73f846b..5f5424f42 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/file/StorageAccessException.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/file/StorageAccessException.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.storage.file;
+package org.researchstack.feature.storage.file;
public class StorageAccessException extends RuntimeException {
public StorageAccessException() {
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/file/StorageAccessListener.java b/storage/src/main/java/org/researchstack/feature/storage/file/StorageAccessListener.java
similarity index 93%
rename from backbone/src/main/java/org/researchstack/backbone/storage/file/StorageAccessListener.java
rename to storage/src/main/java/org/researchstack/feature/storage/file/StorageAccessListener.java
index afac8f42e..6d90903ea 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/file/StorageAccessListener.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/file/StorageAccessListener.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.storage.file;
+package org.researchstack.feature.storage.file;
/**
* Callback for data access. This will change a lot soon.
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/file/UnencryptedProvider.java b/storage/src/main/java/org/researchstack/feature/storage/file/UnencryptedProvider.java
similarity index 85%
rename from backbone/src/main/java/org/researchstack/backbone/storage/file/UnencryptedProvider.java
rename to storage/src/main/java/org/researchstack/feature/storage/file/UnencryptedProvider.java
index 95f041358..a9e639043 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/file/UnencryptedProvider.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/file/UnencryptedProvider.java
@@ -1,9 +1,10 @@
-package org.researchstack.backbone.storage.file;
+package org.researchstack.feature.storage.file;
import android.content.Context;
-import org.researchstack.backbone.storage.file.aes.ClearEncrypter;
-import org.researchstack.backbone.storage.file.aes.Encrypter;
+import org.researchstack.feature.storage.file.aes.ClearEncrypter;
+import org.researchstack.feature.storage.file.aes.Encrypter;
+import org.researchstack.feature.authentication.pincode.PinCodeConfig;
/**
* Use this class as the EncryptionProvider when you want to store all data without encryption. Pin
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/file/aes/AesEncrypter.java b/storage/src/main/java/org/researchstack/feature/storage/file/aes/AesEncrypter.java
similarity index 95%
rename from backbone/src/main/java/org/researchstack/backbone/storage/file/aes/AesEncrypter.java
rename to storage/src/main/java/org/researchstack/feature/storage/file/aes/AesEncrypter.java
index 21712f9ae..280ba275a 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/file/aes/AesEncrypter.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/file/aes/AesEncrypter.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.storage.file.aes;
+package org.researchstack.feature.storage.file.aes;
import com.tozny.crypto.android.AesCbcWithIntegrity;
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/file/aes/AesProvider.java b/storage/src/main/java/org/researchstack/feature/storage/file/aes/AesProvider.java
similarity index 91%
rename from backbone/src/main/java/org/researchstack/backbone/storage/file/aes/AesProvider.java
rename to storage/src/main/java/org/researchstack/feature/storage/file/aes/AesProvider.java
index e901df21b..95ec7e45a 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/file/aes/AesProvider.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/file/aes/AesProvider.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.storage.file.aes;
+package org.researchstack.feature.storage.file.aes;
import com.tozny.crypto.android.AesCbcWithIntegrity;
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/file/aes/ClearEncrypter.java b/storage/src/main/java/org/researchstack/feature/storage/file/aes/ClearEncrypter.java
similarity index 89%
rename from backbone/src/main/java/org/researchstack/backbone/storage/file/aes/ClearEncrypter.java
rename to storage/src/main/java/org/researchstack/feature/storage/file/aes/ClearEncrypter.java
index ca8a3eee3..30eb0ad46 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/file/aes/ClearEncrypter.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/file/aes/ClearEncrypter.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.storage.file.aes;
+package org.researchstack.feature.storage.file.aes;
/**
* This encrypter doesn't actually encrypt or decrypt anything that passes through it. Allows for
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/file/aes/Encrypter.java b/storage/src/main/java/org/researchstack/feature/storage/file/aes/Encrypter.java
similarity index 87%
rename from backbone/src/main/java/org/researchstack/backbone/storage/file/aes/Encrypter.java
rename to storage/src/main/java/org/researchstack/feature/storage/file/aes/Encrypter.java
index f62d147ce..18d8a0ebf 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/file/aes/Encrypter.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/file/aes/Encrypter.java
@@ -1,10 +1,10 @@
-package org.researchstack.backbone.storage.file.aes;
+package org.researchstack.feature.storage.file.aes;
import java.security.GeneralSecurityException;
/**
- * Implement this class and use in your {@link org.researchstack.backbone.storage.file.EncryptionProvider}
- * to encrypt/decrypt all date before it is written using {@link org.researchstack.backbone.storage.file.FileAccess}.
+ * Implement this class and use in your {@link org.researchstack.foundation.storage.file.EncryptionProvider}
+ * to encrypt/decrypt all date before it is written using {@link org.researchstack.foundation.storage.file.FileAccess}.
*/
public interface Encrypter {
/**
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/file/aes/PinProtectedProvider.java b/storage/src/main/java/org/researchstack/feature/storage/file/aes/PinProtectedProvider.java
similarity index 94%
rename from backbone/src/main/java/org/researchstack/backbone/storage/file/aes/PinProtectedProvider.java
rename to storage/src/main/java/org/researchstack/feature/storage/file/aes/PinProtectedProvider.java
index ed94960af..3c8905174 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/file/aes/PinProtectedProvider.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/file/aes/PinProtectedProvider.java
@@ -1,14 +1,14 @@
-package org.researchstack.backbone.storage.file.aes;
+package org.researchstack.feature.storage.file.aes;
import android.content.Context;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
import com.tozny.crypto.android.AesCbcWithIntegrity;
-import org.researchstack.backbone.storage.file.EncryptionProvider;
-import org.researchstack.backbone.storage.file.PinCodeConfig;
-import org.researchstack.backbone.storage.file.StorageAccessException;
-import org.researchstack.backbone.utils.FileUtils;
+import org.researchstack.feature.storage.utils.FileUtils;
+import org.researchstack.feature.storage.file.EncryptionProvider;
+import org.researchstack.feature.authentication.pincode.PinCodeConfig;
+import org.researchstack.feature.storage.file.StorageAccessException;
import java.io.File;
import java.io.IOException;
diff --git a/backbone/src/main/java/org/researchstack/backbone/storage/file/aes/UnencryptedPinProvider.java b/storage/src/main/java/org/researchstack/feature/storage/file/aes/UnencryptedPinProvider.java
similarity index 93%
rename from backbone/src/main/java/org/researchstack/backbone/storage/file/aes/UnencryptedPinProvider.java
rename to storage/src/main/java/org/researchstack/feature/storage/file/aes/UnencryptedPinProvider.java
index 56a4301f8..c7e33ea1b 100644
--- a/backbone/src/main/java/org/researchstack/backbone/storage/file/aes/UnencryptedPinProvider.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/file/aes/UnencryptedPinProvider.java
@@ -1,4 +1,4 @@
-package org.researchstack.backbone.storage.file.aes;
+package org.researchstack.feature.storage.file.aes;
import com.tozny.crypto.android.AesCbcWithIntegrity;
diff --git a/backbone/src/main/java/org/researchstack/backbone/utils/FileUtils.java b/storage/src/main/java/org/researchstack/feature/storage/utils/FileUtils.java
similarity index 92%
rename from backbone/src/main/java/org/researchstack/backbone/utils/FileUtils.java
rename to storage/src/main/java/org/researchstack/feature/storage/utils/FileUtils.java
index e3d9954b3..4351465b4 100644
--- a/backbone/src/main/java/org/researchstack/backbone/utils/FileUtils.java
+++ b/storage/src/main/java/org/researchstack/feature/storage/utils/FileUtils.java
@@ -1,8 +1,10 @@
-package org.researchstack.backbone.utils;
+package org.researchstack.feature.storage.utils;
-import android.support.annotation.NonNull;
+//TODO: MOVE TO STORAGE MODULE
-import org.researchstack.backbone.storage.file.StorageAccessException;
+import androidx.annotation.NonNull;
+
+import org.researchstack.feature.storage.file.StorageAccessException;
import java.io.ByteArrayOutputStream;
import java.io.File;
diff --git a/storage/src/main/res/values/strings.xml b/storage/src/main/res/values/strings.xml
new file mode 100644
index 000000000..f11f7450a
--- /dev/null
+++ b/storage/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/storage/src/test/java/org/researchstack/feature/storage/ExampleUnitTest.java b/storage/src/test/java/org/researchstack/feature/storage/ExampleUnitTest.java
new file mode 100644
index 000000000..f3083ac17
--- /dev/null
+++ b/storage/src/test/java/org/researchstack/feature/storage/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package org.researchstack.feature.storage;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file