From b69510e97210c2f34846f7f4e10b64767b01316b Mon Sep 17 00:00:00 2001 From: inorichi Date: Thu, 24 Sep 2015 17:27:43 +0200 Subject: [PATCH] Initial commit --- .gitignore | 9 + .travis.yml | 19 ++ README.md | 21 ++ app/.gitignore | 4 + app/build.gradle | 85 ++++++++ app/proguard-rules.pro | 17 ++ app/src/main/AndroidManifest.xml | 35 ++++ .../main/java/eu/kanade/mangafeed/App.java | 34 +++ .../eu/kanade/mangafeed/AppComponent.java | 23 ++ .../java/eu/kanade/mangafeed/AppModule.java | 28 +++ .../eu/kanade/mangafeed/data/DataModule.java | 38 ++++ .../kanade/mangafeed/data/entities/Manga.java | 198 ++++++++++++++++++ .../data/helpers/DatabaseHelper.java | 43 ++++ .../mangafeed/data/helpers/DbOpenHelper.java | 31 +++ .../data/helpers/PreferencesHelper.java | 21 ++ .../data/tables/CategoriesTable.java | 18 ++ .../mangafeed/data/tables/ChaptersTable.java | 30 +++ .../data/tables/MangasCategoriesTable.java | 18 ++ .../mangafeed/data/tables/MangasTable.java | 85 ++++++++ .../mangafeed/ui/activity/BaseActivity.java | 32 +++ .../mangafeed/ui/activity/MainActivity.java | 85 ++++++++ .../mangafeed/ui/adapter/DetailHolder.java | 37 ++++ .../mangafeed/util/AndroidComponentUtil.java | 33 +++ .../eu/kanade/mangafeed/util/DataUtils.java | 13 ++ .../kanade/mangafeed/util/DialogFactory.java | 39 ++++ .../eu/kanade/mangafeed/util/NetworkUtil.java | 27 +++ .../mangafeed/util/SnackbarFactory.java | 18 ++ .../eu/kanade/mangafeed/util/ViewUtils.java | 13 ++ .../touchable_background_white.xml | 5 + .../drawable/touchable_background_white.xml | 6 + .../main/res/layout/activity_character.xml | 51 +++++ app/src/main/res/layout/activity_detail.xml | 46 ++++ app/src/main/res/layout/activity_main.xml | 55 +++++ app/src/main/res/layout/fragment_detail.xml | 26 +++ app/src/main/res/layout/item_character.xml | 92 ++++++++ app/src/main/res/layout/item_detail.xml | 11 + app/src/main/res/menu/main.xml | 6 + app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3011 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 1997 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4267 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 6631 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 9352 bytes app/src/main/res/values-w820dp/dimens.xml | 6 + app/src/main/res/values/colors.xml | 17 ++ app/src/main/res/values/dimens.xml | 13 ++ app/src/main/res/values/strings.xml | 57 +++++ app/src/main/res/values/styles.xml | 79 +++++++ .../eu/kanade/mangafeed/DataManagerTest.java | 70 +++++++ .../kanade/mangafeed/DatabaseHelperTest.java | 65 ++++++ .../kanade/mangafeed/util/DefaultConfig.java | 7 + build.gradle | 20 ++ gradle.properties | 18 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 49896 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 164 +++++++++++++++ gradlew.bat | 90 ++++++++ settings.gradle | 1 + 57 files changed, 1965 insertions(+) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 README.md create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/proguard-rules.pro create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/eu/kanade/mangafeed/App.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/AppComponent.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/AppModule.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/data/DataModule.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/data/entities/Manga.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/data/helpers/DatabaseHelper.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/data/helpers/DbOpenHelper.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/data/helpers/PreferencesHelper.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/data/tables/CategoriesTable.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/data/tables/ChaptersTable.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/data/tables/MangasCategoriesTable.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/data/tables/MangasTable.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/ui/activity/BaseActivity.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/ui/activity/MainActivity.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/ui/adapter/DetailHolder.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/util/AndroidComponentUtil.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/util/DataUtils.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/util/DialogFactory.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/util/NetworkUtil.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/util/SnackbarFactory.java create mode 100644 app/src/main/java/eu/kanade/mangafeed/util/ViewUtils.java create mode 100644 app/src/main/res/drawable-v21/touchable_background_white.xml create mode 100644 app/src/main/res/drawable/touchable_background_white.xml create mode 100644 app/src/main/res/layout/activity_character.xml create mode 100644 app/src/main/res/layout/activity_detail.xml create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/layout/fragment_detail.xml create mode 100644 app/src/main/res/layout/item_character.xml create mode 100644 app/src/main/res/layout/item_detail.xml create mode 100644 app/src/main/res/menu/main.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 app/src/main/res/values-w820dp/dimens.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/dimens.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/styles.xml create mode 100644 app/src/test/java/eu/kanade/mangafeed/DataManagerTest.java create mode 100644 app/src/test/java/eu/kanade/mangafeed/DatabaseHelperTest.java create mode 100644 app/src/test/java/eu/kanade/mangafeed/util/DefaultConfig.java create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..af291a578 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.gradle +/local.properties +/.idea/workspace.xml +.DS_Store +/build +.idea/ +*iml +*.iml +*/build \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..75aac8ad3 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,19 @@ +language: android +android: + components: + - platform-tools + - tools + + # The BuildTools version used by your project + - build-tools-23.0.1 + - android-23 + - extra-android-m2repository + - extra-google-m2repository + - extra-android-support + - extra-google-google_play_services + +before_script: + - chmod +x gradlew +#Build, and run tests +script: "./gradlew build testDebug" +sudo: false diff --git a/README.md b/README.md new file mode 100644 index 000000000..9cec6fe18 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +Mangafeed is a Manga reader for Android that tries to have the same features as Manga Watcher, but being Open Source. + +## License + +Copyright 2015 Javier Tomás + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +## Disclaimer + +The developer of this application does not have any affiliation with the content providers available. \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 000000000..8bd2d8bd6 --- /dev/null +++ b/app/.gitignore @@ -0,0 +1,4 @@ +/build +*iml +*.iml +.idea \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 000000000..b732e80f6 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,85 @@ +apply plugin: 'com.android.application' +apply plugin: 'com.neenbedankt.android-apt' + +android { + compileSdkVersion 23 + buildToolsVersion "23.0.1" + publishNonDefault true + + defaultConfig { + applicationId "eu.kanade.mangafeed" + minSdkVersion 16 + targetSdkVersion 23 + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + versionCode 1 + versionName "1.0" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + + packagingOptions { + exclude 'META-INF/DEPENDENCIES' + exclude 'LICENSE.txt' + exclude 'META-INF/LICENSE' + exclude 'META-INF/LICENSE.txt' + exclude 'META-INF/NOTICE' + } + + lintOptions { + abortOnError false + } + +} + +dependencies { + final SUPPORT_LIBRARY_VERSION = '23.0.1' + final DAGGER_VERSION = '2.0.1' + final HAMCREST_VERSION = '1.3' + final MOCKITO_VERSION = '1.10.19' + + compile fileTree(dir: 'libs', include: ['*.jar']) + + compile "com.android.support:support-v4:$SUPPORT_LIBRARY_VERSION" + compile "com.android.support:appcompat-v7:$SUPPORT_LIBRARY_VERSION" + compile "com.android.support:cardview-v7:$SUPPORT_LIBRARY_VERSION" + compile "com.android.support:design:$SUPPORT_LIBRARY_VERSION" + compile "com.android.support:recyclerview-v7:$SUPPORT_LIBRARY_VERSION" + compile "com.android.support:support-annotations:$SUPPORT_LIBRARY_VERSION" + compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta1' + compile 'com.squareup.okhttp:okhttp-urlconnection:2.4.0' + compile 'com.squareup.okhttp:okhttp:2.4.0' + compile 'com.pushtorefresh.storio:sqlite:1.4.0' + compile 'com.pushtorefresh.storio:sqlite-annotations:1.4.0' + compile 'de.greenrobot:eventbus:2.4.0' + compile 'com.github.bumptech.glide:glide:3.6.1' + compile 'de.hdodenhof:circleimageview:1.3.0' + compile 'io.reactivex:rxandroid:1.0.1' + compile 'com.jakewharton:butterknife:7.0.1' + compile 'com.jakewharton.timber:timber:3.1.0' + compile 'uk.co.ribot:easyadapter:1.5.0@aar' + + compile "com.google.dagger:dagger:$DAGGER_VERSION" + apt "com.google.dagger:dagger-compiler:$DAGGER_VERSION" + provided 'org.glassfish:javax.annotation:10.0-b28' + + compile('com.mikepenz:materialdrawer:4.3.0@aar') { + transitive = true + } + + testCompile 'junit:junit:4.12' + testCompile "org.hamcrest:hamcrest-core:$HAMCREST_VERSION" + testCompile "org.hamcrest:hamcrest-library:$HAMCREST_VERSION" + testCompile "org.hamcrest:hamcrest-integration:$HAMCREST_VERSION" + testCompile "org.mockito:mockito-core:$MOCKITO_VERSION" + testCompile('org.robolectric:robolectric:3.0') { + exclude group: 'commons-logging', module: 'commons-logging' + exclude group: 'org.apache.httpcomponents', module: 'httpclient' + } + + androidTestApt "com.google.dagger:dagger-compiler:$DAGGER_VERSION" +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 000000000..8e5eebc2b --- /dev/null +++ b/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/hitherejoe/Android Studio.app/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/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..445d7a99b --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/eu/kanade/mangafeed/App.java b/app/src/main/java/eu/kanade/mangafeed/App.java new file mode 100644 index 000000000..3e0039dcc --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/App.java @@ -0,0 +1,34 @@ +package eu.kanade.mangafeed; + +import android.app.Application; +import android.content.Context; + +import timber.log.Timber; + +public class App extends Application { + + AppComponent mApplicationComponent; + + @Override + public void onCreate() { + super.onCreate(); + if (BuildConfig.DEBUG) Timber.plant(new Timber.DebugTree()); + + mApplicationComponent = DaggerAppComponent.builder() + .appModule(new AppModule(this)) + .build(); + } + + public static App get(Context context) { + return (App) context.getApplicationContext(); + } + + public AppComponent getComponent() { + return mApplicationComponent; + } + + // Needed to replace the component with a test specific one + public void setComponent(AppComponent applicationComponent) { + mApplicationComponent = applicationComponent; + } +} diff --git a/app/src/main/java/eu/kanade/mangafeed/AppComponent.java b/app/src/main/java/eu/kanade/mangafeed/AppComponent.java new file mode 100644 index 000000000..765f1bf94 --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/AppComponent.java @@ -0,0 +1,23 @@ +package eu.kanade.mangafeed; + +import android.app.Application; + +import javax.inject.Singleton; + +import dagger.Component; +import eu.kanade.mangafeed.data.DataModule; +import eu.kanade.mangafeed.ui.activity.MainActivity; + +@Singleton +@Component( + modules = { + AppModule.class, + DataModule.class + } +) +public interface AppComponent { + + void inject(MainActivity mainActivity); + + Application application(); +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/mangafeed/AppModule.java b/app/src/main/java/eu/kanade/mangafeed/AppModule.java new file mode 100644 index 000000000..a9b8c3784 --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/AppModule.java @@ -0,0 +1,28 @@ +package eu.kanade.mangafeed; + +import android.app.Application; + +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; + +/** + * Provide application-level dependencies. Mainly singleton object that can be injected from + * anywhere in the app. + */ +@Module +public class AppModule { + protected final Application mApplication; + + public AppModule(Application application) { + mApplication = application; + } + + @Provides + @Singleton + Application provideApplication() { + return mApplication; + } + +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/mangafeed/data/DataModule.java b/app/src/main/java/eu/kanade/mangafeed/data/DataModule.java new file mode 100644 index 000000000..713ba7d0c --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/data/DataModule.java @@ -0,0 +1,38 @@ +package eu.kanade.mangafeed.data; + +import android.app.Application; + +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; +import eu.kanade.mangafeed.data.helpers.PreferencesHelper; +import eu.kanade.mangafeed.data.helpers.DatabaseHelper; +import rx.Scheduler; +import rx.schedulers.Schedulers; + +/** + * Provide dependencies to the DataManager, mainly Helper classes and Retrofit services. + */ +@Module +public class DataModule { + + @Provides + @Singleton + PreferencesHelper providePreferencesHelper(Application app) { + return new PreferencesHelper(app); + } + + @Provides + @Singleton + DatabaseHelper provideDatabaseHelper(Application app) { + return new DatabaseHelper(app); + } + + @Provides + @Singleton + Scheduler provideSubscribeScheduler() { + return Schedulers.io(); + } + +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/mangafeed/data/entities/Manga.java b/app/src/main/java/eu/kanade/mangafeed/data/entities/Manga.java new file mode 100644 index 000000000..a52873c2b --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/data/entities/Manga.java @@ -0,0 +1,198 @@ +package eu.kanade.mangafeed.data.entities; + +/** + * Created by len on 23/09/2015. + */ + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteColumn; +import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteType; + +import eu.kanade.mangafeed.data.tables.MangasTable; + +@StorIOSQLiteType(table = MangasTable.TABLE) +public class Manga { + + @Nullable + @StorIOSQLiteColumn(name = MangasTable.COLUMN_ID, key = true) + Long id; + + @NonNull + @StorIOSQLiteColumn(name = MangasTable.COLUMN_SOURCE) + int source; + + @NonNull + @StorIOSQLiteColumn(name = MangasTable.COLUMN_URL) + String url; + + @NonNull + @StorIOSQLiteColumn(name = MangasTable.COLUMN_ARTIST) + String artist; + + @NonNull + @StorIOSQLiteColumn(name = MangasTable.COLUMN_AUTHOR) + String author; + + @NonNull + @StorIOSQLiteColumn(name = MangasTable.COLUMN_DESCRIPTION) + String description; + + @NonNull + @StorIOSQLiteColumn(name = MangasTable.COLUMN_GENRE) + String genre; + + @NonNull + @StorIOSQLiteColumn(name = MangasTable.COLUMN_TITLE) + String title; + + @NonNull + @StorIOSQLiteColumn(name = MangasTable.COLUMN_STATUS) + String status; + + @NonNull + @StorIOSQLiteColumn(name = MangasTable.COLUMN_THUMBNAIL_URL) + String thumbnail_url; + + @NonNull + @StorIOSQLiteColumn(name = MangasTable.COLUMN_RANK) + int rank; + + @NonNull + @StorIOSQLiteColumn(name = MangasTable.COLUMN_LAST_UPDATE) + long last_update; + + @NonNull + @StorIOSQLiteColumn(name = MangasTable.COLUMN_INITIALIZED) + boolean initialized; + + @NonNull + @StorIOSQLiteColumn(name = MangasTable.COLUMN_VIEWER) + int viewer; + + @NonNull + @StorIOSQLiteColumn(name = MangasTable.COLUMN_CHAPTER_ORDER) + int chapter_order; + + Manga() {} + + @Nullable + public Long id() { + return id; + } + + @NonNull + public int source() { + return source; + } + + @NonNull + public String url() { + return url; + } + + @NonNull + public String artist() { + return artist; + } + + @NonNull + public String author() { + return author; + } + + @NonNull + public String description() { + return description; + } + + @NonNull + public String genre() { + return genre; + } + + @NonNull + public String title() { + return title; + } + + @NonNull + public String status() { + return status; + } + + @NonNull + public String thumbnail_url() { + return thumbnail_url; + } + + @NonNull + public int rank() { + return rank; + } + + @NonNull + public long last_update() { + return last_update; + } + + @NonNull + public boolean nitialized() { + return initialized; + } + + @NonNull + public int viewer() { + return viewer; + } + + @NonNull + public int chapter_order() { + return chapter_order; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Manga manga = (Manga) o; + + if (source != manga.source) return false; + if (rank != manga.rank) return false; + if (last_update != manga.last_update) return false; + if (initialized != manga.initialized) return false; + if (viewer != manga.viewer) return false; + if (chapter_order != manga.chapter_order) return false; + if (id != null ? !id.equals(manga.id) : manga.id != null) return false; + if (!url.equals(manga.url)) return false; + if (!artist.equals(manga.artist)) return false; + if (!author.equals(manga.author)) return false; + if (!description.equals(manga.description)) return false; + if (!genre.equals(manga.genre)) return false; + if (!title.equals(manga.title)) return false; + if (!status.equals(manga.status)) return false; + return thumbnail_url.equals(manga.thumbnail_url); + + } + + @Override + public int hashCode() { + int result = id != null ? id.hashCode() : 0; + result = 31 * result + source; + result = 31 * result + url.hashCode(); + result = 31 * result + artist.hashCode(); + result = 31 * result + author.hashCode(); + result = 31 * result + description.hashCode(); + result = 31 * result + genre.hashCode(); + result = 31 * result + title.hashCode(); + result = 31 * result + status.hashCode(); + result = 31 * result + thumbnail_url.hashCode(); + result = 31 * result + rank; + result = 31 * result + (int) (last_update ^ (last_update >>> 32)); + result = 31 * result + (initialized ? 1 : 0); + result = 31 * result + viewer; + result = 31 * result + chapter_order; + return result; + } +} diff --git a/app/src/main/java/eu/kanade/mangafeed/data/helpers/DatabaseHelper.java b/app/src/main/java/eu/kanade/mangafeed/data/helpers/DatabaseHelper.java new file mode 100644 index 000000000..2b767e0f5 --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/data/helpers/DatabaseHelper.java @@ -0,0 +1,43 @@ +package eu.kanade.mangafeed.data.helpers; + +import android.content.Context; + +import com.pushtorefresh.storio.sqlite.StorIOSQLite; +import com.pushtorefresh.storio.sqlite.impl.DefaultStorIOSQLite; +import com.pushtorefresh.storio.sqlite.queries.Query; + +import java.util.List; + +import eu.kanade.mangafeed.data.entities.Manga; +import eu.kanade.mangafeed.data.tables.MangasTable; +import rx.Observable; + +/** + * Created by len on 23/09/2015. + */ +public class DatabaseHelper { + + private StorIOSQLite db; + + public DatabaseHelper(Context context) { + db = DefaultStorIOSQLite.builder() + .sqliteOpenHelper(new DbOpenHelper(context)) + .build(); + } + + public StorIOSQLite getStorIODb() { + return db; + } + + public Observable> getMangas() { + return db.get() + .listOfObjects(Manga.class) + .withQuery(Query.builder() + .table(MangasTable.TABLE) + .build()) + .prepare() + .createObservable(); + + } + +} diff --git a/app/src/main/java/eu/kanade/mangafeed/data/helpers/DbOpenHelper.java b/app/src/main/java/eu/kanade/mangafeed/data/helpers/DbOpenHelper.java new file mode 100644 index 000000000..d3e0fcd4d --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/data/helpers/DbOpenHelper.java @@ -0,0 +1,31 @@ +package eu.kanade.mangafeed.data.helpers; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.support.annotation.NonNull; + +import eu.kanade.mangafeed.data.tables.MangasTable; + +/** + * Created by len on 23/09/2015. + */ +public class DbOpenHelper extends SQLiteOpenHelper { + + public static final String DATABASE_NAME = "mangafeed.db"; + public static final int DATABASE_VERSION = 1; + + public DbOpenHelper(@NonNull Context context) { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + + @Override + public void onCreate(@NonNull SQLiteDatabase db) { + db.execSQL(MangasTable.getCreateTableQuery()); + } + + @Override + public void onUpgrade(@NonNull SQLiteDatabase db, int oldVersion, int newVersion) { + // no impl + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/mangafeed/data/helpers/PreferencesHelper.java b/app/src/main/java/eu/kanade/mangafeed/data/helpers/PreferencesHelper.java new file mode 100644 index 000000000..cab0d887c --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/data/helpers/PreferencesHelper.java @@ -0,0 +1,21 @@ +package eu.kanade.mangafeed.data.helpers; + +import android.content.Context; +import android.content.SharedPreferences; + +public class PreferencesHelper { + + private static SharedPreferences mPref; + + public static final String PREF_FILE_NAME = "android_boilerplate_pref_file"; + + + public PreferencesHelper(Context context) { + mPref = context.getSharedPreferences(PREF_FILE_NAME, Context.MODE_PRIVATE); + } + + public void clear() { + mPref.edit().clear().apply(); + } + +} diff --git a/app/src/main/java/eu/kanade/mangafeed/data/tables/CategoriesTable.java b/app/src/main/java/eu/kanade/mangafeed/data/tables/CategoriesTable.java new file mode 100644 index 000000000..5e5c56642 --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/data/tables/CategoriesTable.java @@ -0,0 +1,18 @@ +package eu.kanade.mangafeed.data.tables; + +import android.support.annotation.NonNull; + +/** + * Created by len on 23/09/2015. + */ +public class CategoriesTable { + + @NonNull + public static final String TABLE = "categories"; + + @NonNull + public static final String COLUMN_ID = "_id"; + + @NonNull + public static final String COLUMN_NAME = "name"; +} diff --git a/app/src/main/java/eu/kanade/mangafeed/data/tables/ChaptersTable.java b/app/src/main/java/eu/kanade/mangafeed/data/tables/ChaptersTable.java new file mode 100644 index 000000000..121afb00b --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/data/tables/ChaptersTable.java @@ -0,0 +1,30 @@ +package eu.kanade.mangafeed.data.tables; + +import android.support.annotation.NonNull; + +/** + * Created by len on 23/09/2015. + */ +public class ChaptersTable { + + @NonNull + public static final String TABLE = "chapters"; + + @NonNull + public static final String COLUMN_ID = "_id"; + + @NonNull + public static final String COLUMN_MANGA_ID = "manga_id"; + + @NonNull + public static final String COLUMN_URL = "url"; + + @NonNull + public static final String COLUMN_NAME = "name"; + + @NonNull + public static final String COLUMN_READ = "read"; + + @NonNull + public static final String COLUMN_DATE_FETCH = "date_fetch"; +} diff --git a/app/src/main/java/eu/kanade/mangafeed/data/tables/MangasCategoriesTable.java b/app/src/main/java/eu/kanade/mangafeed/data/tables/MangasCategoriesTable.java new file mode 100644 index 000000000..9b641139c --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/data/tables/MangasCategoriesTable.java @@ -0,0 +1,18 @@ +package eu.kanade.mangafeed.data.tables; + +import android.support.annotation.NonNull; + +/** + * Created by len on 23/09/2015. + */ +public class MangasCategoriesTable { + + @NonNull + public static final String TABLE = "mangas_categories"; + + @NonNull + public static final String COLUMN_MANGA_ID = "_manga_id"; + + @NonNull + public static final String COLUMN_CATEGORY_ID = "_category_id"; +} diff --git a/app/src/main/java/eu/kanade/mangafeed/data/tables/MangasTable.java b/app/src/main/java/eu/kanade/mangafeed/data/tables/MangasTable.java new file mode 100644 index 000000000..e166cbcba --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/data/tables/MangasTable.java @@ -0,0 +1,85 @@ +package eu.kanade.mangafeed.data.tables; + +import android.support.annotation.NonNull; + +/** + * Created by len on 23/09/2015. + */ +public class MangasTable { + + @NonNull + public static final String TABLE = "mangas"; + + @NonNull + public static final String COLUMN_ID = "_id"; + + @NonNull + public static final String COLUMN_SOURCE = "source"; + + @NonNull + public static final String COLUMN_URL = "url"; + + @NonNull + public static final String COLUMN_ARTIST = "artist"; + + @NonNull + public static final String COLUMN_AUTHOR = "author" ; + + @NonNull + public static final String COLUMN_DESCRIPTION = "description"; + + @NonNull + public static final String COLUMN_GENRE = "genre"; + + @NonNull + public static final String COLUMN_TITLE = "title"; + + @NonNull + public static final String COLUMN_STATUS = "status"; + + @NonNull + public static final String COLUMN_THUMBNAIL_URL = "thumbnail_url"; + + @NonNull + public static final String COLUMN_RANK = "rank"; + + @NonNull + public static final String COLUMN_LAST_UPDATE = "last_update"; + + @NonNull + public static final String COLUMN_INITIALIZED = "initialized"; + + @NonNull + public static final String COLUMN_VIEWER = "viewer"; + + @NonNull + public static final String COLUMN_CHAPTER_ORDER = "chapter_order"; + + // This is just class with Meta Data, we don't need instances + private MangasTable() { + throw new IllegalStateException("No instances please"); + } + + // Better than static final field -> allows VM to unload useless String + // Because you need this string only once per application life on the device + @NonNull + public static String getCreateTableQuery() { + return "CREATE TABLE " + TABLE + "(" + + COLUMN_ID + " INTEGER NOT NULL PRIMARY KEY, " + + COLUMN_SOURCE + " INTEGER NOT NULL, " + + COLUMN_URL + " TEXT NOT NULL, " + + COLUMN_ARTIST + " TEXT NOT NULL, " + + COLUMN_AUTHOR + " TEXT NOT NULL, " + + COLUMN_DESCRIPTION + " TEXT NOT NULL, " + + COLUMN_GENRE + " TEXT NOT NULL, " + + COLUMN_TITLE + " TEXT NOT NULL, " + + COLUMN_STATUS + " TEXT NOT NULL, " + + COLUMN_THUMBNAIL_URL + " TEXT NOT NULL, " + + COLUMN_RANK + " INTEGER NOT NULL, " + + COLUMN_LAST_UPDATE + " LONG NOT NULL, " + + COLUMN_INITIALIZED + " BOOLEAN NOT NULL, " + + COLUMN_VIEWER + " INTEGER NOT NULL, " + + COLUMN_CHAPTER_ORDER + " INTEGER NOT NULL" + + ");"; + } +} diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/activity/BaseActivity.java b/app/src/main/java/eu/kanade/mangafeed/ui/activity/BaseActivity.java new file mode 100644 index 000000000..6f96cdea9 --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/ui/activity/BaseActivity.java @@ -0,0 +1,32 @@ +package eu.kanade.mangafeed.ui.activity; + +import android.app.FragmentManager; +import android.support.v7.app.AppCompatActivity; +import android.view.MenuItem; + +import eu.kanade.mangafeed.App; +import eu.kanade.mangafeed.AppComponent; + +public class BaseActivity extends AppCompatActivity { + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + FragmentManager fm = getFragmentManager(); + if (fm.getBackStackEntryCount() > 0) { + fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); + } else { + finish(); + } + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + protected AppComponent applicationComponent() { + return App.get(this).getComponent(); + } + +} diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/activity/MainActivity.java b/app/src/main/java/eu/kanade/mangafeed/ui/activity/MainActivity.java new file mode 100644 index 000000000..3ddeb5772 --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/ui/activity/MainActivity.java @@ -0,0 +1,85 @@ +package eu.kanade.mangafeed.ui.activity; + +import android.os.Bundle; +import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.ProgressBar; + +import javax.inject.Inject; + +import eu.kanade.mangafeed.R; + +import butterknife.Bind; +import butterknife.ButterKnife; +import eu.kanade.mangafeed.data.helpers.DatabaseHelper; +import rx.subscriptions.CompositeSubscription; +import timber.log.Timber; +import uk.co.ribot.easyadapter.EasyRecyclerAdapter; + +public class MainActivity extends BaseActivity { + + @Bind(R.id.recycler_characters) + RecyclerView mCharactersRecycler; + + @Bind(R.id.toolbar) + Toolbar mToolbar; + + @Bind(R.id.progress_indicator) + ProgressBar mProgressBar; + + @Bind(R.id.swipe_container) + SwipeRefreshLayout mSwipeRefresh; + + @Inject DatabaseHelper mDb; + private CompositeSubscription mSubscriptions; + private EasyRecyclerAdapter mEasyRecycleAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + applicationComponent().inject(this); + setContentView(R.layout.activity_main); + ButterKnife.bind(this); + mSubscriptions = new CompositeSubscription(); + //mDataManager = App.get(this).getComponent().dataManager(); + setupToolbar(); + setupRecyclerView(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mSubscriptions.unsubscribe(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_github: + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + private void setupToolbar() { + setSupportActionBar(mToolbar); + } + + private void setupRecyclerView() { + mCharactersRecycler.setLayoutManager(new LinearLayoutManager(this)); + mCharactersRecycler.setAdapter(mEasyRecycleAdapter); + + mSwipeRefresh.setColorSchemeResources(R.color.primary); + } +} diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/adapter/DetailHolder.java b/app/src/main/java/eu/kanade/mangafeed/ui/adapter/DetailHolder.java new file mode 100644 index 000000000..45a7630c3 --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/ui/adapter/DetailHolder.java @@ -0,0 +1,37 @@ +package eu.kanade.mangafeed.ui.adapter; + +import android.content.Intent; +import android.net.Uri; +import android.view.View; +import android.widget.TextView; + +import uk.co.ribot.easyadapter.ItemViewHolder; +import uk.co.ribot.easyadapter.PositionInfo; +import uk.co.ribot.easyadapter.annotations.LayoutId; +import uk.co.ribot.easyadapter.annotations.ViewId; + +@LayoutId(eu.kanade.mangafeed.R.layout.item_detail) +public class DetailHolder extends ItemViewHolder { + + @ViewId(eu.kanade.mangafeed.R.id.text_detail) + TextView mDetailText; + + public DetailHolder(View view) { + super(view); + } + + @Override + public void onSetValues(String item, PositionInfo positionInfo) { + mDetailText.setText(item); + } + + @Override + public void onSetListeners() { + mDetailText.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getItem()))); + } + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/mangafeed/util/AndroidComponentUtil.java b/app/src/main/java/eu/kanade/mangafeed/util/AndroidComponentUtil.java new file mode 100644 index 000000000..3789160fe --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/util/AndroidComponentUtil.java @@ -0,0 +1,33 @@ +package eu.kanade.mangafeed.util; + +import android.app.ActivityManager; +import android.app.ActivityManager.RunningServiceInfo; +import android.content.ComponentName; +import android.content.Context; +import android.content.pm.PackageManager; + +import timber.log.Timber; + +public class AndroidComponentUtil { + + public static void toggleComponent(Context context, Class componentClass, boolean enable) { + Timber.i((enable ? "Enabling " : "Disabling ") + componentClass.getSimpleName()); + ComponentName componentName = new ComponentName(context, componentClass); + PackageManager pm = context.getPackageManager(); + pm.setComponentEnabledSetting(componentName, + enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : + PackageManager.COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP); + } + + public static boolean isServiceRunning(Context context, Class serviceClass) { + ActivityManager manager = + (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { + if (serviceClass.getName().equals(service.service.getClassName())) { + return true; + } + } + return false; + } +} diff --git a/app/src/main/java/eu/kanade/mangafeed/util/DataUtils.java b/app/src/main/java/eu/kanade/mangafeed/util/DataUtils.java new file mode 100644 index 000000000..2e8a09120 --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/util/DataUtils.java @@ -0,0 +1,13 @@ +package eu.kanade.mangafeed.util; + +import android.content.Context; +import android.net.ConnectivityManager; + +public class DataUtils { + + public static boolean isNetworkAvailable(Context context) { + ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + return connectivityManager.getActiveNetworkInfo() != null; + } + +} diff --git a/app/src/main/java/eu/kanade/mangafeed/util/DialogFactory.java b/app/src/main/java/eu/kanade/mangafeed/util/DialogFactory.java new file mode 100644 index 000000000..c9b9ba171 --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/util/DialogFactory.java @@ -0,0 +1,39 @@ +package eu.kanade.mangafeed.util; + +import android.app.Dialog; +import android.app.ProgressDialog; +import android.content.Context; +import android.support.annotation.StringRes; +import android.support.v7.app.AlertDialog; + +import eu.kanade.mangafeed.R; + +public class DialogFactory { + + public static Dialog createSimpleOkErrorDialog(Context context, String title, String message) { + AlertDialog.Builder alertDialog = new AlertDialog.Builder(context) + .setTitle(title) + .setMessage(message) + .setNeutralButton(R.string.dialog_action_ok, null); + return alertDialog.create(); + } + + public static Dialog createSimpleErrorDialog(Context context) { + AlertDialog.Builder alertDialog = new AlertDialog.Builder(context) + .setTitle(context.getString(R.string.dialog_error_title)) + .setMessage(context.getString(R.string.dialog_general_error_Message)) + .setNeutralButton(R.string.dialog_action_ok, null); + return alertDialog.create(); + } + + public static ProgressDialog createProgressDialog(Context context, String message) { + ProgressDialog progressDialog = new ProgressDialog(context); + progressDialog.setMessage(message); + return progressDialog; + } + + public static ProgressDialog createProgressDialog(Context context, @StringRes int messageResoruce) { + return createProgressDialog(context, context.getString(messageResoruce)); + } + +} diff --git a/app/src/main/java/eu/kanade/mangafeed/util/NetworkUtil.java b/app/src/main/java/eu/kanade/mangafeed/util/NetworkUtil.java new file mode 100644 index 000000000..c5fdcf15e --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/util/NetworkUtil.java @@ -0,0 +1,27 @@ +package eu.kanade.mangafeed.util; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; + +import retrofit.HttpException; + +public class NetworkUtil { + + /** + * Returns true if the Throwable is an instance of RetrofitError with an + * http status code equals to the given one. + */ + public static boolean isHttpStatusCode(Throwable throwable, int statusCode) { + return throwable instanceof HttpException + && ((HttpException) throwable).code() == statusCode; + } + + public static boolean isNetworkConnected(Context context) { + ConnectivityManager cm = + (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); + return activeNetwork != null && activeNetwork.isConnectedOrConnecting(); + } + +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/mangafeed/util/SnackbarFactory.java b/app/src/main/java/eu/kanade/mangafeed/util/SnackbarFactory.java new file mode 100644 index 000000000..208798372 --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/util/SnackbarFactory.java @@ -0,0 +1,18 @@ +package eu.kanade.mangafeed.util; + +import android.content.Context; +import android.support.design.widget.Snackbar; +import android.view.View; +import android.view.ViewGroup; + +import eu.kanade.mangafeed.R; + +public class SnackbarFactory { + + public static Snackbar createSnackbar(Context context, View view, String message) { + Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_SHORT); + ViewGroup group = (ViewGroup) snackbar.getView(); + group.setBackgroundColor(context.getResources().getColor(R.color.primary)); + return snackbar; + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/mangafeed/util/ViewUtils.java b/app/src/main/java/eu/kanade/mangafeed/util/ViewUtils.java new file mode 100644 index 000000000..18ba0d533 --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/util/ViewUtils.java @@ -0,0 +1,13 @@ +package eu.kanade.mangafeed.util; + +import android.content.Context; +import android.util.DisplayMetrics; + +public class ViewUtils { + + public static float convertPixelsToDp(float px, Context context){ + DisplayMetrics metrics = context.getResources().getDisplayMetrics(); + return px / (metrics.densityDpi / 160f); + } + +} diff --git a/app/src/main/res/drawable-v21/touchable_background_white.xml b/app/src/main/res/drawable-v21/touchable_background_white.xml new file mode 100644 index 000000000..322353b5f --- /dev/null +++ b/app/src/main/res/drawable-v21/touchable_background_white.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/touchable_background_white.xml b/app/src/main/res/drawable/touchable_background_white.xml new file mode 100644 index 000000000..26044d48f --- /dev/null +++ b/app/src/main/res/drawable/touchable_background_white.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_character.xml b/app/src/main/res/layout/activity_character.xml new file mode 100644 index 000000000..f5308b852 --- /dev/null +++ b/app/src/main/res/layout/activity_character.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_detail.xml b/app/src/main/res/layout/activity_detail.xml new file mode 100644 index 000000000..142aed362 --- /dev/null +++ b/app/src/main/res/layout/activity_detail.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 000000000..8442153a0 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_detail.xml b/app/src/main/res/layout/fragment_detail.xml new file mode 100644 index 000000000..3f8036eb5 --- /dev/null +++ b/app/src/main/res/layout/fragment_detail.xml @@ -0,0 +1,26 @@ + + + + + + + + diff --git a/app/src/main/res/layout/item_character.xml b/app/src/main/res/layout/item_character.xml new file mode 100644 index 000000000..97fc49264 --- /dev/null +++ b/app/src/main/res/layout/item_character.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_detail.xml b/app/src/main/res/layout/item_detail.xml new file mode 100644 index 000000000..e803d438e --- /dev/null +++ b/app/src/main/res/layout/item_detail.xml @@ -0,0 +1,11 @@ + + diff --git a/app/src/main/res/menu/main.xml b/app/src/main/res/menu/main.xml new file mode 100644 index 000000000..537e37cfa --- /dev/null +++ b/app/src/main/res/menu/main.xml @@ -0,0 +1,6 @@ + + + diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..e9a0778879870fecb209d0169a4ddcbf8071734b GIT binary patch literal 3011 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 FV1ivavjhMD literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..03e8228d80bdea089031770aa50180f9be236697 GIT binary patch literal 1997 zcmV;;2Qv7HP)Px+hee5S!rxkRTTc-o2@e)XiF<}u@owl%D8}AED>pqh@v70ZZR4)LE|6& zp?~m?qlp^h5`QX*OALnK0%GD$q=JfQ163(trGj(?OG}sOtnWR~xifE>&a|a7)07{c zst218zT(q^cEY?2y=x$|Fw)}p- z%-5tkO`-C5cv5CJp{z2V2RFS~440g5i#oI^#5bmC#SxVdRs-+9^voGnvSQOaB@xgS z9`*Y@VKx6%Nz?8mMTf3DP4}oKN!wj=;OWhN|A>xJ$70tD)_W-Cd0m#Y$FymgcPo-a zS<@aL3fXxgA06Flcz_oyFP8hB@|QT>?!$m|fd(xiK_ZgV#YCc!wU{hP&S)gu+uPZG z+1Fb(ck5W0jImJl-6k>|D5821HpGrSL^{$mU62zP2!`Z{X;H=o9V?d&0{p-d431Ff zPurBoL5%UMhEyYBbd?kW+#pfh=nCi4T~p7I!1)AvA}nb=Fj1%TsXgsBnhij&$Bi4V zxg3kCDp54k3%lKh;gJxYe``xNX2?d#N zQd&}s)yuEN(u-?y=8236JhbK}BWxI8TSpgcvW%;Ii}3CXo6vRo4EhI$aOCe3I)0QC z6%hD^&=Ofgw2bt3>i&RyVp>}>10wY1Z_vu$+_T70dEWhGXixwqc)bEK0){E_y z8`w%T3r}RUh!<3rCxPMz-f1F{C}w)yXg<;gcb*e>uWCR!t(DQz+jka`Xf!F|qI4M! zr)#w8gwGifP*oKp!4N#|yrcmZFPI0u)~~EjsvrGOTU`a;!uc2pg)ulBFv2Ml5*ZN) z(!foJjtUY<;3%&3z_QtFu-W1fswgV>ZEOhXl@-rI!!=6~j>a%+h8JJ|)PyqwgP1Id zj0k)~TV{3nY;3q`1!fh@G;mo90<@}#ol2(jkWR*`qnFv6zaDNC1h_61jlk}3>doWc zGa_)BVmL-I8>W~aOBk>YT2<+UM5ofk#*@$4+*N$30EW7z|LXleD#WVPA8LxPEFrM44((gx#Wfl}Yav-k)N$&?l0NJitaz z_MFB$JHEh;bytZq|IhTsjmBblaLp>XoDTH#_Tjbnwjn^_!Jh=A9be))+EODF^Gz*( zLZOX-g%0fEp8VNBUrB%xi;f#k857`9yL!*!rOjJ#&n*oUP7#qxa9C~Ja4U{?bc?Xj z-?|KN?}0zWY+tds2BB~SwbhlVES-acM~`7o({F+Z&%7>r$T5krBr5`!(pGr?>IM|j zE^?)>mUfk;sG(3`siT+O#TQj!_x=NvnV!M^KaL1!UXKTJ%Vy)Y70cjs*y)YkDZ(iZ zFcrLBuaI}sNmc~DrQN8vuOE-!dk5^aZO$ncUpJg>*jN zxZyVP*jY-mzd-Y!#}X=Ifi&wa{H$h0IVS|zQj|88ZC~xi_Fa3iX#QMWR9S|S!UB31 z*u)!~(~mdlz|&2;lPM<1v1Wce@N6e%1lX9vl_xUGL&uJTuhF8vq~i6H1#jwG?Pk3O ztj4&^B+^MX;LQvx)pE`W@DQWZ;;919W2GgKi;ufHiJXC_2$Ezu`GuX1fQ?c|T2Sc& zjww$Eu>7)=pXBu{g zBaxKFZKQ%v*f#mm?C}HF(;pm^)6uh2RTU-Je^z9Kjg98;1|$A=hW~$R-2OrD&_Mrp zyzP-QoHQVLgy>{(ktaldnZ&e1zSeD8>Sf7V&qrw4N!T$w(Et6fyFTw07#saYUSW8^ z$H&$d2y<;r!g8HGj5$+nH=f+iySurl)*bGlPK5=Wv*Dvc@Auc8d~_5E;Q*Uo3D zC1SxTil(JROX6QZK3$hqRM%9`@D_OZt6T2Gm^?C>ZvM=XIKLVk9td{*-P%UAJ%lYx zS3D0l)ly4L!sqkxnT}5^d}f@^E1$72rc|U8ghhS5-(FMGmExszhNh~nwY6Mpw8Z>W fjq|_VOlROfngEaEx|%vs00000NkvXXu0mjfcizw> literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..2ec8eb35f7327225aec71f67eaa0bb99f4c69851 GIT binary patch literal 4267 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 N002ovPDHLkV1mYJ5dr`J literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..9abdc53d9e29b005f03e077fe2048f995fdfa792 GIT binary patch literal 6631 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 Q3C@>OTcC?WZ-!?3`JIz^#`6zS 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 + + 64dp + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 000000000..9af6059c6 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,17 @@ + + + #607D8B + #455A64 + #CFD8DC + #009688 + #212121 + #727272 + #FFFFFF + #B6B6B6 + #FFFFFF + #FAFAFA + #D7D7D7 + #D4D4D4 + #E9E9E9 + #DD000000 + \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 000000000..5fd4e5815 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,13 @@ + + + 16dp + 16dp + + 24sp + 22sp + 20sp + 18sp + 16sp + 14sp + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 000000000..b87192286 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,57 @@ + + AndroidBoilerPlate + + + Boilerplate + + + + View on GitHub + View + Collections + No description available + %d films + + + + + Don\'t underestimate the Force. The Force is strong with this one. I have you now. He is here. \n \n + I suggest you try it again, Luke. This time, let go your conscious self and act on instinct. The more you tighten your grip, Tarkin, the more star systems will slip through your fingers. I\'m trying not to, kid. Red Five standing by.\n \n + I care. So, what do you think of her, Han? Obi-Wan is here. The Force is with him. I\'m surprised you had the courage to take the responsibility yourself. Red Five standing by. I need your help, Luke. She needs your help. I\'m getting too old for this sort of thing.\n \n + What!? All right. Well, take care of yourself, Han. I guess that\'s what you\'re best at, ain\'t it? I don\'t know what you\'re talking about. I am a member of the Imperial Senate on a diplomatic mission to Alderaan, Red Five standing by.\n \n + I suggest you try it again, Luke. This time, let go your conscious self and act on instinct. I want to come with you to Alderaan. There\'s nothing for me here now. I want to learn the ways of the Force and be a Jedi, like my father before me. She must have hidden the plans in the escape pod. Send a detachment down to retrieve them, and see to it personally, Commander. There\'ll be no one to stop us this time! Obi-Wan is here. The Force is with him.\n \n + Hey, Luke! May the Force be with you. Alderaan? I\'m not going to Alderaan. I\'ve got to go home. It\'s late, I\'m in for it as it is. Obi-Wan is here. The Force is with him. Don\'t be too proud of this technological terror you\'ve constructed. The ability to destroy a planet is insignificant next to the power of the Force. She must have hidden the plans in the escape pod. Send a detachment down to retrieve them, and see to it personally, Commander. There\'ll be no one to stop us this time!\n \n + + + + + Films + Vehicles + Species + Starships + + + No data to display + + + + OK + Delete + Cancel + + Oops + There was an error making the request + Sorry, you need a connection to do that! + + + + + 1 + 2 + 3 + 4 + 5 + 6 + + + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 000000000..9f848adfa --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/test/java/eu/kanade/mangafeed/DataManagerTest.java b/app/src/test/java/eu/kanade/mangafeed/DataManagerTest.java new file mode 100644 index 000000000..c4a096ac9 --- /dev/null +++ b/app/src/test/java/eu/kanade/mangafeed/DataManagerTest.java @@ -0,0 +1,70 @@ +package eu.kanade.mangafeed; + + +import android.database.Cursor; + +import eu.kanade.mangafeed.data.local.DatabaseHelper; +import eu.kanade.mangafeed.data.local.Db; +import eu.kanade.mangafeed.data.local.PreferencesHelper; +import eu.kanade.mangafeed.data.model.Character; +import eu.kanade.mangafeed.data.remote.AndroidBoilerplateService; +import eu.kanade.mangafeed.util.DefaultConfig; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +import java.util.List; + +import rx.Observable; +import rx.observers.TestSubscriber; +import rx.schedulers.Schedulers; + +import static junit.framework.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(RobolectricTestRunner.class) +@Config(constants = BuildConfig.class, sdk = DefaultConfig.EMULATE_SDK, manifest = DefaultConfig.MANIFEST) +public class DataManagerTest { + + private DataManager mDataManager; + private AndroidBoilerplateService mMockAndroidBoilerplateService; + private DatabaseHelper mDatabaseHelper; + + @Before + public void setUp() { + mMockAndroidBoilerplateService = mock(AndroidBoilerplateService.class); + mDatabaseHelper = new DatabaseHelper(RuntimeEnvironment.application); + mDatabaseHelper.clearTables().subscribe(); + mDataManager = new DataManager(mMockAndroidBoilerplateService, + mDatabaseHelper, + mock(Bus.class), + new PreferencesHelper(RuntimeEnvironment.application), + Schedulers.immediate()); + } + + @Test + public void shouldSyncCharacters() throws Exception { + int[] ids = new int[]{ 10034, 14050, 10435, 35093 }; + List characters = MockModelsUtil.createListOfMockCharacters(4); + for (int i = 0; i < ids.length; i++) { + when(mMockAndroidBoilerplateService.getCharacter(ids[i])) + .thenReturn(Observable.just(characters.get(i))); + } + + TestSubscriber result = new TestSubscriber<>(); + mDataManager.syncCharacters(ids).subscribe(result); + result.assertNoErrors(); + result.assertReceivedOnNext(characters); + + Cursor cursor = mDatabaseHelper.getBriteDb() + .query("SELECT * FROM " + Db.CharacterTable.TABLE_NAME); + assertEquals(4, cursor.getCount()); + cursor.close(); + } + +} diff --git a/app/src/test/java/eu/kanade/mangafeed/DatabaseHelperTest.java b/app/src/test/java/eu/kanade/mangafeed/DatabaseHelperTest.java new file mode 100644 index 000000000..e47b6cf99 --- /dev/null +++ b/app/src/test/java/eu/kanade/mangafeed/DatabaseHelperTest.java @@ -0,0 +1,65 @@ +package eu.kanade.mangafeed; + +import android.database.Cursor; + +import eu.kanade.mangafeed.data.local.DatabaseHelper; +import eu.kanade.mangafeed.data.local.Db; +import eu.kanade.mangafeed.data.model.Character; +import eu.kanade.mangafeed.util.DefaultConfig; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +import java.util.Collections; +import java.util.List; + +import rx.observers.TestSubscriber; + +import static junit.framework.Assert.assertEquals; + +@RunWith(RobolectricTestRunner.class) +@Config(constants = BuildConfig.class, sdk = DefaultConfig.EMULATE_SDK, manifest = DefaultConfig.MANIFEST) +public class DatabaseHelperTest { + + private DatabaseHelper mDatabaseHelper; + + @Before + public void setUp() { + mDatabaseHelper = new DatabaseHelper(RuntimeEnvironment.application); + mDatabaseHelper.clearTables().subscribe(); + } + + @Test + public void shouldSetCharacters() throws Exception { + List characters = MockModelsUtil.createListOfMockCharacters(5); + + TestSubscriber result = new TestSubscriber<>(); + mDatabaseHelper.setCharacters(characters).subscribe(result); + result.assertNoErrors(); + result.assertReceivedOnNext(characters); + + Cursor cursor = mDatabaseHelper.getBriteDb() + .query("SELECT * FROM " + Db.CharacterTable.TABLE_NAME); + assertEquals(5, cursor.getCount()); + for (Character character : characters) { + cursor.moveToNext(); + assertEquals(character, Db.CharacterTable.parseCursor(cursor)); + } + } + + @Test + public void shouldGetCharacters() throws Exception { + List characters = MockModelsUtil.createListOfMockCharacters(5); + + mDatabaseHelper.setCharacters(characters).subscribe(); + + TestSubscriber> result = new TestSubscriber<>(); + mDatabaseHelper.getCharacters().subscribe(result); + result.assertNoErrors(); + result.assertReceivedOnNext(Collections.singletonList(characters)); + } +} \ No newline at end of file diff --git a/app/src/test/java/eu/kanade/mangafeed/util/DefaultConfig.java b/app/src/test/java/eu/kanade/mangafeed/util/DefaultConfig.java new file mode 100644 index 000000000..14b8dccda --- /dev/null +++ b/app/src/test/java/eu/kanade/mangafeed/util/DefaultConfig.java @@ -0,0 +1,7 @@ +package eu.kanade.mangafeed.util; + +public class DefaultConfig { + //The api level that Roboelectric will use to run the unit tests + public static final int EMULATE_SDK = 21; + public static final String MANIFEST = "./src/main/AndroidManifest.xml"; +} \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 000000000..3a6660845 --- /dev/null +++ b/build.gradle @@ -0,0 +1,20 @@ +// 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.3.0' + classpath 'com.neenbedankt.gradle.plugins:android-apt:1.7' + classpath 'me.tatarka:gradle-retrolambda:3.2.3' + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + jcenter() + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 000000000..1d3591c8a --- /dev/null +++ b/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 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..8c0fb64a8698b08ecc4158d828ca593c4928e9dd GIT binary patch literal 49896 zcmagFb986H(k`5d^NVfUwr$(C?M#x1ZQHiZiEVpg+jrjgoQrerx!>1o_ul)D>ebz~ zs=Mmxr&>W81QY-S1PKWQ%N-;H^tS;2*XwVA`dej1RRn1z<;3VgfE4~kaG`A%QSPsR z#ovnZe+tS9%1MfeDyz`RirvdjPRK~p(#^q2(^5@O&NM19EHdvN-A&StN>0g6QA^VN z0Gx%Gq#PD$QMRFzmK+utjS^Y1F0e8&u&^=w5K<;4Rz|i3A=o|IKLY+g`iK6vfr9?+ z-`>gmU&i?FGSL5&F?TXFu`&Js6h;15QFkXp2M1H9|Eq~bpov-GU(uz%mH0n55wUl- zv#~ccAz`F5wlQ>e_KlJS3@{)B?^v*EQM=IxLa&76^y51a((wq|2-`qON>+4dLc{Oo z51}}o^Zen(oAjxDK7b++9_Yg`67p$bPo3~BCpGM7uAWmvIhWc5Gi+gQZ|Pwa-Gll@<1xmcPy z|NZmu6m)g5Ftu~BG&Xdxclw7Cij{xbBMBn-LMII#Slp`AElb&2^Hw+w>(3crLH!;I zN+Vk$D+wP1#^!MDCiad@vM>H#6+`Ct#~6VHL4lzmy;lSdk>`z6)=>Wh15Q2)dQtGqvn0vJU@+(B5{MUc*qs4!T+V=q=wy)<6$~ z!G>e_4dN@lGeF_$q9`Ju6Ncb*x?O7=l{anm7Eahuj_6lA{*#Gv*TaJclevPVbbVYu z(NY?5q+xxbO6%g1xF0r@Ix8fJ~u)VRUp`S%&rN$&e!Od`~s+64J z5*)*WSi*i{k%JjMSIN#X;jC{HG$-^iX+5f5BGOIHWAl*%15Z#!xntpk($-EGKCzKa zT7{siZ9;4TICsWQ$pu&wKZQTCvpI$Xvzwxoi+XkkpeE&&kFb!B?h2hi%^YlXt|-@5 zHJ~%AN!g_^tmn1?HSm^|gCE#!GRtK2(L{9pL#hp0xh zME}|DB>(5)`iE7CM)&_+S}-Bslc#@B5W4_+k4Cp$l>iVyg$KP>CN?SVGZ(&02>iZK zB<^HP$g$Lq*L$BWd?2(F?-MUbNWTJVQdW7$#8a|k_30#vHAD1Z{c#p;bETk0VnU5A zBgLe2HFJ3032$G<`m*OB!KM$*sdM20jm)It5OSru@tXpK5LT>#8)N!*skNu1$TpIw zufjjdp#lyH5bZ%|Iuo|iu9vG1HrIVWLH>278xo>aVBkPN3V$~!=KnlXQ4eDqS7%E% zQ!z^$Q$b^6Q)g#cLpwur(|<0gWHo6A6jc;n`t(V9T;LzTAU{IAu*uEQ%Ort1k+Kn+f_N`9|bxYC+~Z1 zCC1UCWv*Orx$_@ydv9mIe(liLfOr7mhbV@tKw{6)q^1DH1nmvZ0cj215R<~&I<4S| zgnr;9Cdjqpz#o8i0CQjtl`}{c*P)aSdH|abxGdrR)-3z+02-eX(k*B)Uqv6~^nh** z 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 \(.*\)$'` + 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 "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 000000000..8a0b282aa --- /dev/null +++ b/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 diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 000000000..e7b4def49 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +include ':app'