Commit 98708575 authored by Sajal Narang's avatar Sajal Narang Committed by GitHub

Merge pull request #147 from pulsejet/notify

Add notification features
parents f9393d50 d9968957
...@@ -38,6 +38,7 @@ ext { ...@@ -38,6 +38,7 @@ ext {
dependencies { dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar']) implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:support-v4:27.1.1' implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.google.firebase:firebase-messaging:17.1.0'
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', { androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations' exclude group: 'com.android.support', module: 'support-annotations'
}) })
......
{ {
"project_info": { "project_info": {
"project_number": "306601329049", "project_number": "259853447628",
"firebase_url": "https://iitb-app-5c0aa.firebaseio.com", "firebase_url": "https://astral-theory-207617.firebaseio.com",
"project_id": "iitb-app-5c0aa", "project_id": "astral-theory-207617",
"storage_bucket": "iitb-app-5c0aa.appspot.com" "storage_bucket": "astral-theory-207617.appspot.com"
}, },
"client": [ "client": [
{ {
"client_info": { "client_info": {
"mobilesdk_app_id": "1:306601329049:android:950a72a311331b9c", "mobilesdk_app_id": "1:259853447628:android:efaea50ea28ccfec",
"android_client_info": { "android_client_info": {
"package_name": "app.insti" "package_name": "app.insti"
} }
}, },
"oauth_client": [ "oauth_client": [
{ {
"client_id": "306601329049-6v597vrdv0nbi15ehpehq8hiaek8unqp.apps.googleusercontent.com", "client_id": "259853447628-be3teletcqtfpfddj9qnk0bqj221h2mo.apps.googleusercontent.com",
"client_type": 3 "client_type": 3
} }
], ],
"api_key": [ "api_key": [
{ {
"current_key": "AIzaSyC1oThCMZN3JMnK6MUTJRjkp47q1K_gnTA" "current_key": "AIzaSyB8B7N-3hnW_u4jOXHLRUzbMl6To3aDyJo"
} }
], ],
"services": { "services": {
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<meta-data <meta-data
android:name="com.google.android.gms.version" android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" /> android:value="@integer/google_play_services_version" />
...@@ -24,6 +25,11 @@ ...@@ -24,6 +25,11 @@
android:name="com.google.android.geo.API_KEY" android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" /> android:value="@string/google_maps_key" />
<!-- FCM styling -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_lotusgray" />
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:screenOrientation="portrait" android:screenOrientation="portrait"
...@@ -45,11 +51,6 @@ ...@@ -45,11 +51,6 @@
<action android:name="HANDLE_AUTHORIZATION_RESPONSE" /> <action android:name="HANDLE_AUTHORIZATION_RESPONSE" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
</intent-filter> </intent-filter>
<!-- <intent-filter>
<action android:name="android.intent.action.MAIN" />
&lt;!&ndash;<category android:name="android.intent.category.LAUNCHER" />&ndash;&gt;
</intent-filter>-->
</activity> </activity>
<activity android:name="net.openid.appauth.RedirectUriReceiverActivity"> <activity android:name="net.openid.appauth.RedirectUriReceiverActivity">
...@@ -76,23 +77,11 @@ ...@@ -76,23 +77,11 @@
</receiver> </receiver>
<service <service
android:name="app.insti.gcm.MyGcmListenerService" android:name=".InstiAppFirebaseMessagingService">
android:exported="false">
<intent-filter> <intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" /> <action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter> </intent-filter>
</service> </service>
<service
android:name="app.insti.gcm.MyInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
<service
android:name="app.insti.gcm.RegistrationIntentService"
android:exported="false"></service>
</application> </application>
......
package app.insti;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
public class InstiAppFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onNewToken(String s) {
/* For future functionality */
super.onNewToken(s);
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
/* For future functionality */
super.onMessageReceived(remoteMessage);
}
}
...@@ -20,6 +20,7 @@ import android.widget.Toast; ...@@ -20,6 +20,7 @@ import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability; import com.google.android.gms.common.GoogleApiAvailability;
import com.google.firebase.iid.FirebaseInstanceId;
import app.insti.api.RetrofitInterface; import app.insti.api.RetrofitInterface;
import app.insti.api.ServiceGenerator; import app.insti.api.ServiceGenerator;
...@@ -142,8 +143,19 @@ public class LoginActivity extends AppCompatActivity { ...@@ -142,8 +143,19 @@ public class LoginActivity extends AppCompatActivity {
progressDialog.setIndeterminate(true); progressDialog.setIndeterminate(true);
progressDialog.show(); progressDialog.show();
} }
RetrofitInterface retrofitInterface = ServiceGenerator.createService(RetrofitInterface.class); RetrofitInterface retrofitInterface = ServiceGenerator.createService(RetrofitInterface.class);
retrofitInterface.passwordLogin(username, password).enqueue(new Callback<LoginResponse>() { Call<LoginResponse> call;
/* This can be null if play services is hung */
if (FirebaseInstanceId.getInstance().getToken() == null) {
call = retrofitInterface.passwordLogin(username, password);
} else {
call = retrofitInterface.passwordLogin(username, password, FirebaseInstanceId.getInstance().getToken());
}
/* Log in the user */
call.enqueue(new Callback<LoginResponse>() {
@Override @Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) { public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
if (response.isSuccessful()) { if (response.isSuccessful()) {
......
...@@ -27,7 +27,6 @@ import com.google.gson.Gson; ...@@ -27,7 +27,6 @@ import com.google.gson.Gson;
import com.squareup.picasso.Picasso; import com.squareup.picasso.Picasso;
import app.insti.api.UnsafeOkHttpClient; import app.insti.api.UnsafeOkHttpClient;
import app.insti.api.model.NotificationsResponse;
import app.insti.data.User; import app.insti.data.User;
import app.insti.fragment.CalendarFragment; import app.insti.fragment.CalendarFragment;
import app.insti.fragment.FeedFragment; import app.insti.fragment.FeedFragment;
...@@ -52,7 +51,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On ...@@ -52,7 +51,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
private static final String TAG = "MainActivity"; private static final String TAG = "MainActivity";
SessionManager session; SessionManager session;
NotificationsResponse notificationsResponse;
FeedFragment feedFragment; FeedFragment feedFragment;
private User currentUser; private User currentUser;
private boolean showNotifications = false; private boolean showNotifications = false;
...@@ -126,38 +124,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On ...@@ -126,38 +124,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
.into(profilePictureImageView); .into(profilePictureImageView);
} }
// private void fetchNotifications() {
// NotificationsRequest notificationsRequest = new NotificationsRequest(0, 20);
// RetrofitInterface retrofitInterface = ServiceGenerator.createService(RetrofitInterface.class);
// retrofitInterface.getNotifications(notificationsRequest).enqueue(new Callback<NotificationsResponse>() {
// @Override
// public void onResponse(Call<NotificationsResponse> call, Response<NotificationsResponse> response) {
// if (response.isSuccessful()) {
// notificationsResponse = response.body();
// if (showNotifications) {
// showNotifications();
// showNotifications = false;
// }
// }
// //Server Error
// }
//
// @Override
// public void onFailure(Call<NotificationsResponse> call, Throwable t) {
// //Network Error
// }
// });
// }
public void showNotifications() {
String notificationsResponseJson = new Gson().toJson(notificationsResponse);
Bundle bundle = new Bundle();
bundle.putString(Constants.NOTIFICATIONS_RESPONSE_JSON, notificationsResponseJson);
NotificationsFragment notificationsFragment = new NotificationsFragment();
notificationsFragment.setArguments(bundle);
updateFragment(notificationsFragment);
}
@Override @Override
public void onBackPressed() { public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
...@@ -180,17 +146,14 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On ...@@ -180,17 +146,14 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId(); int id = item.getItemId();
//noinspection SimplifiableIfStatement if (id == R.id.action_notifications) {
/*if (id == R.id.action_notifications) {
showNotifications = true; showNotifications = true;
// fetchNotifications(); NotificationsFragment notificationsFragment = new NotificationsFragment();
updateFragment(notificationsFragment);
return true; return true;
}*/ }
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
......
...@@ -5,20 +5,27 @@ import android.support.v7.widget.RecyclerView; ...@@ -5,20 +5,27 @@ import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.google.gson.Gson;
import com.squareup.picasso.Picasso;
import java.util.List; import java.util.List;
import app.insti.ItemClickListener; import app.insti.ItemClickListener;
import app.insti.R; import app.insti.R;
import app.insti.api.model.AppNotification; import app.insti.data.Event;
import app.insti.data.NewsArticle;
import app.insti.data.Notification;
import app.insti.data.PlacementBlogPost;
public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdapter.Viewholder> { public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdapter.Viewholder> {
private List<AppNotification> notifications; private List<Notification> notifications;
private Context context; private Context context;
private ItemClickListener itemClickListener; private ItemClickListener itemClickListener;
public NotificationsAdapter(List<AppNotification> notifications, ItemClickListener itemClickListener) { public NotificationsAdapter(List<Notification> notifications, ItemClickListener itemClickListener) {
this.notifications = notifications; this.notifications = notifications;
this.itemClickListener = itemClickListener; this.itemClickListener = itemClickListener;
} }
...@@ -27,7 +34,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdap ...@@ -27,7 +34,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdap
public Viewholder onCreateViewHolder(ViewGroup viewGroup, int i) { public Viewholder onCreateViewHolder(ViewGroup viewGroup, int i) {
context = viewGroup.getContext(); context = viewGroup.getContext();
LayoutInflater inflater = LayoutInflater.from(context); LayoutInflater inflater = LayoutInflater.from(context);
View notificationView = inflater.inflate(R.layout.notification, viewGroup, false); View notificationView = inflater.inflate(R.layout.body_card_view, viewGroup, false);
final Viewholder notificationsViewHolder = new Viewholder(notificationView); final Viewholder notificationsViewHolder = new Viewholder(notificationView);
notificationView.setOnClickListener(new View.OnClickListener() { notificationView.setOnClickListener(new View.OnClickListener() {
...@@ -41,8 +48,22 @@ public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdap ...@@ -41,8 +48,22 @@ public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdap
@Override @Override
public void onBindViewHolder(Viewholder viewholder, int i) { public void onBindViewHolder(Viewholder viewholder, int i) {
AppNotification appNotification = notifications.get(i); Gson gson = new Gson();
viewholder.notificationTitle.setText(appNotification.getNotificationName()); Notification appNotification = notifications.get(i);
viewholder.notificationVerb.setText(appNotification.getNotificationVerb());
if (appNotification.getNotificationActorType().contains("event")) {
Event event = gson.fromJson(gson.toJson(appNotification.getNotificationActor()), Event.class);
Picasso.get().load(event.getEventImageURL()).into(viewholder.notificationPicture);
viewholder.notificationTitle.setText(event.getEventName());
} else if (appNotification.getNotificationActorType().contains("newsentry")) {
NewsArticle article = gson.fromJson(gson.toJson(appNotification.getNotificationActor()), NewsArticle.class);
Picasso.get().load(article.getBody().getBodyImageURL()).into(viewholder.notificationPicture);
viewholder.notificationTitle.setText(article.getTitle());
} else if (appNotification.getNotificationActorType().contains("blogentry")) {
PlacementBlogPost post = gson.fromJson(gson.toJson(appNotification.getNotificationActor()), PlacementBlogPost.class);
Picasso.get().load(R.drawable.lotus_sq).into(viewholder.notificationPicture);
viewholder.notificationTitle.setText(post.getTitle());
}
} }
@Override @Override
...@@ -52,11 +73,15 @@ public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdap ...@@ -52,11 +73,15 @@ public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdap
public class Viewholder extends RecyclerView.ViewHolder { public class Viewholder extends RecyclerView.ViewHolder {
private TextView notificationTitle; private TextView notificationTitle;
private ImageView notificationPicture;
private TextView notificationVerb;
public Viewholder(View itemView) { public Viewholder(View itemView) {
super(itemView); super(itemView);
notificationTitle = (TextView) itemView.findViewById(R.id.notification_title); notificationPicture = (ImageView) itemView.findViewById(R.id.body_card_avatar);
notificationTitle = (TextView) itemView.findViewById(R.id.body_card_name);
notificationVerb = (TextView) itemView.findViewById(R.id.body_card_description);
} }
} }
} }
...@@ -10,6 +10,7 @@ import app.insti.api.model.LoginResponse; ...@@ -10,6 +10,7 @@ import app.insti.api.model.LoginResponse;
import app.insti.api.model.NewsFeedResponse; import app.insti.api.model.NewsFeedResponse;
import app.insti.data.HostelMessMenu; import app.insti.data.HostelMessMenu;
import app.insti.data.NewsArticle; import app.insti.data.NewsArticle;
import app.insti.data.Notification;
import app.insti.data.PlacementBlogPost; import app.insti.data.PlacementBlogPost;
import app.insti.data.TrainingBlogPost; import app.insti.data.TrainingBlogPost;
import app.insti.data.User; import app.insti.data.User;
...@@ -28,6 +29,9 @@ public interface RetrofitInterface { ...@@ -28,6 +29,9 @@ public interface RetrofitInterface {
@GET("pass-login") @GET("pass-login")
Call<LoginResponse> passwordLogin(@Query("username") String username, @Query("password") String password); Call<LoginResponse> passwordLogin(@Query("username") String username, @Query("password") String password);
@GET("pass-login")
Call<LoginResponse> passwordLogin(@Query("username") String username, @Query("password") String password, @Query("fcm_id") String fcmId);
@POST("events") @POST("events")
Call<EventCreateResponse> createEvent(@Header("Cookie") String sessionId, @Body EventCreateRequest eventCreateRequest); Call<EventCreateResponse> createEvent(@Header("Cookie") String sessionId, @Body EventCreateRequest eventCreateRequest);
...@@ -64,6 +68,12 @@ public interface RetrofitInterface { ...@@ -64,6 +68,12 @@ public interface RetrofitInterface {
@GET("news") @GET("news")
Call<List<NewsArticle>> getNews(@Header("Cookie") String sessionID); Call<List<NewsArticle>> getNews(@Header("Cookie") String sessionID);
@GET("notifications")
Call<List<Notification>> getNotifications(@Header("Cookie") String sessionID);
@GET("notifications/read/{notificationID}")
Call<Void> markNotificationRead(@Header("Cookie") String sessionID, @Path("notificationID") Integer notificationID);
@GET("logout") @GET("logout")
Call<Void> logout(@Header("Cookie") String sessionID); Call<Void> logout(@Header("Cookie") String sessionID);
......
package app.insti.api.model;
import com.google.gson.annotations.SerializedName;
public class AppNotification {
@SerializedName("notification_type")
private int notificationType;
@SerializedName("notification_id")
private String notificationId;
@SerializedName("notification_related_id")
private String notificationRelatedId;
@SerializedName("notification_name")
private String notificationName;
@SerializedName("notification_description")
private String notificationDescription;
@SerializedName("notification_image")
private String notificationImage;
public AppNotification(int notificationType, String notificationId, String notificationRelatedId, String notificationName, String notificationDescription, String notificationImage) {
this.notificationType = notificationType;
this.notificationId = notificationId;
this.notificationRelatedId = notificationRelatedId;
this.notificationName = notificationName;
this.notificationDescription = notificationDescription;
this.notificationImage = notificationImage;
}
public int getNotificationType() {
return notificationType;
}
public void setNotificationType(int notificationType) {
this.notificationType = notificationType;
}
public String getNotificationId() {
return notificationId;
}
public void setNotificationId(String notificationId) {
this.notificationId = notificationId;
}
public String getNotificationRelatedId() {
return notificationRelatedId;
}
public void setNotificationRelatedId(String notificationRelatedId) {
this.notificationRelatedId = notificationRelatedId;
}
public String getNotificationName() {
return notificationName;
}
public void setNotificationName(String notificationName) {
this.notificationName = notificationName;
}
public String getNotificationDescription() {
return notificationDescription;
}
public void setNotificationDescription(String notificationDescription) {
this.notificationDescription = notificationDescription;
}
public String getNotificationImage() {
return notificationImage;
}
public void setNotificationImage(String notificationImage) {
this.notificationImage = notificationImage;
}
}
package app.insti.api.model;
public class NotificationsRequest {
private int from;
private int to;
public NotificationsRequest(int from, int to) {
this.from = from;
this.to = to;
}
public int getFrom() {
return from;
}
public void setFrom(int from) {
this.from = from;
}
public int getTo() {
return to;
}
public void setTo(int to) {
this.to = to;
}
}
package app.insti.api.model;
import java.util.List;
public class NotificationsResponse {
private String result;
private List<AppNotification> notifications;
public NotificationsResponse(String result, List<AppNotification> notifications) {
this.result = result;
this.notifications = notifications;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public List<AppNotification> getNotifications() {
return notifications;
}
public void setNotifications(List<AppNotification> notifications) {
this.notifications = notifications;
}
}
...@@ -114,6 +114,20 @@ public class Converters { ...@@ -114,6 +114,20 @@ public class Converters {
return json; return json;
} }
@TypeConverter
public static Object objectFromString(String value) {
Type listType = new TypeToken<Object>() {
}.getType();
return new Gson().fromJson(value, listType);
}
@TypeConverter
public static String stringFromObject(Object object) {
Gson gson = new Gson();
String json = gson.toJson(object);
return json;
}
@TypeConverter @TypeConverter
public static List<String> stringsfromString(String value) { public static List<String> stringsfromString(String value) {
Type listType = new TypeToken<List<String>>() { Type listType = new TypeToken<List<String>>() {
......
package app.insti.data;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.PrimaryKey;
import android.support.annotation.NonNull;
import com.google.gson.annotations.SerializedName;
@Entity(tableName = "news")
public class Notification {
@NonNull()
@PrimaryKey()
@ColumnInfo(name = "id")
@SerializedName("id")
private Integer notificationId;
@ColumnInfo(name = "verb")
@SerializedName("verb")
private String notificationVerb;
@ColumnInfo(name = "unread")
@SerializedName("unread")
private boolean notificationUnread;
@ColumnInfo(name = "actor_type")
@SerializedName("actor_type")
private String notificationActorType;
@ColumnInfo(name = "actor")
@SerializedName("actor")
private Object notificationActor;
public Notification(@NonNull Integer notificationId, String notificationVerb, boolean notificationUnread, String notificationActorType, Object notificationActor) {
this.notificationId = notificationId;
this.notificationVerb = notificationVerb;
this.notificationUnread = notificationUnread;
this.notificationActorType = notificationActorType;
this.notificationActor = notificationActor;
}
@NonNull
public Integer getNotificationId() {
return notificationId;
}
public void setNotificationId(@NonNull Integer notificationId) {
this.notificationId = notificationId;
}
public String getNotificationVerb() {
return notificationVerb;
}
public void setNotificationVerb(String notificationVerb) {
this.notificationVerb = notificationVerb;
}
public boolean isNotificationUnread() {
return notificationUnread;
}
public void setNotificationUnread(boolean notificationUnread) {
this.notificationUnread = notificationUnread;
}
public String getNotificationActorType() {
return notificationActorType;
}
public void setNotificationActorType(String notificationActorType) {
this.notificationActorType = notificationActorType;
}
public Object getNotificationActor() {
return notificationActor;
}
public void setNotificationActor(Object notificationActor) {
this.notificationActor = notificationActor;
}
}
...@@ -3,6 +3,8 @@ package app.insti.fragment; ...@@ -3,6 +3,8 @@ package app.insti.fragment;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
...@@ -16,10 +18,16 @@ import java.util.List; ...@@ -16,10 +18,16 @@ import java.util.List;
import app.insti.Constants; import app.insti.Constants;
import app.insti.ItemClickListener; import app.insti.ItemClickListener;
import app.insti.MainActivity;
import app.insti.R; import app.insti.R;
import app.insti.adapter.NotificationsAdapter; import app.insti.adapter.NotificationsAdapter;
import app.insti.api.model.AppNotification; import app.insti.api.RetrofitInterface;
import app.insti.api.model.NotificationsResponse; import app.insti.api.ServiceGenerator;
import app.insti.data.Notification;
import app.insti.data.PlacementBlogPost;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/** /**
* A simple {@link Fragment} subclass. * A simple {@link Fragment} subclass.
...@@ -28,6 +36,8 @@ public class NotificationsFragment extends BaseFragment { ...@@ -28,6 +36,8 @@ public class NotificationsFragment extends BaseFragment {
RecyclerView notificationsRecyclerView; RecyclerView notificationsRecyclerView;
List<Notification> notifications;
public NotificationsFragment() { public NotificationsFragment() {
// Required empty public constructor // Required empty public constructor
} }
...@@ -47,18 +57,83 @@ public class NotificationsFragment extends BaseFragment { ...@@ -47,18 +57,83 @@ public class NotificationsFragment extends BaseFragment {
Toolbar toolbar = getActivity().findViewById(R.id.toolbar); Toolbar toolbar = getActivity().findViewById(R.id.toolbar);
toolbar.setTitle("Notifications"); toolbar.setTitle("Notifications");
Bundle bundle = getArguments(); RetrofitInterface retrofitInterface = ServiceGenerator.createService(RetrofitInterface.class);
String notificationsResponseJson = bundle.getString(Constants.NOTIFICATIONS_RESPONSE_JSON); retrofitInterface.getNotifications(((MainActivity)getActivity()).getSessionIDHeader()).enqueue(new Callback<List<Notification>>() {
NotificationsResponse notificationsResponse = new Gson().fromJson(notificationsResponseJson, NotificationsResponse.class); @Override
showNotifications(notificationsResponse); public void onResponse(Call<List<Notification>> call, Response<List<Notification>> response) {
if (response.isSuccessful()) {
notifications = response.body();
showNotifications(notifications);
}
}
@Override
public void onFailure(Call<List<Notification>> call, Throwable t) { }
});
} }
private void showNotifications(NotificationsResponse notificationsResponse) { private void showNotifications(final List<Notification> notifications) {
List<AppNotification> notifications = notificationsResponse.getNotifications(); /* Check if activity is done with */
if (getActivity() == null) return;
/* Hide loader */
getActivity().findViewById(R.id.loadingPanel).setVisibility(View.GONE);
NotificationsAdapter notificationsAdapter = new NotificationsAdapter(notifications, new ItemClickListener() { NotificationsAdapter notificationsAdapter = new NotificationsAdapter(notifications, new ItemClickListener() {
@Override @Override
public void onItemClick(View v, int position) { public void onItemClick(View v, int position) {
//TODO: What to do? /* Get the notification */
Notification notification = notifications.get(position);
/* Mark notification read */
RetrofitInterface retrofitInterface = ServiceGenerator.createService(RetrofitInterface.class);
String sessId = ((MainActivity)getActivity()).getSessionIDHeader();
retrofitInterface.markNotificationRead(sessId, notification.getNotificationId()).enqueue(new Callback<Void>() {
@Override
public void onResponse(Call<Void> call, Response<Void> response) { }
@Override
public void onFailure(Call<Void> call, Throwable t) { }
});
FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
String tag = "";
Bundle bundle = getArguments();
if (bundle == null) { bundle = new Bundle(); }
bundle.putString(Constants.SESSION_ID, ((MainActivity) getActivity()).getSessionIDHeader());
/* Open event */
if (notification.getNotificationActorType().contains("event")) {
String eventJson = new Gson().toJson(notification.getNotificationActor());
bundle.putString(Constants.EVENT_JSON, eventJson);
EventFragment eventFragment = new EventFragment();
eventFragment.setArguments(bundle);
tag = eventFragment.getTag();
transaction.replace(R.id.framelayout_for_fragment, eventFragment, tag);
} else if (notification.getNotificationActorType().contains("newsentry")) {
NewsFragment newsFragment = new NewsFragment();
tag = newsFragment.getTag();
transaction.replace(R.id.framelayout_for_fragment, newsFragment, tag);
newsFragment.setArguments(bundle);
} else if (notification.getNotificationActorType().contains("blogentry")) {
Gson gson = new Gson();
PlacementBlogPost post = gson.fromJson(gson.toJson(notification.getNotificationActor()), PlacementBlogPost.class);
if (post.getLink().contains("training")) {
TrainingBlogFragment trainingBlogFragment = new TrainingBlogFragment();
trainingBlogFragment.setArguments(bundle);
tag = trainingBlogFragment.getTag();
transaction.replace(R.id.framelayout_for_fragment, trainingBlogFragment, tag);
} else {
PlacementBlogFragment placementBlogFragment = new PlacementBlogFragment();
placementBlogFragment.setArguments(bundle);
tag = placementBlogFragment.getTag();
transaction.replace(R.id.framelayout_for_fragment, placementBlogFragment, tag);
}
}
transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_left, R.anim.slide_in_right, R.anim.slide_out_right);
transaction.addToBackStack(tag).commit();
} }
}); });
notificationsRecyclerView = (RecyclerView) getActivity().findViewById(R.id.notifications_recycler_view); notificationsRecyclerView = (RecyclerView) getActivity().findViewById(R.id.notifications_recycler_view);
......
package app.insti.gcm;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.android.gms.gcm.GcmListenerService;
import app.insti.MainActivity;
import app.insti.R;
public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
@Override
public void onMessageReceived(String s, Bundle bundle) {
String message = bundle.getString("message");
Log.d(TAG, "From: " + s);
Log.d(TAG, "Message: " + message);
sendNotification(message);
}
public void sendNotification(String message) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
//TODO Change the notification icon
.setSmallIcon(R.drawable.ic_notifications_black_24dp)
.setContentTitle("GCM Message")
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
package app.insti.gcm;
import android.content.Intent;
import com.google.android.gms.iid.InstanceIDListenerService;
public class MyInstanceIDListenerService extends InstanceIDListenerService {
@Override
public void onTokenRefresh() {
// Fetch updated Instance ID token and notify our app's server of any changes (if applicable).
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
}
package app.insti.gcm;
import android.annotation.TargetApi;
import android.app.IntentService;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.google.android.gms.iid.InstanceID;
import app.insti.Constants;
@TargetApi(Build.VERSION_CODES.CUPCAKE)
public class RegistrationIntentService extends IntentService {
private static final String TAG = "RegIntentService";
@RequiresApi(api = Build.VERSION_CODES.CUPCAKE)
public RegistrationIntentService() {
super(TAG);
}
@RequiresApi(api = Build.VERSION_CODES.GINGERBREAD)
@Override
protected void onHandleIntent(@Nullable Intent intent) {
String token = null;
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
try {
InstanceID instanceID = InstanceID.getInstance(this);
token = instanceID.getToken("306601329049",
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
Log.i(TAG, "GCM Registration Token: " + token);
Toast.makeText(this, "GCM Registration Token: " + token, Toast.LENGTH_SHORT).show();
sharedPreferences.edit().putBoolean(Constants.SENT_TOKEN_TO_SERVER, true).apply();
} catch (Exception e) {
Log.d(TAG, "Failed to complete token refresh", e);
sharedPreferences.edit().putBoolean(Constants.SENT_TOKEN_TO_SERVER, false).apply();
}
//Notify UI that registration is complete
Intent registrationComplete = new Intent(Constants.REGISTRATION_COMPLETE);
registrationComplete.putExtra("Token", token);
LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
}
}
<vector android:height="24dp" android:viewportHeight="792"
android:viewportWidth="792" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillAlpha="0.4" android:fillColor="#448aff"
android:pathData="m396.004,170.224l0,0a303.09,303.09 90,0 1,-0.007 428.627l0,0 0,0A303.09,303.09 90,0 1,396.004 170.224Z" android:strokeAlpha="0.4"/>
<path android:fillAlpha="0.4" android:fillColor="#448aff"
android:pathData="M726.43,533.13A302.83,302.83 0,0 1,396 598.85,303.38 303.38,0 0,1 726.43,533.13Z" android:strokeAlpha="0.4"/>
<path android:fillAlpha="0.4" android:fillColor="#448aff"
android:pathData="M297.36,532.94A302,302 0,0 1,396 598.85,303.48 303.48,0 0,1 65.57,533.13 304,304 0,0 1,297.36 532.94Z" android:strokeAlpha="0.4"/>
<path android:fillAlpha="0.4" android:fillColor="#448aff"
android:pathData="m699.09,295.76l-0,0a303.09,303.09 0,0 1,-303.09 303.09l-0,0 -0,0A303.09,303.09 0,0 1,699.09 295.76Z" android:strokeAlpha="0.4"/>
<path android:fillAlpha="0.4" android:fillColor="#448aff"
android:pathData="M512.38,622A302.31,302.31 0,0 1,396 598.85,302.22 302.22,0 0,1 512.38,622Z" android:strokeAlpha="0.4"/>
<path android:fillAlpha="0.4" android:fillColor="#448aff"
android:pathData="M279.62,622A302.22,302.22 0,0 1,396 598.85,302.31 302.31,0 0,1 279.62,622Z" android:strokeAlpha="0.4"/>
<path android:fillAlpha="0.4" android:fillColor="#448aff"
android:pathData="m92.91,295.76v0A303.09,303.09 0,0 1,396 598.85v0,0A303.09,303.09 0,0 1,92.91 295.76Z" android:strokeAlpha="0.4"/>
<path android:fillAlpha="0.4" android:fillColor="#448aff"
android:pathData="m231.969,202.853l0,0a303.09,303.09 67.5,0 1,164.035 395.997l0,0 0,0A303.09,303.09 67.5,0 1,231.969 202.853Z" android:strokeAlpha="0.4"/>
<path android:fillAlpha="0.4" android:fillColor="#448aff"
android:pathData="m792,434.82a302.83,302.83 0,0 1,-396 164,302.83 302.83,0 0,1 396,-164z" android:strokeAlpha="0.4"/>
<path android:fillAlpha="0.4" android:fillColor="#448aff"
android:pathData="m279.62,575.7a301.94,301.94 0,0 1,116.38 23.15,302.06 302.06,0 0,1 -232,0 303.77,303.77 0,0 1,115.62 -23.15z" android:strokeAlpha="0.4"/>
<path android:fillAlpha="0.4" android:fillColor="#448aff"
android:pathData="m560.025,202.845l0,0a303.09,303.09 112.5,0 1,-164.022 396.002l0,0 0,0A303.09,303.09 112.5,0 1,560.025 202.845Z" android:strokeAlpha="0.4"/>
<path android:fillAlpha="0.4" android:fillColor="#448aff"
android:pathData="m628,598.84a302.06,302.06 0,0 1,-232 0,302.18 302.18,0 0,1 232,0z" android:strokeAlpha="0.4"/>
<path android:fillAlpha="0.4" android:fillColor="#448aff"
android:pathData="M396,598.85A302.83,302.83 0,0 1,0 434.82a302.83,302.83 0,0 1,396 164z" android:strokeAlpha="0.4"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z"/>
</vector>
...@@ -9,4 +9,16 @@ ...@@ -9,4 +9,16 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
<RelativeLayout
android:id="@+id/loadingPanel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true" />
</RelativeLayout>
</FrameLayout> </FrameLayout>
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<!--<item <item
android:id="@+id/action_notifications" android:id="@+id/action_notifications"
android:icon="@drawable/ic_notifications_black_24dp" android:icon="@drawable/ic_notifications_white_24dp"
android:orderInCategory="1" android:orderInCategory="1"
android:title="Notifications" android:title="Notifications"
app:showAsAction="always" />--> app:showAsAction="always" />
</menu> </menu>
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