Commit 0c3df067 authored by Sajal Narang's avatar Sajal Narang Committed by GitHub

Merge pull request #209 from pulsejet/patch20

Generify fragments, add rich notifications
parents cf659451 cafb0bd9
......@@ -8,8 +8,8 @@ android {
manifestPlaceholders 'appAuthRedirectScheme': 'https'
minSdkVersion 21
targetSdkVersion 27
versionCode 16
versionName "1.0.11"
versionCode 17
versionName "1.0.12"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
resValue "string", "google_maps_key", (project.findProperty("GOOGLE_MAPS_API_KEY") ?: "")
vectorDrawables.useSupportLibrary = true
......
......@@ -8,6 +8,7 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:allowBackup="true"
......@@ -67,39 +68,6 @@
android:pathPattern="/event/.*"
android:scheme="https" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="insti.app"
android:pathPattern="/org/.*"
android:scheme="http" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="insti.app"
android:pathPattern="/user/.*"
android:scheme="http" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="insti.app"
android:pathPattern="/event/.*"
android:scheme="http" />
</intent-filter>
</activity>
<activity
android:name=".activity.LoginActivity"
......@@ -117,21 +85,6 @@
</activity>
<service
android:name=".notifications.NotificationIntentService"
android:enabled="true"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE" />
<receiver android:name=".notifications.NotificationEventReceiver" />
<receiver android:name=".notifications.NotificationServiceStarterReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.TIMEZONE_CHANGED" />
<action android:name="android.intent.action.TIME_SET" />
</intent-filter>
</receiver>
<service android:name=".InstiAppFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
......
......@@ -28,6 +28,27 @@ public class Constants {
public static final String LOGIN_MESSAGE = "Please login to continue!";
public static final String MAIN_INTENT_EXTRAS = "MAIN_EXTRA";
public static final String FCM_BUNDLE_TYPE = "type";
public static final String FCM_BUNDLE_ID = "id";
public static final String FCM_BUNDLE_EXTRA = "extra";
public static final String FCM_BUNDLE_NOTIFICATION_ID = "notification_id";
public static final String FCM_BUNDLE_ACTION = "action";
public static final String FCM_BUNDLE_RICH = "rich";
public static final String FCM_BUNDLE_TITLE = "title";
public static final String FCM_BUNDLE_VERB = "verb";
public static final String FCM_BUNDLE_IMAGE = "image_url";
public static final String FCM_BUNDLE_LARGE_ICON = "large_icon";
public static final String FCM_BUNDLE_LARGE_CONTENT = "large_content";
public static final String FCM_BUNDLE_ACTION_STARTING = "starting";
public static final String DATA_TYPE_EVENT = "event";
public static final String DATA_TYPE_BODY = "body";
public static final String DATA_TYPE_USER = "userprofile";
public static final String DATA_TYPE_NEWS = "newsentry";
public static final String DATA_TYPE_PT = "blogentry";
/* Map */
public static final double MAP_Xn = 19.134417, MAP_Yn = 72.901229, MAP_Zn = 1757, MAP_Zyn = 501;
public static final double[] MAP_WEIGHTS_X = {-11.392001766454612, -36.31634553309953, 73.91269388324432, -24.14021153064087, 3.4508817531539115, -0.1462262375477863, 5.532505074667804, -1.542391995870977, 36.14211738142935};
......
package app.insti;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import com.squareup.picasso.Picasso;
import java.io.IOException;
import java.util.Map;
import app.insti.activity.MainActivity;
import app.insti.notifications.NotificationId;
public class InstiAppFirebaseMessagingService extends FirebaseMessagingService {
String channel;
@Override
public void onNewToken(String s) {
/* For future functionality */
super.onNewToken(s);
}
/** Convert a string to string map to a bundle */
private Bundle stringMapToBundle(Map<String, String> map) {
Bundle bundle = new Bundle();
for (Map.Entry<String, String> entry : map.entrySet()) {
bundle.putString(entry.getKey(), entry.getValue());
}
return bundle;
}
/** Get a PendingIntent to open MainActivity from a notification message */
private PendingIntent getNotificationIntent(RemoteMessage remoteMessage, Integer notificationId) {
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra(Constants.MAIN_INTENT_EXTRAS, stringMapToBundle(remoteMessage.getData()));
return PendingIntent.getActivity(this, notificationId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
/* For future functionality */
channel = getResources().getString(R.string.default_notification_channel_id);
// Check for empty data notifications
if (remoteMessage.getData().size() > 0) {
sendRichNotification(remoteMessage);
}
super.onMessageReceived(remoteMessage);
}
/** Ensure key is in data */
private boolean ensureKeyExists(RemoteMessage remoteMessage, String key) {
return (remoteMessage.getData().get(key) != null);
}
/** Send a rich notification with image support */
private void sendRichNotification(RemoteMessage remoteMessage) {
if (!ensureKeyExists(remoteMessage, Constants.FCM_BUNDLE_TITLE) ||
!ensureKeyExists(remoteMessage, Constants.FCM_BUNDLE_VERB)) { return; }
final String message = remoteMessage.getData().get(Constants.FCM_BUNDLE_VERB);
/* Get unique id */
int notification_id = NotificationId.getID();
/* Default options */
NotificationCompat.Builder builder = standardNotificationBuilder()
.setContentTitle(remoteMessage.getData().get(Constants.FCM_BUNDLE_TITLE))
.setContentText(message)
.setContentIntent(getNotificationIntent(remoteMessage, notification_id));
/* Check for article */
String largeContent = remoteMessage.getData().get(Constants.FCM_BUNDLE_LARGE_CONTENT);
if (largeContent != null) {
builder.setStyle(new NotificationCompat.BigTextStyle()
.bigText(largeContent));
}
/* Get images and show */
showBitmapNotification(
this,
remoteMessage.getData().get(Constants.FCM_BUNDLE_IMAGE),
remoteMessage.getData().get(Constants.FCM_BUNDLE_LARGE_ICON),
notification_id,
builder,
message
);
}
/** Show the notification */
private static void showNotification(Context context, int id, Notification notification) {
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
notificationManager.notify(id, notification);
}
/** Common builder */
private NotificationCompat.Builder standardNotificationBuilder() {
Uri soundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
return new NotificationCompat.Builder(this, channel)
.setSmallIcon(R.drawable.ic_lotusgray)
.setColor(getResources().getColor(R.color.colorPrimary))
.setVibrate(new long[]{0, 200})
.setSound(soundUri)
.setAutoCancel(true)
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
}
/** Gets a bitmap from a URL asynchronously and shows notification */
public static void showBitmapNotification(
final Context context, final String imageUrl, final String largeIconUrl,
final int notification_id, final NotificationCompat.Builder builder, final String content){
new AsyncTask<Void, Void, Bitmap[]>() {
@Override
protected Bitmap[] doInBackground(Void... params) {
try {
Bitmap image = null;
if (imageUrl != null) {
image = Picasso.get().load(imageUrl).get();
}
Bitmap largeIcon = null;
if (largeIconUrl != null) {
largeIcon = getCroppedBitmap(
Picasso.get().load(Constants.resizeImageUrl(largeIconUrl, 200)).get(), 200);
}
return new Bitmap[]{image, largeIcon};
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Bitmap[] bitmaps) {
// Check if we loaded big image
if (bitmaps != null && bitmaps[0] != null) {
builder.setStyle(
new NotificationCompat.BigPictureStyle()
.bigPicture(bitmaps[0])
.setSummaryText(content)
);
}
// Check if we loaded large icon
if (bitmaps != null && bitmaps[1] != null) {
builder.setLargeIcon(bitmaps[1]);
}
showNotification(context, notification_id, builder.build());
super.onPostExecute(bitmaps);
}
}.execute();
}
/** Get circular center cropped bitmap */
public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
Bitmap sbmp;
if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
float factor = smallest / radius;
sbmp = Bitmap.createScaledBitmap(bmp, (int)(bmp.getWidth() / factor), (int)(bmp.getHeight() / factor), false);
} else {
sbmp = bmp;
}
Bitmap output = Bitmap.createBitmap(radius, radius,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffa19774;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, radius, radius);
final Rect destRect = new Rect(
(sbmp.getWidth() - radius) / 2,
(sbmp.getHeight() - radius) / 2,
radius + (sbmp.getWidth() - radius) / 2,
radius + (sbmp.getHeight() - radius) / 2);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(radius / 2,
radius / 2, radius / 2, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(sbmp, destRect, rect, paint);
return output;
}
}
......@@ -18,11 +18,12 @@ import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.InstanceIdResult;
import app.insti.Constants;
import app.insti.R;
import app.insti.SessionManager;
import app.insti.api.RetrofitInterface;
import app.insti.api.ServiceGenerator;
import app.insti.api.model.LoginResponse;
import app.insti.api.response.LoginResponse;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
......@@ -58,6 +59,13 @@ public class LoginActivity extends AppCompatActivity {
private void openMainActivity() {
Intent i = new Intent(mContext, MainActivity.class);
/* Pass FCM data if available */
Intent myIntent = getIntent();
if (myIntent.getExtras() != null) {
i.putExtra(Constants.MAIN_INTENT_EXTRAS, myIntent.getExtras());
}
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
......
......@@ -34,6 +34,7 @@ import android.widget.Toast;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.InstanceIdResult;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.squareup.picasso.Picasso;
......@@ -43,8 +44,10 @@ import java.util.List;
import app.insti.Constants;
import app.insti.R;
import app.insti.SessionManager;
import app.insti.api.EmptyCallback;
import app.insti.api.RetrofitInterface;
import app.insti.api.ServiceGenerator;
import app.insti.api.request.UserFCMPatchRequest;
import app.insti.api.model.Body;
import app.insti.api.model.Event;
import app.insti.api.model.Notification;
......@@ -61,22 +64,24 @@ import app.insti.fragment.MessMenuFragment;
import app.insti.fragment.NewsFragment;
import app.insti.fragment.NotificationsFragment;
import app.insti.fragment.PlacementBlogFragment;
import app.insti.fragment.UserFragment;
import app.insti.fragment.QuickLinksFragment;
import app.insti.fragment.SettingsFragment;
import app.insti.fragment.TrainingBlogFragment;
import app.insti.notifications.NotificationEventReceiver;
import app.insti.fragment.UserFragment;
import okhttp3.Cache;
import okhttp3.OkHttpClient;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import static app.insti.Constants.DATA_TYPE_BODY;
import static app.insti.Constants.DATA_TYPE_EVENT;
import static app.insti.Constants.DATA_TYPE_NEWS;
import static app.insti.Constants.DATA_TYPE_PT;
import static app.insti.Constants.DATA_TYPE_USER;
import static app.insti.Constants.FCM_BUNDLE_NOTIFICATION_ID;
import static app.insti.Constants.MY_PERMISSIONS_REQUEST_ACCESS_LOCATION;
import static app.insti.Constants.MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE;
import static app.insti.Constants.RESULT_LOAD_IMAGE;
import static app.insti.notifications.NotificationIntentService.ACTION_OPEN_EVENT;
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, BackHandledFragment.BackHandlerInterface {
......@@ -90,6 +95,9 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
private Menu menu;
private RetrofitInterface retrofitInterface;
/** which menu item should be checked on activity start */
private int initMenuChecked = R.id.nav_feed;
public RetrofitInterface getRetrofitInterface() {
return retrofitInterface;
}
......@@ -138,25 +146,20 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
Intent intent = getIntent();
if (intent != null) {
if (intent.getAction() != null && intent.getAction().equals(ACTION_OPEN_EVENT)) {
EventFragment eventFragment = new EventFragment();
Bundle bundle = new Bundle();
bundle.putString(Constants.EVENT_JSON, intent.getStringExtra(Constants.EVENT_JSON));
eventFragment.setArguments(bundle);
updateFragment(eventFragment);
// Check for data passed by FCM
if (intent.getExtras() != null && intent.getBundleExtra(Constants.MAIN_INTENT_EXTRAS) != null) {
handleFCMIntent(intent.getBundleExtra(Constants.MAIN_INTENT_EXTRAS));
} else {
handleIntent(intent);
}
}
checkLatestVersion();
NotificationEventReceiver.setupAlarm(getApplicationContext());
}
private void fetchNotifications() {
RetrofitInterface retrofitInterface = getRetrofitInterface();
retrofitInterface.getNotifications(getSessionIDHeader()).enqueue(new Callback<List<Notification>>() {
retrofitInterface.getNotifications(getSessionIDHeader()).enqueue(new EmptyCallback<List<Notification>>() {
@Override
public void onResponse(Call<List<Notification>> call, Response<List<Notification>> response) {
if (response.isSuccessful()) {
......@@ -168,38 +171,37 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
}
}
}
@Override
public void onFailure(Call<List<Notification>> call, Throwable t) {
}
});
}
private void checkLatestVersion() {
/** Get version code we are currently on */
private int getCurrentVersion() {
try {
PackageInfo pInfo = this.getPackageManager().getPackageInfo(getPackageName(), 0);
final int versionCode = pInfo.versionCode;
RetrofitInterface retrofitInterface = getRetrofitInterface();
retrofitInterface.getLatestVersion().enqueue(new Callback<JsonObject>() {
@Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
if (response.isSuccessful()) {
if (response.body().get("version").getAsInt() > versionCode) {
showUpdateSnackBar(response.body().get("message").getAsString());
}
}
}
@Override
public void onFailure(Call<JsonObject> call, Throwable t) {
}
});
return pInfo.versionCode;
} catch (PackageManager.NameNotFoundException ignored) {
return 0;
}
}
/** Check for updates in andro.json */
private void checkLatestVersion() {
final int versionCode = getCurrentVersion();
if (versionCode == 0) { return; }
RetrofitInterface retrofitInterface = getRetrofitInterface();
retrofitInterface.getLatestVersion().enqueue(new EmptyCallback<JsonObject>() {
@Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
if (response.isSuccessful()) {
final JsonElement currentVersion = response.body().get("version");
if (currentVersion != null && currentVersion.getAsInt() > versionCode) {
showUpdateSnackBar(response.body().get("message").getAsString());
}
}
}
});
}
private void showUpdateSnackBar(String message) {
View parentLayout = findViewById(android.R.id.content);
Snackbar.make(parentLayout, message, Snackbar.LENGTH_LONG).setAction("UPDATE", new View.OnClickListener() {
......@@ -247,62 +249,121 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
mNotificationManager.createNotificationChannel(mChannel);
}
/** Handle opening event/body/blog from FCM notification */
private void handleFCMIntent(Bundle bundle) {
/* Mark the notification read */
final String notificationId = bundle.getString(FCM_BUNDLE_NOTIFICATION_ID);
if (notificationId != null) {
getRetrofitInterface().markNotificationRead(getSessionIDHeader(), notificationId).enqueue(new EmptyCallback<Void>());
}
/* Follow the notification */
chooseIntent(
bundle.getString(Constants.FCM_BUNDLE_TYPE),
bundle.getString(Constants.FCM_BUNDLE_ID),
bundle.getString(Constants.FCM_BUNDLE_EXTRA)
);
}
/** Handle intents for links */
private void handleIntent(Intent appLinkIntent) {
String appLinkAction = appLinkIntent.getAction();
String appLinkData = appLinkIntent.getDataString();
if (Intent.ACTION_VIEW.equals(appLinkAction) && appLinkData != null) {
switch (getType(appLinkData)) {
case "body":
Body body = new Body(getID(appLinkData));
BodyFragment bodyFragment = BodyFragment.newInstance(body);
updateFragment(bodyFragment);
break;
case "user":
UserFragment userFragment = UserFragment.newInstance(getID(appLinkData));
updateFragment(userFragment);
break;
case "event":
RetrofitInterface retrofitInterface = getRetrofitInterface();
retrofitInterface.getEvent(getSessionIDHeader(), getID(appLinkData)).enqueue(new Callback<Event>() {
@Override
public void onResponse(Call<Event> call, Response<Event> response) {
EventFragment eventFragment = new EventFragment();
Bundle bundle = new Bundle();
bundle.putString(Constants.EVENT_JSON, response.body().toString());
eventFragment.setArguments(bundle);
updateFragment(eventFragment);
}
chooseIntent(getType(appLinkData), getID(appLinkData));
}
}
@Override
public void onFailure(Call<Event> call, Throwable t) {
/** Open the proper fragment from given type and id */
private void chooseIntent(String type, String id) {
if (type == null || id == null) { return; }
switch (type) {
case DATA_TYPE_BODY:
openBodyFragment(id);
return;
case DATA_TYPE_USER:
openUserFragment(id);
return;
case DATA_TYPE_EVENT:
openEventFragment(id);
return;
case DATA_TYPE_NEWS:
initMenuChecked = R.id.nav_news;
updateFragment(new NewsFragment());
return;
}
Log.e("NOTIFICATIONS", "Server sent invalid notification?");
}
}
});
/** Open the proper fragment from given type, id and extra */
private void chooseIntent(String type, String id, String extra) {
if (extra == null) {
chooseIntent(type, id);
} else {
switch (type) {
case DATA_TYPE_PT:
if (extra.contains("/trainingblog")) {
initMenuChecked = R.id.nav_training_blog;
openTrainingBlog();
} else {
initMenuChecked = R.id.nav_placement_blog;
openPlacementBlog();
}
return;
}
chooseIntent(type, id);
}
}
/** Open user fragment from given id */
private void openUserFragment(String id) {
UserFragment userFragment = UserFragment.newInstance(id);
updateFragment(userFragment);
}
/** Open the body fragment from given id */
private void openBodyFragment(String id) {
Body body = new Body(id);
BodyFragment bodyFragment = BodyFragment.newInstance(body);
updateFragment(bodyFragment);
}
/** Open the event fragment from the provided id */
private void openEventFragment(String id) {
RetrofitInterface retrofitInterface = getRetrofitInterface();
retrofitInterface.getEvent(getSessionIDHeader(), id).enqueue(new EmptyCallback<Event>() {
@Override
public void onResponse(Call<Event> call, Response<Event> response) {
EventFragment eventFragment = new EventFragment();
Bundle bundle = new Bundle();
bundle.putString(Constants.EVENT_JSON, response.body().toString());
eventFragment.setArguments(bundle);
updateFragment(eventFragment);
}
});
}
private String getID(String appLinkData) {
if (appLinkData.charAt(appLinkData.length() - 1) == '/')
appLinkData = appLinkData.substring(0, appLinkData.length() - 1);
switch (getType(appLinkData)) {
case "body":
case DATA_TYPE_BODY:
return appLinkData.substring(appLinkData.indexOf("org") + 4);
case "user":
case DATA_TYPE_USER:
return appLinkData.substring(appLinkData.indexOf("user") + 5);
case "event":
case DATA_TYPE_EVENT:
return appLinkData.substring(appLinkData.indexOf("event") + 6);
}
return null;
}
private String getType(String appLinkData) {
if (appLinkData.startsWith("http://insti.app/org/") || appLinkData.startsWith("https://insti.app/org/")) {
return "body";
} else if (appLinkData.startsWith("http://insti.app/user/") || appLinkData.startsWith("https://insti.app/user/")) {
return "user";
} else if (appLinkData.startsWith("http://insti.app/event/") || appLinkData.startsWith("https://insti.app/event/")) {
return "event";
if (appLinkData.contains("://insti.app/org/")) {
return DATA_TYPE_BODY;
} else if (appLinkData.contains("://insti.app/user/")) {
return DATA_TYPE_USER;
} else if (appLinkData.contains("://insti.app/event/")) {
return DATA_TYPE_EVENT;
}
return null;
}
......@@ -325,9 +386,10 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
@Override
public void onSuccess(InstanceIdResult instanceIdResult) {
String fcmId = instanceIdResult.getToken();
final String fcmId = instanceIdResult.getToken();
RetrofitInterface retrofitInterface = getRetrofitInterface();
retrofitInterface.getUserMe(getSessionIDHeader(), fcmId).enqueue(new Callback<User>() {
retrofitInterface.patchUserMe(getSessionIDHeader(), new UserFCMPatchRequest(fcmId, getCurrentVersion())).enqueue(new EmptyCallback<User>() {
@Override
public void onResponse(Call<User> call, Response<User> response) {
if (response.isSuccessful()) {
......@@ -339,10 +401,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
Toast.makeText(MainActivity.this, "Your session has expired!", Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<User> call, Throwable t) {
}
});
}
});
......@@ -351,7 +409,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
private void initNavigationView() {
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
navigationView.setCheckedItem(R.id.nav_feed);
navigationView.setCheckedItem(initMenuChecked);
}
private void updateNavigationView() {
......@@ -426,7 +484,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
......@@ -443,26 +500,16 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
break;
case R.id.nav_news:
NewsFragment newsFragment = new NewsFragment();
updateFragment(newsFragment);
updateFragment(new NewsFragment());
break;
case R.id.nav_placement_blog:
if (session.isLoggedIn()) {
PlacementBlogFragment placementBlogFragment = new PlacementBlogFragment();
updateFragment(placementBlogFragment);
} else {
Toast.makeText(this, Constants.LOGIN_MESSAGE, Toast.LENGTH_LONG).show();
}
openPlacementBlog();
break;
case R.id.nav_training_blog:
if (session.isLoggedIn()) {
TrainingBlogFragment trainingBlogFragment = new TrainingBlogFragment();
updateFragment(trainingBlogFragment);
} else {
Toast.makeText(this, Constants.LOGIN_MESSAGE, Toast.LENGTH_LONG).show();
}
openTrainingBlog();
break;
case R.id.nav_mess_menu:
MessMenuFragment messMenuFragment = new MessMenuFragment();
updateFragment(messMenuFragment);
......@@ -483,9 +530,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
case R.id.nav_settings:
SettingsFragment settingsFragment = new SettingsFragment();
updateFragment(settingsFragment);
//Checking the about fragment
//AboutFragment aboutFragment = new AboutFragment();
//updateFragment(aboutFragment);
break;
}
......@@ -494,6 +538,26 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
return true;
}
/** Open placement blog fragment */
private void openPlacementBlog() {
if (session.isLoggedIn()) {
PlacementBlogFragment placementBlogFragment = new PlacementBlogFragment();
updateFragment(placementBlogFragment);
} else {
Toast.makeText(this, Constants.LOGIN_MESSAGE, Toast.LENGTH_LONG).show();
}
}
private void openTrainingBlog() {
if (session.isLoggedIn()) {
TrainingBlogFragment trainingBlogFragment = new TrainingBlogFragment();
updateFragment(trainingBlogFragment);
} else {
Toast.makeText(this, Constants.LOGIN_MESSAGE, Toast.LENGTH_LONG).show();
}
}
/** Change the active fragment to the supplied one */
public void updateFragment(Fragment fragment) {
Log.d(TAG, "updateFragment: " + fragment.toString());
Bundle bundle = fragment.getArguments();
......
......@@ -13,7 +13,7 @@ import com.squareup.picasso.Picasso;
import java.util.List;
import app.insti.Constants;
import app.insti.ItemClickListener;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.api.model.Body;
......
......@@ -18,7 +18,7 @@ import java.util.Calendar;
import app.insti.Constants;
import app.insti.ItemClickListener;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.api.model.Event;
import app.insti.api.model.Venue;
......
......@@ -16,13 +16,15 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
import app.insti.ItemClickListener;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.interfaces.Readable;
import app.insti.interfaces.Writable;
import app.insti.api.model.NewsArticle;
import app.insti.fragment.NewsFragment;
import ru.noties.markwon.Markwon;
public class NewsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public class NewsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Readable<NewsArticle>,Writable<NewsArticle> {
private final int VIEW_ITEM = 1;
private final int VIEW_PROG = 0;
......@@ -35,12 +37,14 @@ public class NewsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
this.itemClickListener = itemClickListener;
}
public List<NewsArticle> getNewsArticles() {
@Override
public List<NewsArticle> getPosts() {
return newsArticles;
}
public void setNewsArticles(List<NewsArticle> newsArticles) {
this.newsArticles = newsArticles;
@Override
public void setPosts(List<NewsArticle> posts) {
this.newsArticles = posts;
}
@NonNull
......
......@@ -14,7 +14,7 @@ import com.squareup.picasso.Picasso;
import java.util.List;
import app.insti.Constants;
import app.insti.ItemClickListener;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.api.model.Event;
import app.insti.api.model.NewsArticle;
......
......@@ -15,13 +15,15 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
import app.insti.ItemClickListener;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.api.model.PlacementBlogPost;
import app.insti.fragment.PlacementBlogFragment;
import app.insti.interfaces.Readable;
import app.insti.interfaces.Writable;
import ru.noties.markwon.Markwon;
public class PlacementBlogAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public class PlacementBlogAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Readable<PlacementBlogPost>,Writable<PlacementBlogPost> {
private final int VIEW_ITEM = 1;
private final int VIEW_PROG = 0;
private List<PlacementBlogPost> posts;
......
......@@ -13,7 +13,7 @@ import com.squareup.picasso.Picasso;
import java.util.List;
import app.insti.ItemClickListener;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.api.model.Body;
import app.insti.api.model.Role;
......
......@@ -15,13 +15,15 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
import app.insti.ItemClickListener;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.api.model.TrainingBlogPost;
import app.insti.fragment.TrainingBlogFragment;
import app.insti.interfaces.Readable;
import app.insti.interfaces.Writable;
import ru.noties.markwon.Markwon;
public class TrainingBlogAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public class TrainingBlogAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Readable<TrainingBlogPost>,Writable<TrainingBlogPost> {
private final int VIEW_ITEM = 1;
private final int VIEW_PROG = 0;
......
......@@ -12,7 +12,7 @@ import com.squareup.picasso.Picasso;
import java.util.List;
import app.insti.ItemClickListener;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.api.model.User;
......
package app.insti.api;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class EmptyCallback<T> implements Callback<T> {
@Override
public void onResponse(Call<T> call, Response<T> response) {}
@Override
public void onFailure(Call<T> call, Throwable t) {}
}
......@@ -4,13 +4,14 @@ import com.google.gson.JsonObject;
import java.util.List;
import app.insti.api.model.EventCreateRequest;
import app.insti.api.model.EventCreateResponse;
import app.insti.api.model.ExploreResponse;
import app.insti.api.model.ImageUploadRequest;
import app.insti.api.model.ImageUploadResponse;
import app.insti.api.model.LoginResponse;
import app.insti.api.model.NewsFeedResponse;
import app.insti.api.request.EventCreateRequest;
import app.insti.api.response.EventCreateResponse;
import app.insti.api.response.ExploreResponse;
import app.insti.api.request.ImageUploadRequest;
import app.insti.api.response.ImageUploadResponse;
import app.insti.api.response.LoginResponse;
import app.insti.api.response.NewsFeedResponse;
import app.insti.api.request.UserFCMPatchRequest;
import app.insti.api.model.Event;
import app.insti.api.model.HostelMessMenu;
import app.insti.api.model.NewsArticle;
......@@ -23,6 +24,7 @@ import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.PATCH;
import retrofit2.http.POST;
import retrofit2.http.Path;
import retrofit2.http.Query;
......@@ -76,8 +78,8 @@ public interface RetrofitInterface {
@GET("user-me")
Call<User> getUserMe(@Header("Cookie") String sessionID);
@GET("user-me")
Call<User> getUserMe(@Header("Cookie") String sessionID, @Query("fcm_id") String fcmId);
@PATCH("user-me")
Call<User> patchUserMe(@Header("Cookie") String sessionID, @Body UserFCMPatchRequest userFCMPatchRequest);
@GET("user-me/ues/{eventID}")
Call<Void> updateUserEventStatus(@Header("Cookie") String sessionID, @Path("eventID") String eventID, @Query("status") int status);
......@@ -98,7 +100,7 @@ public interface RetrofitInterface {
Call<List<Notification>> getNotifications(@Header("Cookie") String sessionID);
@GET("notifications/read/{notificationID}")
Call<Void> markNotificationRead(@Header("Cookie") String sessionID, @Path("notificationID") Integer notificationID);
Call<Void> markNotificationRead(@Header("Cookie") String sessionID, @Path("notificationID") String notificationID);
@GET("logout")
Call<Void> logout(@Header("Cookie") String sessionID);
......
......@@ -84,17 +84,12 @@ public class ServiceGenerator {
}
public boolean isConnected() {
Log.wtf("cache", "MEOW");
try {
android.net.ConnectivityManager e = (android.net.ConnectivityManager) context.getSystemService(
Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = e.getActiveNetworkInfo();
Log.wtf("cache", Boolean.toString(activeNetwork != null && activeNetwork.isConnectedOrConnecting()));
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
} catch (Exception e) {
Log.w("cache", e.toString());
}
} catch (Exception e) {}
return false;
}
......
......@@ -6,7 +6,9 @@ import com.google.gson.annotations.SerializedName;
import java.sql.Timestamp;
public class NewsArticle {
import app.insti.interfaces.Browsable;
public class NewsArticle implements Browsable {
@NonNull()
@SerializedName("id")
private String articleID;
......
......@@ -6,7 +6,9 @@ import com.google.gson.annotations.SerializedName;
import java.sql.Timestamp;
public class PlacementBlogPost {
import app.insti.interfaces.Browsable;
public class PlacementBlogPost implements Browsable {
@NonNull()
@SerializedName("id")
private String postID;
......
......@@ -6,7 +6,9 @@ import com.google.gson.annotations.SerializedName;
import java.sql.Timestamp;
public class TrainingBlogPost {
import app.insti.interfaces.Browsable;
public class TrainingBlogPost implements Browsable {
@NonNull()
@SerializedName("id")
private String postID;
......
package app.insti.api.model;
package app.insti.api.request;
import com.google.gson.annotations.SerializedName;
......
package app.insti.api.model;
package app.insti.api.request;
import com.google.gson.annotations.SerializedName;
......
package app.insti.api.request;
import com.google.gson.annotations.SerializedName;
public class UserFCMPatchRequest {
@SerializedName("fcm_id")
private String userFCMId;
@SerializedName("android_version")
private int userAndroidVersion;
public UserFCMPatchRequest(String userFCMId, int userAndroidVersion) {
this.userFCMId = userFCMId;
this.userAndroidVersion = userAndroidVersion;
}
}
package app.insti.api.model;
package app.insti.api.response;
import com.google.gson.annotations.SerializedName;
import java.util.List;
import app.insti.api.model.Body;
import app.insti.api.model.Event;
import app.insti.api.model.User;
public class ExploreResponse {
@SerializedName("bodies")
private List<Body> bodies;
......
package app.insti.api.model;
package app.insti.api.response;
import com.google.gson.annotations.SerializedName;
......
package app.insti.api.model;
package app.insti.api.response;
import com.google.gson.annotations.SerializedName;
import app.insti.api.model.User;
public class LoginResponse {
@SerializedName("sessionid")
private String sessionID;
......
package app.insti.api.model;
package app.insti.api.response;
import com.google.gson.annotations.SerializedName;
import java.util.List;
import app.insti.api.model.Event;
public class NewsFeedResponse {
@SerializedName("data")
private List<Event> events;
......
......@@ -36,7 +36,7 @@ import java.util.ArrayList;
import java.util.List;
import app.insti.Constants;
import app.insti.ItemClickListener;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.ShareURLMaker;
import app.insti.activity.MainActivity;
......
......@@ -16,7 +16,7 @@ import com.google.gson.reflect.TypeToken;
import java.util.List;
import app.insti.Constants;
import app.insti.ItemClickListener;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.adapter.BodyAdapter;
import app.insti.api.model.Body;
......
......@@ -28,12 +28,12 @@ import java.util.List;
import java.util.TimeZone;
import app.insti.Constants;
import app.insti.ItemClickListener;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.activity.MainActivity;
import app.insti.adapter.FeedAdapter;
import app.insti.api.RetrofitInterface;
import app.insti.api.model.NewsFeedResponse;
import app.insti.api.response.NewsFeedResponse;
import app.insti.api.model.Event;
import retrofit2.Call;
import retrofit2.Callback;
......
......@@ -42,7 +42,7 @@ import java.util.Date;
import java.util.List;
import app.insti.Constants;
import app.insti.ItemClickListener;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.ShareURLMaker;
import app.insti.activity.MainActivity;
......
......@@ -15,7 +15,7 @@ import com.google.gson.reflect.TypeToken;
import java.util.List;
import app.insti.Constants;
import app.insti.ItemClickListener;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.adapter.FeedAdapter;
import app.insti.api.model.Event;
......
......@@ -20,14 +20,14 @@ import java.util.ArrayList;
import java.util.List;
import app.insti.Constants;
import app.insti.ItemClickListener;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.activity.MainActivity;
import app.insti.adapter.BodyAdapter;
import app.insti.adapter.FeedAdapter;
import app.insti.adapter.UserAdapter;
import app.insti.api.RetrofitInterface;
import app.insti.api.model.ExploreResponse;
import app.insti.api.response.ExploreResponse;
import app.insti.api.model.Body;
import app.insti.api.model.Event;
import app.insti.api.model.User;
......
......@@ -21,12 +21,12 @@ import java.util.List;
import app.insti.ActivityBuffer;
import app.insti.Constants;
import app.insti.ItemClickListener;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.activity.MainActivity;
import app.insti.adapter.FeedAdapter;
import app.insti.api.RetrofitInterface;
import app.insti.api.model.NewsFeedResponse;
import app.insti.api.response.NewsFeedResponse;
import app.insti.api.model.Event;
import retrofit2.Call;
import retrofit2.Callback;
......
package app.insti.fragment;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
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.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
import app.insti.ActivityBuffer;
import app.insti.Constants;
import app.insti.ItemClickListener;
import app.insti.R;
import app.insti.activity.MainActivity;
import app.insti.adapter.NewsAdapter;
import app.insti.api.RetrofitInterface;
import app.insti.api.model.NewsArticle;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* A simple {@link Fragment} subclass.
*/
public class NewsFragment extends BaseFragment {
public static boolean showLoader = true;
private RecyclerView newsRecyclerView;
private SwipeRefreshLayout newsSwipeRefreshLayout;
private boolean freshNewsDisplayed = false;
private String searchQuery;
public class NewsFragment extends RecyclerViewFragment<NewsArticle, NewsAdapter> {
public NewsFragment() {
// Required empty public constructor
......@@ -63,145 +40,23 @@ public class NewsFragment extends BaseFragment {
Toolbar toolbar = getActivity().findViewById(R.id.toolbar);
toolbar.setTitle("News");
setHasOptionsMenu(true);
updateData();
updateNews();
newsSwipeRefreshLayout = getActivity().findViewById(R.id.news_swipe_refresh_layout);
newsSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
postType = NewsArticle.class;
adapterType = NewsAdapter.class;
recyclerView = getActivity().findViewById(R.id.news_recycler_view);
swipeRefreshLayout = getActivity().findViewById(R.id.news_swipe_refresh_layout);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
updateNews();
}
});
}
private void updateNews() {
RetrofitInterface retrofitInterface = ((MainActivity) getActivity()).getRetrofitInterface();
retrofitInterface.getNews("sessionid=" + getArguments().getString(Constants.SESSION_ID), 0, 20, searchQuery).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();
freshNewsDisplayed = true;
displayNews(articles);
}
//Server Error
newsSwipeRefreshLayout.setRefreshing(false);
}
@Override
public void onFailure(Call<List<NewsArticle>> call, Throwable t) {
//Network Error
newsSwipeRefreshLayout.setRefreshing(false);
updateData();
}
});
}
private void displayNews(final List<NewsArticle> result) {
/* Skip if we're already destroyed */
if (getActivity() == null || getView() == null) return;
final NewsAdapter newsAdapter = new NewsAdapter(result, new ItemClickListener() {
@Override
public void onItemClick(View v, int position) {
String link = result.get(position).getLink();
if (link != null && !link.isEmpty())
openWebURL(link);
}
});
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()));
newsRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
// multiple calls should not be made
boolean loading = false;
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (dy > 0) {
LinearLayoutManager layoutManager = (LinearLayoutManager) newsRecyclerView.getLayoutManager();
if (((layoutManager.getChildCount() + layoutManager.findFirstVisibleItemPosition()) > (layoutManager.getItemCount() - 5)) && (!loading)) {
loading = true;
View v = getActivity().findViewById(R.id.training_feed_swipe_refresh_layout);
RetrofitInterface retrofitInterface = ((MainActivity) getActivity()).getRetrofitInterface();
retrofitInterface.getNews("sessionid=" + getArguments().getString(Constants.SESSION_ID), layoutManager.getItemCount(), 10, searchQuery).enqueue(new Callback<List<NewsArticle>>() {
@Override
public void onResponse(Call<List<NewsArticle>> call, Response<List<NewsArticle>> response) {
loading = false;
List<NewsArticle> newsArticles = (ArrayList<NewsArticle>) newsAdapter.getNewsArticles();
newsArticles.addAll(response.body());
if (response.body().size() == 0) {
showLoader = false;
}
newsAdapter.setNewsArticles(newsArticles);
newsAdapter.notifyDataSetChanged();
// new updateDatabase().execute(blogPosts);
}
@Override
public void onFailure(Call<List<NewsArticle>> call, Throwable t) {
loading = false;
}
});
}
}
}
});
} catch (NullPointerException e) {
e.printStackTrace();
}
}
});
getActivity().findViewById(R.id.loadingPanel).setVisibility(View.GONE);
}
private void openWebURL(String URL) {
Intent browse = new Intent(Intent.ACTION_VIEW, Uri.parse(URL));
startActivity(browse);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.search_view_menu, menu);
MenuItem item = menu.findItem(R.id.action_search);
SearchView sv = new SearchView(((MainActivity) getActivity()).getSupportActionBar().getThemedContext());
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItem.SHOW_AS_ACTION_IF_ROOM);
item.setActionView(sv);
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
performSearch(query);
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (TextUtils.isEmpty(newText)) {
//Text is cleared, do your thing
searchQuery = null;
updateNews();
showLoader = true;
return true;
} else if (newText.length() >= 3) {
performSearch(newText);
return true;
}
return false;
}
});
}
private void performSearch(String query) {
searchQuery = query;
updateNews();
showLoader = false;
Call<List<NewsArticle>> getCall(RetrofitInterface retrofitInterface, String sessionIDHeader) {
return retrofitInterface.getNews(sessionIDHeader, getPostCount(), 20, searchQuery);
}
}
......@@ -17,10 +17,11 @@ import com.google.gson.Gson;
import java.util.List;
import app.insti.Constants;
import app.insti.ItemClickListener;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.activity.MainActivity;
import app.insti.adapter.NotificationsAdapter;
import app.insti.api.EmptyCallback;
import app.insti.api.RetrofitInterface;
import app.insti.api.model.Notification;
import app.insti.api.model.PlacementBlogPost;
......@@ -88,15 +89,7 @@ public class NotificationsFragment extends BaseFragment {
/* Mark notification read */
RetrofitInterface retrofitInterface = ((MainActivity) getActivity()).getRetrofitInterface();
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) {
}
});
retrofitInterface.markNotificationRead(sessId, notification.getNotificationId().toString()).enqueue(new EmptyCallback<Void>());
FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
......
......@@ -24,7 +24,7 @@ import java.util.List;
import app.insti.ActivityBuffer;
import app.insti.Constants;
import app.insti.ItemClickListener;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.activity.MainActivity;
import app.insti.adapter.PlacementBlogAdapter;
......@@ -37,15 +37,7 @@ import retrofit2.Response;
/**
* A simple {@link Fragment} subclass.
*/
public class PlacementBlogFragment extends BaseFragment {
public static boolean showLoader = true;
private RecyclerView placementFeedRecyclerView;
private PlacementBlogAdapter placementBlogAdapter;
private SwipeRefreshLayout feedSwipeRefreshLayout;
private boolean freshBlogDisplayed = false;
private String searchQuery;
public class PlacementBlogFragment extends RecyclerViewFragment<PlacementBlogPost, PlacementBlogAdapter> {
public PlacementBlogFragment() {
// Required empty public constructor
......@@ -65,143 +57,23 @@ public class PlacementBlogFragment extends BaseFragment {
Toolbar toolbar = getActivity().findViewById(R.id.toolbar);
toolbar.setTitle("Placement Blog");
setHasOptionsMenu(true);
updateData();
updatePlacementFeed();
feedSwipeRefreshLayout = getActivity().findViewById(R.id.placement_feed_swipe_refresh_layout);
feedSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
postType = PlacementBlogPost.class;
adapterType = PlacementBlogAdapter.class;
recyclerView = getActivity().findViewById(R.id.placement_feed_recycler_view);
swipeRefreshLayout = getActivity().findViewById(R.id.placement_feed_swipe_refresh_layout);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
updatePlacementFeed();
}
});
}
private void updatePlacementFeed() {
RetrofitInterface retrofitInterface = ((MainActivity) getActivity()).getRetrofitInterface();
retrofitInterface.getPlacementBlogFeed("sessionid=" + getArguments().getString(Constants.SESSION_ID), 0, 20, searchQuery).enqueue(new Callback<List<PlacementBlogPost>>() {
@Override
public void onResponse(Call<List<PlacementBlogPost>> call, Response<List<PlacementBlogPost>> response) {
if (response.isSuccessful()) {
List<PlacementBlogPost> posts = response.body();
freshBlogDisplayed = true;
displayPlacementFeed(posts);
}
//Server Error
feedSwipeRefreshLayout.setRefreshing(false);
}
@Override
public void onFailure(Call<List<PlacementBlogPost>> call, Throwable t) {
//Network Error
feedSwipeRefreshLayout.setRefreshing(false);
updateData();
}
});
}
private void displayPlacementFeed(final List<PlacementBlogPost> result) {
/* Skip if we're already destroyed */
if (getActivity() == null || getView() == null) return;
placementBlogAdapter = new PlacementBlogAdapter(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 {
placementFeedRecyclerView = getActivity().findViewById(R.id.placement_feed_recycler_view);
placementFeedRecyclerView.setAdapter(placementBlogAdapter);
placementFeedRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
placementFeedRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
// multiple calls should not be made
boolean loading = false;
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (dy > 0) {
LinearLayoutManager layoutManager = (LinearLayoutManager) placementFeedRecyclerView.getLayoutManager();
if (((layoutManager.getChildCount() + layoutManager.findFirstVisibleItemPosition()) > (layoutManager.getItemCount() - 5)) && (!loading)) {
loading = true;
View v = getActivity().findViewById(R.id.placement_feed_swipe_refresh_layout);
RetrofitInterface retrofitInterface = ((MainActivity) getActivity()).getRetrofitInterface();
retrofitInterface.getPlacementBlogFeed("sessionid=" + getArguments().getString(Constants.SESSION_ID), layoutManager.getItemCount(), 10, searchQuery).enqueue(new Callback<List<PlacementBlogPost>>() {
@Override
public void onResponse(Call<List<PlacementBlogPost>> call, Response<List<PlacementBlogPost>> response) {
loading = false;
List<PlacementBlogPost> blogPosts = (ArrayList<PlacementBlogPost>) placementBlogAdapter.getPosts();
blogPosts.addAll(response.body());
if (response.body().size() == 0) {
showLoader = false;
}
placementBlogAdapter.setPosts(blogPosts);
placementBlogAdapter.notifyDataSetChanged();
// new updateDatabase().execute(blogPosts);
}
@Override
public void onFailure(Call<List<PlacementBlogPost>> call, Throwable t) {
loading = false;
}
});
}
}
}
});
} catch (NullPointerException e) {
e.printStackTrace();
}
}
});
getActivity().findViewById(R.id.loadingPanel).setVisibility(View.GONE);
}
private void openWebURL(String URL) {
Intent browse = new Intent(Intent.ACTION_VIEW, Uri.parse(URL));
startActivity(browse);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.search_view_menu, menu);
MenuItem item = menu.findItem(R.id.action_search);
SearchView sv = new SearchView(((MainActivity) getActivity()).getSupportActionBar().getThemedContext());
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItem.SHOW_AS_ACTION_IF_ROOM);
item.setActionView(sv);
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
performSearch(query);
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (TextUtils.isEmpty(newText)) {
//Text is cleared, do your thing
searchQuery = null;
updatePlacementFeed();
showLoader = true;
return true;
} else if (newText.length() >= 3) {
performSearch(newText);
return true;
}
return false;
}
});
}
private void performSearch(String query) {
searchQuery = query;
updatePlacementFeed();
showLoader = false;
Call<List<PlacementBlogPost>> getCall(RetrofitInterface retrofitInterface, String sessionIDHeader) {
return retrofitInterface.getPlacementBlogFeed(sessionIDHeader, getPostCount(), 20, searchQuery);
}
}
package app.insti.fragment;
public class RecyclerViewFragment {
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import app.insti.ActivityBuffer;
import app.insti.api.RetrofitInterface;
import app.insti.interfaces.Browsable;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.interfaces.Readable;
import app.insti.interfaces.Writable;
import app.insti.activity.MainActivity;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import static android.view.View.GONE;
public abstract class RecyclerViewFragment<T extends Browsable, S extends RecyclerView.Adapter<RecyclerView.ViewHolder> & Readable<T> & Writable<T>> extends BaseFragment {
public static boolean showLoader = true;
protected RecyclerView recyclerView;
protected Class<T> postType;
protected Class<S> adapterType;
protected SwipeRefreshLayout swipeRefreshLayout;
protected String searchQuery;
private S adapter = null;
protected void updateData() {
String sessionIDHeader = ((MainActivity) getActivity()).getSessionIDHeader();
RetrofitInterface retrofitInterface = ((MainActivity) getActivity()).getRetrofitInterface();
Call<List<T>> call = getCall(retrofitInterface, sessionIDHeader);
call.enqueue(new Callback<List<T>>() {
@Override
public void onResponse(Call<List<T>> call, Response<List<T>> response) {
if (response.isSuccessful()) {
List<T> posts = response.body();
displayData(posts);
}
swipeRefreshLayout.setRefreshing(false);
}
@Override
public void onFailure(Call<List<T>> call, Throwable t) {
swipeRefreshLayout.setRefreshing(false);
}
});
}
abstract Call<List<T>> getCall(RetrofitInterface retrofitInterface, String sessionIDHeader);
private void displayData(final List<T> result) {
/* Skip if we're already destroyed */
if (getActivity() == null || getView() == null) return;
try {
adapter = adapterType.getDeclaredConstructor(List.class, ItemClickListener.class).newInstance(result, new ItemClickListener() {
@Override
public void onItemClick(View v, int position) {
String link = result.get(position).getLink();
if (link != null && !link.isEmpty())
openWebURL(link);
}
});
getActivityBuffer().safely(new ActivityBuffer.IRunnable() {
@Override
public void run(Activity pActivity) {
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
boolean loading = false;
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (dy > 0) {
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
if (((layoutManager.getChildCount() + layoutManager.findFirstVisibleItemPosition()) > (layoutManager.getItemCount() - 5)) && (!loading)) {
loading = true;
String sessionIDHeader = ((MainActivity) getActivity()).getSessionIDHeader();
RetrofitInterface retrofitInterface = ((MainActivity) getActivity()).getRetrofitInterface();
Call<List<T>> call = getCall(retrofitInterface, sessionIDHeader);
call.enqueue(new Callback<List<T>>() {
@Override
public void onResponse(Call<List<T>> call, Response<List<T>> response) {
if (response.isSuccessful()) {
loading = false;
List<T> posts = adapter.getPosts();
posts.addAll(response.body());
if (response.body().size() == 0) {
showLoader = false;
}
adapter.setPosts(posts);
adapter.notifyDataSetChanged();
}
}
@Override
public void onFailure(Call<List<T>> call, Throwable t) {
loading = false;
}
});
}
}
}
});
}
});
getActivity().findViewById(R.id.loadingPanel).setVisibility(GONE);
} catch (java.lang.InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
}
}
protected int getPostCount() {
if (adapter == null) { return 0; }
return adapter.getPosts().size();
}
private void openWebURL(String URL) {
Intent browse = new Intent(Intent.ACTION_VIEW, Uri.parse(URL));
startActivity(browse);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.search_view_menu, menu);
MenuItem item = menu.findItem(R.id.action_search);
SearchView sv = new SearchView(((MainActivity) getActivity()).getSupportActionBar().getThemedContext());
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItem.SHOW_AS_ACTION_IF_ROOM);
item.setActionView(sv);
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
performSearch(query);
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (TextUtils.isEmpty(newText)) {
searchQuery = null;
updateData();
showLoader = true;
return true;
} else if (newText.length() >= 3) {
performSearch(newText);
return true;
}
return false;
}
});
}
private void performSearch(String query) {
searchQuery = query;
updateData();
showLoader = false;
}
}
......@@ -24,7 +24,7 @@ import java.util.List;
import app.insti.ActivityBuffer;
import app.insti.Constants;
import app.insti.ItemClickListener;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.activity.MainActivity;
import app.insti.adapter.TrainingBlogAdapter;
......@@ -37,14 +37,7 @@ import retrofit2.Response;
/**
* A simple {@link Fragment} subclass.
*/
public class TrainingBlogFragment extends BaseFragment {
public static boolean showLoader = true;
private RecyclerView trainingFeedRecyclerView;
private SwipeRefreshLayout feedSwipeRefreshLayout;
private boolean freshBlogDisplayed = false;
private String searchQuery;
public class TrainingBlogFragment extends RecyclerViewFragment<TrainingBlogPost, TrainingBlogAdapter> {
public TrainingBlogFragment() {
// Required empty public constructor
......@@ -64,143 +57,23 @@ public class TrainingBlogFragment extends BaseFragment {
Toolbar toolbar = getActivity().findViewById(R.id.toolbar);
toolbar.setTitle("Internship Blog");
setHasOptionsMenu(true);
updateData();
updateTrainingFeed();
feedSwipeRefreshLayout = getActivity().findViewById(R.id.training_feed_swipe_refresh_layout);
feedSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
postType = TrainingBlogPost.class;
adapterType = TrainingBlogAdapter.class;
recyclerView = getActivity().findViewById(R.id.training_feed_recycler_view);
swipeRefreshLayout = getActivity().findViewById(R.id.training_feed_swipe_refresh_layout);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
updateTrainingFeed();
}
});
}
private void updateTrainingFeed() {
RetrofitInterface retrofitInterface = ((MainActivity) getActivity()).getRetrofitInterface();
retrofitInterface.getTrainingBlogFeed("sessionid=" + getArguments().getString(Constants.SESSION_ID), 0, 20, searchQuery).enqueue(new Callback<List<TrainingBlogPost>>() {
@Override
public void onResponse(Call<List<TrainingBlogPost>> call, Response<List<TrainingBlogPost>> response) {
if (response.isSuccessful()) {
List<TrainingBlogPost> posts = response.body();
freshBlogDisplayed = true;
displayTrainingFeed(posts);
}
//Server Error
feedSwipeRefreshLayout.setRefreshing(false);
}
@Override
public void onFailure(Call<List<TrainingBlogPost>> call, Throwable t) {
//Network Error
feedSwipeRefreshLayout.setRefreshing(false);
updateData();
}
});
}
private void displayTrainingFeed(final List<TrainingBlogPost> result) {
/* Skip if we're already destroyed */
if (getActivity() == null || getView() == null) return;
final TrainingBlogAdapter trainingBlogAdapter = new TrainingBlogAdapter(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 {
trainingFeedRecyclerView = getActivity().findViewById(R.id.training_feed_recycler_view);
trainingFeedRecyclerView.setAdapter(trainingBlogAdapter);
trainingFeedRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
trainingFeedRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
// multiple calls should not be made
boolean loading = false;
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (dy > 0) {
LinearLayoutManager layoutManager = (LinearLayoutManager) trainingFeedRecyclerView.getLayoutManager();
if (((layoutManager.getChildCount() + layoutManager.findFirstVisibleItemPosition()) > (layoutManager.getItemCount() - 5)) && (!loading)) {
loading = true;
View v = getActivity().findViewById(R.id.training_feed_swipe_refresh_layout);
RetrofitInterface retrofitInterface = ((MainActivity) getActivity()).getRetrofitInterface();
retrofitInterface.getTrainingBlogFeed("sessionid=" + getArguments().getString(Constants.SESSION_ID), layoutManager.getItemCount(), 10, searchQuery).enqueue(new Callback<List<TrainingBlogPost>>() {
@Override
public void onResponse(Call<List<TrainingBlogPost>> call, Response<List<TrainingBlogPost>> response) {
loading = false;
List<TrainingBlogPost> blogPosts = (ArrayList<TrainingBlogPost>) trainingBlogAdapter.getPosts();
blogPosts.addAll(response.body());
if (response.body().size() == 0) {
showLoader = false;
}
trainingBlogAdapter.setPosts(blogPosts);
trainingBlogAdapter.notifyDataSetChanged();
// new updateDatabase().execute(blogPosts);
}
@Override
public void onFailure(Call<List<TrainingBlogPost>> call, Throwable t) {
loading = false;
}
});
}
}
}
});
} catch (NullPointerException e) {
e.printStackTrace();
}
}
});
getActivity().findViewById(R.id.loadingPanel).setVisibility(View.GONE);
}
private void openWebURL(String URL) {
Intent browse = new Intent(Intent.ACTION_VIEW, Uri.parse(URL));
startActivity(browse);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.search_view_menu, menu);
MenuItem item = menu.findItem(R.id.action_search);
SearchView sv = new SearchView(((MainActivity) getActivity()).getSupportActionBar().getThemedContext());
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItem.SHOW_AS_ACTION_IF_ROOM);
item.setActionView(sv);
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
performSearch(query);
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (TextUtils.isEmpty(newText)) {
//Text is cleared, do your thing
searchQuery = null;
updateTrainingFeed();
showLoader = true;
return true;
} else if (newText.length() >= 3) {
performSearch(newText);
return true;
}
return false;
}
});
}
private void performSearch(String query) {
searchQuery = query;
updateTrainingFeed();
showLoader = false;
Call<List<TrainingBlogPost>> getCall(RetrofitInterface retrofitInterface, String sessionIDHeader) {
return retrofitInterface.getTrainingBlogFeed(sessionIDHeader, getPostCount(), 20, searchQuery);
}
}
......@@ -31,7 +31,7 @@ import com.squareup.picasso.Picasso;
import java.util.List;
import app.insti.Constants;
import app.insti.ItemClickListener;
import app.insti.interfaces.ItemClickListener;
import app.insti.R;
import app.insti.ShareURLMaker;
import app.insti.activity.MainActivity;
......
package app.insti.interfaces;
public interface Browsable {
String getLink();
}
package app.insti.interfaces;
import java.util.List;
public interface Readable<T> {
List<T> getPosts();
}
package app.insti.interfaces;
import java.util.List;
public interface Writable<T> {
void setPosts(List<T> posts);
}
package app.insti.notifications;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import java.util.Calendar;
import java.util.Date;
public class
NotificationEventReceiver extends BroadcastReceiver {
private static final String ACTION_START_NOTIFICATION_SERVICE = "ACTION_START_NOTIFICATION_SERVICE";
private static final String ACTION_DELETE_NOTIFICATION = "ACTION_DELETE_NOTIFICATION";
public static void setupAlarm(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent alarmIntent = getStartPendingIntent(context);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
getTriggerAt(new Date()),
1000 * 60 * 10, //Change this to 1000 * 60 for testing => runs every minute
alarmIntent);
}
private static long getTriggerAt(Date now) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(now);
//calendar.add(Calendar.HOUR, NOTIFICATIONS_INTERVAL_IN_HOURS);
return calendar.getTimeInMillis();
}
private static PendingIntent getStartPendingIntent(Context context) {
Intent intent = new Intent(context, NotificationEventReceiver.class);
intent.setAction(ACTION_START_NOTIFICATION_SERVICE);
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public static PendingIntent getDeleteIntent(Context context) {
Intent intent = new Intent(context, NotificationEventReceiver.class);
intent.setAction(ACTION_DELETE_NOTIFICATION);
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Intent serviceIntent = null;
if (ACTION_START_NOTIFICATION_SERVICE.equals(action)) {
Log.i(getClass().getSimpleName(), "onReceive from alarm, starting notification service");
serviceIntent = NotificationIntentService.createIntentStartNotificationService(context);
} else if (ACTION_DELETE_NOTIFICATION.equals(action)) {
Log.i(getClass().getSimpleName(), "onReceive delete notification action, starting notification service to handle delete");
serviceIntent = NotificationIntentService.createIntentDeleteNotification(context);
}
if (serviceIntent != null) {
NotificationIntentService.enqueueWork(context, NotificationIntentService.class, 200, serviceIntent);
}
}
}
\ No newline at end of file
package app.insti.notifications;
import java.util.concurrent.atomic.AtomicInteger;
public class NotificationId {
private final static AtomicInteger c = new AtomicInteger(0);
public static int getID() {
return c.incrementAndGet();
}
}
package app.insti.notifications;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.support.v4.app.JobIntentService;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.squareup.picasso.Picasso;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import app.insti.Constants;
import app.insti.R;
import app.insti.SessionManager;
import app.insti.activity.MainActivity;
import app.insti.api.RetrofitInterface;
import app.insti.api.ServiceGenerator;
import app.insti.api.model.Event;
import app.insti.api.model.User;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class NotificationIntentService extends JobIntentService {
public static final String ACTION_OPEN_EVENT = "ACTION_OPEN_EVENT";
private static final String ACTION_START = "ACTION_START";
private static final String ACTION_DELETE = "ACTION_DELETE";
private static final String ACTION_NAVIGATE = "ACTION_NAVIGATE";
private static final String ACTION_NOT_GOING = "ACTION_NOT_GOING";
private static int NOTIFICATION_ID = 1;
private NotificationManager manager;
public NotificationIntentService() {
super();
}
public static Intent createIntentStartNotificationService(Context context) {
Intent intent = new Intent(context, NotificationIntentService.class);
intent.setAction(ACTION_START);
return intent;
}
public static Intent createIntentDeleteNotification(Context context) {
Intent intent = new Intent(context, NotificationIntentService.class);
intent.setAction(ACTION_DELETE);
return intent;
}
public static long getDateDiff(Date date1, Date date2, TimeUnit timeUnit) {
long diffInMillies = date2.getTime() - date1.getTime();
return timeUnit.convert(diffInMillies, TimeUnit.MILLISECONDS);
}
public static Bitmap getImageBitmapFromURL(final String imageUrl){
Bitmap imageBitmap = null;
try {
imageBitmap = new AsyncTask<Void, Void, Bitmap>() {
@Override
protected Bitmap doInBackground(Void... params) {
{
int targetHeight = 200;
int targetWidth = 200;
try {
return Picasso.get()
.load(String.valueOf(imageUrl)).get();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}.execute().get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e)
{
e.printStackTrace();
}
return imageBitmap;
}
@Override
protected void onHandleWork(Intent intent) {
Log.d(getClass().getSimpleName(), "onHandleIntent, started handling a notification event");
try {
String action = intent.getAction();
if (ACTION_START.equals(action)) {
processStartNotification();
}
if (ACTION_DELETE.equals(action)) {
processDeleteNotification(intent);
}
if (ACTION_NOT_GOING.equals(action)) {
String eventID = intent.getStringExtra(Constants.EVENT_ID);
String sessionID = intent.getStringExtra(Constants.SESSION_ID);
ServiceGenerator serviceGenerator = new ServiceGenerator(getApplicationContext());
RetrofitInterface retrofitInterface = serviceGenerator.getRetrofitInterface();
retrofitInterface.updateUserEventStatus("sessionid=" + sessionID, eventID, Constants.STATUS_NOT_GOING).enqueue(new Callback<Void>() {
@Override
public void onResponse(Call<Void> call, Response<Void> response) {
}
@Override
public void onFailure(Call<Void> call, Throwable t) {
}
});
manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(intent.getIntExtra("NOTIFICATION_ID", -1));
}
if (ACTION_NAVIGATE.equals(action)) {
manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(intent.getIntExtra("NOTIFICATION_ID", -1));
double latitude = intent.getDoubleExtra(Constants.EVENT_LATITUDE, 0);
double longitude = intent.getDoubleExtra(Constants.EVENT_LONGITUDE, 0);
Uri gmmIntentUri = Uri.parse("google.navigation:q=" + latitude + "," + longitude + "&mode=w");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
startActivity(mapIntent);
}
} finally {
}
}
private void processDeleteNotification(Intent intent) {
// Log something?
}
private void processStartNotification() {
SessionManager sessionManager = new SessionManager(this);
String userID = sessionManager.getUserID();
final String sessionID = sessionManager.getSessionID();
ServiceGenerator serviceGenerator = new ServiceGenerator(getApplicationContext());
RetrofitInterface retrofitInterface = serviceGenerator.getRetrofitInterface();
retrofitInterface.getUser("sessionid=" + sessionID, userID).enqueue(new Callback<User>() {
@Override
public void onResponse(Call<User> call, Response<User> response) {
if (response.isSuccessful()) {
User user = response.body();
List<Event> goingEventList = user.getUserGoingEvents();
if (goingEventList != null) {
for (Event event : goingEventList) {
long timediff = getDateDiff(new Date(), event.getEventStartTime(), TimeUnit.MINUTES);
if (timediff <= 30 && timediff > 0) { // Change this to 30*10000 for testing
NOTIFICATION_ID = event.getEventID().hashCode();
final NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), getResources().getString(R.string.default_notification_channel_id));
builder.setContentTitle(event.getEventName())
.setAutoCancel(true)
.setColor(getResources().getColor(R.color.colorAccent))
.setContentText("Event is about to start in " + getDateDiff(new Date(), event.getEventStartTime(), TimeUnit.MINUTES) + ((getDateDiff(new Date(), event.getEventStartTime(), TimeUnit.MINUTES) == 1) ? " minute." : " minutes."))
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.lotus_white))
.setSmallIcon(R.drawable.lotus_white)
.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(getImageBitmapFromURL(event.getEventImageURL())));
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.setAction(ACTION_OPEN_EVENT);
intent.putExtra(Constants.SESSION_ID, sessionID);
intent.putExtra(Constants.EVENT_JSON, event.toString());
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),
NOTIFICATION_ID,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pendingIntent);
builder.setDeleteIntent(NotificationEventReceiver.getDeleteIntent(getApplicationContext()));
if(event.getEventVenues().size() > 0)
{
Intent navigateIntent = new Intent(getApplicationContext(), NotificationIntentService.class);
navigateIntent.setAction(ACTION_NAVIGATE);
navigateIntent.putExtra(Constants.EVENT_ID, event.getEventID());
navigateIntent.putExtra(Constants.EVENT_LATITUDE, event.getEventVenues().get(0).getVenueLatitude());
navigateIntent.putExtra(Constants.EVENT_LONGITUDE, event.getEventVenues().get(0).getVenueLongitude());
navigateIntent.putExtra("NOTIFICATION_ID", NOTIFICATION_ID);
PendingIntent navigatePendingIntent = PendingIntent.getService(getApplicationContext(), 0, navigateIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.addAction(R.drawable.baseline_navigation_white_24, "Navigate", navigatePendingIntent);
}
Intent notGoingIntent = new Intent(getApplicationContext(), NotificationIntentService.class);
notGoingIntent.setAction(ACTION_NOT_GOING);
notGoingIntent.putExtra(Constants.SESSION_ID, sessionID);
notGoingIntent.putExtra(Constants.EVENT_ID, event.getEventID());
notGoingIntent.putExtra("NOTIFICATION_ID", NOTIFICATION_ID);
PendingIntent notGoingPendingIntent = PendingIntent.getService(getApplicationContext(), 0, notGoingIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.addAction(R.drawable.baseline_close_white_24, "Not Going", notGoingPendingIntent);
manager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = builder.build();
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
manager.notify(NOTIFICATION_ID, notification);
}
}
}
}
}
@Override
public void onFailure(Call<User> call, Throwable t) {
}
});
}
}
\ No newline at end of file
package app.insti.notifications;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public final class NotificationServiceStarterReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
NotificationEventReceiver.setupAlarm(context);
}
}
\ No newline at end of file
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