commit c6bfad37f0f9166dd17dbd70f3208629d2902c4d Author: Tariel Hlontsi Date: Sat Apr 23 19:13:33 2016 +0300 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c6cbe56 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..8225020 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +BackPack \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..96cc43e --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..e7bedf3 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..97626ba --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..508b3d9 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,23 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..477b86a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1.8 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..ea59753 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..88aa64f --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,42 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 23 + buildToolsVersion "23.0.1" +/* + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +*/ + defaultConfig { + applicationId "hikapro.com.backpack" + minSdkVersion 17 + targetSdkVersion 23 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + testCompile 'junit:junit:4.12' + + compile 'com.google.code.gson:gson:2.6.2' + compile 'com.squareup.retrofit2:retrofit:2.0.1' + compile 'com.squareup.retrofit2:converter-gson:2.0.1' + compile 'com.squareup.okhttp3:okhttp:3.2.0' + + compile 'com.squareup.okhttp:logging-interceptor:2.7.0' + compile 'com.android.support:support-v4:23.3.0' + compile 'com.android.support:appcompat-v7:23.3.0' + compile 'com.android.support:design:23.3.0' + compile 'com.android.support:support-v4:23.3.0' + compile 'com.android.support:cardview-v7:23.3.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..d12463f --- /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 /home/tariel/Android/Sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/app/src/androidTest/java/hikapro/com/backpack/ApplicationTest.java b/app/src/androidTest/java/hikapro/com/backpack/ApplicationTest.java new file mode 100644 index 0000000..50b1479 --- /dev/null +++ b/app/src/androidTest/java/hikapro/com/backpack/ApplicationTest.java @@ -0,0 +1,13 @@ +package hikapro.com.backpack; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..ee72e5f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/hikapro/com/backpack/MainActivity.java b/app/src/main/java/hikapro/com/backpack/MainActivity.java new file mode 100644 index 0000000..522520e --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/MainActivity.java @@ -0,0 +1,48 @@ +package hikapro.com.backpack; + +import android.app.Activity; +import android.app.Fragment; +import android.app.FragmentManager; +import android.app.FragmentTransaction; +import android.os.Bundle; + +import hikapro.com.backpack.model.entities.Set; +import hikapro.com.backpack.view.View; +import hikapro.com.backpack.view.fragments.ItemListFragment; +import hikapro.com.backpack.view.fragments.SetListFragment; + +public class MainActivity extends Activity implements View.ActivityCallback { + + private static String TAG = "TAG"; + + private FragmentManager fragmentManager; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + fragmentManager = getFragmentManager(); + + Fragment fragment = fragmentManager.findFragmentByTag(TAG); + if (fragment == null) + replaceFragment(SetListFragment.construct(), false); + } + + @Override + public void startItemListFragment(Set set) { + replaceFragment(ItemListFragment.newFromSet(set), true); + } + + @Override + public void startItemDetailFragment() { + + } + + private void replaceFragment(Fragment fragment, boolean addBackStack) { + FragmentTransaction transaction = fragmentManager.beginTransaction(); + transaction.replace(R.id.container, fragment, TAG); + if (addBackStack) + transaction.addToBackStack(null); + transaction.commit(); + } +} diff --git a/app/src/main/java/hikapro/com/backpack/model/Api.java b/app/src/main/java/hikapro/com/backpack/model/Api.java new file mode 100644 index 0000000..48a86f7 --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/model/Api.java @@ -0,0 +1,25 @@ +package hikapro.com.backpack.model; + +import java.util.List; + +import hikapro.com.backpack.model.entities.Category; +import hikapro.com.backpack.model.entities.Item; +import hikapro.com.backpack.model.entities.Set; + +import retrofit2.Call; +import retrofit2.http.GET; + +/** + * Created by tariel on 19/04/16. + */ +public interface Api { + + @GET("/api/v1/backpack/items") + Call> getItems(); + + @GET("/api/v1/backpack/item_categories") + Call> getItemCategories(); + + @GET("/api/v1/backpack/sets") + Call> getSets(); +} diff --git a/app/src/main/java/hikapro/com/backpack/model/ItemModel.java b/app/src/main/java/hikapro/com/backpack/model/ItemModel.java new file mode 100644 index 0000000..6f9fa19 --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/model/ItemModel.java @@ -0,0 +1,197 @@ +package hikapro.com.backpack.model; + + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Hashtable; +import java.util.List; + +import hikapro.com.backpack.model.entities.Category; +import hikapro.com.backpack.model.entities.Item; +import hikapro.com.backpack.presenter.Presenter; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +/** + * Created by tariel on 22/04/16. + */ +public class ItemModel implements Model.Item { + + private Api api; + private Presenter.ItemList presenter; + private List rawCategories; + private List sortedCategories; + private List rawItems; + + private Hashtable> items; + + public ItemModel(Presenter.ItemList presenter) { + this.api = RestClient.getApi(); + this.presenter = presenter; + this.rawCategories = new ArrayList<>(); + this.rawItems = new ArrayList<>(); + this.sortedCategories = new ArrayList<>(); + } + + // categories --> + + @Override + public Category getCategoryByPosition(int position) { + return sortedCategories.get(position); + } + @Override + public int getCategoriesCount() { + return sortedCategories.size(); + } + + // categories <-- + + // items --> + + @Override + public int insertItem(Item item) { + return 0; + } + @Override + public boolean deleteItem(int id) { + return false; + } + @Override + public Item findItem(int id) { // TODO rename to find + return null; + } + @Override + public Item getItemByPosition(int categoryId, int position) { + Item ret = null; + Category category = findSortedCategory(categoryId); + if (category != null) { + ret = items.get(category).get(position); + } + return ret; + } + @Override + public int getItemsCount(int categoryId) { + int ret = 0; + Category category = findSortedCategory(categoryId); + if (category != null) { + ret = items.get(category).size(); + } + return ret; + } + // items <-- + + // events --> + + @Override + public void notifyDataSetChanged() { + presenter.notifyDataSetChanged(); + } + + @Override + public void onDestroy(boolean isConfigurationChanging) { + + } + @Override + public void sendMessage(String message) { + presenter.showMessage(message); + } + // events <-- + + // process --> + + @Override + public void executeQuery() { + loadCategories(); + loadItems(); + } + private void loadCategories() { + Call> call = api.getItemCategories(); + call.enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + int statusCode = response.code(); + rawCategories = response.body(); + } + @Override + public void onFailure(Call> call, Throwable t) { + + } + }); + } + private void loadItems() { + Call> call2 = api.getItems(); + call2.enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + int statusCode = response.code(); + rawItems = response.body(); + initData(); + } + @Override + public void onFailure(Call> call, Throwable t) { + + } + }); + } + private void syncData() { + // TODO sync data here + } + // process <-- + + // other --> + + private void initData() { + List ids = presenter.getCurrentSet().getItems(); + List sortedItems = new ArrayList<>(ids.size()); + Category category; + + for (Item item : rawItems) { + if (ids.contains(item.getId())) { + sortedItems.add(item); + } + } + Collections.sort(sortedItems); + items = new Hashtable<>(sortedItems.size()); + + for (Item item : sortedItems) { + category = findCategory(item.getCategory()); + if (category != null) { + if (items.containsKey(category)) { + items.get(category).add(item); + } else { + List innerList = new ArrayList<>(20); + innerList.add(item); + items.put(category, innerList); + } + } + } + Category[] array = items.keySet().toArray(new Category[items.size()]); + sortedCategories = Arrays.asList(array); + notifyDataSetChanged(); + } + private Category findSortedCategory(int categoryId) { + Category category = null; + for (Category c : sortedCategories) { + if (c.getId() == categoryId) { + category = c; + break; + } + } + return category; + + } + private Category findCategory(int categoryId) { + Category category = null; + + for (Category c : rawCategories) { + if (c.getId() == categoryId) { + category = c; + break; + } + } + return category; + } + // other <-- +} diff --git a/app/src/main/java/hikapro/com/backpack/model/Model.java b/app/src/main/java/hikapro/com/backpack/model/Model.java new file mode 100644 index 0000000..96ab146 --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/model/Model.java @@ -0,0 +1,38 @@ +package hikapro.com.backpack.model; + +import java.util.List; + +import hikapro.com.backpack.model.entities.Category; +import hikapro.com.backpack.model.entities.Item; +import hikapro.com.backpack.model.entities.Set; + +/** + * Created by tariel on 19/04/16. + */ +public interface Model { + + interface Base { + void onDestroy(boolean isConfigurationChanging); + void executeQuery(); + void sendMessage(String message); + } + + interface Set extends Base { + hikapro.com.backpack.model.entities.Set getSetByPosition(int position); + hikapro.com.backpack.model.entities.Set findSet(int id); + int getSetsCount(); + void notifyDataSetChanged(); + } + + interface Item extends Base { + int insertItem(hikapro.com.backpack.model.entities.Item item); + boolean deleteItem(int id); + hikapro.com.backpack.model.entities.Item findItem(int id); + hikapro.com.backpack.model.entities.Item getItemByPosition(int categoryId, int position); + int getItemsCount(int categoryId); + hikapro.com.backpack.model.entities.Category getCategoryByPosition(int position); + int getCategoriesCount(); + void notifyDataSetChanged(); + } + +} diff --git a/app/src/main/java/hikapro/com/backpack/model/RestClient.java b/app/src/main/java/hikapro/com/backpack/model/RestClient.java new file mode 100644 index 0000000..0561ec9 --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/model/RestClient.java @@ -0,0 +1,31 @@ +package hikapro.com.backpack.model; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +/** + * Created by tariel on 22/04/16. + */ +public class RestClient { + + public static final String BASE_URL = "http://hikapro.com"; + + public static Api getApi() { + + Gson gson = new GsonBuilder() + .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") + .create(); + + Retrofit retrofit = new Retrofit.Builder() + .baseUrl(BASE_URL) + .addConverterFactory(GsonConverterFactory.create(gson)) + .build(); + + return retrofit.create(Api.class); + + } + +} diff --git a/app/src/main/java/hikapro/com/backpack/model/SetModel.java b/app/src/main/java/hikapro/com/backpack/model/SetModel.java new file mode 100644 index 0000000..abc5bae --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/model/SetModel.java @@ -0,0 +1,102 @@ +package hikapro.com.backpack.model; + +import java.util.ArrayList; +import java.util.List; + +import hikapro.com.backpack.model.entities.Set; +import hikapro.com.backpack.presenter.Presenter; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +/** + * Created by tariel on 20/04/16. + */ +public class SetModel implements Model.Set { + + private List iList; + private Api api; + private Presenter.SetList presenter; + + public SetModel(Presenter.SetList presenter) { + this.api = RestClient.getApi(); + this.iList = new ArrayList<>(); + this.presenter = presenter; + } + + // sets --> + + @Override + public hikapro.com.backpack.model.entities.Set getSetByPosition(int position) { + return iList.get(position); + } + @Override + public hikapro.com.backpack.model.entities.Set findSet(int id) { + Set ret = null; + for (Set s : iList) { + if (s.getId() == id) { + ret = s; + break; + } + } + return ret; + } + + @Override + public int getSetsCount() { + return iList.size(); + } + + // sets <-- + + // events --> + + @Override + public void onDestroy(boolean isConfigurationChanging) { + + } + @Override + public void notifyDataSetChanged() { + presenter.notifyDataSetChanged(); + } + + @Override + public void sendMessage(String message) { + presenter.showMessage(message); + } + + // events <-- + + // process --> + + @Override + public void executeQuery() { + Call> call = api.getSets(); + call.enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + int statusCode = response.code(); + iList = response.body(); + notifyDataSetChanged(); + } + @Override + public void onFailure(Call> call, Throwable t) { + + } + }); + } + private void syncData() { + + } + // process <-- + + // other --> + // other <-- + + + + + + + +} diff --git a/app/src/main/java/hikapro/com/backpack/model/database/DAO.java b/app/src/main/java/hikapro/com/backpack/model/database/DAO.java new file mode 100644 index 0000000..3f2e0c6 --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/model/database/DAO.java @@ -0,0 +1,26 @@ +package hikapro.com.backpack.model.database; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; + +/** + * Created by tariel on 20/04/16. + */ +public class DAO { + + private Context context; + private DbHelper helper; + + public DAO(Context context) { + this.context = context; + this.helper = new DbHelper(this.context); + } + + private SQLiteDatabase getReadDB(){ + return helper.getReadableDatabase(); + } + + private SQLiteDatabase getWriteDB(){ + return helper.getWritableDatabase(); + } +} diff --git a/app/src/main/java/hikapro/com/backpack/model/database/Db.java b/app/src/main/java/hikapro/com/backpack/model/database/Db.java new file mode 100644 index 0000000..de45801 --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/model/database/Db.java @@ -0,0 +1,195 @@ +package hikapro.com.backpack.model.database; + +import android.content.ContentValues; +import android.database.Cursor; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; +import java.util.List; + +import hikapro.com.backpack.model.entities.Category; +import hikapro.com.backpack.model.entities.Item; +import hikapro.com.backpack.model.entities.Set; + +/** + * Created by tariel on 20/04/16. + */ +public class Db { + + public Db() { + } + + public abstract static class CategoriesTable { + + public static final String TABLE_NAME = "CATEGORIES"; + + public static final String COLUMN_ID = "_id"; + public static final String COLUMN_NAME = "NAME"; + + public static final String CREATE = + "CREATE TABLE " + TABLE_NAME + " (" + + COLUMN_ID + " INTEGER PRIMARY KEY, " + + COLUMN_NAME + " TEXT NOT NULL" + + " ); "; + + public static ContentValues toContentValues(Category category) { + ContentValues values = new ContentValues(); + values.put(COLUMN_ID, category.getId()); + values.put(COLUMN_NAME, category.getName()); + return values; + } + + public static Category parseCursor(Cursor cursor) { + Category category = new Category(); + category.setId(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_ID))); + category.setName(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_NAME))); + return category; + } + + } + + public abstract static class ItemsTable { + public static final String TABLE_NAME = "ITEMS"; + + public static final String COLUMN_ID = "_id"; + public static final String COLUMN_NAME = "NAME"; + public static final String COLUMN_CATEGORY = "CATEGORY"; + public static final String COLUMN_DESCRIPTION = "DESCRIPTION"; + public static final String COLUMN_BUY_URLS = "BUY_URLS"; + public static final String COLUMN_PHOTO_URL = "PHOTO_URL"; + public static final String COLUMN_PHOTO_THUMB_URL = "PHOTO_THUMB_URL"; + public static final String COLUMN_PHOTO_LOCAL = "PHOTO_LOCAL"; + public static final String COLUMN_PHOTO_THUMB_LOCAL = "PHOTO_THUMB_LOCAL"; + + + public static final String CREATE = + "CREATE TABLE " + TABLE_NAME + " (" + + COLUMN_ID + " INTEGER PRIMARY KEY, " + + COLUMN_NAME + " TEXT NOT NULL, " + + COLUMN_CATEGORY + " INTEGER NOT NULL, " + + COLUMN_DESCRIPTION + " TEXT, " + + COLUMN_BUY_URLS + " TEXT, " + + COLUMN_PHOTO_URL + " TEXT, " + + COLUMN_PHOTO_THUMB_URL + " TEXT, " + + COLUMN_PHOTO_LOCAL + " TEXT, " + + COLUMN_PHOTO_THUMB_LOCAL + " TEXT" + + " ); "; + + public static ContentValues toContentValues(Item item) { + ContentValues values = new ContentValues(); + values.put(COLUMN_ID, item.getId()); + values.put(COLUMN_NAME, item.getName()); + values.put(COLUMN_CATEGORY, item.getCategory()); + if (item.getDescription() != null) + values.put(COLUMN_DESCRIPTION, item.getDescription()); + if (item.getBuyUrls() != null && !item.getBuyUrls().isEmpty()) { + Gson gson = new Gson(); + Type type = new TypeToken>() {}.getType(); + String json = gson.toJson(item.getBuyUrls(), type); + values.put(COLUMN_BUY_URLS, json); + } + if (item.getPhotoUrl() != null) + values.put(COLUMN_PHOTO_URL, item.getPhotoUrl()); + if (item.getPhotoThumbUrl() != null) + values.put(COLUMN_PHOTO_THUMB_URL, item.getPhotoThumbUrl()); + /* + values.put(COLUMN_PHOTO_LOCAL, ); + values.put(COLUMN_PHOTO_THUMB_LOCAL, item.getName()); + */ + return values; + } + + public static Item parseCursor(Cursor cursor) { + Item item = new Item(); + item.setId(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_ID))); + item.setName(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_NAME))); + + item.setCategory(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_CATEGORY))); + + item.setDescription(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_DESCRIPTION))); + String urls = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_BUY_URLS)); + if (urls != null && !urls.isEmpty()) { + Gson gson = new Gson(); + Type type = new TypeToken>() {}.getType(); + List fromJson = gson.fromJson(urls, type); + item.setBuyUrls(fromJson); + } + item.setPhotoUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_URL))); + item.setPhotoThumbUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_THUMB_URL))); + return item; + } + + } + + public abstract static class SetsTable { + public static final String TABLE_NAME = "SETS"; + + public static final String COLUMN_ID = "_id"; + public static final String COLUMN_NAME = "NAME"; + public static final String COLUMN_ITEMS = "ITEMS"; + public static final String COLUMN_PHOTO_URL = "PHOTO_URL"; + public static final String COLUMN_PHOTO_THUMB_URL = "PHOTO_THUMB_URL"; + public static final String COLUMN_PHOTO_LOCAL = "PHOTO_LOCAL"; + public static final String COLUMN_PHOTO_THUMB_LOCAL = "PHOTO_THUMB_LOCAL"; + public static final String COLUMN_PHOTO_THUMBNAIL_URL = "PHOTO_THUMBNAIL_URL"; + public static final String COLUMN_PHOTO_THUMBNAIL_LOCAL = "PHOTO_THUMBNAIL_LOCAL"; + + public static final String CREATE = + "CREATE TABLE " + TABLE_NAME + " (" + + COLUMN_ID + " INTEGER PRIMARY KEY, " + + COLUMN_NAME + " TEXT NOT NULL, " + + COLUMN_ITEMS + " TEXT, " + + COLUMN_PHOTO_URL + " TEXT, " + + COLUMN_PHOTO_THUMB_URL + " TEXT, " + + COLUMN_PHOTO_LOCAL + " TEXT, " + + COLUMN_PHOTO_THUMB_LOCAL + " TEXT, " + + COLUMN_PHOTO_THUMBNAIL_URL + " TEXT, " + + COLUMN_PHOTO_THUMBNAIL_LOCAL + " TEXT" + + " ); "; + + public static ContentValues toContentValues(Set set) { + ContentValues values = new ContentValues(); + values.put(COLUMN_ID, set.getId()); + values.put(COLUMN_NAME, set.getName()); + + List items = set.getItems(); + if (items != null && !items.isEmpty()) { + Gson gson = new Gson(); + Type type = new TypeToken>() {}.getType(); + String json = gson.toJson(items, type); + values.put(COLUMN_ITEMS, json); + } + values.put(COLUMN_PHOTO_URL, set.getPhoto()); + values.put(COLUMN_PHOTO_THUMB_URL, set.getPhotoThumb()); + values.put(COLUMN_PHOTO_THUMBNAIL_URL, set.getPhotoThumbnail()); + /* + values.put(COLUMN_PHOTO_LOCAL, ""); + values.put(COLUMN_PHOTO_THUMB_LOCAL, ""); + values.put(COLUMN_PHOTO_THUMBNAIL_LOCAL, ""); + */ + return values; + } + + public static Set parseCursor(Cursor cursor) { + Set set = new Set(); + set.setId(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_ID))); + set.setName(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_NAME))); + + String items = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_ITEMS)); + if (items != null && !items.isEmpty()) { + Gson gson = new Gson(); + Type type = new TypeToken>() {}.getType(); + List fromJson = gson.fromJson(items, type); + set.setItems(fromJson); + } + set.setPhoto(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_URL))); + set.setPhotoThumb(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_THUMB_URL))); + set.setPhotoThumbnail(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_THUMBNAIL_URL))); + + return set; + } + + } +} diff --git a/app/src/main/java/hikapro/com/backpack/model/database/DbHelper.java b/app/src/main/java/hikapro/com/backpack/model/database/DbHelper.java new file mode 100644 index 0000000..3e3668c --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/model/database/DbHelper.java @@ -0,0 +1,46 @@ +package hikapro.com.backpack.model.database; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; + +/** + * Created by tariel on 20/04/16. + */ +public class DbHelper extends SQLiteOpenHelper { + + public static final String DATABASE_NAME = "backpack"; + + public static final int DATABASE_VERSION = 1; + + + public DbHelper(Context context) { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + + @Override + public void onCreate(SQLiteDatabase db) { + db.beginTransaction(); + try { + updateDatabase(db, 0, DATABASE_VERSION); + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + } + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + updateDatabase(db, oldVersion, newVersion); + } + + private void updateDatabase(SQLiteDatabase db, int oldVersion, int newVersion) { + + db.execSQL(Db.ItemsTable.CREATE); + db.execSQL(Db.CategoriesTable.CREATE); + db.execSQL(Db.SetsTable.CREATE); + + if (oldVersion < 2) { + // place the logic here + } + } +} diff --git a/app/src/main/java/hikapro/com/backpack/model/entities/Category.java b/app/src/main/java/hikapro/com/backpack/model/entities/Category.java new file mode 100644 index 0000000..d4187b5 --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/model/entities/Category.java @@ -0,0 +1,61 @@ +package hikapro.com.backpack.model.entities; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +import java.io.Serializable; + +/** + * Created by tariel on 28/03/16. + */ +public class Category implements Serializable { + + @SerializedName("id") + @Expose + private int id; + @SerializedName("name") + @Expose + private String name; + + public Category() { + } + + public Category(int id, String name) { + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int hashCode() { + return 31 * id; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Category that = (Category) o; + + if (id != that.id) + return false; + return true; + + } +} diff --git a/app/src/main/java/hikapro/com/backpack/model/entities/Item.java b/app/src/main/java/hikapro/com/backpack/model/entities/Item.java new file mode 100644 index 0000000..078727c --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/model/entities/Item.java @@ -0,0 +1,131 @@ +package hikapro.com.backpack.model.entities; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by tariel on 02/04/16. + */ +public class Item implements Comparable { + + @SerializedName("id") + @Expose + private int id; + @SerializedName("name") + @Expose + private String name; + @SerializedName("item_category_id") + @Expose + private int category; + @SerializedName("description") + @Expose + private String description; + @SerializedName("buy_urls") + @Expose + private List buyUrls = new ArrayList(); + @SerializedName("photo") + @Expose + private String photoUrl; + @SerializedName("photo_thumb") + @Expose + private String photoThumbUrl; + + public Item() { + } + + public Item(int id, String name, int category, String description, List buyUrls, + String photoUrl, String photoThumbUrl) { + this.id = id; + this.name = name; + this.category = category; + this.description = description; + this.buyUrls = buyUrls; + this.photoUrl = photoUrl; + this.photoThumbUrl = photoThumbUrl; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getCategory() { + return category; + } + + public void setCategory(int category) { + this.category = category; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public List getBuyUrls() { + return buyUrls; + } + + public void setBuyUrls(List buyUrls) { + this.buyUrls = buyUrls; + } + + public String getPhotoUrl() { + return photoUrl; + } + + public void setPhotoUrl(String photoUrl) { + this.photoUrl = photoUrl; + } + + public String getPhotoThumbUrl() { + return photoThumbUrl; + } + + public void setPhotoThumbUrl(String photoThumbUrl) { + this.photoThumbUrl = photoThumbUrl; + } + + @Override + public int hashCode() { + int result = name != null ? name.hashCode() : 0; + result = 31 * result + (name != null ? name.hashCode() : 0); + return result; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Item that = (Item) o; + + if (id != that.id) + return false; + return true; + + } + + @Override + public int compareTo(Item another) { + int cmp = Integer.valueOf(category).compareTo(Integer.valueOf(another.category)); + return (cmp != 0 ? cmp : name.compareTo(another.name)); + } +} diff --git a/app/src/main/java/hikapro/com/backpack/model/entities/Set.java b/app/src/main/java/hikapro/com/backpack/model/entities/Set.java new file mode 100644 index 0000000..b017060 --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/model/entities/Set.java @@ -0,0 +1,112 @@ +package hikapro.com.backpack.model.entities; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by tariel on 02/04/16. + */ +public class Set implements Serializable { + + @SerializedName("id") + @Expose + private int id; + @SerializedName("item_ids") + @Expose + private List items = new ArrayList(); + @SerializedName("name") + @Expose + private String name; + @SerializedName("photo") + @Expose + private String photo; + @SerializedName("photo_thumb") + @Expose + private String photoThumb; + @SerializedName("photo_thumbnail") + @Expose + private String photoThumbnail; + + public Set() { + } + + public Set(int id, List items, String name, String photo, String photoThumb, String photoThumbnail) { + this.id = id; + this.items = items; + this.name = name; + this.photo = photo; + this.photoThumb = photoThumb; + this.photoThumbnail = photoThumbnail; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhoto() { + return photo; + } + + public void setPhoto(String photo) { + this.photo = photo; + } + + public String getPhotoThumb() { + return photoThumb; + } + + public void setPhotoThumb(String photoThumb) { + this.photoThumb = photoThumb; + } + + public String getPhotoThumbnail() { + return photoThumbnail; + } + + public void setPhotoThumbnail(String photoThumbnail) { + this.photoThumbnail = photoThumbnail; + } + + @Override + public int hashCode() { + int result = name != null ? name.hashCode() : 0; + result = 31 * result + (name != null ? name.hashCode() : 0); + return result; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Set that = (Set) o; + + if (id != that.id) + return false; + return true; + } +} diff --git a/app/src/main/java/hikapro/com/backpack/presenter/ItemListPresenter.java b/app/src/main/java/hikapro/com/backpack/presenter/ItemListPresenter.java new file mode 100644 index 0000000..8e46596 --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/presenter/ItemListPresenter.java @@ -0,0 +1,186 @@ +package hikapro.com.backpack.presenter; + +import android.content.Context; +import android.os.Bundle; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.ViewGroup; +import android.widget.Toast; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; + +import hikapro.com.backpack.R; +import hikapro.com.backpack.model.ItemModel; +import hikapro.com.backpack.model.Model; +import hikapro.com.backpack.model.entities.Set; +import hikapro.com.backpack.presenter.adapters.CategoryListAdapter; +import hikapro.com.backpack.presenter.adapters.ItemListAdapter; +import hikapro.com.backpack.view.View; +import hikapro.com.backpack.view.recycler.CategoryViewHolder; +import hikapro.com.backpack.view.recycler.ItemViewHolder; + +/** + * Created by tariel on 20/04/16. + */ +public class ItemListPresenter implements Presenter.ItemList { + + private static final String BUNDLE_SET_LIST_KEY = "BUNDLE_SET_LIST_KEY"; + + private WeakReference view; + private Model.Item model; + private Set set; + private CategoryListAdapter categoryListAdapter; + + public ItemListPresenter(View.ItemList view, Set set) { + this.view = new WeakReference<>(view); + this.set = set; + this.categoryListAdapter = new CategoryListAdapter(this); + setModel(new ItemModel(this)); + } + + // life cycle --> + + @Override + public void onDestroy(boolean isChangingConfiguration) { + view = null; + model.onDestroy(isChangingConfiguration); + if ( !isChangingConfiguration ) { + model = null; + } + } + @Override + public android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + if (savedInstanceState != null) + set = (Set) savedInstanceState.getSerializable(BUNDLE_SET_LIST_KEY); + android.view.View view = inflater.inflate(R.layout.fragment_item_list, container, false); + LinearLayoutManager llm = new LinearLayoutManager(getActivityContext()); + RecyclerView mainRecycler = (RecyclerView) view.findViewById(R.id.categories_main_recycler); + mainRecycler.setLayoutManager(llm); + mainRecycler.setAdapter(categoryListAdapter); + mainRecycler.setItemAnimator(new DefaultItemAnimator()); + model.executeQuery(); + return view; + } + @Override + public void onSaveInstanceState(Bundle outState) { + if (set != null) + outState.putSerializable(BUNDLE_SET_LIST_KEY, set); + } + + // life cycle <-- + + // recycler --> + + @Override + public CategoryViewHolder createViewHolderCategory(ViewGroup parent, int viewType) { + CategoryViewHolder viewHolder; + android.view.View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.section, + parent, false); + viewHolder = new CategoryViewHolder(v); + return viewHolder; + } + @Override + public void bindViewHolderCategory(CategoryViewHolder holder, int position) { + final hikapro.com.backpack.model.entities.Category category = model.getCategoryByPosition(position); + holder.sectionText.setText(category.getName()); + LinearLayoutManager llm = new LinearLayoutManager(getActivityContext()); + holder.itemsRecycler.setLayoutManager(llm); + ItemListAdapter itemListAdapter = new ItemListAdapter(this); + itemListAdapter.setCategoryId(category.getId()); + holder.itemsRecycler.setAdapter(itemListAdapter); + holder.itemsRecycler.setItemAnimator(new DefaultItemAnimator()); + categoryListAdapter.addItemAdapter(itemListAdapter); + } + + @Override + public ItemViewHolder createViewHolderItem(ViewGroup parent, int viewType) { + ItemViewHolder viewHolder; + android.view.View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, + parent, false); + viewHolder = new ItemViewHolder(v); + return viewHolder; + } + @Override + public void bindViewHolderItem(final ItemViewHolder holder, final int position, int categoryId) { + + hikapro.com.backpack.model.entities.Item item = model.getItemByPosition(categoryId, position); + holder.title.setText(item.getName()); + holder.id = item.getId(); + holder.title.setOnClickListener(new android.view.View.OnClickListener() { + @Override + public void onClick(android.view.View view) { + showMessage("Position " + position + " Id " + holder.id); + } + }); + } + @Override + public int getItemsCount(int categoryId) { + return model.getItemsCount(categoryId);//TODO category Id + } + + // recycler <-- + + // process --> + + @Override + public void notifyDataSetChanged() { + categoryListAdapter.notifyDataSetChanged(); + categoryListAdapter.notifyItemAdapters(); + } + + // process <-- + + // other impl --> + + @Override + public void setView(View.ItemList view) { + this.view = new WeakReference<>(view); + } + @Override + public Context getAppContext() { + try { + return getView().getAppContext(); + } catch (NullPointerException e) { + return null; + } + } + @Override + public Context getActivityContext() { + try { + return getView().getActivityContext(); + } catch (NullPointerException e) { + return null; + } + } + @Override + public void setModel(Model.Item model) { + this.model = model; + } + @Override + public void showMessage(String message) { + Toast.makeText(getView().getAppContext(), message, Toast.LENGTH_SHORT).show(); + } + + // other impl <-- + + private View.ItemList getView() throws NullPointerException { + if ( view != null ) + return view.get(); + else + throw new NullPointerException("View is unavailable"); + } + + @Override + public int getCategoriesCount() { + return model.getCategoriesCount(); + } + + @Override + public Set getCurrentSet() { + return set; + } +} diff --git a/app/src/main/java/hikapro/com/backpack/presenter/Presenter.java b/app/src/main/java/hikapro/com/backpack/presenter/Presenter.java new file mode 100644 index 0000000..c0175ea --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/presenter/Presenter.java @@ -0,0 +1,55 @@ +package hikapro.com.backpack.presenter; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import hikapro.com.backpack.model.Model; +import hikapro.com.backpack.model.entities.Set; +import hikapro.com.backpack.view.recycler.CategoryViewHolder; +import hikapro.com.backpack.view.recycler.ItemViewHolder; +import hikapro.com.backpack.view.recycler.SetViewHolder; + +/** + * Created by tariel on 19/04/16. + */ +public interface Presenter { + + interface Base { + Context getAppContext(); + Context getActivityContext(); + } + + interface SetList extends Base { + SetViewHolder createViewHolder(ViewGroup parent, int viewType); + void bindViewHolder(SetViewHolder holder, int position); + int getSetsCount(); + void clickSet(int setId); + void onDestroy(boolean isChangingConfiguration); + android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState); + void setView(hikapro.com.backpack.view.View.SetList view); + void setModel(Model.Set model); + void notifyDataSetChanged(); + void showMessage(String message); + } + + interface ItemList extends Base { + ItemViewHolder createViewHolderItem(ViewGroup parent, int viewType); + void bindViewHolderItem(ItemViewHolder holder, int position, int categoryId); + int getItemsCount(int categoryId); + CategoryViewHolder createViewHolderCategory(ViewGroup parent, int viewType); + void bindViewHolderCategory(CategoryViewHolder holder, int position); + int getCategoriesCount(); + void onDestroy(boolean isChangingConfiguration); + android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState); + void setView(hikapro.com.backpack.view.View.ItemList view); + void setModel(Model.Item model); + void notifyDataSetChanged(); + Set getCurrentSet(); + void showMessage(String message); + void onSaveInstanceState(Bundle outState); + } + + +} diff --git a/app/src/main/java/hikapro/com/backpack/presenter/SetListPresenter.java b/app/src/main/java/hikapro/com/backpack/presenter/SetListPresenter.java new file mode 100644 index 0000000..4038ddf --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/presenter/SetListPresenter.java @@ -0,0 +1,152 @@ +package hikapro.com.backpack.presenter; + +import android.content.Context; +import android.os.Bundle; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.ViewGroup; +import android.widget.Toast; + +import java.lang.ref.WeakReference; + +import hikapro.com.backpack.R; +import hikapro.com.backpack.model.SetModel; +import hikapro.com.backpack.model.Model; +import hikapro.com.backpack.model.entities.Set; +import hikapro.com.backpack.presenter.adapters.SetListAdapter; +import hikapro.com.backpack.view.View; +import hikapro.com.backpack.view.recycler.SetViewHolder; + +/** + * Created by tariel on 20/04/16. + */ +public class SetListPresenter implements Presenter.SetList { + + private WeakReference view; + private Model.Set model; + private SetListAdapter adapter; + + public SetListPresenter() { + this.adapter = new SetListAdapter(this); + setModel(new SetModel(this)); + } + + // life cycle --> + + @Override + public void onDestroy(boolean isChangingConfiguration) { + view = null; + model.onDestroy(isChangingConfiguration); + if ( !isChangingConfiguration ) { + model = null; + } + } + @Override + public android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + android.view.View view = inflater.inflate(R.layout.fragment_set_list, container, false); + LinearLayoutManager llm = new LinearLayoutManager(getActivityContext()); + RecyclerView setRecycler = (RecyclerView) view.findViewById(R.id.set_recycler); + setRecycler.setLayoutManager(llm); + setRecycler.setAdapter(adapter); + setRecycler.setItemAnimator(new DefaultItemAnimator()); + model.executeQuery(); + return view; + } + + // life cycle <-- + + // recycler --> + + @Override + public SetViewHolder createViewHolder(ViewGroup parent, int viewType) { + SetViewHolder viewHolder; + android.view.View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.set_card, + parent, false); + viewHolder = new SetViewHolder(v); + return viewHolder; + } + @Override + public void bindViewHolder(final SetViewHolder holder, int position) { + + final hikapro.com.backpack.model.entities.Set set = model.getSetByPosition(position); + holder.textView.setText(set.getName()); + holder.cardView.setOnClickListener(new android.view.View.OnClickListener() { + @Override + public void onClick(android.view.View v) { + if (getView() != null) + getView().showItemList(set); + else + showMessage("There is no view in presenter"); + } + }); + } + @Override + public int getSetsCount() { + return model.getSetsCount(); + } + + // recycler <-- + + // process --> + + @Override + public void clickSet(int setId) { + Set set = model.findSet(setId); + if (set != null) { + getView().showItemList(set); + } else { + showMessage("Set not found!"); + } + } + @Override + public void notifyDataSetChanged() { + adapter.notifyDataSetChanged(); + } + + // process <-- + + // other impl --> + + @Override + public Context getAppContext() { + try { + return getView().getAppContext(); + } catch (NullPointerException e) { + return null; + } + } + @Override + public Context getActivityContext() { + try { + return getView().getActivityContext(); + } catch (NullPointerException e) { + return null; + } + } + @Override + public void setView(View.SetList view) { + this.view = new WeakReference<>(view); + } + @Override + public void setModel(Model.Set model) { + this.model = model; + } + @Override + public void showMessage(String message) { + Toast.makeText(getView().getAppContext(), message, Toast.LENGTH_SHORT).show(); + } + + // other impl <-- + + private View.SetList getView() throws NullPointerException { + if ( view != null ) + return view.get(); + else + throw new NullPointerException("View is unavailable"); + } + + +} diff --git a/app/src/main/java/hikapro/com/backpack/presenter/adapters/CategoryListAdapter.java b/app/src/main/java/hikapro/com/backpack/presenter/adapters/CategoryListAdapter.java new file mode 100644 index 0000000..d3d2a6c --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/presenter/adapters/CategoryListAdapter.java @@ -0,0 +1,50 @@ +package hikapro.com.backpack.presenter.adapters; + +import android.support.v7.widget.RecyclerView; +import android.view.ViewGroup; + +import java.util.ArrayList; +import java.util.List; + +import hikapro.com.backpack.presenter.Presenter; +import hikapro.com.backpack.view.recycler.CategoryViewHolder; + +/** + * Created by tariel on 20/04/16. + */ +public class CategoryListAdapter extends RecyclerView.Adapter { + + private Presenter.ItemList presenter; + private List itemAdapters; + + public CategoryListAdapter(Presenter.ItemList presenter) { + this.presenter = presenter; + this.itemAdapters = new ArrayList<>(); + } + + @Override + public int getItemCount() { + return presenter.getCategoriesCount(); + } + + @Override + public void onBindViewHolder(CategoryViewHolder holder, int position) { + presenter.bindViewHolderCategory(holder, position); + } + + @Override + public CategoryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + return presenter.createViewHolderCategory(parent, viewType); + } + + public void addItemAdapter(ItemListAdapter adapter) { + itemAdapters.add(adapter); + adapter.notifyDataSetChanged(); + } + public void notifyItemAdapters() { + for (ItemListAdapter adapter : itemAdapters) { + adapter.notifyDataSetChanged(); + } + } + +} diff --git a/app/src/main/java/hikapro/com/backpack/presenter/adapters/ItemListAdapter.java b/app/src/main/java/hikapro/com/backpack/presenter/adapters/ItemListAdapter.java new file mode 100644 index 0000000..19fc89a --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/presenter/adapters/ItemListAdapter.java @@ -0,0 +1,38 @@ +package hikapro.com.backpack.presenter.adapters; + +import android.support.v7.widget.RecyclerView; +import android.view.ViewGroup; + +import hikapro.com.backpack.presenter.Presenter; +import hikapro.com.backpack.view.recycler.ItemViewHolder; + +/** + * Created by tariel on 20/04/16. + */ +public class ItemListAdapter extends RecyclerView.Adapter { + + private Presenter.ItemList presenter; + private int categoryId; + + public ItemListAdapter(Presenter.ItemList presenter) { + this.presenter = presenter; + } + + @Override + public int getItemCount() { + return presenter.getItemsCount(categoryId); + } + + @Override + public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + return presenter.createViewHolderItem(parent, viewType); + } + + @Override + public void onBindViewHolder(ItemViewHolder holder, int position) { + presenter.bindViewHolderItem(holder, position, categoryId); + } + public void setCategoryId(int categoryId) { + this.categoryId = categoryId; + } +} diff --git a/app/src/main/java/hikapro/com/backpack/presenter/adapters/SetListAdapter.java b/app/src/main/java/hikapro/com/backpack/presenter/adapters/SetListAdapter.java new file mode 100644 index 0000000..15034fb --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/presenter/adapters/SetListAdapter.java @@ -0,0 +1,34 @@ +package hikapro.com.backpack.presenter.adapters; + +import android.support.v7.widget.RecyclerView; +import android.view.ViewGroup; + +import hikapro.com.backpack.presenter.SetListPresenter; +import hikapro.com.backpack.view.recycler.SetViewHolder; + +/** + * Created by tariel on 20/04/16. + */ +public class SetListAdapter extends RecyclerView.Adapter { + + private SetListPresenter presenter; + + public SetListAdapter(SetListPresenter presenter) { + this.presenter = presenter; + } + + @Override + public void onBindViewHolder(SetViewHolder holder, int position) { + presenter.bindViewHolder(holder, position); + } + + @Override + public SetViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + return presenter.createViewHolder(parent, viewType); + } + + @Override + public int getItemCount() { + return presenter.getSetsCount(); + } +} diff --git a/app/src/main/java/hikapro/com/backpack/view/View.java b/app/src/main/java/hikapro/com/backpack/view/View.java new file mode 100644 index 0000000..2df7e47 --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/view/View.java @@ -0,0 +1,36 @@ +package hikapro.com.backpack.view; + +import android.content.Context; +import android.widget.Toast; + +import hikapro.com.backpack.model.entities.Item; +import hikapro.com.backpack.model.entities.Set; +import hikapro.com.backpack.presenter.Presenter; + +/** + * Created by tariel on 19/04/16. + */ +public interface View { + + interface Base { + Context getAppContext(); + Context getActivityContext(); + } + interface SetList extends Base { + void showItemList(Set set); + void setPresenter(Presenter.SetList presenter); + } + + interface ItemList extends Base { + void showItemDetail(Item item); + void setPresenter(Presenter.ItemList presenter); + } + interface ItemDetail extends Base { + + } + interface ActivityCallback { + void startItemListFragment(Set set); + void startItemDetailFragment(); + + } +} diff --git a/app/src/main/java/hikapro/com/backpack/view/fragments/ItemListFragment.java b/app/src/main/java/hikapro/com/backpack/view/fragments/ItemListFragment.java new file mode 100644 index 0000000..c6644ac --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/view/fragments/ItemListFragment.java @@ -0,0 +1,144 @@ +package hikapro.com.backpack.view.fragments; + + +import android.app.Activity; +import android.app.Fragment; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import hikapro.com.backpack.R; +import hikapro.com.backpack.model.entities.Item; +import hikapro.com.backpack.model.entities.Set; +import hikapro.com.backpack.presenter.ItemListPresenter; +import hikapro.com.backpack.presenter.Presenter; + + +public class ItemListFragment extends Fragment implements hikapro.com.backpack.view.View.ItemList { + + private static final String BUNDLE_SET_KEY = "BUNDLE_SET_KEY"; + private hikapro.com.backpack.view.View.ActivityCallback activityCallback; + private Presenter.ItemList presenter; + + + public ItemListFragment() { + // Required empty public constructor + } + + protected static ItemListFragment construct() { + return new ItemListFragment(); + } + + public static ItemListFragment newFromSet(Set set) { + ItemListFragment ret = ItemListFragment.construct(); + Bundle args = new Bundle(); + args.putSerializable(BUNDLE_SET_KEY, set); + ret.setArguments(args); + ret.setPresenter(new ItemListPresenter(ret, set)); + return ret; + } + + // life cycle --> + @Override + public void onAttach(Context context) { + super.onAttach(context); + try { + activityCallback = (hikapro.com.backpack.view.View.ActivityCallback) context; + } catch (ClassCastException e) { + throw new ClassCastException(context.toString() + + " must implement activityCallback"); + } + } + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + try { + activityCallback = (hikapro.com.backpack.view.View.ActivityCallback) activity; + } catch (ClassCastException e) { + throw new ClassCastException(activity.toString() + + " must implement activityCallback"); + } + Log.i(this.toString(), "onAttach"); + } + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Log.i(this.toString(), "onCreate"); + } + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View view = presenter.onCreateView(inflater, container, savedInstanceState); + Log.i(this.toString(), "onCreateView"); + return view; + } + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + Log.i(this.toString(), "onActivityCreated"); + } + @Override + public void onStart() { + super.onStart(); + Log.i(this.toString(), "onStart"); + } + @Override + public void onResume() { + super.onResume(); + Log.i(this.toString(), "onResume"); + } + @Override + public void onStop() { + super.onStop(); + Log.i(this.toString(), "onStop"); + } + @Override + public void onDestroyView() { + super.onDestroyView(); + presenter.onDestroy(true); // TODO isChangingConfigurations + Log.i(this.toString(), "onDestroyView"); + } + @Override + public void onDestroy() { + super.onDestroy(); + Log.i(this.toString(), "onDestroy"); + } + @Override + public void onDetach() { + super.onDetach(); + Log.i(this.toString(), "onDetach"); + } + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + Log.i(this.toString(), "onSaveInstanceState"); + } + + // life cycle <-- + + @Override + public void showItemDetail(Item item) { + //TODO not implemented + } + + @Override + public void setPresenter(Presenter.ItemList presenter) { + this.presenter = presenter; + } + + @Override + public Context getAppContext() { + return this.getActivity().getApplicationContext(); + } + + @Override + public Context getActivityContext() { + return this.getActivity(); + } + +} diff --git a/app/src/main/java/hikapro/com/backpack/view/fragments/SetListFragment.java b/app/src/main/java/hikapro/com/backpack/view/fragments/SetListFragment.java new file mode 100644 index 0000000..3e0ee28 --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/view/fragments/SetListFragment.java @@ -0,0 +1,133 @@ +package hikapro.com.backpack.view.fragments; + + +import android.app.Activity; +import android.app.Fragment; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import hikapro.com.backpack.R; +import hikapro.com.backpack.model.entities.Set; +import hikapro.com.backpack.presenter.Presenter; +import hikapro.com.backpack.presenter.SetListPresenter; + +public class SetListFragment extends Fragment implements hikapro.com.backpack.view.View.SetList { + + private Presenter.SetList presenter; + private hikapro.com.backpack.view.View.ActivityCallback activityCallback; + + + public SetListFragment() { + // Required empty public constructor + } + public static SetListFragment construct() { + SetListFragment ret = new SetListFragment(); + return ret; + } + + // life cycle --> + @Override + public void onAttach(Context context) { + super.onAttach(context); + try { + activityCallback = (hikapro.com.backpack.view.View.ActivityCallback) context; + } catch (ClassCastException e) { + throw new ClassCastException(context.toString() + + " must implement activityCallback"); + } + } + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + try { + activityCallback = (hikapro.com.backpack.view.View.ActivityCallback) activity; + } catch (ClassCastException e) { + throw new ClassCastException(activity.toString() + + " must implement activityCallback"); + } + Log.i(this.toString(), "onAttach"); + } + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setPresenter(new SetListPresenter()); + Log.i(this.toString(), "onCreate"); + } + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View view = presenter.onCreateView(inflater, container, savedInstanceState); + presenter.setView(this); + Log.i(this.toString(), "onCreateView"); + return view; + } + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + Log.i(this.toString(), "onActivityCreated"); + } + @Override + public void onStart() { + super.onStart(); + Log.i(this.toString(), "onStart"); + } + @Override + public void onResume() { + super.onResume(); + Log.i(this.toString(), "onResume"); + } + @Override + public void onPause() { + super.onPause(); + Log.i(this.toString(), "onPause"); + } + @Override + public void onStop() { + super.onStop(); + Log.i(this.toString(), "onStop"); + } + @Override + public void onDestroyView() { + super.onDestroyView(); + presenter.onDestroy(true); // TODO isChangingConfigurations + Log.i(this.toString(), "onDestroyView"); + } + @Override + public void onDestroy() { + super.onDestroy(); + Log.i(this.toString(), "onDestroy"); + } + @Override + public void onDetach() { + super.onDetach(); + Log.i(this.toString(), "onDetach"); + } + // life cycle <-- + + @Override + public void showItemList(Set set) { + activityCallback.startItemListFragment(set); + } + + @Override + public Context getAppContext() { + return this.getActivity().getApplicationContext(); + } + + @Override + public Context getActivityContext() { + return this.getActivity(); + } + + + @Override + public void setPresenter(Presenter.SetList presenter) { + this.presenter = presenter; + } +} diff --git a/app/src/main/java/hikapro/com/backpack/view/recycler/CategoryViewHolder.java b/app/src/main/java/hikapro/com/backpack/view/recycler/CategoryViewHolder.java new file mode 100644 index 0000000..62352e9 --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/view/recycler/CategoryViewHolder.java @@ -0,0 +1,31 @@ +package hikapro.com.backpack.view.recycler; + +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.TextView; + +import hikapro.com.backpack.R; + +/** + * Created by tariel on 20/04/16. + */ +public class CategoryViewHolder extends RecyclerView.ViewHolder { + + public LinearLayout section; + public TextView sectionText; + public RecyclerView itemsRecycler; + + public CategoryViewHolder(View v) { + super(v); + setupViews(v); + } + + private void setupViews(View view) { + section = (LinearLayout)view.findViewById(R.id.linear); + sectionText = (TextView)view.findViewById(R.id.section_text); + itemsRecycler = (RecyclerView) view.findViewById(R.id.category_inner_recycler); + } + +} diff --git a/app/src/main/java/hikapro/com/backpack/view/recycler/ItemViewHolder.java b/app/src/main/java/hikapro/com/backpack/view/recycler/ItemViewHolder.java new file mode 100644 index 0000000..5a86246 --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/view/recycler/ItemViewHolder.java @@ -0,0 +1,26 @@ +package hikapro.com.backpack.view.recycler; + +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.widget.TextView; + +import hikapro.com.backpack.R; + +/** + * Created by tariel on 20/04/16. + */ +public class ItemViewHolder extends RecyclerView.ViewHolder { + + public TextView title; + public int id; + public int categoryId; + + public ItemViewHolder(View v) { + super(v); + setupViews(v); + } + + private void setupViews(View view) { + title = (TextView) view.findViewById(R.id.item_text); + } +} diff --git a/app/src/main/java/hikapro/com/backpack/view/recycler/SetViewHolder.java b/app/src/main/java/hikapro/com/backpack/view/recycler/SetViewHolder.java new file mode 100644 index 0000000..c51778c --- /dev/null +++ b/app/src/main/java/hikapro/com/backpack/view/recycler/SetViewHolder.java @@ -0,0 +1,27 @@ +package hikapro.com.backpack.view.recycler; + +import android.support.v7.widget.CardView; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.widget.TextView; + +import hikapro.com.backpack.R; + +/** + * Created by tariel on 20/04/16. + */ +public class SetViewHolder extends RecyclerView.ViewHolder { + + public CardView cardView; + public TextView textView; + + public SetViewHolder(View v) { + super(v); + setupViews(v); + } + + private void setupViews(View view) { + cardView = (CardView) view.findViewById(R.id.card_view_set); + textView = (TextView) view.findViewById(R.id.set_text); + } +} 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 0000000..2a8e37d --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/app/src/main/res/layout/fragment_item_list.xml b/app/src/main/res/layout/fragment_item_list.xml new file mode 100644 index 0000000..361ca3b --- /dev/null +++ b/app/src/main/res/layout/fragment_item_list.xml @@ -0,0 +1,14 @@ + + + + diff --git a/app/src/main/res/layout/fragment_set_list.xml b/app/src/main/res/layout/fragment_set_list.xml new file mode 100644 index 0000000..613037b --- /dev/null +++ b/app/src/main/res/layout/fragment_set_list.xml @@ -0,0 +1,7 @@ + + diff --git a/app/src/main/res/layout/item.xml b/app/src/main/res/layout/item.xml new file mode 100644 index 0000000..773bfbf --- /dev/null +++ b/app/src/main/res/layout/item.xml @@ -0,0 +1,10 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/layout/section.xml b/app/src/main/res/layout/section.xml new file mode 100644 index 0000000..b722a57 --- /dev/null +++ b/app/src/main/res/layout/section.xml @@ -0,0 +1,25 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/set_card.xml b/app/src/main/res/layout/set_card.xml new file mode 100644 index 0000000..a1d2d37 --- /dev/null +++ b/app/src/main/res/layout/set_card.xml @@ -0,0 +1,25 @@ + + + + + + + + + + \ No newline at end of file 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 0000000..cde69bc Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ 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 0000000..c133a0c Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ 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 0000000..bfa42f0 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ 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 0000000..324e72c Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..aee44e1 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml new file mode 100644 index 0000000..63fc816 --- /dev/null +++ b/app/src/main/res/values-w820dp/dimens.xml @@ -0,0 +1,6 @@ + + + 64dp + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..3ab3e9c --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ + + + #3F51B5 + #303F9F + #FF4081 + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..47c8224 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,5 @@ + + + 16dp + 16dp + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..b77dfd1 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + BackPack + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..5885930 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/app/src/test/java/hikapro/com/backpack/ExampleUnitTest.java b/app/src/test/java/hikapro/com/backpack/ExampleUnitTest.java new file mode 100644 index 0000000..bed9698 --- /dev/null +++ b/app/src/test/java/hikapro/com/backpack/ExampleUnitTest.java @@ -0,0 +1,15 @@ +package hikapro.com.backpack; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * To work on unit tests, switch the Test Artifact in the Build Variants view. + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() throws Exception { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..168f129 --- /dev/null +++ b/build.gradle @@ -0,0 +1,23 @@ +// 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:2.0.0' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + jcenter() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..1d3591c --- /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 0000000..13372ae Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..122a0dc --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Mon Dec 28 10:00:20 PST 2015 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..9d82f78 --- /dev/null +++ b/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +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"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # 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 0000000..aec9973 --- /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 0000000..e7b4def --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +include ':app'