Commit e2bad655 authored by Sajal Narang's avatar Sajal Narang

Implement News

parent a706c93b
......@@ -12,6 +12,7 @@ android {
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
resValue "string", "google_maps_key", (project.findProperty("GOOGLE_MAPS_API_KEY") ?: "")
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
......@@ -36,6 +37,7 @@ ext {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:support-v4:27.1.1'
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
......
......@@ -37,6 +37,7 @@ import in.ac.iitb.gymkhana.iitbapp.fragment.GCRankingsFragment;
import in.ac.iitb.gymkhana.iitbapp.fragment.MapFragment;
import in.ac.iitb.gymkhana.iitbapp.fragment.MessMenuFragment;
import in.ac.iitb.gymkhana.iitbapp.fragment.MyEventsFragment;
import in.ac.iitb.gymkhana.iitbapp.fragment.NewsFragment;
import in.ac.iitb.gymkhana.iitbapp.fragment.NotificationsFragment;
import in.ac.iitb.gymkhana.iitbapp.fragment.PeopleFragment;
import in.ac.iitb.gymkhana.iitbapp.fragment.PlacementBlogFragment;
......@@ -203,6 +204,10 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
MyEventsFragment myeventsFragment = new MyEventsFragment();
updateFragment(myeventsFragment);
break;
case R.id.nav_news:
NewsFragment newsFragment = new NewsFragment();
updateFragment(newsFragment);
break;
case R.id.nav_placement_blog:
PlacementBlogFragment placementBlogFragment = new PlacementBlogFragment();
updateFragment(placementBlogFragment);
......
package in.ac.iitb.gymkhana.iitbapp.adapter;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;
import in.ac.iitb.gymkhana.iitbapp.ItemClickListener;
import in.ac.iitb.gymkhana.iitbapp.R;
import in.ac.iitb.gymkhana.iitbapp.data.NewsArticle;
import ru.noties.markwon.Markwon;
public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder> {
private List<NewsArticle> newsArticles;
private Context context;
private ItemClickListener itemClickListener;
public NewsAdapter(List<NewsArticle> newsArticles, ItemClickListener itemClickListener) {
this.newsArticles = newsArticles;
this.itemClickListener = itemClickListener;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View newsArticleView = inflater.inflate(R.layout.news_article_card, parent, false);
final NewsAdapter.ViewHolder articleViewHolder = new NewsAdapter.ViewHolder(newsArticleView);
newsArticleView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
itemClickListener.onItemClick(v, articleViewHolder.getAdapterPosition());
}
});
return articleViewHolder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
NewsArticle article = newsArticles.get(position);
Markwon.setMarkdown(holder.articleTitle, article.getTitle());
holder.articlePublished.setText(article.getPublished());
Markwon.setMarkdown(holder.articleContent, article.getContent());
}
@Override
public int getItemCount() {
return newsArticles.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView articleTitle;
private TextView articlePublished;
private TextView articleContent;
public ViewHolder(View itemView) {
super(itemView);
articleTitle = (TextView) itemView.findViewById(R.id.article_title);
articlePublished = (TextView) itemView.findViewById(R.id.article_published);
articleContent = (TextView) itemView.findViewById(R.id.article_content);
}
}
}
......@@ -9,6 +9,7 @@ import in.ac.iitb.gymkhana.iitbapp.api.model.ImageUploadResponse;
import in.ac.iitb.gymkhana.iitbapp.api.model.LoginResponse;
import in.ac.iitb.gymkhana.iitbapp.api.model.NewsFeedResponse;
import in.ac.iitb.gymkhana.iitbapp.data.HostelMessMenu;
import in.ac.iitb.gymkhana.iitbapp.data.NewsArticle;
import in.ac.iitb.gymkhana.iitbapp.data.PlacementBlogPost;
import in.ac.iitb.gymkhana.iitbapp.data.TrainingBlogPost;
import in.ac.iitb.gymkhana.iitbapp.data.User;
......@@ -50,6 +51,10 @@ public interface RetrofitInterface {
@GET("mess")
Call<List<HostelMessMenu>> getInstituteMessMenu(@Header("Cookie") String sessionID);
@GET("news")
Call<List<NewsArticle>> getNews(@Header("Cookie") String sessionID);
// @POST("getNotifications/")
// Call<NotificationsResponse> getNotifications(@Body NotificationsRequest notificationsRequest);
}
......@@ -6,7 +6,7 @@ import android.arch.persistence.room.RoomDatabase;
import android.arch.persistence.room.TypeConverters;
import android.content.Context;
@Database(entities = {Event.class, Body.class, Venue.class, User.class, Role.class, PlacementBlogPost.class, TrainingBlogPost.class, HostelMessMenu.class}, version = 1)
@Database(entities = {Event.class, Body.class, Venue.class, User.class, Role.class, PlacementBlogPost.class, TrainingBlogPost.class, HostelMessMenu.class, NewsArticle.class}, version = 1)
@TypeConverters({Converters.class})
public abstract class AppDatabase extends RoomDatabase {
......
......@@ -33,12 +33,15 @@ public interface DbDao {
@Query("SELECT * FROM hostelMessMenus")
List<HostelMessMenu> getAllHostelMessMenus();
@Query("SELECT * FROM bodies WHERE id == :id")
public Body[] getBody(String id);
@Query("SELECT * FROM news")
List<NewsArticle> getAllNewsArticles();
@Query("SELECT COUNT(*) from events")
int countEvents();
@Query("SELECT * FROM bodies WHERE id == :id")
public Body[] getBody(String id);
@Query("SELECT COUNT(*) from venues")
int countVenues();
......@@ -102,6 +105,12 @@ public interface DbDao {
@Insert
void insertHostelMessMenus(List<HostelMessMenu> hostelMessMenus);
@Insert
void insertNewsArticle(NewsArticle newsArticle);
@Insert
void insertNewsArticles(List<NewsArticle> newsArticles);
@Delete
void deleteEvent(Event event);
......@@ -140,4 +149,7 @@ public interface DbDao {
@Query("DELETE from hostelMessMenus")
void deleteHostelMessMenus();
@Query("DELETE from news")
void deleteNewsArticles();
}
package in.ac.iitb.gymkhana.iitbapp.data;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.PrimaryKey;
import com.google.gson.annotations.SerializedName;
import java.util.Map;
@Entity(tableName = "news")
public class NewsArticle {
@PrimaryKey(autoGenerate = true)
int db_id;
@ColumnInfo(name = "id")
@SerializedName("id")
private String articleID;
@ColumnInfo(name = "link")
@SerializedName("link")
private String link;
@ColumnInfo(name = "title")
@SerializedName("title")
private String title;
@ColumnInfo(name = "content")
@SerializedName("content")
private String content;
@ColumnInfo(name = "published")
@SerializedName("published")
private String published;
@ColumnInfo(name = "body")
@SerializedName("body")
private Body body;
public NewsArticle(String articleID, String link, String title, String content, String published, Body body) {
this.articleID = articleID;
this.link = link;
this.title = title;
this.content = content;
this.published = published;
this.body = body;
}
public String getArticleID() {
return articleID;
}
public void setArticleID(String articleID) {
this.articleID = articleID;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getPublished() {
return published;
}
public void setPublished(String published) {
this.published = published;
}
public Body getBody() {
return body;
}
public void setBody(Body body) {
this.body = body;
}
}
package in.ac.iitb.gymkhana.iitbapp.fragment;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
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 java.util.List;
import in.ac.iitb.gymkhana.iitbapp.ActivityBuffer;
import in.ac.iitb.gymkhana.iitbapp.Constants;
import in.ac.iitb.gymkhana.iitbapp.ItemClickListener;
import in.ac.iitb.gymkhana.iitbapp.R;
import in.ac.iitb.gymkhana.iitbapp.adapter.NewsAdapter;
import in.ac.iitb.gymkhana.iitbapp.api.RetrofitInterface;
import in.ac.iitb.gymkhana.iitbapp.api.ServiceGenerator;
import in.ac.iitb.gymkhana.iitbapp.data.AppDatabase;
import in.ac.iitb.gymkhana.iitbapp.data.NewsArticle;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* A simple {@link Fragment} subclass.
*/
public class NewsFragment extends BaseFragment {
private RecyclerView newsRecyclerView;
private SwipeRefreshLayout newsSwipeRefreshLayout;
private AppDatabase appDatabase;
public NewsFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_news, container, false);
}
@Override
public void onStart() {
super.onStart();
appDatabase = AppDatabase.getAppDatabase(getContext());
new NewsFragment.showNewsFromDB().execute();
updateNews();
newsSwipeRefreshLayout = getActivity().findViewById(R.id.news_swipe_refresh_layout);
newsSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
updateNews();
}
});
}
private void updateNews() {
RetrofitInterface retrofitInterface = ServiceGenerator.createService(RetrofitInterface.class);
retrofitInterface.getNews("sessionid=" + getArguments().getString(Constants.SESSION_ID)).enqueue(new Callback<List<NewsArticle>>() {
@Override
public void onResponse(Call<List<NewsArticle>> call, Response<List<NewsArticle>> response) {
if (response.isSuccessful()) {
List<NewsArticle> articles = response.body();
displayNews(articles);
new updateDatabase().execute(articles);
}
//Server Error
newsSwipeRefreshLayout.setRefreshing(false);
}
@Override
public void onFailure(Call<List<NewsArticle>> call, Throwable t) {
//Network Error
newsSwipeRefreshLayout.setRefreshing(false);
}
});
}
private void displayNews(final List<NewsArticle> result) {
final NewsAdapter newsAdapter = new NewsAdapter(result, new ItemClickListener() {
@Override
public void onItemClick(View v, int position) {
openWebURL(result.get(position).getLink());
}
});
getActivityBuffer().safely(new ActivityBuffer.IRunnable() {
@Override
public void run(Activity pActivity) {
try {
newsRecyclerView = getActivity().findViewById(R.id.news_recycler_view);
newsRecyclerView.setAdapter(newsAdapter);
newsRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
} catch (NullPointerException e) {
e.printStackTrace();
}
}
});
}
private void openWebURL(String URL) {
Intent browse = new Intent(Intent.ACTION_VIEW, Uri.parse(URL));
startActivity(browse);
}
private class updateDatabase extends AsyncTask<List<NewsArticle>, Void, Integer> {
@Override
protected Integer doInBackground(List<NewsArticle>... posts) {
appDatabase.dbDao().deleteNewsArticles();
appDatabase.dbDao().insertNewsArticles(posts[0]);
return 1;
}
}
private class showNewsFromDB extends AsyncTask<String, Void, List<NewsArticle>> {
@Override
protected List<NewsArticle> doInBackground(String... posts) {
return appDatabase.dbDao().getAllNewsArticles();
}
protected void onPostExecute(List<NewsArticle> result) {
displayNews(result);
}
}
}
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M6.18,17.82m-2.18,0a2.18,2.18 0,1 1,4.36 0a2.18,2.18 0,1 1,-4.36 0"/>
<path
android:fillColor="@android:color/white"
android:pathData="M4,4.44v2.83c7.03,0 12.73,5.7 12.73,12.73h2.83c0,-8.59 -6.97,-15.56 -15.56,-15.56zM4,10.1v2.83c3.9,0 7.07,3.17 7.07,7.07h2.83c0,-5.47 -4.43,-9.9 -9.9,-9.9z"/>
</vector>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="in.ac.iitb.gymkhana.iitbapp.fragment.NewsFragment">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/news_swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="in.ac.iitb.gymkhana.iitbapp.fragment.NewsFragment">
<android.support.v7.widget.RecyclerView
android:id="@+id/news_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="8dp" />
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="4dp"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:orientation="vertical">
<TextView
android:id="@+id/article_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="@+id/article_published"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/article_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:textColor="#000000" />
</LinearLayout>
</android.support.v7.widget.CardView>
\ No newline at end of file
......@@ -14,6 +14,11 @@
android:icon="@drawable/ic_event"
android:title="My Events" />
<item
android:id="@+id/nav_news"
android:icon="@drawable/baseline_rss_feed_black_48"
android:title="News" />
<item
android:id="@+id/nav_placement_blog"
android:icon="@drawable/ic_work_black_48dp"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment