Permalink
Please sign in to comment.
Browse files
Initial commit of FirebaseArray and FirebaseListAdapter
FirebaseRecyclerView.Adapter is also in here, but not really done yet
Showing
with
1,256 additions
and 0 deletions.
- +6 −0 .gitignore
- +19 −0 FirebaseUI-Android.iml
- +1 −0 app/.gitignore
- +96 −0 app/app.iml
- +25 −0 app/build.gradle
- +17 −0 app/proguard-rules.pro
- +13 −0 app/src/androidTest/java/com/firebase/firebaseui_android/ApplicationTest.java
- +9 −0 app/src/main/AndroidManifest.xml
- BIN app/src/main/res/mipmap-hdpi/ic_launcher.png
- BIN app/src/main/res/mipmap-mdpi/ic_launcher.png
- BIN app/src/main/res/mipmap-xhdpi/ic_launcher.png
- BIN app/src/main/res/mipmap-xxhdpi/ic_launcher.png
- +3 −0 app/src/main/res/values/strings.xml
- +8 −0 app/src/main/res/values/styles.xml
- +19 −0 build.gradle
- +18 −0 gradle.properties
- BIN gradle/wrapper/gradle-wrapper.jar
- +6 −0 gradle/wrapper/gradle-wrapper.properties
- +164 −0 gradlew
- +90 −0 gradlew.bat
- +1 −0 library/.gitignore
- +32 −0 library/build.gradle
- +106 −0 library/library.iml
- +17 −0 library/proguard-rules.pro
- +13 −0 library/src/androidTest/java/com/firebase/ui/ApplicationTest.java
- +177 −0 library/src/androidTest/java/com/firebase/ui/FirebaseArrayOfObjectsTest.java
- +149 −0 library/src/androidTest/java/com/firebase/ui/FirebaseArrayTest.java
- +7 −0 library/src/main/AndroidManifest.xml
- +90 −0 library/src/main/java/com/firebase/ui/FirebaseArray.java
- +91 −0 library/src/main/java/com/firebase/ui/FirebaseListAdapter.java
- +75 −0 library/src/main/java/com/firebase/ui/FirebaseRecyclerViewAdapter.java
- +3 −0 library/src/main/res/values/strings.xml
- +1 −0 settings.gradle
6
.gitignore
| @@ -0,0 +1,6 @@ | ||
| +.gradle | ||
| +/local.properties | ||
| +.idea | ||
| +.DS_Store | ||
| +/build | ||
| +/captures |
19
FirebaseUI-Android.iml
| @@ -0,0 +1,19 @@ | ||
| +<?xml version="1.0" encoding="UTF-8"?> | ||
| +<module external.linked.project.id="FirebaseUI-Android" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4"> | ||
| + <component name="FacetManager"> | ||
| + <facet type="java-gradle" name="Java-Gradle"> | ||
| + <configuration> | ||
| + <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" /> | ||
| + <option name="BUILDABLE" value="false" /> | ||
| + </configuration> | ||
| + </facet> | ||
| + </component> | ||
| + <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true"> | ||
| + <exclude-output /> | ||
| + <content url="file://$MODULE_DIR$"> | ||
| + <excludeFolder url="file://$MODULE_DIR$/.gradle" /> | ||
| + </content> | ||
| + <orderEntry type="inheritedJdk" /> | ||
| + <orderEntry type="sourceFolder" forTests="false" /> | ||
| + </component> | ||
| +</module> |
1
app/.gitignore
| @@ -0,0 +1 @@ | ||
| +/build |
96
app/app.iml
| @@ -0,0 +1,96 @@ | ||
| +<?xml version="1.0" encoding="UTF-8"?> | ||
| +<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="FirebaseUI-Android" external.system.module.version="unspecified" type="JAVA_MODULE" version="4"> | ||
| + <component name="FacetManager"> | ||
| + <facet type="android-gradle" name="Android-Gradle"> | ||
| + <configuration> | ||
| + <option name="GRADLE_PROJECT_PATH" value=":app" /> | ||
| + </configuration> | ||
| + </facet> | ||
| + <facet type="android" name="Android"> | ||
| + <configuration> | ||
| + <option name="SELECTED_BUILD_VARIANT" value="debug" /> | ||
| + <option name="SELECTED_TEST_ARTIFACT" value="_android_test_" /> | ||
| + <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" /> | ||
| + <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" /> | ||
| + <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" /> | ||
| + <option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" /> | ||
| + <afterSyncTasks> | ||
| + <task>generateDebugAndroidTestSources</task> | ||
| + <task>generateDebugSources</task> | ||
| + </afterSyncTasks> | ||
| + <option name="ALLOW_USER_CONFIGURATION" value="false" /> | ||
| + <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" /> | ||
| + <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" /> | ||
| + <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" /> | ||
| + <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" /> | ||
| + </configuration> | ||
| + </facet> | ||
| + </component> | ||
| + <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false"> | ||
| + <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" /> | ||
| + <output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" /> | ||
| + <exclude-output /> | ||
| + <content url="file://$MODULE_DIR$"> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug" type="java-test-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/22.2.0/jars" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/22.2.0/jars" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/outputs" /> | ||
| + </content> | ||
| + <orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" /> | ||
| + <orderEntry type="sourceFolder" forTests="false" /> | ||
| + <orderEntry type="library" exported="" name="support-v4-22.2.0" level="project" /> | ||
| + <orderEntry type="library" exported="" name="support-annotations-22.2.0" level="project" /> | ||
| + <orderEntry type="library" exported="" name="appcompat-v7-22.2.0" level="project" /> | ||
| + </component> | ||
| +</module> |
25
app/build.gradle
| @@ -0,0 +1,25 @@ | ||
| +apply plugin: 'com.android.application' | ||
| + | ||
| +android { | ||
| + compileSdkVersion 22 | ||
| + buildToolsVersion "23.0.0 rc2" | ||
| + | ||
| + defaultConfig { | ||
| + applicationId "com.firebase.firebaseui_android" | ||
| + minSdkVersion 10 | ||
| + targetSdkVersion 22 | ||
| + versionCode 1 | ||
| + versionName "1.0" | ||
| + } | ||
| + buildTypes { | ||
| + release { | ||
| + minifyEnabled false | ||
| + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | ||
| + } | ||
| + } | ||
| +} | ||
| + | ||
| +dependencies { | ||
| + compile fileTree(dir: 'libs', include: ['*.jar']) | ||
| + compile 'com.android.support:appcompat-v7:22.2.0' | ||
| +} |
17
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/puf/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 *; | ||
| +#} |
13
app/src/androidTest/java/com/firebase/firebaseui_android/ApplicationTest.java
| @@ -0,0 +1,13 @@ | ||
| +package com.firebase.firebaseui_android; | ||
| + | ||
| +import android.app.Application; | ||
| +import android.test.ApplicationTestCase; | ||
| + | ||
| +/** | ||
| + * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a> | ||
| + */ | ||
| +public class ApplicationTest extends ApplicationTestCase<Application> { | ||
| + public ApplicationTest() { | ||
| + super(Application.class); | ||
| + } | ||
| +} |
9
app/src/main/AndroidManifest.xml
| @@ -0,0 +1,9 @@ | ||
| +<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
| + package="com.firebase.firebaseui_android"> | ||
| + | ||
| + <application android:allowBackup="true" android:label="@string/app_name" | ||
| + android:icon="@mipmap/ic_launcher" android:theme="@style/AppTheme"> | ||
| + | ||
| + </application> | ||
| + | ||
| +</manifest> |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3
app/src/main/res/values/strings.xml
| @@ -0,0 +1,3 @@ | ||
| +<resources> | ||
| + <string name="app_name">FirebaseUI-Android</string> | ||
| +</resources> |
8
app/src/main/res/values/styles.xml
| @@ -0,0 +1,8 @@ | ||
| +<resources> | ||
| + | ||
| + <!-- Base application theme. --> | ||
| + <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> | ||
| + <!-- Customize your theme here. --> | ||
| + </style> | ||
| + | ||
| +</resources> |
19
build.gradle
| @@ -0,0 +1,19 @@ | ||
| +// Top-level build file where you can add configuration options common to all sub-projects/modules. | ||
| + | ||
| +buildscript { | ||
| + repositories { | ||
| + jcenter() | ||
| + } | ||
| + dependencies { | ||
| + classpath 'com.android.tools.build:gradle:1.2.3' | ||
| + | ||
| + // NOTE: Do not place your application dependencies here; they belong | ||
| + // in the individual module build.gradle files | ||
| + } | ||
| +} | ||
| + | ||
| +allprojects { | ||
| + repositories { | ||
| + jcenter() | ||
| + } | ||
| +} |
18
gradle.properties
| @@ -0,0 +1,18 @@ | ||
| +# Project-wide Gradle settings. | ||
| + | ||
| +# IDE (e.g. Android Studio) users: | ||
| +# Gradle settings configured through the IDE *will override* | ||
| +# any settings specified in this file. | ||
| + | ||
| +# For more details on how to configure your build environment visit | ||
| +# http://www.gradle.org/docs/current/userguide/build_environment.html | ||
| + | ||
| +# Specifies the JVM arguments used for the daemon process. | ||
| +# The setting is particularly useful for tweaking memory settings. | ||
| +# Default value: -Xmx10248m -XX:MaxPermSize=256m | ||
| +# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 | ||
| + | ||
| +# 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 |
BIN
gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
6
gradle/wrapper/gradle-wrapper.properties
| @@ -0,0 +1,6 @@ | ||
| +#Mon Jul 13 17:23:05 PDT 2015 | ||
| +distributionBase=GRADLE_USER_HOME | ||
| +distributionPath=wrapper/dists | ||
| +zipStoreBase=GRADLE_USER_HOME | ||
| +zipStorePath=wrapper/dists | ||
| +distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip |
164
gradlew
| @@ -0,0 +1,164 @@ | ||
| +#!/usr/bin/env bash | ||
| + | ||
| +############################################################################## | ||
| +## | ||
| +## Gradle start up script for UN*X | ||
| +## | ||
| +############################################################################## | ||
| + | ||
| +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||
| +DEFAULT_JVM_OPTS="" | ||
| + | ||
| +APP_NAME="Gradle" | ||
| +APP_BASE_NAME=`basename "$0"` | ||
| + | ||
| +# Use the maximum available, or set MAX_FD != -1 to use that value. | ||
| +MAX_FD="maximum" | ||
| + | ||
| +warn ( ) { | ||
| + echo "$*" | ||
| +} | ||
| + | ||
| +die ( ) { | ||
| + echo | ||
| + echo "$*" | ||
| + echo | ||
| + exit 1 | ||
| +} | ||
| + | ||
| +# OS specific support (must be 'true' or 'false'). | ||
| +cygwin=false | ||
| +msys=false | ||
| +darwin=false | ||
| +case "`uname`" in | ||
| + CYGWIN* ) | ||
| + cygwin=true | ||
| + ;; | ||
| + Darwin* ) | ||
| + darwin=true | ||
| + ;; | ||
| + MINGW* ) | ||
| + msys=true | ||
| + ;; | ||
| +esac | ||
| + | ||
| +# For Cygwin, ensure paths are in UNIX format before anything is touched. | ||
| +if $cygwin ; then | ||
| + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` | ||
| +fi | ||
| + | ||
| +# Attempt to set APP_HOME | ||
| +# Resolve links: $0 may be a link | ||
| +PRG="$0" | ||
| +# Need this for relative symlinks. | ||
| +while [ -h "$PRG" ] ; do | ||
| + ls=`ls -ld "$PRG"` | ||
| + link=`expr "$ls" : '.*-> \(.*\)$'` | ||
| + if expr "$link" : '/.*' > /dev/null; then | ||
| + PRG="$link" | ||
| + else | ||
| + PRG=`dirname "$PRG"`"/$link" | ||
| + fi | ||
| +done | ||
| +SAVED="`pwd`" | ||
| +cd "`dirname \"$PRG\"`/" >&- | ||
| +APP_HOME="`pwd -P`" | ||
| +cd "$SAVED" >&- | ||
| + | ||
| +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | ||
| + | ||
| +# Determine the Java command to use to start the JVM. | ||
| +if [ -n "$JAVA_HOME" ] ; then | ||
| + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | ||
| + # IBM's JDK on AIX uses strange locations for the executables | ||
| + JAVACMD="$JAVA_HOME/jre/sh/java" | ||
| + else | ||
| + JAVACMD="$JAVA_HOME/bin/java" | ||
| + fi | ||
| + if [ ! -x "$JAVACMD" ] ; then | ||
| + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME | ||
| + | ||
| +Please set the JAVA_HOME variable in your environment to match the | ||
| +location of your Java installation." | ||
| + fi | ||
| +else | ||
| + JAVACMD="java" | ||
| + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||
| + | ||
| +Please set the JAVA_HOME variable in your environment to match the | ||
| +location of your Java installation." | ||
| +fi | ||
| + | ||
| +# Increase the maximum file descriptors if we can. | ||
| +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then | ||
| + MAX_FD_LIMIT=`ulimit -H -n` | ||
| + if [ $? -eq 0 ] ; then | ||
| + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then | ||
| + MAX_FD="$MAX_FD_LIMIT" | ||
| + fi | ||
| + ulimit -n $MAX_FD | ||
| + if [ $? -ne 0 ] ; then | ||
| + warn "Could not set maximum file descriptor limit: $MAX_FD" | ||
| + fi | ||
| + else | ||
| + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" | ||
| + fi | ||
| +fi | ||
| + | ||
| +# For Darwin, add options to specify how the application appears in the dock | ||
| +if $darwin; then | ||
| + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" | ||
| +fi | ||
| + | ||
| +# For Cygwin, switch paths to Windows format before running java | ||
| +if $cygwin ; then | ||
| + APP_HOME=`cygpath --path --mixed "$APP_HOME"` | ||
| + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` | ||
| + | ||
| + # We build the pattern for arguments to be converted via cygpath | ||
| + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` | ||
| + SEP="" | ||
| + for dir in $ROOTDIRSRAW ; do | ||
| + ROOTDIRS="$ROOTDIRS$SEP$dir" | ||
| + SEP="|" | ||
| + done | ||
| + OURCYGPATTERN="(^($ROOTDIRS))" | ||
| + # Add a user-defined pattern to the cygpath arguments | ||
| + if [ "$GRADLE_CYGPATTERN" != "" ] ; then | ||
| + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" | ||
| + fi | ||
| + # Now convert the arguments - kludge to limit ourselves to /bin/sh | ||
| + i=0 | ||
| + for arg in "$@" ; do | ||
| + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` | ||
| + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option | ||
| + | ||
| + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition | ||
| + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` | ||
| + else | ||
| + eval `echo args$i`="\"$arg\"" | ||
| + fi | ||
| + i=$((i+1)) | ||
| + done | ||
| + case $i in | ||
| + (0) set -- ;; | ||
| + (1) set -- "$args0" ;; | ||
| + (2) set -- "$args0" "$args1" ;; | ||
| + (3) set -- "$args0" "$args1" "$args2" ;; | ||
| + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; | ||
| + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; | ||
| + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; | ||
| + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; | ||
| + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; | ||
| + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; | ||
| + esac | ||
| +fi | ||
| + | ||
| +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules | ||
| +function splitJvmOpts() { | ||
| + JVM_OPTS=("$@") | ||
| +} | ||
| +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS | ||
| +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" | ||
| + | ||
| +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" |
90
gradlew.bat
| @@ -0,0 +1,90 @@ | ||
| +@if "%DEBUG%" == "" @echo off | ||
| +@rem ########################################################################## | ||
| +@rem | ||
| +@rem Gradle startup script for Windows | ||
| +@rem | ||
| +@rem ########################################################################## | ||
| + | ||
| +@rem Set local scope for the variables with windows NT shell | ||
| +if "%OS%"=="Windows_NT" setlocal | ||
| + | ||
| +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||
| +set DEFAULT_JVM_OPTS= | ||
| + | ||
| +set DIRNAME=%~dp0 | ||
| +if "%DIRNAME%" == "" set DIRNAME=. | ||
| +set APP_BASE_NAME=%~n0 | ||
| +set APP_HOME=%DIRNAME% | ||
| + | ||
| +@rem Find java.exe | ||
| +if defined JAVA_HOME goto findJavaFromJavaHome | ||
| + | ||
| +set JAVA_EXE=java.exe | ||
| +%JAVA_EXE% -version >NUL 2>&1 | ||
| +if "%ERRORLEVEL%" == "0" goto init | ||
| + | ||
| +echo. | ||
| +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||
| +echo. | ||
| +echo Please set the JAVA_HOME variable in your environment to match the | ||
| +echo location of your Java installation. | ||
| + | ||
| +goto fail | ||
| + | ||
| +:findJavaFromJavaHome | ||
| +set JAVA_HOME=%JAVA_HOME:"=% | ||
| +set JAVA_EXE=%JAVA_HOME%/bin/java.exe | ||
| + | ||
| +if exist "%JAVA_EXE%" goto init | ||
| + | ||
| +echo. | ||
| +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | ||
| +echo. | ||
| +echo Please set the JAVA_HOME variable in your environment to match the | ||
| +echo location of your Java installation. | ||
| + | ||
| +goto fail | ||
| + | ||
| +:init | ||
| +@rem Get command-line arguments, handling Windowz variants | ||
| + | ||
| +if not "%OS%" == "Windows_NT" goto win9xME_args | ||
| +if "%@eval[2+2]" == "4" goto 4NT_args | ||
| + | ||
| +:win9xME_args | ||
| +@rem Slurp the command line arguments. | ||
| +set CMD_LINE_ARGS= | ||
| +set _SKIP=2 | ||
| + | ||
| +:win9xME_args_slurp | ||
| +if "x%~1" == "x" goto execute | ||
| + | ||
| +set CMD_LINE_ARGS=%* | ||
| +goto execute | ||
| + | ||
| +:4NT_args | ||
| +@rem Get arguments from the 4NT Shell from JP Software | ||
| +set CMD_LINE_ARGS=%$ | ||
| + | ||
| +:execute | ||
| +@rem Setup the command line | ||
| + | ||
| +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar | ||
| + | ||
| +@rem Execute Gradle | ||
| +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% | ||
| + | ||
| +:end | ||
| +@rem End local scope for the variables with windows NT shell | ||
| +if "%ERRORLEVEL%"=="0" goto mainEnd | ||
| + | ||
| +:fail | ||
| +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of | ||
| +rem the _cmd.exe /c_ return code! | ||
| +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 | ||
| +exit /b 1 | ||
| + | ||
| +:mainEnd | ||
| +if "%OS%"=="Windows_NT" endlocal | ||
| + | ||
| +:omega |
1
library/.gitignore
| @@ -0,0 +1 @@ | ||
| +/build |
32
library/build.gradle
| @@ -0,0 +1,32 @@ | ||
| +apply plugin: 'com.android.library' | ||
| + | ||
| +android { | ||
| + compileSdkVersion 22 | ||
| + buildToolsVersion "23.0.0 rc2" | ||
| + | ||
| + defaultConfig { | ||
| + minSdkVersion 10 | ||
| + targetSdkVersion 22 | ||
| + versionCode 1 | ||
| + versionName "1.0" | ||
| + } | ||
| + buildTypes { | ||
| + release { | ||
| + minifyEnabled false | ||
| + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | ||
| + } | ||
| + } | ||
| + packagingOptions { | ||
| + exclude 'META-INF/LICENSE' | ||
| + exclude 'META-INF/LICENSE-FIREBASE.txt' | ||
| + exclude 'META-INF/NOTICE' | ||
| + } | ||
| +} | ||
| + | ||
| +dependencies { | ||
| + compile fileTree(dir: 'libs', include: ['*.jar']) | ||
| + compile 'com.android.support:appcompat-v7:22.2.0' | ||
| + compile 'com.firebase:firebase-client-android:2.3.1' | ||
| + compile 'com.android.support:recyclerview-v7:22.2.0' | ||
| + androidTestCompile 'junit:junit:4.12' | ||
| +} |
106
library/library.iml
| @@ -0,0 +1,106 @@ | ||
| +<?xml version="1.0" encoding="UTF-8"?> | ||
| +<module external.linked.project.id=":library" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="FirebaseUI-Android" external.system.module.version="unspecified" type="JAVA_MODULE" version="4"> | ||
| + <component name="FacetManager"> | ||
| + <facet type="android-gradle" name="Android-Gradle"> | ||
| + <configuration> | ||
| + <option name="GRADLE_PROJECT_PATH" value=":library" /> | ||
| + </configuration> | ||
| + </facet> | ||
| + <facet type="android" name="Android"> | ||
| + <configuration> | ||
| + <option name="SELECTED_BUILD_VARIANT" value="debug" /> | ||
| + <option name="SELECTED_TEST_ARTIFACT" value="_android_test_" /> | ||
| + <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" /> | ||
| + <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" /> | ||
| + <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" /> | ||
| + <option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" /> | ||
| + <afterSyncTasks> | ||
| + <task>generateDebugAndroidTestSources</task> | ||
| + <task>generateDebugSources</task> | ||
| + </afterSyncTasks> | ||
| + <option name="ALLOW_USER_CONFIGURATION" value="false" /> | ||
| + <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" /> | ||
| + <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" /> | ||
| + <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" /> | ||
| + <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" /> | ||
| + <option name="LIBRARY_PROJECT" value="true" /> | ||
| + </configuration> | ||
| + </facet> | ||
| + </component> | ||
| + <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false"> | ||
| + <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" /> | ||
| + <output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" /> | ||
| + <exclude-output /> | ||
| + <content url="file://$MODULE_DIR$"> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug" type="java-test-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" /> | ||
| + <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/recyclerview-v7/22.2.0/jars" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/outputs" /> | ||
| + <excludeFolder url="file://$MODULE_DIR$/build/tmp" /> | ||
| + </content> | ||
| + <orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" /> | ||
| + <orderEntry type="sourceFolder" forTests="false" /> | ||
| + <orderEntry type="library" exported="" name="jackson-core-2.2.2" level="project" /> | ||
| + <orderEntry type="library" exported="" name="jackson-databind-2.2.2" level="project" /> | ||
| + <orderEntry type="library" exported="" name="firebase-client-jvm-2.3.1" level="project" /> | ||
| + <orderEntry type="library" exported="" name="support-v4-22.2.0" level="project" /> | ||
| + <orderEntry type="library" exported="" name="support-annotations-22.2.0" level="project" /> | ||
| + <orderEntry type="library" exported="" name="tubesock-0.0.11" level="project" /> | ||
| + <orderEntry type="library" exported="" name="recyclerview-v7-22.2.0" level="project" /> | ||
| + <orderEntry type="library" exported="" name="jackson-annotations-2.2.2" level="project" /> | ||
| + <orderEntry type="library" exported="" name="firebase-client-android-2.3.1" level="project" /> | ||
| + <orderEntry type="library" exported="" name="appcompat-v7-22.2.0" level="project" /> | ||
| + <orderEntry type="library" exported="" scope="TEST" name="hamcrest-core-1.3" level="project" /> | ||
| + <orderEntry type="library" exported="" scope="TEST" name="junit-4.12" level="project" /> | ||
| + </component> | ||
| +</module> |
17
library/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/puf/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 *; | ||
| +#} |
13
library/src/androidTest/java/com/firebase/ui/ApplicationTest.java
| @@ -0,0 +1,13 @@ | ||
| +package com.firebase.ui; | ||
| + | ||
| +import android.app.Application; | ||
| +import android.test.ApplicationTestCase; | ||
| + | ||
| +/** | ||
| + * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a> | ||
| + */ | ||
| +public class ApplicationTest extends ApplicationTestCase<Application> { | ||
| + public ApplicationTest() { | ||
| + super(Application.class); | ||
| + } | ||
| +} |
177
library/src/androidTest/java/com/firebase/ui/FirebaseArrayOfObjectsTest.java
| @@ -0,0 +1,177 @@ | ||
| +package com.firebase.ui; | ||
| + | ||
| +import android.test.AndroidTestCase; | ||
| + | ||
| +import com.firebase.client.Firebase; | ||
| + | ||
| +import junit.framework.AssertionFailedError; | ||
| + | ||
| +import org.junit.After; | ||
| +import org.junit.Before; | ||
| +import org.junit.Test; | ||
| + | ||
| +import java.util.concurrent.Callable; | ||
| +import java.util.concurrent.TimeUnit; | ||
| + | ||
| +public class FirebaseArrayOfObjectsTest extends AndroidTestCase { | ||
| + public static class Bean { | ||
| + int number; | ||
| + String text; | ||
| + boolean bool; | ||
| + | ||
| + public Bean() { | ||
| + // necessary for Jackson | ||
| + } | ||
| + | ||
| + public Bean(int number, String text, boolean bool) { | ||
| + this.number = number; | ||
| + this.text = text; | ||
| + this.bool = bool; | ||
| + } | ||
| + public Bean(int index) { | ||
| + this(index, "Text "+index, index % 2 == 0); | ||
| + } | ||
| + | ||
| + public int getNumber() { | ||
| + return number; | ||
| + } | ||
| + | ||
| + public String getText() { | ||
| + return text; | ||
| + } | ||
| + | ||
| + public boolean isBool() { | ||
| + return bool; | ||
| + } | ||
| + } | ||
| + | ||
| + private Firebase mRef; | ||
| + private FirebaseArray mArray; | ||
| + | ||
| + @Before | ||
| + public void setUp() throws Exception { | ||
| + Firebase.setAndroidContext(this.getContext()); | ||
| + | ||
| + mRef = new Firebase("https://firebaseui-tests.firebaseio-demo.com/firebasearray/objects"); | ||
| + mArray = new FirebaseArray(mRef); | ||
| + mRef.removeValue(); | ||
| + runAndWaitUntil(mArray, mRef, new Runnable() { | ||
| + @Override | ||
| + public void run() { | ||
| + for (int i = 1; i <= 3; i++) { | ||
| + mRef.push().setValue(new Bean(i, "Text " + i, i % 2 == 0 ? true : false), i); | ||
| + } | ||
| + } | ||
| + }, new Callable<Boolean>() { | ||
| + @Override | ||
| + public Boolean call() throws Exception { | ||
| + return mArray.getCount() == 3; | ||
| + } | ||
| + } | ||
| + ); | ||
| + } | ||
| + | ||
| + @After | ||
| + public void tearDown() throws Exception { | ||
| + mRef.removeValue(); | ||
| + mArray.cleanup(); | ||
| + } | ||
| + | ||
| + @Test | ||
| + public void testSize() throws Exception { | ||
| + assertEquals(3, mArray.getCount()); | ||
| + } | ||
| + | ||
| + @Test | ||
| + public void testPushIncreasesSize() throws Exception { | ||
| + assertEquals(3, mArray.getCount()); | ||
| + runAndWaitUntil(mArray, mRef, new Runnable() { | ||
| + public void run() { | ||
| + mRef.push().setValue(new Bean(4)); | ||
| + } | ||
| + }, new Callable<Boolean>() { | ||
| + @Override | ||
| + public Boolean call() throws Exception { | ||
| + return mArray.getCount() == 4; | ||
| + } | ||
| + }); | ||
| + } | ||
| + @Test | ||
| + public void testPushAppends() throws Exception { | ||
| + runAndWaitUntil(mArray, mRef, new Runnable() { | ||
| + public void run() { | ||
| + mRef.push().setValue(new Bean(4), 4); | ||
| + } | ||
| + }, new Callable<Boolean>() { | ||
| + @Override | ||
| + public Boolean call() throws Exception { | ||
| + return mArray.getItem(3).getValue(Bean.class).getNumber() == 4; | ||
| + } | ||
| + }); | ||
| + } | ||
| + | ||
| + @Test | ||
| + public void testAddValueWithPriority() throws Exception { | ||
| + runAndWaitUntil(mArray, mRef, new Runnable() { | ||
| + public void run() { | ||
| + mRef.push().setValue(new Bean(4), 0.5); | ||
| + } | ||
| + }, new Callable<Boolean>() { | ||
| + public Boolean call() throws Exception { | ||
| + return mArray.getItem(3).getValue(Bean.class).getNumber() == 3 && mArray.getItem(0).getValue(Bean.class).getNumber() == 4; | ||
| + } | ||
| + }); | ||
| + } | ||
| + | ||
| + @Test | ||
| + public void testChangePriorities() throws Exception { | ||
| + runAndWaitUntil(mArray, mRef, new Runnable() { | ||
| + public void run() { | ||
| + mArray.getItem(2).getRef().setPriority(0.5); | ||
| + } | ||
| + }, new Callable<Boolean>() { | ||
| + public Boolean call() throws Exception { | ||
| + return getBean(mArray, 0).getNumber() == 3 && getBean(mArray, 1).getNumber() == 1 && getBean(mArray, 2).getNumber() == 2; | ||
| + //return isValuesEqual(mArray, new int[]{3, 1, 2}); | ||
| + } | ||
| + }); | ||
| + } | ||
| + | ||
| + private static boolean isValuesEqual(FirebaseArray array, int[] expected) { | ||
| + if (array.getCount() != expected.length) return false; | ||
| + for (int i=0; i < array.getCount(); i++) { | ||
| + if (!array.getItem(i).getValue(Integer.class).equals(expected[i])) { | ||
| + return false; | ||
| + } | ||
| + } | ||
| + return true; | ||
| + } | ||
| + | ||
| + private Bean getBean(FirebaseArray array, int index) { | ||
| + return array.getItem(index).getValue(Bean.class); | ||
| + } | ||
| + | ||
| + public static void runAndWaitUntil(final FirebaseArray array, Firebase ref, Runnable task, Callable<Boolean> done) throws InterruptedException { | ||
| + final java.util.concurrent.Semaphore semaphore = new java.util.concurrent.Semaphore(0); | ||
| + array.setOnChangedListener(new FirebaseArray.OnChangedListener() { | ||
| + public void onChanged() { | ||
| + semaphore.release(); | ||
| + } | ||
| + }); | ||
| + task.run(); | ||
| + boolean isDone = false; | ||
| + long startedAt = System.currentTimeMillis(); | ||
| + while (!isDone && System.currentTimeMillis() - startedAt < 5000) { | ||
| + semaphore.tryAcquire(1, TimeUnit.SECONDS); | ||
| + try { | ||
| + isDone = done.call(); | ||
| + } catch (Exception e) { | ||
| + e.printStackTrace(); | ||
| + // and we're not done | ||
| + } | ||
| + } | ||
| + if (!isDone) { | ||
| + throw new AssertionFailedError(); | ||
| + } | ||
| + array.setOnChangedListener(null); | ||
| + }} |
149
library/src/androidTest/java/com/firebase/ui/FirebaseArrayTest.java
| @@ -0,0 +1,149 @@ | ||
| +package com.firebase.ui; | ||
| + | ||
| +import android.test.AndroidTestCase; | ||
| + | ||
| +import com.firebase.client.Firebase; | ||
| + | ||
| +import junit.framework.AssertionFailedError; | ||
| + | ||
| +import org.junit.After; | ||
| +import org.junit.Before; | ||
| +import org.junit.Test; | ||
| + | ||
| +import java.util.concurrent.Callable; | ||
| +import java.util.concurrent.TimeUnit; | ||
| + | ||
| +public class FirebaseArrayTest extends AndroidTestCase { | ||
| + private Firebase mRef; | ||
| + private FirebaseArray mArray; | ||
| + | ||
| + @Before | ||
| + public void setUp() throws Exception { | ||
| + Firebase.setAndroidContext(this.getContext()); | ||
| + mRef = new Firebase("https://firebaseui-tests.firebaseio-demo.com/firebasearray"); | ||
| + mArray = new FirebaseArray(mRef); | ||
| + mRef.removeValue(); | ||
| + runAndWaitUntil(mArray, mRef, new Runnable() { | ||
| + public void run() { | ||
| + for (int i = 1; i <= 3; i++) { | ||
| + mRef.push().setValue(i, i); | ||
| + } | ||
| + } | ||
| + }, new Callable<Boolean>() { | ||
| + public Boolean call() throws Exception { | ||
| + return mArray.getCount() == 3; | ||
| + } | ||
| + }); | ||
| + } | ||
| + | ||
| + @After | ||
| + public void tearDown() throws Exception { | ||
| + mArray.cleanup(); | ||
| + mRef.removeValue(); | ||
| + } | ||
| + | ||
| + @Test | ||
| + public void testSize() throws Exception { | ||
| + assertEquals(3, mArray.getCount()); | ||
| + } | ||
| + | ||
| + @Test | ||
| + public void testPushIncreasesSize() throws Exception { | ||
| + assertEquals(3, mArray.getCount()); | ||
| + runAndWaitUntil(mArray, mRef, new Runnable() { | ||
| + public void run() { | ||
| + mRef.push().setValue(4); | ||
| + } | ||
| + }, new Callable<Boolean>() { | ||
| + @Override | ||
| + public Boolean call() throws Exception { | ||
| + return mArray.getCount() == 4; | ||
| + } | ||
| + }); | ||
| + } | ||
| + @Test | ||
| + public void testPushAppends() throws Exception { | ||
| + runAndWaitUntil(mArray, mRef, new Runnable() { | ||
| + public void run() { | ||
| + mRef.push().setValue(4, 4); | ||
| + } | ||
| + }, new Callable<Boolean>() { | ||
| + @Override | ||
| + public Boolean call() throws Exception { | ||
| + return mArray.getItem(3).getValue(Integer.class).equals(4); | ||
| + } | ||
| + }); | ||
| + } | ||
| + | ||
| + @Test | ||
| + public void testAddValueWithPriority() throws Exception { | ||
| + runAndWaitUntil(mArray, mRef, new Runnable() { | ||
| + public void run() { | ||
| + mRef.push().setValue(4, 0.5); | ||
| + } | ||
| + }, new Callable<Boolean>() { | ||
| + public Boolean call() throws Exception { | ||
| + return mArray.getItem(3).getValue(Integer.class).equals(3) && mArray.getItem(0).getValue(Integer.class).equals(4); | ||
| + } | ||
| + }); | ||
| + } | ||
| + | ||
| + @Test | ||
| + public void testChangePriorities() throws Exception { | ||
| + runAndWaitUntil(mArray, mRef, new Runnable() { | ||
| + public void run() { | ||
| + mArray.getItem(2).getRef().setPriority(0.5); | ||
| + } | ||
| + }, new Callable<Boolean>() { | ||
| + public Boolean call() throws Exception { | ||
| + return isValuesEqual(mArray, new int[]{3, 1, 2}); | ||
| + } | ||
| + }); | ||
| + } | ||
| + | ||
| + private static boolean isValuesEqual(FirebaseArray array, int[] expected) { | ||
| + if (array.getCount() != expected.length) return false; | ||
| + for (int i=0; i < array.getCount(); i++) { | ||
| + if (!array.getItem(i).getValue(Integer.class).equals(expected[i])) { | ||
| + return false; | ||
| + } | ||
| + } | ||
| + return true; | ||
| + } | ||
| + | ||
| + private Integer getIntValue(FirebaseArray array, int index) { | ||
| + return array.getItem(index).getValue(Integer.class); | ||
| + } | ||
| + | ||
| + private static void print(FirebaseArray array) { | ||
| + for (int i=0; i < array.getCount(); i++) { | ||
| + System.out.println(i+": key="+array.getItem(i).getKey()+" value="+array.getItem(i).getValue()); | ||
| + | ||
| + } | ||
| + } | ||
| + | ||
| + public static void runAndWaitUntil(final FirebaseArray array, Firebase ref, Runnable task, Callable<Boolean> done) throws InterruptedException { | ||
| + final java.util.concurrent.Semaphore semaphore = new java.util.concurrent.Semaphore(0); | ||
| + array.setOnChangedListener(new FirebaseArray.OnChangedListener() { | ||
| + public void onChanged() { | ||
| + semaphore.release(); | ||
| + } | ||
| + }); | ||
| + task.run(); | ||
| + boolean isDone = false; | ||
| + long startedAt = System.currentTimeMillis(); | ||
| + while (!isDone && System.currentTimeMillis() - startedAt < 5000) { | ||
| + semaphore.tryAcquire(1, TimeUnit.SECONDS); | ||
| + try { | ||
| + isDone = done.call(); | ||
| + } catch (Exception e) { | ||
| + e.printStackTrace(); | ||
| + // and we're not done | ||
| + } | ||
| + } | ||
| + if (!isDone) { | ||
| + throw new AssertionFailedError(); | ||
| + } | ||
| + array.setOnChangedListener(null); | ||
| + } | ||
| +} |
7
library/src/main/AndroidManifest.xml
| @@ -0,0 +1,7 @@ | ||
| +<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.firebase.ui"> | ||
| + | ||
| + <application android:allowBackup="true" android:label="@string/app_name"> | ||
| + | ||
| + </application> | ||
| + | ||
| +</manifest> |
90
library/src/main/java/com/firebase/ui/FirebaseArray.java
| @@ -0,0 +1,90 @@ | ||
| +package com.firebase.ui; | ||
| + | ||
| +import com.firebase.client.*; | ||
| + | ||
| +import java.util.ArrayList; | ||
| + | ||
| +/** | ||
| + * This class implements an array-like collection on top of a Firebase location. | ||
| + */ | ||
| +class FirebaseArray implements ChildEventListener { | ||
| + public interface OnChangedListener { | ||
| + void onChanged(); | ||
| + } | ||
| + | ||
| + private Query mQuery; | ||
| + private OnChangedListener mListener; | ||
| + private ArrayList<DataSnapshot> mSnapshots; | ||
| + | ||
| + public FirebaseArray(Query ref) { | ||
| + mQuery = ref; | ||
| + mSnapshots = new ArrayList<>(); | ||
| + mQuery.addChildEventListener(this); | ||
| + } | ||
| + | ||
| + public void cleanup() { | ||
| + mQuery.removeEventListener(this); | ||
| + } | ||
| + | ||
| + public int getCount() { | ||
| + return mSnapshots.size(); | ||
| + | ||
| + } | ||
| + public DataSnapshot getItem(int index) { | ||
| + return mSnapshots.get(index); | ||
| + } | ||
| + | ||
| + private int getIndexForKey(String key) { | ||
| + int index = 0; | ||
| + for (DataSnapshot snapshot : mSnapshots) { | ||
| + if (snapshot.getKey().equals(key)) { | ||
| + return index; | ||
| + } else { | ||
| + index++; | ||
| + } | ||
| + } | ||
| + throw new IllegalArgumentException("Key not found"); | ||
| + } | ||
| + | ||
| + // Start of ChildEventListener methods | ||
| + public void onChildAdded(DataSnapshot snapshot, String previousChildKey) { | ||
| + int index = 0; | ||
| + if (previousChildKey != null) { | ||
| + index = getIndexForKey(previousChildKey) + 1; | ||
| + } | ||
| + mSnapshots.add(index, snapshot); | ||
| + notifyChangedListeners(); | ||
| + } | ||
| + | ||
| + public void onChildChanged(DataSnapshot snapshot, String previousChildKey) { | ||
| + int index = getIndexForKey(snapshot.getKey()); | ||
| + mSnapshots.set(index, snapshot); | ||
| + notifyChangedListeners(); | ||
| + } | ||
| + | ||
| + public void onChildRemoved(DataSnapshot snapshot) { | ||
| + int index = getIndexForKey(snapshot.getKey()); | ||
| + mSnapshots.remove(index); | ||
| + notifyChangedListeners(); | ||
| + } | ||
| + | ||
| + public void onChildMoved(DataSnapshot snapshot, String previousChildKey) { | ||
| + onChildRemoved(snapshot); | ||
| + onChildAdded(snapshot, previousChildKey); | ||
| + // TODO: this will send two change notifications, which is wrong | ||
| + } | ||
| + | ||
| + public void onCancelled(FirebaseError firebaseError) { | ||
| + // TODO: what do we do with this? | ||
| + } | ||
| + // End of ChildEventListener methods | ||
| + | ||
| + public void setOnChangedListener(OnChangedListener listener) { | ||
| + mListener = listener; | ||
| + } | ||
| + protected void notifyChangedListeners() { | ||
| + if (mListener != null) { | ||
| + mListener.onChanged(); | ||
| + } | ||
| + } | ||
| +} |
91
library/src/main/java/com/firebase/ui/FirebaseListAdapter.java
| @@ -0,0 +1,91 @@ | ||
| +package com.firebase.ui; | ||
| + | ||
| + | ||
| +import android.app.Activity; | ||
| +import android.view.View; | ||
| +import android.view.ViewGroup; | ||
| +import android.widget.BaseAdapter; | ||
| + | ||
| +import com.firebase.client.Query; | ||
| + | ||
| +/** | ||
| + * This class is a generic way of backing an Android ListView with a Firebase location. | ||
| + * It handles all of the child events at the given Firebase location. It marshals received data into the given | ||
| + * class type. Extend this class and provide an implementation of <code>populateView</code>, which will be given an | ||
| + * instance of your list item mLayout and an instance your class that holds your data. Simply populate the view however | ||
| + * you like and this class will handle updating the list as the data changes. | ||
| + * | ||
| + * @param <T> The class type to use as a model for the data contained in the children of the given Firebase location | ||
| + */ | ||
| +public abstract class FirebaseListAdapter<T> extends BaseAdapter { | ||
| + | ||
| + private final Class<T> mModelClass; | ||
| + protected int mLayout; | ||
| + protected Activity mActivity; | ||
| + FirebaseArray mSnapshots; | ||
| + | ||
| + | ||
| + /** | ||
| + * @param modelClass Firebase will marshall the data at a location into an instance of a class that you provide | ||
| + * @param layout This is the mLayout used to represent a single list item. You will be responsible for populating an | ||
| + * instance of the corresponding view with the data from an instance of mModelClass. | ||
| + * @param activity The activity containing the ListView | ||
| + * @param ref The Firebase location to watch for data changes. Can also be a slice of a location, using some | ||
| + * combination of <code>limit()</code>, <code>startAt()</code>, and <code>endAt()</code>, | ||
| + */ | ||
| + public FirebaseListAdapter(Class<T> modelClass, int layout, Activity activity, Query ref) { | ||
| + mModelClass = modelClass; | ||
| + mLayout = layout; | ||
| + mActivity = activity; | ||
| + mSnapshots = new FirebaseArray(ref); | ||
| + mSnapshots.setOnChangedListener(new FirebaseArray.OnChangedListener() { | ||
| + @Override | ||
| + public void onChanged() { | ||
| + notifyDataSetChanged(); | ||
| + } | ||
| + }); | ||
| + } | ||
| + | ||
| + public void cleanup() { | ||
| + // We're being destroyed, let go of our mListener and forget about all of the mModels | ||
| + mSnapshots.cleanup(); | ||
| + } | ||
| + | ||
| + @Override | ||
| + public int getCount() { | ||
| + return mSnapshots.getCount(); | ||
| + } | ||
| + | ||
| + @Override | ||
| + public Object getItem(int i) { return mSnapshots.getItem(i); } | ||
| + | ||
| + @Override | ||
| + public long getItemId(int i) { | ||
| + // http://stackoverflow.com/questions/5100071/whats-the-purpose-of-item-ids-in-android-listview-adapter | ||
| + return mSnapshots.getItem(i).getKey().hashCode(); | ||
| + } | ||
| + | ||
| + @Override | ||
| + public View getView(int i, View view, ViewGroup viewGroup) { | ||
| + if (view == null) { | ||
| + view = mActivity.getLayoutInflater().inflate(mLayout, viewGroup, false); | ||
| + } | ||
| + | ||
| + T model = mSnapshots.getItem(i).getValue(mModelClass); | ||
| + | ||
| + // Call out to subclass to marshall this model into the provided view | ||
| + populateView(view, model); | ||
| + return view; | ||
| + } | ||
| + | ||
| + /** | ||
| + * Each time the data at the given Firebase location changes, this method will be called for each item that needs | ||
| + * to be displayed. The arguments correspond to the mLayout and mModelClass given to the constructor of this class. | ||
| + * <p/> | ||
| + * Your implementation should populate the view using the data contained in the model. | ||
| + * | ||
| + * @param v The view to populate | ||
| + * @param model The object containing the data used to populate the view | ||
| + */ | ||
| + protected abstract void populateView(View v, T model); | ||
| +} |
75
library/src/main/java/com/firebase/ui/FirebaseRecyclerViewAdapter.java
| @@ -0,0 +1,75 @@ | ||
| +package com.firebase.ui; | ||
| + | ||
| +import android.support.v7.widget.RecyclerView; | ||
| +import android.util.Log; | ||
| + | ||
| +import com.firebase.client.ChildEventListener; | ||
| +import com.firebase.client.DataSnapshot; | ||
| +import com.firebase.client.FirebaseError; | ||
| +import com.firebase.client.Query; | ||
| + | ||
| +import java.util.ArrayList; | ||
| +import java.util.HashMap; | ||
| +import java.util.List; | ||
| +import java.util.Map; | ||
| + | ||
| +/** | ||
| + * This class is a generic way of backing an RecyclerView with a Firebase location. | ||
| + * It handles all of the child events at the given Firebase location. It marshals received data into the given | ||
| + * class type. | ||
| + * | ||
| + * @param <T> The collection type | ||
| + */ | ||
| +public abstract class FirebaseRecyclerViewAdapter<T, VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> { | ||
| + | ||
| + FirebaseArray mSnapshots; | ||
| + Class<T> mModelClass; | ||
| + protected RecyclerViewClickListener clickListener; | ||
| + | ||
| + | ||
| + /** | ||
| + * @param ref The Firebase location to watch for data changes. Can also be a slice of a location, using some | ||
| + * combination of <code>limit()</code>, <code>startAt()</code>, and <code>endAt()</code>, | ||
| + * @param modelClass Firebase will marshall the data at a location into an instance of a class that you provide | ||
| + */ | ||
| + public FirebaseRecyclerViewAdapter(Query ref, Class<T> modelClass) { | ||
| + mModelClass = modelClass; | ||
| + mSnapshots = new FirebaseArray(ref); | ||
| + | ||
| + // TODO: implement separate notifications for added, removed, changed and moved | ||
| + mSnapshots.setOnChangedListener(new FirebaseArray.OnChangedListener() { | ||
| + @Override | ||
| + public void onChanged() { | ||
| + notifyDataSetChanged(); | ||
| + } | ||
| + }); | ||
| + | ||
| + } | ||
| + | ||
| + public void cleanup() { | ||
| + mSnapshots.cleanup(); | ||
| + } | ||
| + | ||
| + @Override | ||
| + public int getItemCount() { | ||
| + return mSnapshots.getCount(); | ||
| + } | ||
| + | ||
| + public T getItem(int position) { | ||
| + return mSnapshots.getItem(position).getValue(mModelClass); | ||
| + } | ||
| + | ||
| + @Override | ||
| + public long getItemId(int position) { | ||
| + // http://stackoverflow.com/questions/5100071/whats-the-purpose-of-item-ids-in-android-listview-adapter | ||
| + return mSnapshots.getItem(position).getKey().hashCode(); | ||
| + } | ||
| + | ||
| + public void setClickListener(RecyclerViewClickListener clickListener) { | ||
| + this.clickListener = clickListener; | ||
| + } | ||
| + | ||
| + public interface RecyclerViewClickListener { | ||
| + public void onItemClicked(int position); | ||
| + } | ||
| +} |
3
library/src/main/res/values/strings.xml
| @@ -0,0 +1,3 @@ | ||
| +<resources> | ||
| + <string name="app_name">Library</string> | ||
| +</resources> |
1
settings.gradle
| @@ -0,0 +1 @@ | ||
| +include ':app', ':library' |
0 comments on commit
daf8a96