diff --git a/app/build.gradle b/app/build.gradle
index 4268c3a..6f868ee 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -21,9 +21,14 @@ android {
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
- compile 'com.android.support:appcompat-v7:23.1.0'
+ compile 'com.android.support:appcompat-v7:22.2.0'
compile 'se.emilsjolander:StickyScrollViewItems:1.1.0'
compile 'com.google.android.gms:play-services:7.5.0'
compile 'com.squareup.picasso:picasso:2.5.2'
+ compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
+ compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
+ compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2'
compile 'com.jakewharton:butterknife:7.0.1'
+ compile 'io.reactivex:rxandroid:1.0.1'
+ compile 'io.reactivex:rxjava:1.0.14'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 56b25f3..d3446d2 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -14,7 +14,7 @@
+ android:value="@string/google_maps_api_key" />
>>() {
+ @Override
+ public void call(Pair> pair) {
+ //Setup the header
+ headerArticle = pair.first;
+ if (pair.first != null) {
+ setupHeader(headerArticle);
+ } else {
+
+ //TODO: We need to replace the header with something else.
+ }
+
+ //Setup the remaining articles
+ if (pair.second != null && pair.second.size() > 0) {
+ setupListView(pair.second);
+ } else {
+ //TODO: Handle an empty list.
+ }
+
+ }
+ }, new Action1() {
+ @Override
+ public void call(Throwable throwable) {
+ setupHeader(new NewsArticle("Unable to Load News", "Check your connection and try again."));
+ }
+ });
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ if (newsSubscription != null && !newsSubscription.isUnsubscribed())
+ newsSubscription.unsubscribe();
+ }
+
+ @OnClick({R.id.txtSubHeader, R.id.txtHeader})
+ void onHeaderClicked() {
+ if (headerArticle != null)
+ ((actMainPage) getActivity()).loadEvent(headerArticle);
+ }
+
+ private void setupHeader(NewsArticle article) {
+ subHeader.setText(Html.fromHtml(article.getContent()));
+ String s = article.getTitle();
+ s = s.length() > 40 ? s.substring(0, 40) + "..." : s;
+ header.setText(s);
+ }
+
+ private void setupListView(List articles) {
+ Collections.sort(articles);
+ adapter.addAll(articles);
+ ((ImgTxtAdapter) list.getAdapter()).notifyDataSetChanged();
+ list.setVisibility(View.VISIBLE);
+ progressBar.setVisibility(View.GONE);
+ list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ ((actMainPage) getActivity()).loadEvent((NewsArticle) list.getAdapter().getItem(position));
+ }
+ });
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/spielpark/steve/bernieapp/fragments/SingleIssueFragment.java b/app/src/main/java/com/spielpark/steve/bernieapp/fragments/SingleIssueFragment.java
index 48cc936..c1649c7 100644
--- a/app/src/main/java/com/spielpark/steve/bernieapp/fragments/SingleIssueFragment.java
+++ b/app/src/main/java/com/spielpark/steve/bernieapp/fragments/SingleIssueFragment.java
@@ -13,7 +13,7 @@
import android.widget.TextView;
import com.spielpark.steve.bernieapp.R;
-import com.spielpark.steve.bernieapp.wrappers.Issue;
+import com.spielpark.steve.bernieapp.model.Issue;
import butterknife.Bind;
import butterknife.ButterKnife;
diff --git a/app/src/main/java/com/spielpark/steve/bernieapp/fragments/SingleNewsFragment.java b/app/src/main/java/com/spielpark/steve/bernieapp/fragments/SingleNewsFragment.java
index 62c6e50..73b69a9 100644
--- a/app/src/main/java/com/spielpark/steve/bernieapp/fragments/SingleNewsFragment.java
+++ b/app/src/main/java/com/spielpark/steve/bernieapp/fragments/SingleNewsFragment.java
@@ -15,7 +15,7 @@
import com.spielpark.steve.bernieapp.R;
import com.spielpark.steve.bernieapp.misc.Util;
-import com.spielpark.steve.bernieapp.wrappers.NewsArticle;
+import com.spielpark.steve.bernieapp.model.news.NewsArticle;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -56,14 +56,14 @@ public void onViewCreated(View view, Bundle savedInstanceState) {
((TextView) root.findViewById(R.id.e_txtTitle)).setText(event.getTitle());
((TextView) root.findViewById(R.id.e_txtTitle)).setShadowLayer(13, 0, 0, Color.BLACK);
((TextView) root.findViewById(R.id.e_txtDate)).setText(event.getPubDate() + " at " + time);
- ((TextView) root.findViewById(R.id.e_txtDesc)).setText(Html.fromHtml(event.getDesc()));
+ ((TextView) root.findViewById(R.id.e_txtDesc)).setText(Html.fromHtml(event.getContent()));
((TextView) root.findViewById(R.id.e_txtDesc)).setMovementMethod(new LinkMovementMethod());
Util.getPicasso(getActivity()).load(event.getImgSrc()).placeholder(R.drawable.logo).into((ImageView) root.findViewById(R.id.e_imgLogo));
root.findViewById(R.id.e_btnWebsite).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_VIEW);
- i.setData(Uri.parse(event.getUrl()));
+ i.setData(Uri.parse(event.getPermalink()));
startActivity(i);
}
});
@@ -87,7 +87,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
title.setText(event.getTitle());
title.setShadowLayer(13, 0, 0, Color.BLACK);
date.setText(event.getPubDate());
- description.setText(Html.fromHtml(event.getDesc()));
+ description.setText(Html.fromHtml(event.getContent()));
description.setMovementMethod(new LinkMovementMethod());
return view;
}
@@ -101,7 +101,7 @@ public void onDestroyView() {
@OnClick(R.id.e_btnWebsite)
void onWebsiteClicked() {
Intent i = new Intent(Intent.ACTION_VIEW);
- i.setData(Uri.parse(event.getUrl()));
+ i.setData(Uri.parse(event.getPermalink()));
startActivity(i);
}
}
diff --git a/app/src/main/java/com/spielpark/steve/bernieapp/misc/ImgTxtAdapter.java b/app/src/main/java/com/spielpark/steve/bernieapp/misc/ImgTxtAdapter.java
index 126793e..1a6ad8d 100644
--- a/app/src/main/java/com/spielpark/steve/bernieapp/misc/ImgTxtAdapter.java
+++ b/app/src/main/java/com/spielpark/steve/bernieapp/misc/ImgTxtAdapter.java
@@ -12,7 +12,7 @@
import android.widget.TextView;
import com.spielpark.steve.bernieapp.R;
-import com.spielpark.steve.bernieapp.wrappers.ImgTxtItem;
+import com.spielpark.steve.bernieapp.model.ImgTxtItem;
import java.util.List;
@@ -55,11 +55,11 @@ public View getView(int position, View convertView, ViewGroup parent) {
}
public static class ViewHolder {
- @Bind(R.id.txtItem) TextView txt;
@Bind(R.id.picThumb) ImageView img;
+ @Bind(R.id.txtItem) TextView txt;
public ViewHolder(View convertView, Typeface typeface) {
- ButterKnife.bind(this, convertView);
+ ButterKnife.bind(ViewHolder.this, convertView);
txt.setTypeface(typeface);
}
}
diff --git a/app/src/main/java/com/spielpark/steve/bernieapp/model/ApiManager.java b/app/src/main/java/com/spielpark/steve/bernieapp/model/ApiManager.java
new file mode 100644
index 0000000..1d59f99
--- /dev/null
+++ b/app/src/main/java/com/spielpark/steve/bernieapp/model/ApiManager.java
@@ -0,0 +1,67 @@
+package com.spielpark.steve.bernieapp.model;
+
+import android.util.Log;
+
+import com.squareup.okhttp.Interceptor;
+import com.squareup.okhttp.Request;
+import com.squareup.okhttp.Response;
+import com.squareup.okhttp.ResponseBody;
+
+import java.io.IOException;
+
+import retrofit.GsonConverterFactory;
+import retrofit.Retrofit;
+import retrofit.RxJavaCallAdapterFactory;
+
+public class ApiManager {
+
+ private static ApiManager instance;
+ public BernieApi api;
+
+ public ApiManager(BernieApi api) {
+ this.api = api;
+ }
+
+ public static ApiManager get() {
+ if (instance == null) {
+
+ LoggingInterceptor interceptor = new LoggingInterceptor();
+ Retrofit retrofit = new Retrofit.Builder()
+ .baseUrl("https://berniesanders.com/")
+ .addConverterFactory(GsonConverterFactory.create())
+ .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
+ .build();
+
+ retrofit.client().interceptors().add(interceptor);
+ instance = new ApiManager(retrofit.create(BernieApi.class));
+
+ }
+ return instance;
+ }
+
+ private static class LoggingInterceptor implements Interceptor {
+ @Override
+ public Response intercept(Interceptor.Chain chain) throws IOException {
+ Request request = chain.request();
+
+ long t1 = System.nanoTime();
+ Log.d("Retrofit", String.format("Sending request %s on %s%n%s",
+ request.url(), chain.connection(), request.headers()));
+
+ Response response = chain.proceed(request);
+
+ long t2 = System.nanoTime();
+ Log.d("Retrofit", String.format("Received response for %s in %.1fms%n%s",
+ response.request().url(), (t2 - t1) / 1e6d, response.headers()));
+
+
+ final String responseString = new String(response.body().bytes());
+
+ Log.d("Retrofit", "Response: " + responseString);
+
+ return response.newBuilder()
+ .body(ResponseBody.create(response.body().contentType(), responseString))
+ .build();
+ }
+ }
+}
diff --git a/app/src/main/java/com/spielpark/steve/bernieapp/model/BernieApi.java b/app/src/main/java/com/spielpark/steve/bernieapp/model/BernieApi.java
new file mode 100644
index 0000000..8d08abf
--- /dev/null
+++ b/app/src/main/java/com/spielpark/steve/bernieapp/model/BernieApi.java
@@ -0,0 +1,17 @@
+package com.spielpark.steve.bernieapp.model;
+
+import com.spielpark.steve.bernieapp.model.news.NewsArticle;
+
+import java.util.List;
+
+import retrofit.http.GET;
+import retrofit.http.Query;
+import rx.Observable;
+
+public interface BernieApi {
+ String NEWS = "news";
+ String DAILY = "daily";
+
+ @GET("?json=true&limit=12")
+ Observable> getNews(@Query("which") String newsType);
+}
diff --git a/app/src/main/java/com/spielpark/steve/bernieapp/wrappers/Event.java b/app/src/main/java/com/spielpark/steve/bernieapp/model/Event.java
similarity index 98%
rename from app/src/main/java/com/spielpark/steve/bernieapp/wrappers/Event.java
rename to app/src/main/java/com/spielpark/steve/bernieapp/model/Event.java
index 2de3cdc..7ea36a8 100644
--- a/app/src/main/java/com/spielpark/steve/bernieapp/wrappers/Event.java
+++ b/app/src/main/java/com/spielpark/steve/bernieapp/model/Event.java
@@ -1,4 +1,4 @@
-package com.spielpark.steve.bernieapp.wrappers;
+package com.spielpark.steve.bernieapp.model;
import java.text.ParseException;
import java.text.SimpleDateFormat;
diff --git a/app/src/main/java/com/spielpark/steve/bernieapp/model/ImgTxtItem.java b/app/src/main/java/com/spielpark/steve/bernieapp/model/ImgTxtItem.java
new file mode 100644
index 0000000..5990588
--- /dev/null
+++ b/app/src/main/java/com/spielpark/steve/bernieapp/model/ImgTxtItem.java
@@ -0,0 +1,14 @@
+package com.spielpark.steve.bernieapp.model;
+
+/**
+ * Created by Steve on 8/17/2015.
+ */
+public interface ImgTxtItem {
+ String getTxt();
+
+ void setTxt(String txt);
+
+ String getImgSrc();
+
+ void setImgSrc(String img);
+}
diff --git a/app/src/main/java/com/spielpark/steve/bernieapp/wrappers/Issue.java b/app/src/main/java/com/spielpark/steve/bernieapp/model/Issue.java
similarity index 98%
rename from app/src/main/java/com/spielpark/steve/bernieapp/wrappers/Issue.java
rename to app/src/main/java/com/spielpark/steve/bernieapp/model/Issue.java
index ce1eb68..1fcee94 100644
--- a/app/src/main/java/com/spielpark/steve/bernieapp/wrappers/Issue.java
+++ b/app/src/main/java/com/spielpark/steve/bernieapp/model/Issue.java
@@ -1,4 +1,4 @@
-package com.spielpark.steve.bernieapp.wrappers;
+package com.spielpark.steve.bernieapp.model;
import android.app.Activity;
import android.os.Parcel;
diff --git a/app/src/main/java/com/spielpark/steve/bernieapp/wrappers/NavDrawerItem.java b/app/src/main/java/com/spielpark/steve/bernieapp/model/NavDrawerItem.java
similarity index 82%
rename from app/src/main/java/com/spielpark/steve/bernieapp/wrappers/NavDrawerItem.java
rename to app/src/main/java/com/spielpark/steve/bernieapp/model/NavDrawerItem.java
index 18a8ca6..6c798a7 100644
--- a/app/src/main/java/com/spielpark/steve/bernieapp/wrappers/NavDrawerItem.java
+++ b/app/src/main/java/com/spielpark/steve/bernieapp/model/NavDrawerItem.java
@@ -1,4 +1,4 @@
-package com.spielpark.steve.bernieapp.wrappers;
+package com.spielpark.steve.bernieapp.model;
/**
* Created by Steve on 8/16/2015.
diff --git a/app/src/main/java/com/spielpark/steve/bernieapp/model/news/Category.java b/app/src/main/java/com/spielpark/steve/bernieapp/model/news/Category.java
new file mode 100644
index 0000000..d319b3e
--- /dev/null
+++ b/app/src/main/java/com/spielpark/steve/bernieapp/model/news/Category.java
@@ -0,0 +1,15 @@
+package com.spielpark.steve.bernieapp.model.news;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * Created by Patrick on 10/29/15.
+ */
+public enum Category {
+ @SerializedName("On the Road")
+ OnTheRoad,
+ @SerializedName("News")
+ News,
+ @SerializedName("Press Release")
+ PressRelease
+}
diff --git a/app/src/main/java/com/spielpark/steve/bernieapp/wrappers/NewsArticle.java b/app/src/main/java/com/spielpark/steve/bernieapp/model/news/NewsArticle.java
similarity index 58%
rename from app/src/main/java/com/spielpark/steve/bernieapp/wrappers/NewsArticle.java
rename to app/src/main/java/com/spielpark/steve/bernieapp/model/news/NewsArticle.java
index a5813d9..a2d9814 100644
--- a/app/src/main/java/com/spielpark/steve/bernieapp/wrappers/NewsArticle.java
+++ b/app/src/main/java/com/spielpark/steve/bernieapp/model/news/NewsArticle.java
@@ -1,11 +1,15 @@
-package com.spielpark.steve.bernieapp.wrappers;
+package com.spielpark.steve.bernieapp.model.news;
import android.os.Parcel;
import android.os.Parcelable;
+import com.google.gson.annotations.SerializedName;
+import com.spielpark.steve.bernieapp.model.ImgTxtItem;
+
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.List;
/**
* Created by Steve on 8/14/2015.
@@ -21,43 +25,32 @@ public NewsArticle[] newArray(int size) {
return new NewsArticle[size];
}
};
+ private static final String NULL_IMAGE = "https://s.bsd.net/bernie16/main/page/-/website/fb-share.png";
private String title;
- private String desc;
- private String url;
- private String pubdate;
- private String time;
- private String htmlTitle;
- private String imgSrc;
+ private String content;
+ private String permalink;
+ private String date;
+ @SerializedName("og_image")
+ private String image;
+ private List categories;
public NewsArticle() {
}
- protected NewsArticle(Parcel in) {
- this.title = in.readString();
- this.desc = in.readString();
- this.url = in.readString();
- this.pubdate = in.readString();
- this.time = in.readString();
- this.htmlTitle = in.readString();
- this.imgSrc = in.readString();
- }
-
- public String getHtmlTitle() {
- return htmlTitle;
- }
-
- public void setHtmlTitle(String htmlTitle) {
- this.htmlTitle = htmlTitle;
+ public NewsArticle(String title, String content) {
+ this.title = title;
+ this.content = content;
}
- public String getTime() {
- return time;
+ protected NewsArticle(Parcel in) {
+ this.title = in.readString();
+ this.content = in.readString();
+ this.permalink = in.readString();
+ this.date = in.readString();
+ this.image = in.readString();
}
- public void setTime(String time) {
- this.time = time;
- }
public String getTitle() {
return title;
@@ -67,48 +60,52 @@ public void setTitle(String title) {
this.title = title;
}
- public String getDesc() {
- return desc;
+ public String getContent() {
+ return content;
}
- public void setDesc(String desc) {
- this.desc = desc;
+ public void setContent(String content) {
+ this.content = content;
}
- public String getUrl() {
- return url;
+ public String getPermalink() {
+ return permalink;
}
- public void setUrl(String url) {
- this.url = url;
+ public void setPermalink(String permalink) {
+ this.permalink = permalink;
}
public String getPubDate() {
- return pubdate;
+ return date;
}
public void setPubDate(String pubdate) {
- this.pubdate = pubdate;
+ this.date = pubdate;
+ }
+
+ public List getCategories() {
+ return categories;
}
@Override
public String getTxt() {
- return getHtmlTitle();
+ return getTitle();
}
@Override
public void setTxt(String txt) {
- this.setHtmlTitle(txt);
+ this.setTitle(txt);
}
@Override
public String getImgSrc() {
- return imgSrc;
+ return image == null ? NULL_IMAGE : image;
}
@Override
public void setImgSrc(String img) {
- this.imgSrc = img;
+ this.image = img;
}
@Override
@@ -136,11 +133,9 @@ public int describeContents() {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.title);
- dest.writeString(this.desc);
- dest.writeString(this.url);
- dest.writeString(this.pubdate);
- dest.writeString(this.time);
- dest.writeString(this.htmlTitle);
- dest.writeString(this.imgSrc);
+ dest.writeString(this.content);
+ dest.writeString(this.permalink);
+ dest.writeString(this.date);
+ dest.writeString(this.image);
}
}
diff --git a/app/src/main/java/com/spielpark/steve/bernieapp/model/news/NewsManager.java b/app/src/main/java/com/spielpark/steve/bernieapp/model/news/NewsManager.java
new file mode 100644
index 0000000..44c03ac
--- /dev/null
+++ b/app/src/main/java/com/spielpark/steve/bernieapp/model/news/NewsManager.java
@@ -0,0 +1,54 @@
+package com.spielpark.steve.bernieapp.model.news;
+
+import android.util.Pair;
+
+import com.spielpark.steve.bernieapp.model.ApiManager;
+import com.spielpark.steve.bernieapp.model.BernieApi;
+
+import java.util.List;
+
+import rx.Observable;
+import rx.functions.Func2;
+import rx.schedulers.Schedulers;
+
+public class NewsManager {
+
+ private static NewsManager instance;
+ private final BernieApi api;
+
+ public NewsManager() {
+ api = ApiManager.get().api;
+
+ }
+
+ public static NewsManager get() {
+ if (instance == null) {
+ instance = new NewsManager();
+ }
+ return instance;
+ }
+
+ public Observable>> getNews() {
+ return Observable.zip(api.getNews(BernieApi.NEWS), api.getNews(BernieApi.DAILY), new Func2, List, Pair>>() {
+ @Override
+ public Pair> call(List newsArticles, List newsArticles2) {
+ newsArticles.addAll(newsArticles2);
+ //Filter out only the first press release article to be used as the header.
+ NewsArticle pressRelease = null;
+ for (NewsArticle newsArticle : newsArticles) {
+ if (newsArticle.getCategories().contains(Category.PressRelease)) {
+ pressRelease = newsArticle;
+ break;
+ }
+ }
+ //Remove the header from the list of articles
+ if (pressRelease != null) {
+ newsArticles.remove(pressRelease);
+ }
+
+ return new Pair<>(pressRelease, newsArticles);
+ }
+ }).cache().subscribeOn(Schedulers.io());
+ }
+}
+
diff --git a/app/src/main/java/com/spielpark/steve/bernieapp/tasks/ConnectTask.java b/app/src/main/java/com/spielpark/steve/bernieapp/tasks/ConnectTask.java
index 975d33d..86b26e6 100644
--- a/app/src/main/java/com/spielpark/steve/bernieapp/tasks/ConnectTask.java
+++ b/app/src/main/java/com/spielpark/steve/bernieapp/tasks/ConnectTask.java
@@ -10,7 +10,7 @@
import com.spielpark.steve.bernieapp.R;
import com.spielpark.steve.bernieapp.fragments.ConnectFragment;
-import com.spielpark.steve.bernieapp.wrappers.Event;
+import com.spielpark.steve.bernieapp.model.Event;
import java.io.BufferedReader;
import java.io.IOException;
diff --git a/app/src/main/java/com/spielpark/steve/bernieapp/tasks/IssuesTask.java b/app/src/main/java/com/spielpark/steve/bernieapp/tasks/IssuesTask.java
index cea4ee2..b0c050c 100644
--- a/app/src/main/java/com/spielpark/steve/bernieapp/tasks/IssuesTask.java
+++ b/app/src/main/java/com/spielpark/steve/bernieapp/tasks/IssuesTask.java
@@ -11,7 +11,7 @@
import com.spielpark.steve.bernieapp.R;
import com.spielpark.steve.bernieapp.misc.ImgTxtAdapter;
-import com.spielpark.steve.bernieapp.wrappers.Issue;
+import com.spielpark.steve.bernieapp.model.Issue;
import java.io.BufferedReader;
import java.io.IOException;
diff --git a/app/src/main/java/com/spielpark/steve/bernieapp/tasks/NewsTask.java b/app/src/main/java/com/spielpark/steve/bernieapp/tasks/NewsTask.java
deleted file mode 100644
index c90636e..0000000
--- a/app/src/main/java/com/spielpark/steve/bernieapp/tasks/NewsTask.java
+++ /dev/null
@@ -1,208 +0,0 @@
-package com.spielpark.steve.bernieapp.tasks;
-
-import android.content.Context;
-import android.os.AsyncTask;
-import android.text.Html;
-import android.util.JsonReader;
-import android.util.JsonToken;
-import android.util.Log;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.ListView;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import com.spielpark.steve.bernieapp.R;
-import com.spielpark.steve.bernieapp.actMainPage;
-import com.spielpark.steve.bernieapp.misc.ImgTxtAdapter;
-import com.spielpark.steve.bernieapp.wrappers.NewsArticle;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
-
-/**
- * Created by Steve on 7/8/2015.
- */
-public class NewsTask extends AsyncTask