diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9c4de58 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.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..6bc0c98 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +TwitterCrashlytics \ 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/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..1bbc21d --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..1a3eaff --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..82d4bc2 --- /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..6564d52 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..d4bb011 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# VolleyExample diff --git a/TwitterCrashlytics.iml b/TwitterCrashlytics.iml new file mode 100644 index 0000000..2a3f222 --- /dev/null +++ b/TwitterCrashlytics.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ 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/app.iml b/app/app.iml new file mode 100644 index 0000000..c75b8d8 --- /dev/null +++ b/app/app.iml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..82926c0 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,30 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 23 + buildToolsVersion "23.0.1" + + defaultConfig { + applicationId "com.twittercrashlytics" + minSdkVersion 15 + 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']) + compile 'com.android.support:appcompat-v7:23.0.1' + compile 'com.android.support:cardview-v7:23.0.1' + compile 'com.android.support:recyclerview-v7:23.0.1' + compile 'com.mcxiaoke.volley:library:1.0.19' + compile 'com.google.code.gson:gson:2.5' + compile 'com.jakewharton:butterknife:7.0.1' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..d45c1f2 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/nayanesh.gupte/Library/Android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/app/src/androidTest/java/com/twittercrashlytics/ApplicationTest.java b/app/src/androidTest/java/com/twittercrashlytics/ApplicationTest.java new file mode 100644 index 0000000..7bebecd --- /dev/null +++ b/app/src/androidTest/java/com/twittercrashlytics/ApplicationTest.java @@ -0,0 +1,13 @@ +package com.twittercrashlytics; + +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..efa61d5 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/com/twittercrashlytics/TwitterCrashlyticsApplication.java b/app/src/main/java/com/twittercrashlytics/TwitterCrashlyticsApplication.java new file mode 100644 index 0000000..37a5e4f --- /dev/null +++ b/app/src/main/java/com/twittercrashlytics/TwitterCrashlyticsApplication.java @@ -0,0 +1,85 @@ +package com.twittercrashlytics; + +import android.app.Application; +import android.text.TextUtils; + +import com.android.volley.Request; +import com.android.volley.RequestQueue; +import com.android.volley.toolbox.ImageLoader; +import com.android.volley.toolbox.Volley; +import com.twittercrashlytics.network.LruBitmapCache; + +/** + * + */ +public class TwitterCrashlyticsApplication extends Application { + + public static final String TAG = TwitterCrashlyticsApplication.class.getSimpleName(); + + + private RequestQueue mRequestQueue; + + private static TwitterCrashlyticsApplication mInstance; + + private ImageLoader mImageLoader; + LruBitmapCache mLruBitmapCache; + + @Override + public void onCreate() { + super.onCreate(); + mInstance = this; + } + + public static synchronized TwitterCrashlyticsApplication getInstance() { + return mInstance; + } + + /** + * Set up request Queue + *

+ * https://developer.android.com/training/volley/requestqueue.html + * + * @return + */ + public RequestQueue getRequestQueue() { + if (mRequestQueue == null) { + mRequestQueue = Volley.newRequestQueue(getApplicationContext()); + } + + return mRequestQueue; + } + + public void addToRequestQueue(Request req, String tag) { + req.setTag(TextUtils.isEmpty(tag) ? TAG : tag); + getRequestQueue().add(req); + } + + public void addToRequestQueue(Request req) { + req.setTag(TAG); + getRequestQueue().add(req); + } + + public void cancelPendingRequests(Object tag) { + if (mRequestQueue != null) { + mRequestQueue.cancelAll(tag); + } + } + + + public LruBitmapCache getLruBitmapCache() { + if (mLruBitmapCache == null) + mLruBitmapCache = new LruBitmapCache(); + return this.mLruBitmapCache; + } + + public ImageLoader getImageLoader() { + getRequestQueue(); + if (mImageLoader == null) { + getLruBitmapCache(); + mImageLoader = new ImageLoader(this.mRequestQueue, mLruBitmapCache); + } + + return this.mImageLoader; + } + +} diff --git a/app/src/main/java/com/twittercrashlytics/Utils/AppUtil.java b/app/src/main/java/com/twittercrashlytics/Utils/AppUtil.java new file mode 100644 index 0000000..6200d25 --- /dev/null +++ b/app/src/main/java/com/twittercrashlytics/Utils/AppUtil.java @@ -0,0 +1,26 @@ +package com.twittercrashlytics.Utils; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; + +/** + * + */ +public class AppUtil { + + /** + * Check if network is available or not + * + * @param context + * @return + */ + public static boolean isNetworkAvailable(Context context) { + ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo netInfo = manager.getActiveNetworkInfo(); + if (netInfo != null && netInfo.isConnectedOrConnecting()) { + return true; + } + return false; + } +} diff --git a/app/src/main/java/com/twittercrashlytics/Utils/DataInitilizer.java b/app/src/main/java/com/twittercrashlytics/Utils/DataInitilizer.java new file mode 100644 index 0000000..2e1fe84 --- /dev/null +++ b/app/src/main/java/com/twittercrashlytics/Utils/DataInitilizer.java @@ -0,0 +1,73 @@ +package com.twittercrashlytics.Utils; + +import android.content.Context; + +import com.android.volley.Response; +import com.android.volley.VolleyError; +import com.twittercrashlytics.TwitterCrashlyticsApplication; +import com.twittercrashlytics.network.GsonRequest; +import com.twittercrashlytics.network.model.Comment; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Created by Nayanesh Gupte + */ +public class DataInitilizer implements Response.Listener, Response.ErrorListener { + + + private final static String TAG = DataInitilizer.class.getSimpleName(); + + + private Context context; + + private OnDataReeceivedListener onDataReeceivedListener; + + + public DataInitilizer(Context context) { + + this.context = context; + } + + public void setOnDataReeceivedListener(OnDataReeceivedListener onDataReeceivedListener) { + this.onDataReeceivedListener = onDataReeceivedListener; + } + + + public void getCommentsList(String commentsUrl) { + + if (AppUtil.isNetworkAvailable(context)) { + GsonRequest myReq = new GsonRequest(commentsUrl, + Comment[].class, + null, + this, + this); + + TwitterCrashlyticsApplication.getInstance().addToRequestQueue(myReq, TAG); + } else { + + + } + } + + + @Override + public void onResponse(Comment[] response) { + + List listIssues = Arrays.asList(response); + + Collections.sort(listIssues, new DateComparator()); + + onDataReeceivedListener.onDataReceived(listIssues); + + } + + @Override + public void onErrorResponse(VolleyError error) { + + onDataReeceivedListener.onError(error); + + } +} diff --git a/app/src/main/java/com/twittercrashlytics/Utils/DateComparator.java b/app/src/main/java/com/twittercrashlytics/Utils/DateComparator.java new file mode 100644 index 0000000..da7a632 --- /dev/null +++ b/app/src/main/java/com/twittercrashlytics/Utils/DateComparator.java @@ -0,0 +1,31 @@ +package com.twittercrashlytics.Utils; + +import com.twittercrashlytics.network.model.BaseModel; + +import java.util.Comparator; + +/** + * Date comparator to compare dates on most updated (Ascending order) basis. + */ +public class DateComparator implements Comparator { + + + @Override + public int compare(BaseModel lhs, BaseModel rhs) { + + long date1 = DateTimeUtil.convertDatetToTimeStamp(lhs.getUpdatedAt()); + + long date2 = DateTimeUtil.convertDatetToTimeStamp(rhs.getUpdatedAt()); + + if (date1 > date2) { + + return 1; + } else if (date1 < date2) { + + return -1; + } + + + return 0; + } +} diff --git a/app/src/main/java/com/twittercrashlytics/Utils/DateTimeUtil.java b/app/src/main/java/com/twittercrashlytics/Utils/DateTimeUtil.java new file mode 100644 index 0000000..dcde3ed --- /dev/null +++ b/app/src/main/java/com/twittercrashlytics/Utils/DateTimeUtil.java @@ -0,0 +1,40 @@ +package com.twittercrashlytics.Utils; + +import android.util.Log; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +/** + * + */ +public class DateTimeUtil { + + private static final String TAG = DateTimeUtil.class.getSimpleName(); + + /** + * Convert formatted date to long timedtamp for comparison + * + * @param dateString + * @return date converted in timestamp + */ + public static long convertDatetToTimeStamp(String dateString) { + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:SS'Z'", Locale.ENGLISH); + Date convertedDate; + try { + convertedDate = sdf.parse(dateString); + + return convertedDate.getTime(); + + } catch (ParseException e) { + + Log.e(TAG, e.getMessage()); + + } + + return 0; + } +} diff --git a/app/src/main/java/com/twittercrashlytics/Utils/IAppConstants.java b/app/src/main/java/com/twittercrashlytics/Utils/IAppConstants.java new file mode 100644 index 0000000..b995aa3 --- /dev/null +++ b/app/src/main/java/com/twittercrashlytics/Utils/IAppConstants.java @@ -0,0 +1,14 @@ +package com.twittercrashlytics.Utils; + +/** + * + */ +public interface IAppConstants { + + String BASE_URL = "https://api.github.com/repos/crashlytics/secureudid/issues"; + + String KEY_COMMENTS_URL = "commentsUrl"; + String KEY_ISSUE_ID = "issueId"; + + +} diff --git a/app/src/main/java/com/twittercrashlytics/Utils/OnDataReeceivedListener.java b/app/src/main/java/com/twittercrashlytics/Utils/OnDataReeceivedListener.java new file mode 100644 index 0000000..9ce2a40 --- /dev/null +++ b/app/src/main/java/com/twittercrashlytics/Utils/OnDataReeceivedListener.java @@ -0,0 +1,15 @@ +package com.twittercrashlytics.Utils; + +import com.android.volley.VolleyError; + +import java.util.List; + +/** + * Created by Nayanesh Gupte on 06/03/16. + */ +public interface OnDataReeceivedListener { + + void onDataReceived(List object); + + void onError(VolleyError volleyError); +} diff --git a/app/src/main/java/com/twittercrashlytics/Utils/OnItemClickListener.java b/app/src/main/java/com/twittercrashlytics/Utils/OnItemClickListener.java new file mode 100644 index 0000000..98e3c11 --- /dev/null +++ b/app/src/main/java/com/twittercrashlytics/Utils/OnItemClickListener.java @@ -0,0 +1,9 @@ +package com.twittercrashlytics.Utils; + +/** + * + */ +public interface OnItemClickListener { + + void onItemClick(Object object, int position); +} diff --git a/app/src/main/java/com/twittercrashlytics/activity/GitIssuesListActivity.java b/app/src/main/java/com/twittercrashlytics/activity/GitIssuesListActivity.java new file mode 100644 index 0000000..f0a36b9 --- /dev/null +++ b/app/src/main/java/com/twittercrashlytics/activity/GitIssuesListActivity.java @@ -0,0 +1,53 @@ +package com.twittercrashlytics.activity; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; + +import com.twittercrashlytics.R; +import com.twittercrashlytics.fragment.GitIssuesListFragment; + +/** + * Activity holding issues list fragment. + *

+ * Launcher Activity. + */ +public class GitIssuesListActivity extends AppCompatActivity { + + + private Toolbar mToolbar; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_git_issues_list); + + setupToolbar(); + + addIssuesListFragment(); + + + } + + private void setupToolbar() { + mToolbar = (Toolbar) findViewById(R.id.toolbar); + + setSupportActionBar(mToolbar); + getSupportActionBar().setDisplayShowHomeEnabled(true); + + } + + /** + * Add fragment to display list of issues + */ + private void addIssuesListFragment() { + + GitIssuesListFragment gitIssuesListFragment = new GitIssuesListFragment(); + + getSupportFragmentManager().beginTransaction().add(R.id.frame_container, gitIssuesListFragment).commit(); + + } + + +} diff --git a/app/src/main/java/com/twittercrashlytics/adapter/CommentsListAdapter.java b/app/src/main/java/com/twittercrashlytics/adapter/CommentsListAdapter.java new file mode 100644 index 0000000..ab2c6e5 --- /dev/null +++ b/app/src/main/java/com/twittercrashlytics/adapter/CommentsListAdapter.java @@ -0,0 +1,77 @@ +package com.twittercrashlytics.adapter; + +import android.content.Context; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.twittercrashlytics.R; +import com.twittercrashlytics.network.model.Comment; + +import java.util.ArrayList; +import java.util.List; + +/** + * + */ +public class CommentsListAdapter extends RecyclerView.Adapter { + private List data = new ArrayList<>(); + private LayoutInflater inflater; + private Context context; + + public CommentsListAdapter(Context context) { + this.context = context; + inflater = LayoutInflater.from(context); + + } + + public void add(List data) { + + this.data.addAll(data); + notifyDataSetChanged(); + } + + + @Override + public CommentsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = inflater.inflate(R.layout.row_comments, parent, false); + CommentsViewHolder holder = new CommentsViewHolder(view); + return holder; + } + + @Override + public void onBindViewHolder(CommentsViewHolder holder, int position) { + + Comment comment = data.get(position); + + //--- set title + holder.txtvTitle.setText(comment.getUser().getLogin()); + + + //--- set Issue body + holder.txtvIssue.setText(comment.getBody()); + } + + @Override + public int getItemCount() { + return data.size(); + } + + static class CommentsViewHolder extends RecyclerView.ViewHolder { + + TextView txtvTitle; + + TextView txtvIssue; + + public CommentsViewHolder(View itemView) { + super(itemView); + + txtvTitle = (TextView) itemView.findViewById(R.id.txtvTitle); + + txtvIssue = (TextView) itemView.findViewById(R.id.txtvIssue); + + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/twittercrashlytics/adapter/IssuesListAdapter.java b/app/src/main/java/com/twittercrashlytics/adapter/IssuesListAdapter.java new file mode 100644 index 0000000..1baf00f --- /dev/null +++ b/app/src/main/java/com/twittercrashlytics/adapter/IssuesListAdapter.java @@ -0,0 +1,120 @@ +package com.twittercrashlytics.adapter; + +import android.content.Context; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.android.volley.toolbox.ImageLoader; +import com.android.volley.toolbox.NetworkImageView; +import com.twittercrashlytics.R; +import com.twittercrashlytics.TwitterCrashlyticsApplication; +import com.twittercrashlytics.Utils.OnItemClickListener; +import com.twittercrashlytics.network.model.Issue; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.Bind; +import butterknife.ButterKnife; + +/** + * + */ +public class IssuesListAdapter extends RecyclerView.Adapter { + List data = new ArrayList<>(); + private LayoutInflater inflater; + private Context context; + + private OnItemClickListener onItemClickListener; + + private ImageLoader imageLoader; + + public IssuesListAdapter(Context context) { + this.context = context; + inflater = LayoutInflater.from(context); + + imageLoader = TwitterCrashlyticsApplication.getInstance().getImageLoader(); + } + + + public void setOnItemClickListener(OnItemClickListener onItemClickListener) { + this.onItemClickListener = onItemClickListener; + } + + + public void add(List data) { + + this.data.addAll(data); + notifyDataSetChanged(); + } + + + @Override + public IssuesViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = inflater.inflate(R.layout.row_issues, parent, false); + IssuesViewHolder holder = new IssuesViewHolder(view); + return holder; + } + + @Override + public void onBindViewHolder(final IssuesViewHolder holder, final int position) { + + final Issue issue = data.get(position); + + //--- setImage + + holder.imgUser.setDefaultImageResId(R.drawable.ic_launcher); + holder.imgUser.setErrorImageResId(R.drawable.ic_launcher); + holder.imgUser.setImageUrl(issue.getUser().getProfilepicUrl(), imageLoader); + + //--- set title + holder.txtvTitle.setText(issue.getTitle()); + + + //--- set Issue body + holder.txtvIssue.setText(issue.getBody()); + + + //----- + holder.view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + onItemClickListener.onItemClick(issue, position); + } + }); + + } + + @Override + public int getItemCount() { + return data.size(); + } + + static class IssuesViewHolder extends RecyclerView.ViewHolder { + + @Bind(R.id.txtvTitle) + TextView txtvTitle; + + @Bind(R.id.txtvIssue) + TextView txtvIssue; + + @Bind(R.id.imgUser) + NetworkImageView imgUser; + + @Bind(R.id.cardView) + View view; + + public IssuesViewHolder(View itemView) { + super(itemView); + + + ButterKnife.bind(this, itemView); + + + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/twittercrashlytics/fragment/GitCommentsListFragment.java b/app/src/main/java/com/twittercrashlytics/fragment/GitCommentsListFragment.java new file mode 100644 index 0000000..c9c5426 --- /dev/null +++ b/app/src/main/java/com/twittercrashlytics/fragment/GitCommentsListFragment.java @@ -0,0 +1,140 @@ +package com.twittercrashlytics.fragment; + +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ProgressBar; + +import com.android.volley.VolleyError; +import com.twittercrashlytics.R; +import com.twittercrashlytics.TwitterCrashlyticsApplication; +import com.twittercrashlytics.Utils.DataInitilizer; +import com.twittercrashlytics.Utils.IAppConstants; +import com.twittercrashlytics.Utils.OnDataReeceivedListener; +import com.twittercrashlytics.adapter.CommentsListAdapter; +import com.twittercrashlytics.network.model.Comment; + +import java.util.List; + +/** + * Fragment holding list of comments for every issue. + */ +public class GitCommentsListFragment extends DialogFragment implements IAppConstants, OnDataReeceivedListener { + + + private static final String TAG = GitCommentsListFragment.class.getSimpleName(); + + //------------------------------------------------------- + //Views + //------------------------------------------------------- + private RecyclerView recyListComments; + private ProgressBar progressBar; + + + //------------------------------------------------------- + //Variables + //------------------------------------------------------- + private CommentsListAdapter commentsListAdapter; + + private String commentsUrl; + private String issueId; + + private DataInitilizer dataInitilizer; + + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + getDataFromBundle(); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + + View view = inflater.inflate(R.layout.fragment_git_comments_list, container, false); + + init(view); + + return view; + } + + private void init(View view) { + + recyListComments = (RecyclerView) view.findViewById(R.id.recyListComments); + progressBar = (ProgressBar) view.findViewById(R.id.progressBar); + + dataInitilizer = new DataInitilizer(getActivity()); + dataInitilizer.setOnDataReeceivedListener(this); + + } + + private void getDataFromBundle() { + + Bundle bundle = getArguments(); + + if (null != bundle) { + + commentsUrl = bundle.getString(KEY_COMMENTS_URL); + issueId = bundle.getString(KEY_ISSUE_ID); + } + } + + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + getDialog().setTitle(getString(R.string.issue) + issueId); + + initRecyclerView(); + } + + /** + * Initialize recycler view. Initialization in onCreateView crashes in some devices. + */ + private void initRecyclerView() { + + recyListComments.setLayoutManager(new LinearLayoutManager(getActivity())); + commentsListAdapter = new CommentsListAdapter(getActivity()); + recyListComments.setAdapter(commentsListAdapter); + + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + progressBar.setVisibility(View.VISIBLE); + dataInitilizer.getCommentsList(commentsUrl); + } + + + @Override + public void onDetach() { + super.onDetach(); + + TwitterCrashlyticsApplication.getInstance().cancelPendingRequests(TAG); + } + + + @Override + public void onDataReceived(List listIssues) { + + progressBar.setVisibility(View.GONE); + + commentsListAdapter.add(listIssues); + progressBar.setVisibility(View.GONE); + } + + @Override + public void onError(VolleyError volleyError) { + + progressBar.setVisibility(View.GONE); + + } +} diff --git a/app/src/main/java/com/twittercrashlytics/fragment/GitIssuesListFragment.java b/app/src/main/java/com/twittercrashlytics/fragment/GitIssuesListFragment.java new file mode 100644 index 0000000..ae4ee1a --- /dev/null +++ b/app/src/main/java/com/twittercrashlytics/fragment/GitIssuesListFragment.java @@ -0,0 +1,170 @@ +package com.twittercrashlytics.fragment; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ProgressBar; +import android.widget.Toast; + +import com.android.volley.Response; +import com.android.volley.VolleyError; +import com.twittercrashlytics.R; +import com.twittercrashlytics.TwitterCrashlyticsApplication; +import com.twittercrashlytics.Utils.AppUtil; +import com.twittercrashlytics.Utils.DateComparator; +import com.twittercrashlytics.Utils.IAppConstants; +import com.twittercrashlytics.Utils.OnItemClickListener; +import com.twittercrashlytics.adapter.IssuesListAdapter; +import com.twittercrashlytics.network.GsonRequest; +import com.twittercrashlytics.network.model.Issue; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Fragment holding list of issues. + */ +public class GitIssuesListFragment extends Fragment implements IAppConstants, OnItemClickListener { + + + private static final String TAG = GitIssuesListFragment.class.getSimpleName(); + + //------------------------------------------------------- + //Views + //------------------------------------------------------- + private RecyclerView recyListComments; + private ProgressBar progressBar; + + //------------------------------------------------------- + //Variables + //------------------------------------------------------- + private IssuesListAdapter issuesListAdapter; + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + + View view = inflater.inflate(R.layout.fragment_git_issues_list, container, false); + + init(view); + + return view; + } + + private void init(View view) { + + recyListComments = (RecyclerView) view.findViewById(R.id.recyListComments); + progressBar = (ProgressBar) view.findViewById(R.id.progressBar); + + } + + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + + initRecyclerView(); + } + + /** + * Initialize recycler view. Initialization in onCreateView crashes in some devices. + */ + private void initRecyclerView() { + + recyListComments.setLayoutManager(new LinearLayoutManager(getActivity())); + issuesListAdapter = new IssuesListAdapter(getActivity()); + recyListComments.setAdapter(issuesListAdapter); + issuesListAdapter.setOnItemClickListener(this); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + getIssuesList(); + } + + private void getIssuesList() { + + if (AppUtil.isNetworkAvailable(getActivity())) { + + GsonRequest myReq = new GsonRequest(BASE_URL, + Issue[].class, + null, + createMyReqSuccessListener(), + createMyReqErrorListener()); + + TwitterCrashlyticsApplication.getInstance().addToRequestQueue(myReq, TAG); + } else { + + progressBar.setVisibility(View.GONE); + + Toast.makeText(getActivity(), getString(R.string.no_network), Toast.LENGTH_SHORT).show(); + + } + + + } + + private Response.Listener createMyReqSuccessListener() { + return new Response.Listener() { + @Override + public void onResponse(Issue[] response) { + + List listIssues = Arrays.asList(response); + + Collections.sort(listIssues, new DateComparator()); + + issuesListAdapter.add(listIssues); + + + progressBar.setVisibility(View.GONE); + + } + + }; + } + + private Response.ErrorListener createMyReqErrorListener() { + return new Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { + + progressBar.setVisibility(View.GONE); + + Log.e(TAG, "onErrorResponse: " + error.toString()); + + } + }; + } + + @Override + public void onItemClick(Object object, int position) { + + Issue issue = (Issue) object; + + GitCommentsListFragment gitCommentsListFragment = new GitCommentsListFragment(); + Bundle bundle = new Bundle(); + bundle.putString(KEY_COMMENTS_URL, issue.getCommentsUrl()); + bundle.putString(KEY_ISSUE_ID, issue.getId()); + gitCommentsListFragment.setArguments(bundle); + gitCommentsListFragment.show(getActivity().getSupportFragmentManager(), TAG); + + } + + @Override + public void onDetach() { + super.onDetach(); + + TwitterCrashlyticsApplication.getInstance().cancelPendingRequests(TAG); + } + + +} diff --git a/app/src/main/java/com/twittercrashlytics/network/GsonRequest.java b/app/src/main/java/com/twittercrashlytics/network/GsonRequest.java new file mode 100644 index 0000000..f40065d --- /dev/null +++ b/app/src/main/java/com/twittercrashlytics/network/GsonRequest.java @@ -0,0 +1,68 @@ +package com.twittercrashlytics.network; + +import com.android.volley.AuthFailureError; +import com.android.volley.NetworkResponse; +import com.android.volley.ParseError; +import com.android.volley.Request; +import com.android.volley.Response; +import com.android.volley.toolbox.HttpHeaderParser; +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; + +import java.io.UnsupportedEncodingException; +import java.util.Map; + +/** + * complete implementation of a Volley request that uses Gson for parsing: + *

+ * https://developer.android.com/training/volley/request-custom.html#custom-request + * + * @param + */ +public class GsonRequest extends Request { + private final Gson gson = new Gson(); + private final Class clazz; + private final Map headers; + private final Response.Listener listener; + + /** + * Make a GET request and return a parsed object from JSON. + * + * @param url URL of the request to make + * @param clazz Relevant class object, for Gson's reflection + * @param headers Map of request headers + */ + public GsonRequest(String url, Class clazz, Map headers, + Response.Listener listener, Response.ErrorListener errorListener) { + super(Method.GET, url, errorListener); + this.clazz = clazz; + this.headers = headers; + this.listener = listener; + } + + @Override + public Map getHeaders() throws AuthFailureError { + return headers != null ? headers : super.getHeaders(); + } + + @Override + protected void deliverResponse(T response) { + listener.onResponse(response); + } + + @Override + protected Response parseNetworkResponse(NetworkResponse response) { + try { + String json = new String(response.data,HttpHeaderParser.parseCharset(response.headers)); + + + return Response.success( + gson.fromJson(json, clazz), + HttpHeaderParser.parseCacheHeaders(response)); + } catch (UnsupportedEncodingException e) { + return Response.error(new ParseError(e)); + } catch (JsonSyntaxException e) { + return Response.error(new ParseError(e)); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/twittercrashlytics/network/LruBitmapCache.java b/app/src/main/java/com/twittercrashlytics/network/LruBitmapCache.java new file mode 100644 index 0000000..7167392 --- /dev/null +++ b/app/src/main/java/com/twittercrashlytics/network/LruBitmapCache.java @@ -0,0 +1,39 @@ +package com.twittercrashlytics.network; + +import android.graphics.Bitmap; +import android.support.v4.util.LruCache; + +import com.android.volley.toolbox.ImageLoader.ImageCache; + +public class LruBitmapCache extends LruCache implements + ImageCache { + public static int getDefaultLruCacheSize() { + final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); + final int cacheSize = maxMemory / 8; + + return cacheSize; + } + + public LruBitmapCache() { + this(getDefaultLruCacheSize()); + } + + public LruBitmapCache(int sizeInKiloBytes) { + super(sizeInKiloBytes); + } + + @Override + protected int sizeOf(String key, Bitmap value) { + return value.getRowBytes() * value.getHeight() / 1024; + } + + @Override + public Bitmap getBitmap(String url) { + return get(url); + } + + @Override + public void putBitmap(String url, Bitmap bitmap) { + put(url, bitmap); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/twittercrashlytics/network/model/BaseModel.java b/app/src/main/java/com/twittercrashlytics/network/model/BaseModel.java new file mode 100644 index 0000000..974f580 --- /dev/null +++ b/app/src/main/java/com/twittercrashlytics/network/model/BaseModel.java @@ -0,0 +1,54 @@ +package com.twittercrashlytics.network.model; + +import com.google.gson.annotations.SerializedName; + +/** + */ +public abstract class BaseModel { + + @SerializedName("updated_at") + protected String updatedAt; + + protected String body; + + protected User user; + + protected String id; + + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + + public String getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(String updatedAt) { + this.updatedAt = updatedAt; + } + + + public String getBody() { + return body; + } + + public void setBody(String body) { + this.body = body; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + +} diff --git a/app/src/main/java/com/twittercrashlytics/network/model/Comment.java b/app/src/main/java/com/twittercrashlytics/network/model/Comment.java new file mode 100644 index 0000000..5b048f3 --- /dev/null +++ b/app/src/main/java/com/twittercrashlytics/network/model/Comment.java @@ -0,0 +1,9 @@ +package com.twittercrashlytics.network.model; + +/** + * Model for issues + */ +public class Comment extends BaseModel { + + +} diff --git a/app/src/main/java/com/twittercrashlytics/network/model/Issue.java b/app/src/main/java/com/twittercrashlytics/network/model/Issue.java new file mode 100644 index 0000000..f9a1271 --- /dev/null +++ b/app/src/main/java/com/twittercrashlytics/network/model/Issue.java @@ -0,0 +1,43 @@ +package com.twittercrashlytics.network.model; + +import com.google.gson.annotations.SerializedName; + +/** + * Model for issues + */ +public class Issue extends BaseModel { + + private String title; + + private String url; + + @SerializedName("comments_url") + private String commentsUrl; + + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getCommentsUrl() { + return commentsUrl; + } + + public void setCommentsUrl(String commentsUrl) { + this.commentsUrl = commentsUrl; + } + +} diff --git a/app/src/main/java/com/twittercrashlytics/network/model/User.java b/app/src/main/java/com/twittercrashlytics/network/model/User.java new file mode 100644 index 0000000..20d7530 --- /dev/null +++ b/app/src/main/java/com/twittercrashlytics/network/model/User.java @@ -0,0 +1,31 @@ +package com.twittercrashlytics.network.model; + +import com.google.gson.annotations.SerializedName; + +/** + * + */ +public class User { + + private String login; + + @SerializedName("avatar_url") + private String profilepicUrl; + + + public String getLogin() { + return login; + } + + public void setLogin(String login) { + this.login = login; + } + + public String getProfilepicUrl() { + return profilepicUrl; + } + + public void setProfilepicUrl(String profilepicUrl) { + this.profilepicUrl = profilepicUrl; + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher.png b/app/src/main/res/drawable/ic_launcher.png new file mode 100644 index 0000000..cde69bc Binary files /dev/null and b/app/src/main/res/drawable/ic_launcher.png differ diff --git a/app/src/main/res/layout/activity_git_issues_list.xml b/app/src/main/res/layout/activity_git_issues_list.xml new file mode 100644 index 0000000..b49b2cf --- /dev/null +++ b/app/src/main/res/layout/activity_git_issues_list.xml @@ -0,0 +1,18 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_git_comments_list.xml b/app/src/main/res/layout/fragment_git_comments_list.xml new file mode 100644 index 0000000..e605329 --- /dev/null +++ b/app/src/main/res/layout/fragment_git_comments_list.xml @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_git_issues_list.xml b/app/src/main/res/layout/fragment_git_issues_list.xml new file mode 100644 index 0000000..e605329 --- /dev/null +++ b/app/src/main/res/layout/fragment_git_issues_list.xml @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/row_comments.xml b/app/src/main/res/layout/row_comments.xml new file mode 100644 index 0000000..ad72c46 --- /dev/null +++ b/app/src/main/res/layout/row_comments.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/layout/row_issues.xml b/app/src/main/res/layout/row_issues.xml new file mode 100644 index 0000000..3acdebb --- /dev/null +++ b/app/src/main/res/layout/row_issues.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/toolbar.xml b/app/src/main/res/layout/toolbar.xml new file mode 100644 index 0000000..12c9e08 --- /dev/null +++ b/app/src/main/res/layout/toolbar.xml @@ -0,0 +1,10 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml new file mode 100644 index 0000000..0dd1538 --- /dev/null +++ b/app/src/main/res/menu/menu_main.xml @@ -0,0 +1,7 @@ +

+ + 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/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/color.xml b/app/src/main/res/values/color.xml new file mode 100644 index 0000000..f682183 --- /dev/null +++ b/app/src/main/res/values/color.xml @@ -0,0 +1,10 @@ + + + #55ACEE + #00ACEE + #FFFFFF + #EFEFEF + #000000 + #888888 + + \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 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..4d3137b --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,8 @@ + + TwitterCrashlytics + Hello world! + Settings + "Issue # " + No Network Available + MainActivity + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..053065c --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..1b7886d --- /dev/null +++ b/build.gradle @@ -0,0 +1,19 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:1.3.0' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + jcenter() + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 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..8c0fb64 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..b609b6b --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Thu Oct 01 19:13:32 IST 2015 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..91a7e26 --- /dev/null +++ b/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 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'