mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 02:34:39 +00:00
Initial commit
This commit is contained in:
commit
b69510e972
57 changed files with 1965 additions and 0 deletions
4
app/.gitignore
vendored
Normal file
4
app/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
/build
|
||||
*iml
|
||||
*.iml
|
||||
.idea
|
85
app/build.gradle
Normal file
85
app/build.gradle
Normal file
|
@ -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"
|
||||
}
|
17
app/proguard-rules.pro
vendored
Normal file
17
app/proguard-rules.pro
vendored
Normal file
|
@ -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 *;
|
||||
#}
|
35
app/src/main/AndroidManifest.xml
Normal file
35
app/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="eu.kanade.mangafeed" >
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme" >
|
||||
<activity
|
||||
android:name="eu.kanade.mangafeed.ui.activity.MainActivity"
|
||||
android:label="@string/label_main"
|
||||
android:theme="@style/AppTheme.NoActionBar">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<receiver
|
||||
android:name="eu.kanade.mangafeed.data.SyncService$SyncOnConnectionAvailable"
|
||||
android:enabled="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
34
app/src/main/java/eu/kanade/mangafeed/App.java
Normal file
34
app/src/main/java/eu/kanade/mangafeed/App.java
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
23
app/src/main/java/eu/kanade/mangafeed/AppComponent.java
Normal file
23
app/src/main/java/eu/kanade/mangafeed/AppComponent.java
Normal file
|
@ -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();
|
||||
}
|
28
app/src/main/java/eu/kanade/mangafeed/AppModule.java
Normal file
28
app/src/main/java/eu/kanade/mangafeed/AppModule.java
Normal file
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
38
app/src/main/java/eu/kanade/mangafeed/data/DataModule.java
Normal file
38
app/src/main/java/eu/kanade/mangafeed/data/DataModule.java
Normal file
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
198
app/src/main/java/eu/kanade/mangafeed/data/entities/Manga.java
Normal file
198
app/src/main/java/eu/kanade/mangafeed/data/entities/Manga.java
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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<List<Manga>> getMangas() {
|
||||
return db.get()
|
||||
.listOfObjects(Manga.class)
|
||||
.withQuery(Query.builder()
|
||||
.table(MangasTable.TABLE)
|
||||
.build())
|
||||
.prepare()
|
||||
.createObservable();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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";
|
||||
}
|
|
@ -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";
|
||||
}
|
|
@ -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";
|
||||
}
|
|
@ -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"
|
||||
+ ");";
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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<Character> 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);
|
||||
}
|
||||
}
|
|
@ -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<String> {
|
||||
|
||||
@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())));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
13
app/src/main/java/eu/kanade/mangafeed/util/DataUtils.java
Normal file
13
app/src/main/java/eu/kanade/mangafeed/util/DataUtils.java
Normal file
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
27
app/src/main/java/eu/kanade/mangafeed/util/NetworkUtil.java
Normal file
27
app/src/main/java/eu/kanade/mangafeed/util/NetworkUtil.java
Normal file
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
13
app/src/main/java/eu/kanade/mangafeed/util/ViewUtils.java
Normal file
13
app/src/main/java/eu/kanade/mangafeed/util/ViewUtils.java
Normal file
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/line_grey">
|
||||
<item android:drawable="@color/white"/>
|
||||
</ripple>
|
6
app/src/main/res/drawable/touchable_background_white.xml
Normal file
6
app/src/main/res/drawable/touchable_background_white.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@color/super_light_grey" android:state_pressed="true"/>
|
||||
<item android:drawable="@color/super_light_grey" android:state_focused="true"/>
|
||||
<item android:drawable="@color/white"/>
|
||||
</selector>
|
51
app/src/main/res/layout/activity_character.xml
Normal file
51
app/src/main/res/layout/activity_character.xml
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.design.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/main_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:id="@+id/app_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="180dp"
|
||||
android:layout_gravity="top"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
|
||||
|
||||
<android.support.design.widget.CollapsingToolbarLayout
|
||||
android:id="@+id/toolbar_collapsing"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_scrollFlags="scroll|exitUntilCollapsed">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
app:layout_scrollFlags="scroll|enterAlways"
|
||||
app:layout_collapseMode="pin"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
|
||||
|
||||
</android.support.design.widget.CollapsingToolbarLayout>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<android.support.v4.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/bg_light_grey"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:text="@string/text_lorem_ipsum"
|
||||
android:textColor="@color/black_87pc"
|
||||
android:textSize="@dimen/text_body"/>
|
||||
|
||||
</android.support.v4.widget.NestedScrollView>
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
46
app/src/main/res/layout/activity_detail.xml
Normal file
46
app/src/main/res/layout/activity_detail.xml
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.design.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/main_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:id="@+id/app_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/primary"
|
||||
app:layout_scrollFlags="scroll|enterAlways"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
|
||||
|
||||
<android.support.design.widget.TabLayout
|
||||
android:id="@+id/sliding_tabs"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/primary"
|
||||
app:tabGravity="center"
|
||||
app:tabIndicatorColor="@color/accent"
|
||||
app:tabIndicatorHeight="3dp"
|
||||
app:tabMode="scrollable"
|
||||
app:tabSelectedTextColor="@color/white"
|
||||
app:tabTextColor="@color/primary_light"/>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<android.support.v4.view.ViewPager
|
||||
android:id="@+id/pager_character_detail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/app_bar"
|
||||
android:background="@color/white"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
55
app/src/main/res/layout/activity_main.xml
Normal file
55
app/src/main/res/layout/activity_main.xml
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.design.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/bg_light_grey">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<android.support.v4.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swipe_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/recycler_characters"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:clipToPadding="false"/>
|
||||
|
||||
</android.support.v4.widget.SwipeRefreshLayout>
|
||||
|
||||
<ProgressBar
|
||||
style="?android:attr/progressBarStyleLarge"
|
||||
android:id="@+id/progress_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:layout_scrollFlags="scroll|enterAlways"
|
||||
android:background="@color/primary"
|
||||
android:theme="@style/AppTheme.ActionBar"/>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
26
app/src/main/res/layout/fragment_detail.xml
Normal file
26
app/src/main/res/layout/fragment_detail.xml
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/white">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_no_data"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
android:text="@string/text_no_data"
|
||||
android:textColor="@color/black_87pc"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/recycler_detail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:clipToPadding="false"/>
|
||||
|
||||
</FrameLayout>
|
92
app/src/main/res/layout/item_character.xml
Normal file
92
app/src/main/res/layout/item_character.xml
Normal file
|
@ -0,0 +1,92 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.v7.widget.CardView
|
||||
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_marginBottom="2dp"
|
||||
card_view:cardCornerRadius="2dp"
|
||||
card_view:cardUseCompatPadding="true">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/white">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/container_character"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/touchable_background_white">
|
||||
|
||||
<de.hdodenhof.circleimageview.CircleImageView
|
||||
android:id="@+id/image_character"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginTop="16dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toRightOf="@id/image_character"
|
||||
android:layout_alignTop="@id/image_character"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:textColor="@color/black_87pc"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/text_name"
|
||||
android:layout_alignLeft="@id/text_name"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
android:textColor="@color/black_87pc"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/container_character"
|
||||
android:background="@color/white">
|
||||
|
||||
<View
|
||||
android:id="@+id/seperator_line"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_alignParentTop="true"
|
||||
android:background="@color/light_grey"/>
|
||||
|
||||
<TextView
|
||||
style="@style/CardButtonTextStyle"
|
||||
android:id="@+id/text_view"
|
||||
android:layout_below="@+id/seperator_line"
|
||||
android:background="@drawable/touchable_background_white"
|
||||
android:textColor="@color/primary_text"
|
||||
android:text="@string/text_view"/>
|
||||
|
||||
<TextView
|
||||
style="@style/CardButtonTextStyle"
|
||||
android:id="@+id/text_tab"
|
||||
android:layout_toRightOf="@+id/text_view"
|
||||
android:layout_alignBottom="@+id/text_view"
|
||||
android:background="@drawable/touchable_background_white"
|
||||
android:textColor="@color/primary"
|
||||
android:text="@string/text_collections"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</android.support.v7.widget.CardView>
|
11
app/src/main/res/layout/item_detail.xml
Normal file
11
app/src/main/res/layout/item_detail.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/text_detail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:maxLines="2"
|
||||
android:background="@drawable/touchable_background_white"
|
||||
android:ellipsize="end"
|
||||
android:textColor="@color/black_87pc"
|
||||
android:textSize="@dimen/text_large_body"/>
|
6
app/src/main/res/menu/main.xml
Normal file
6
app/src/main/res/menu/main.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
|
||||
<item android:id="@+id/action_github" android:title="@string/action_github"
|
||||
android:orderInCategory="100" app:showAsAction="never" />
|
||||
</menu>
|
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.1 KiB |
6
app/src/main/res/values-w820dp/dimens.xml
Normal file
6
app/src/main/res/values-w820dp/dimens.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<resources>
|
||||
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
|
||||
(such as screen margins) for screens with more than 820dp of available width. This
|
||||
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
|
||||
<dimen name="activity_horizontal_margin">64dp</dimen>
|
||||
</resources>
|
17
app/src/main/res/values/colors.xml
Normal file
17
app/src/main/res/values/colors.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="primary">#607D8B</color>
|
||||
<color name="primary_dark">#455A64</color>
|
||||
<color name="primary_light">#CFD8DC</color>
|
||||
<color name="accent">#009688</color>
|
||||
<color name="primary_text">#212121</color>
|
||||
<color name="secondary_text">#727272</color>
|
||||
<color name="icons">#FFFFFF</color>
|
||||
<color name="divider">#B6B6B6</color>
|
||||
<color name="white">#FFFFFF</color>
|
||||
<color name="super_light_grey">#FAFAFA</color>
|
||||
<color name="line_grey">#D7D7D7</color>
|
||||
<color name="light_grey">#D4D4D4</color>
|
||||
<color name="bg_light_grey">#E9E9E9</color>
|
||||
<color name="black_87pc">#DD000000</color>
|
||||
</resources>
|
13
app/src/main/res/values/dimens.xml
Normal file
13
app/src/main/res/values/dimens.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<resources>
|
||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
|
||||
<dimen name="text_headline">24sp</dimen>
|
||||
<dimen name="text_large_title">22sp</dimen>
|
||||
<dimen name="text_title">20sp</dimen>
|
||||
<dimen name="text_large_body">18sp</dimen>
|
||||
<dimen name="text_body">16sp</dimen>
|
||||
<dimen name="text_small_body">14sp</dimen>
|
||||
|
||||
</resources>
|
57
app/src/main/res/values/strings.xml
Normal file
57
app/src/main/res/values/strings.xml
Normal file
|
@ -0,0 +1,57 @@
|
|||
<resources>
|
||||
<string name="app_name">AndroidBoilerPlate</string>
|
||||
|
||||
<!-- Activity labels -->
|
||||
<string name="label_main">Boilerplate</string>
|
||||
|
||||
<!-- Main Activity -->
|
||||
|
||||
<string name="action_github">View on GitHub</string>
|
||||
<string name="text_view">View</string>
|
||||
<string name="text_collections">Collections</string>
|
||||
<string name="text_no_description">No description available</string>
|
||||
<string name="text_films_description">%d films</string>
|
||||
|
||||
<!-- Character Activity -->
|
||||
|
||||
<string name="text_lorem_ipsum">
|
||||
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
|
||||
</string>
|
||||
<!-- Detail Fragment -->
|
||||
|
||||
<string-array name="detail_fragment_titles">
|
||||
<item>Films</item>
|
||||
<item>Vehicles</item>
|
||||
<item>Species</item>
|
||||
<item>Starships</item>
|
||||
</string-array>
|
||||
|
||||
<string name="text_no_data">No data to display</string>
|
||||
|
||||
<!-- Dialogs -->
|
||||
|
||||
<string name="dialog_action_ok">OK</string>
|
||||
<string name="dialog_action_delete">Delete</string>
|
||||
<string name="dialog_action_cancel">Cancel</string>
|
||||
|
||||
<string name="dialog_error_title">Oops</string>
|
||||
<string name="dialog_general_error_Message">There was an error making the request</string>
|
||||
<string name="dialog_error_no_connection">Sorry, you need a connection to do that!</string>
|
||||
|
||||
<!-- Arrays -->
|
||||
|
||||
<integer-array name="characters">
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
<item>4</item>
|
||||
<item>5</item>
|
||||
<item>6</item>
|
||||
</integer-array>
|
||||
|
||||
</resources>
|
79
app/src/main/res/values/styles.xml
Normal file
79
app/src/main/res/values/styles.xml
Normal file
|
@ -0,0 +1,79 @@
|
|||
<resources>
|
||||
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light">
|
||||
<item name="colorPrimary">@color/primary</item>
|
||||
<item name="colorPrimaryDark">@color/primary_dark</item>
|
||||
<item name="colorAccent">@color/accent</item>
|
||||
<item name="alertDialogTheme">@style/AlertDialogStyle</item>
|
||||
<item name="android:itemTextAppearance">@style/OptionsMenuTextColor</item>
|
||||
<item name="android:textColorPrimary">@color/black_87pc</item>
|
||||
<item name="android:textColor">@color/black_87pc</item>
|
||||
<item name="colorControlNormal">@color/white</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.NoActionBar" parent="AppTheme">
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="windowActionBar">false</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.ActionBar" parent="AppTheme">
|
||||
<item name="android:textColorPrimary">@color/white</item>
|
||||
<item name="drawerArrowStyle">@style/HamburgerIconStyle</item>
|
||||
<item name="android:itemTextAppearance">@style/OptionsMenuTextColor</item>
|
||||
</style>
|
||||
|
||||
<style name="AlertDialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert">
|
||||
<item name="android:windowTitleStyle">@style/DialogTitleText</item>
|
||||
<item name="colorAccent">@color/primary</item>
|
||||
</style>
|
||||
|
||||
<style name="DialogTitleText">
|
||||
<item name="android:textColor">@color/black_87pc</item>
|
||||
<item name="android:textAppearance">@style/TextAppearance.AppCompat.Title</item>
|
||||
</style>
|
||||
|
||||
<style name="HamburgerIconStyle" parent="Widget.AppCompat.DrawerArrowToggle">
|
||||
<item name="color">@color/icons</item>
|
||||
</style>
|
||||
|
||||
<style name="OptionsMenuTextColor" parent="@android:style/TextAppearance.Widget.IconMenu.Item">
|
||||
<item name="android:textColor">@android:color/black</item>
|
||||
</style>
|
||||
|
||||
<style name="TitleTextStyle">
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:textColor">@color/primary</item>
|
||||
<item name="android:textSize">@dimen/text_body</item>
|
||||
<item name="android:textStyle">bold</item>
|
||||
</style>
|
||||
|
||||
<style name="CardButtonTextStyle">
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:padding">16dp</item>
|
||||
<item name="android:textSize">@dimen/text_small_body</item>
|
||||
<item name="android:textStyle">bold</item>
|
||||
<item name="android:background">@drawable/touchable_background_white</item>
|
||||
</style>
|
||||
|
||||
<style name="ErrorTextStyle">
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:layout_marginLeft">4dp</item>
|
||||
<item name="android:layout_marginRight">4dp</item>
|
||||
<item name="android:textColor">@android:color/holo_red_light</item>
|
||||
<item name="android:textSize">@dimen/text_small_body</item>
|
||||
<item name="android:visibility">invisible</item>
|
||||
</style>
|
||||
|
||||
<style name="EmptyListTextStyle">
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:layout_centerInParent">true</item>
|
||||
<item name="android:textColor">@color/primary_text</item>
|
||||
<item name="android:textSize">@dimen/text_small_body</item>
|
||||
<item name="android:visibility">gone</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
70
app/src/test/java/eu/kanade/mangafeed/DataManagerTest.java
Normal file
70
app/src/test/java/eu/kanade/mangafeed/DataManagerTest.java
Normal file
|
@ -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<Character> characters = MockModelsUtil.createListOfMockCharacters(4);
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
when(mMockAndroidBoilerplateService.getCharacter(ids[i]))
|
||||
.thenReturn(Observable.just(characters.get(i)));
|
||||
}
|
||||
|
||||
TestSubscriber<Character> 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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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<Character> characters = MockModelsUtil.createListOfMockCharacters(5);
|
||||
|
||||
TestSubscriber<Character> 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<Character> characters = MockModelsUtil.createListOfMockCharacters(5);
|
||||
|
||||
mDatabaseHelper.setCharacters(characters).subscribe();
|
||||
|
||||
TestSubscriber<List<Character>> result = new TestSubscriber<>();
|
||||
mDatabaseHelper.getCharacters().subscribe(result);
|
||||
result.assertNoErrors();
|
||||
result.assertReceivedOnNext(Collections.singletonList(characters));
|
||||
}
|
||||
}
|
|
@ -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";
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue