diff --git a/app/src/fdroid/java/fr.gouv.etalab.mastodon/activities/MainActivity.java b/app/src/fdroid/java/fr.gouv.etalab.mastodon/activities/MainActivity.java
index da5a9ae3e..a31d8b211 100644
--- a/app/src/fdroid/java/fr.gouv.etalab.mastodon/activities/MainActivity.java
+++ b/app/src/fdroid/java/fr.gouv.etalab.mastodon/activities/MainActivity.java
@@ -15,9 +15,11 @@
package fr.gouv.etalab.mastodon.activities;
import android.annotation.SuppressLint;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.PorterDuff;
@@ -31,6 +33,7 @@ import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat;
+import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.SearchView;
@@ -67,8 +70,11 @@ import java.util.Locale;
import java.util.Stack;
import java.util.concurrent.TimeUnit;
+import fr.gouv.etalab.mastodon.asynctasks.StreamingUserAsyncTask;
import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoByIDAsyncTask;
import fr.gouv.etalab.mastodon.client.Entities.Account;
+import fr.gouv.etalab.mastodon.client.Entities.Notification;
+import fr.gouv.etalab.mastodon.client.Entities.Status;
import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
import fr.gouv.etalab.mastodon.fragments.DisplayAccountsFragment;
import fr.gouv.etalab.mastodon.fragments.DisplayFollowRequestSentFragment;
@@ -76,6 +82,7 @@ import fr.gouv.etalab.mastodon.fragments.DisplayNotificationsFragment;
import fr.gouv.etalab.mastodon.fragments.DisplayScheduledTootsFragment;
import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.interfaces.OnUpdateAccountInfoInterface;
+import fr.gouv.etalab.mastodon.services.StreamingService;
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
import fr.gouv.etalab.mastodon.asynctasks.RetrieveAccountsAsyncTask;
import fr.gouv.etalab.mastodon.asynctasks.RetrieveFeedsAsyncTask;
@@ -119,14 +126,53 @@ public class MainActivity extends AppCompatActivity
private DisplayStatusFragment homeFragment;
private DisplayNotificationsFragment notificationsFragment;
-
-
+ private BroadcastReceiver receive_data;
+ private int newNotif, newHome;
public MainActivity() {
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ receive_data = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Bundle b = intent.getExtras();
+ StreamingUserAsyncTask.EventStreaming eventStreaming = (StreamingUserAsyncTask.EventStreaming) intent.getSerializableExtra("eventStreaming");
+
+ if( eventStreaming == StreamingUserAsyncTask.EventStreaming.NOTIFICATION){
+ Notification notification = b.getParcelable("data");
+ if(notificationsFragment != null && notificationsFragment.getUserVisibleHint()){
+ notificationsFragment.updateData(notification);
+ }else{
+ newNotif++;
+ updateNotifCounter();
+ notificationsFragment.updateData(notification);
+ }
+ }else if(eventStreaming == StreamingUserAsyncTask.EventStreaming.UPDATE){
+ Status status = b.getParcelable("data");
+ if(homeFragment != null && homeFragment.getUserVisibleHint()){
+ homeFragment.updateData(status);
+ }else{
+ newHome++;
+ updateHomeCounter();
+ homeFragment.updateData(status);
+ }
+ }else if(eventStreaming == StreamingUserAsyncTask.EventStreaming.DELETE){
+ String id = b.getString("id");
+ if(notificationsFragment != null && notificationsFragment.getUserVisibleHint()){
+
+ }else{
+
+ }
+ }
+ }
+ };
+ LocalBroadcastManager.getInstance(this).registerReceiver(receive_data, new IntentFilter(Helper.RECEIVE_DATA));
+
+ newNotif = 0;
+ newHome = 0;
+
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
final int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
@@ -145,7 +191,7 @@ public class MainActivity extends AppCompatActivity
finish();
return;
}
-
+ startService(new Intent(getApplicationContext(), StreamingService.class));
Helper.fillMapEmoji(getApplicationContext());
//Here, the user is authenticated
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
@@ -203,7 +249,6 @@ public class MainActivity extends AppCompatActivity
(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
- final boolean bubbles = sharedpreferences.getBoolean(Helper.SET_BUBBLE_COUNTER, true);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
@@ -226,16 +271,19 @@ public class MainActivity extends AppCompatActivity
case 0:
item = navigationView.getMenu().findItem(R.id.nav_home);
fragmentTag = "HOME_TIMELINE";
- if( bubbles && homeFragment != null)
- homeFragment.refreshData();
- updateHomeCounter(0);
+ newHome = 0;
+ if( homeFragment != null)
+ homeFragment.refresh();
+ updateHomeCounter();
break;
case 1:
fragmentTag = "NOTIFICATIONS";
item = navigationView.getMenu().findItem(R.id.nav_notification);
- updateNotifCounter(0);
- if( bubbles && notificationsFragment != null)
- notificationsFragment.refreshData();
+ newNotif = 0;
+
+ if( notificationsFragment != null)
+ notificationsFragment.refresh();
+ updateNotifCounter();
break;
case 2:
fragmentTag = "LOCAL_TIMELINE";
@@ -805,22 +853,23 @@ public class MainActivity extends AppCompatActivity
@Override
public void onResume(){
super.onResume();
- SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
- boolean bubbles = sharedpreferences.getBoolean(Helper.SET_BUBBLE_COUNTER, true);
- if( bubbles){
- Handler handler = new Handler();
- handler.postDelayed(new Runnable() {
- @Override
- public void run() {refreshData();}
- }, 1000);
- }
+ MainActivity.activityResumed();
//Proceeds to update of the authenticated account
if(Helper.isLoggedIn(getApplicationContext()))
new UpdateAccountInfoByIDAsyncTask(getApplicationContext(), MainActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
+ @Override
+ protected void onPause() {
+ super.onPause();
+ MainActivity.activityPaused();
+ }
-
+ @Override
+ public void onDestroy(){
+ super.onDestroy();
+ LocalBroadcastManager.getInstance(this).unregisterReceiver(receive_data);
+ }
@SuppressWarnings("StatementWithEmptyBody")
@Override
@@ -1008,40 +1057,8 @@ public class MainActivity extends AppCompatActivity
}
}
- private void refreshData(){
- final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
- String prefKeyOauthTokenT = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null);
- SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
- Account account = new AccountDAO(getApplicationContext(), db).getAccountByToken(prefKeyOauthTokenT);
- if( account != null){
- String last_refresh = sharedpreferences.getString(Helper.LAST_BUBBLE_REFRESH_NOTIF + account.getId(), null);
- Date last_refresh_date = Helper.stringToDate(getApplicationContext(), last_refresh);
- if (last_refresh_date == null || (new Date().getTime() - last_refresh_date.getTime()) >= TimeUnit.SECONDS.toMillis(60)) {
-
- if( notificationsFragment != null ){
- notificationsFragment.update();
- SharedPreferences.Editor editor = sharedpreferences.edit();
- editor.putString(Helper.LAST_BUBBLE_REFRESH_NOTIF+ account.getId(),Helper.dateToString(getApplicationContext(), new Date()));
- editor.apply();
- }
- }
-
- last_refresh = sharedpreferences.getString(Helper.LAST_BUBBLE_REFRESH_HOME + account.getId(), null);
- last_refresh_date = Helper.stringToDate(getApplicationContext(), last_refresh);
-
- if (last_refresh_date == null || (new Date().getTime() - last_refresh_date.getTime()) >= TimeUnit.SECONDS.toMillis(60)) {
- if( homeFragment != null ){
- homeFragment.update();
- SharedPreferences.Editor editor = sharedpreferences.edit();
- editor.putString(Helper.LAST_BUBBLE_REFRESH_HOME+ account.getId(),Helper.dateToString(getApplicationContext(), new Date()));
- editor.apply();
- }
- }
- }
- }
-
- public void updateHomeCounter(int newHomeCount){
+ public void updateHomeCounter(){
if( tabLayout.getTabAt(0) == null )
return;
//noinspection ConstantConditions
@@ -1049,8 +1066,8 @@ public class MainActivity extends AppCompatActivity
if( tabHome == null)
return;
TextView tabCounterHome = (TextView) tabHome.findViewById(R.id.tab_counter);
- tabCounterHome.setText(String.valueOf(newHomeCount));
- if( newHomeCount > 0){
+ tabCounterHome.setText(String.valueOf(newHome));
+ if( newHome > 0){
//New data are available
//The fragment is not displayed, so the counter is displayed
if( tabLayout.getSelectedTabPosition() != 0)
@@ -1062,7 +1079,7 @@ public class MainActivity extends AppCompatActivity
}
}
- public void updateNotifCounter(int newNotifCount){
+ public void updateNotifCounter(){
if(tabLayout.getTabAt(1) == null)
return;
//noinspection ConstantConditions
@@ -1070,8 +1087,8 @@ public class MainActivity extends AppCompatActivity
if( tabNotif == null)
return;
TextView tabCounterNotif = (TextView) tabNotif.findViewById(R.id.tab_counter);
- tabCounterNotif.setText(String.valueOf(newNotifCount));
- if( newNotifCount > 0){
+ tabCounterNotif.setText(String.valueOf(newNotif));
+ if( newNotif > 0){
if( tabLayout.getSelectedTabPosition() != 1)
tabCounterNotif.setVisibility(View.VISIBLE);
else
@@ -1081,4 +1098,18 @@ public class MainActivity extends AppCompatActivity
}
}
+ public static boolean isActivityVisible() {
+ return activityVisible;
+ }
+
+ private static void activityResumed() {
+ activityVisible = true;
+ }
+
+ private static void activityPaused() {
+ activityVisible = false;
+ }
+
+ private static boolean activityVisible;
+
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 72d3b2012..5c0910447 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -34,6 +34,9 @@
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="@style/AppThemeDark">
+
{
this.max_id = max_id;
this.listener = onRetrieveFeedsInterface;
this.refreshData = true;
- updateTimeRefresh();
-
}
public RetrieveFeedsAsyncTask(Context context, Type action, String targetedID, String max_id, boolean showMediaOnly, OnRetrieveFeedsInterface onRetrieveFeedsInterface){
@@ -73,7 +66,6 @@ public class RetrieveFeedsAsyncTask extends AsyncTask {
this.targetedID = targetedID;
this.showMediaOnly = showMediaOnly;
this.refreshData = true;
- updateTimeRefresh();
}
public RetrieveFeedsAsyncTask(Context context, Type action, String tag, String targetedID, String max_id, OnRetrieveFeedsInterface onRetrieveFeedsInterface){
this.context = context;
@@ -83,17 +75,8 @@ public class RetrieveFeedsAsyncTask extends AsyncTask {
this.targetedID = targetedID;
this.tag = tag;
this.refreshData = true;
- updateTimeRefresh();
}
- public RetrieveFeedsAsyncTask(Context context, Type action, String max_id, boolean refreshData, OnRetrieveFeedsInterface onRetrieveFeedsInterface){
- this.context = context;
- this.action = action;
- this.max_id = max_id;
- this.listener = onRetrieveFeedsInterface;
- this.refreshData = refreshData;
- updateTimeRefresh();
- }
@Override
protected Void doInBackground(Void... params) {
@@ -134,14 +117,4 @@ public class RetrieveFeedsAsyncTask extends AsyncTask {
protected void onPostExecute(Void result) {
listener.onRetrieveFeeds(apiResponse, refreshData);
}
-
- private void updateTimeRefresh(){
- if( action == Type.HOME) {
- final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
- SharedPreferences.Editor editor = sharedpreferences.edit();
- String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
- editor.putString(Helper.LAST_BUBBLE_REFRESH_HOME + userId, Helper.dateToString(context, new Date()));
- editor.apply();
- }
- }
}
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveNotificationsAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveNotificationsAsyncTask.java
index e59bb8417..6b7a8b7c6 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveNotificationsAsyncTask.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveNotificationsAsyncTask.java
@@ -15,14 +15,9 @@
package fr.gouv.etalab.mastodon.asynctasks;
import android.content.Context;
-import android.content.SharedPreferences;
import android.os.AsyncTask;
-
-import java.util.Date;
-
import fr.gouv.etalab.mastodon.client.API;
import fr.gouv.etalab.mastodon.client.APIResponse;
-import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveNotificationsInterface;
@@ -51,20 +46,8 @@ public class RetrieveNotificationsAsyncTask extends AsyncTask
this.userId = userId;
this.token = token;
this.refreshData = true;
- updateTimeRefresh();
}
- public RetrieveNotificationsAsyncTask(Context context, String instance, String token, String max_id, String acct, String userId, boolean refreshData, OnRetrieveNotificationsInterface onRetrieveNotificationsInterface){
- this.context = context;
- this.max_id = max_id;
- this.listener = onRetrieveNotificationsInterface;
- this.acct = acct;
- this.instance = instance;
- this.userId = userId;
- this.token = token;
- this.refreshData = refreshData;
- updateTimeRefresh();
- }
@Override
protected Void doInBackground(Void... params) {
@@ -82,10 +65,4 @@ public class RetrieveNotificationsAsyncTask extends AsyncTask
listener.onRetrieveNotifications(apiResponse, acct, userId, refreshData);
}
- private void updateTimeRefresh(){
- final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
- SharedPreferences.Editor editor = sharedpreferences.edit();
- editor.putString(Helper.LAST_BUBBLE_REFRESH_NOTIF+ userId,Helper.dateToString(context, new Date()));
- editor.apply();
- }
}
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/StreamingUserAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/StreamingUserAsyncTask.java
new file mode 100644
index 000000000..333ca8a8a
--- /dev/null
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/StreamingUserAsyncTask.java
@@ -0,0 +1,153 @@
+/* Copyright 2017 Thomas Schneider
+ *
+ * This file is a part of Mastalab
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with Mastalab; if not,
+ * see . */
+package fr.gouv.etalab.mastodon.asynctasks;
+
+
+import android.os.AsyncTask;
+import android.util.Log;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.HashMap;
+
+import fr.gouv.etalab.mastodon.helper.Helper;
+import fr.gouv.etalab.mastodon.interfaces.OnRetrieveStreamingInterface;
+
+
+/**
+ * Created by Thomas on 28/08/2017.
+ * Calls user streaming api
+ */
+
+public class StreamingUserAsyncTask extends AsyncTask {
+
+ private String instance, token, acct, userId;
+ private OnRetrieveStreamingInterface listener;
+ private static HashMap connectionHashMap;
+ private EventStreaming lastEvent;
+
+
+ public StreamingUserAsyncTask(String instance, String token, String acct, String userId, OnRetrieveStreamingInterface onRetrieveStreamingInterface){
+ this.instance = instance;
+ this.token = token;
+ this.acct = acct;
+ this.userId = userId;
+ this.listener = onRetrieveStreamingInterface;
+ }
+ public enum EventStreaming{
+ UPDATE,
+ NOTIFICATION,
+ DELETE,
+ NONE
+ }
+
+
+ @Override
+ protected Object doInBackground(Object[] params){
+ if( connectionHashMap == null)
+ connectionHashMap = new HashMap<>();
+
+ boolean connectionAlive = false;
+ if( connectionHashMap.get(acct+userId) != null) {
+ try {
+ connectionAlive = (connectionHashMap.get(acct + userId).getResponseCode() == 200);
+ } catch (IOException e) {
+ connectionAlive = false;
+ }
+ }
+
+ if( !connectionAlive) {
+ try {
+ URL url = new URL("https://" + this.instance + "/api/v1/streaming/user");
+ HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
+ urlConnection.setRequestProperty("Content-Type", "application/json");
+ urlConnection.setRequestProperty("Authorization", "Bearer " + this.token);
+ urlConnection.setRequestProperty("Connection", "Keep-Alive");
+ urlConnection.setRequestProperty("Keep-Alive", "header");
+ connectionHashMap.put(acct+userId, urlConnection);
+
+ InputStream inputStream = new BufferedInputStream(urlConnection.getInputStream());
+ readStream(inputStream);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return null;
+ }
+
+ private String readStream(InputStream inputStream) {
+ BufferedReader reader = null;
+ try{
+ reader = new BufferedReader(new InputStreamReader(inputStream));
+ String event;
+ EventStreaming eventStreaming = null;
+ while((event = reader.readLine()) != null){
+ if( lastEvent == EventStreaming.NONE || lastEvent == null) {
+ switch (event.trim()) {
+ case "event: update":
+ lastEvent = EventStreaming.UPDATE;
+ break;
+ case "event: notification":
+ lastEvent = EventStreaming.NOTIFICATION;
+ break;
+ case "event: delete":
+ lastEvent = EventStreaming.DELETE;
+ break;
+ default:
+ lastEvent = EventStreaming.NONE;
+ }
+ }else{
+ event = event.replace("data: ","");
+ if(lastEvent == EventStreaming.UPDATE) {
+ eventStreaming = EventStreaming.UPDATE;
+ }else if(lastEvent == EventStreaming.NOTIFICATION) {
+ eventStreaming = EventStreaming.NOTIFICATION;
+ }else if( lastEvent == EventStreaming.DELETE) {
+ eventStreaming = EventStreaming.DELETE;
+ event = "{id:" + event + "}";
+ }
+ lastEvent = EventStreaming.NONE;
+ try {
+ JSONObject eventJson = new JSONObject(event);
+ listener.onRetrieveStreaming(eventStreaming, eventJson, acct, userId);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+ }catch (Exception e){
+ e.printStackTrace();
+ }finally {
+ if(reader != null){
+ try{
+ reader.close();
+ }catch (IOException e){
+ e.printStackTrace();
+ }
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java b/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java
index baa7b2d60..312c42e4b 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java
@@ -188,12 +188,12 @@ public class API {
get("/accounts/verify_credentials", null, new JsonHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
- account = parseAccountResponse(response);
+ account = parseAccountResponse(context, response);
}
@Override
public void onSuccess(int statusCode, Header[] headers, JSONArray response) {
try {
- account = parseAccountResponse(response.getJSONObject(0));
+ account = parseAccountResponse(context, response.getJSONObject(0));
} catch (JSONException e) {
e.printStackTrace();
}
@@ -217,12 +217,12 @@ public class API {
get(String.format("/accounts/%s",accountId), null, new JsonHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
- account = parseAccountResponse(response);
+ account = parseAccountResponse(context, response);
}
@Override
public void onSuccess(int statusCode, Header[] headers, JSONArray response) {
try {
- account = parseAccountResponse(response.getJSONObject(0));
+ account = parseAccountResponse(context, response.getJSONObject(0));
} catch (JSONException e) {
e.printStackTrace();
}
@@ -330,7 +330,7 @@ public class API {
get(String.format("/accounts/%s/statuses", accountId), params, new JsonHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
- Status status = parseStatuses(response);
+ Status status = parseStatuses(context, response);
statuses.add(status);
apiResponse.setSince_id(findSinceId(headers));
apiResponse.setMax_id(findMaxId(headers));
@@ -365,7 +365,7 @@ public class API {
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
apiResponse.setSince_id(findSinceId(headers));
apiResponse.setMax_id(findMaxId(headers));
- Status status = parseStatuses(response);
+ Status status = parseStatuses(context, response);
statuses.add(status);
}
@Override
@@ -445,7 +445,7 @@ public class API {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
- Status status = parseStatuses(response);
+ Status status = parseStatuses(context, response);
statuses.add(status);
apiResponse.setSince_id(findSinceId(headers));
apiResponse.setMax_id(findMaxId(headers));
@@ -500,7 +500,7 @@ public class API {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
- Status status = parseStatuses(response);
+ Status status = parseStatuses(context, response);
statuses.add(status);
apiResponse.setSince_id(findSinceId(headers));
apiResponse.setMax_id(findMaxId(headers));
@@ -557,7 +557,7 @@ public class API {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
- Status status = parseStatuses(response);
+ Status status = parseStatuses(context, response);
statuses.add(status);
apiResponse.setSince_id(findSinceId(headers));
apiResponse.setMax_id(findMaxId(headers));
@@ -641,7 +641,7 @@ public class API {
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
apiResponse.setSince_id(findSinceId(headers));
apiResponse.setMax_id(findMaxId(headers));
- Account account = parseAccountResponse(response);
+ Account account = parseAccountResponse(context, response);
accounts.add(account);
}
@Override
@@ -692,7 +692,7 @@ public class API {
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
apiResponse.setSince_id(findSinceId(headers));
apiResponse.setMax_id(findMaxId(headers));
- Account account = parseAccountResponse(response);
+ Account account = parseAccountResponse(context, response);
accounts.add(account);
}
@Override
@@ -741,7 +741,7 @@ public class API {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
- Status status = parseStatuses(response);
+ Status status = parseStatuses(context, response);
statuses.add(status);
apiResponse.setSince_id(findSinceId(headers));
apiResponse.setMax_id(findMaxId(headers));
@@ -945,7 +945,7 @@ public class API {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
- Status statusreturned = parseStatuses(response);
+ Status statusreturned = parseStatuses(context, response);
statuses.add(statusreturned);
apiResponse.setSince_id(findSinceId(headers));
apiResponse.setMax_id(findMaxId(headers));
@@ -1041,7 +1041,7 @@ public class API {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
- Notification notification = parseNotificationResponse(response);
+ Notification notification = parseNotificationResponse(context, response);
notifications.add(notification);
apiResponse.setSince_id(findSinceId(headers));
apiResponse.setMax_id(findMaxId(headers));
@@ -1130,7 +1130,7 @@ public class API {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
accounts = new ArrayList<>();
- account = parseAccountResponse(response);
+ account = parseAccountResponse(context, response);
accounts.add(account);
apiResponse.setSince_id(findSinceId(headers));
apiResponse.setMax_id(findMaxId(headers));
@@ -1170,7 +1170,7 @@ public class API {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
accounts = new ArrayList<>();
- account = parseAccountResponse(response);
+ account = parseAccountResponse(context, response);
accounts.add(account);
apiResponse.setSince_id(findSinceId(headers));
apiResponse.setMax_id(findMaxId(headers));
@@ -1236,7 +1236,7 @@ public class API {
while (i < jsonArray.length() ){
JSONObject resobj = jsonArray.getJSONObject(i);
- Status status = parseStatuses(resobj);
+ Status status = parseStatuses(context, resobj);
i++;
statuses.add(status);
}
@@ -1253,7 +1253,7 @@ public class API {
* @return Status
*/
@SuppressWarnings("InfiniteRecursion")
- private Status parseStatuses(JSONObject resobj){
+ public static Status parseStatuses(Context context, JSONObject resobj){
Status status = new Status();
try {
status.setId(resobj.get("id").toString());
@@ -1315,14 +1315,14 @@ public class API {
}
status.setTags(tags);
- status.setAccount(parseAccountResponse(resobj.getJSONObject("account")));
+ status.setAccount(parseAccountResponse(context, resobj.getJSONObject("account")));
status.setContent(resobj.get("content").toString());
status.setFavourites_count(Integer.valueOf(resobj.get("favourites_count").toString()));
status.setReblogs_count(Integer.valueOf(resobj.get("reblogs_count").toString()));
status.setReblogged(Boolean.valueOf(resobj.get("reblogged").toString()));
status.setFavourited(Boolean.valueOf(resobj.get("favourited").toString()));
try{
- status.setReblog(parseStatuses(resobj.getJSONObject("reblog")));
+ status.setReblog(parseStatuses(context, resobj.getJSONObject("reblog")));
}catch (Exception ignored){}
} catch (JSONException e) {
e.printStackTrace();
@@ -1355,7 +1355,7 @@ public class API {
* @param resobj JSONObject
* @return Account
*/
- private Account parseAccountResponse(JSONObject resobj){
+ private static Account parseAccountResponse(Context context, JSONObject resobj){
Account account = new Account();
try {
@@ -1392,7 +1392,7 @@ public class API {
int i = 0;
while (i < jsonArray.length() ) {
JSONObject resobj = jsonArray.getJSONObject(i);
- Account account = parseAccountResponse(resobj);
+ Account account = parseAccountResponse(context, resobj);
accounts.add(account);
i++;
}
@@ -1416,7 +1416,7 @@ public class API {
Account account = null;
while (i < jsonArray.length() ) {
JSONObject resobj = jsonArray.getJSONObject(i);
- account = parseAccountResponse(resobj);
+ account = parseAccountResponse(context, resobj);
if( account.getAcct().contains(Helper.DEVELOPER_INSTANCE))
accounts.add(account);
i++;
@@ -1500,16 +1500,16 @@ public class API {
* @param resobj JSONObject
* @return Account
*/
- private Notification parseNotificationResponse(JSONObject resobj){
+ public static Notification parseNotificationResponse(Context context, JSONObject resobj){
Notification notification = new Notification();
try {
notification.setId(resobj.get("id").toString());
notification.setType(resobj.get("type").toString());
notification.setCreated_at(Helper.mstStringToDate(context, resobj.get("created_at").toString()));
- notification.setAccount(parseAccountResponse(resobj.getJSONObject("account")));
+ notification.setAccount(parseAccountResponse(context, resobj.getJSONObject("account")));
try{
- notification.setStatus(parseStatuses(resobj.getJSONObject("status")));
+ notification.setStatus(parseStatuses(context, resobj.getJSONObject("status")));
}catch (Exception ignored){}
notification.setCreated_at(Helper.mstStringToDate(context, resobj.get("created_at").toString()));
} catch (JSONException e) {
@@ -1531,7 +1531,7 @@ public class API {
while (i < jsonArray.length() ) {
JSONObject resobj = jsonArray.getJSONObject(i);
- Notification notification = parseNotificationResponse(resobj);
+ Notification notification = parseNotificationResponse(context, resobj);
notifications.add(notification);
i++;
}
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/client/Entities/Notification.java b/app/src/main/java/fr/gouv/etalab/mastodon/client/Entities/Notification.java
index a8cc8f74d..c415088dc 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/client/Entities/Notification.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/client/Entities/Notification.java
@@ -15,13 +15,16 @@
package fr.gouv.etalab.mastodon.client.Entities;
+import android.os.Parcel;
+import android.os.Parcelable;
+
import java.util.Date;
/**
* Created by Thomas on 23/04/2017.
*/
-public class Notification {
+public class Notification implements Parcelable {
private String id;
private String type;
@@ -29,6 +32,27 @@ public class Notification {
private Account account;
private Status status;
+ protected Notification(Parcel in) {
+ id = in.readString();
+ type = in.readString();
+ account = in.readParcelable(Account.class.getClassLoader());
+ status = in.readParcelable(Status.class.getClassLoader());
+ }
+
+ public Notification(){};
+
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public Notification createFromParcel(Parcel in) {
+ return new Notification(in);
+ }
+
+ @Override
+ public Notification[] newArray(int size) {
+ return new Notification[size];
+ }
+ };
+
public String getId() {
return id;
}
@@ -68,4 +92,17 @@ public class Notification {
public void setStatus(Status status) {
this.status = status;
}
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(id);
+ dest.writeString(type);
+ dest.writeParcelable(account, flags);
+ dest.writeParcelable(status, flags);
+ }
}
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayNotificationsFragment.java b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayNotificationsFragment.java
index 6823f340b..45b374f46 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayNotificationsFragment.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayNotificationsFragment.java
@@ -37,6 +37,7 @@ import java.util.List;
import fr.gouv.etalab.mastodon.activities.MainActivity;
import fr.gouv.etalab.mastodon.client.APIResponse;
import fr.gouv.etalab.mastodon.client.Entities.Account;
+import fr.gouv.etalab.mastodon.client.Entities.Status;
import fr.gouv.etalab.mastodon.drawers.NotificationsListAdapter;
import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
@@ -145,13 +146,6 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
for(Notification notification: notificationsTmp){
notifications.add(notification);
}
- //The user clicked on the banner to refresh values so, the pointer is changed
- if( notificationsTmp.size() > 0 ) {
- SharedPreferences.Editor editor = sharedpreferences.edit();
- String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
- editor.putString(Helper.LAST_MAX_ID_BUBBLE_NOTIF + userId, notificationsTmp.get(0).getId());
- editor.apply();
- }
notificationsListAdapter = new NotificationsListAdapter(context,isOnWifi, behaviorWithAttachments, notifications);
lv_notifications.setAdapter(notificationsListAdapter);
if( notificationsTmp.size() > 0 && textviewNoAction.getVisibility() == View.VISIBLE)
@@ -205,64 +199,11 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
return;
}
SharedPreferences.Editor editor = sharedpreferences.edit();
- editor.putString(Helper.LAST_BUBBLE_REFRESH_NOTIF+ userId,Helper.dateToString(context, new Date()));
- editor.apply();
- String bubble_max_id = sharedpreferences.getString(Helper.LAST_MAX_ID_BUBBLE_NOTIF + userId, null);
List notifications = apiResponse.getNotifications();
since_id = apiResponse.getSince_id();
max_id = apiResponse.getMax_id();
//The initial call comes from a classic tab refresh
- if( refreshData ) {
- manageNotifications(notifications, max_id, since_id);
- //The current tab is displayed, so user is supposed to have seen the notifications
- if( since_id != null && displayNotificationsFragment.getUserVisibleHint() && firstLoad) {
- editor.putString(Helper.LAST_MAX_ID_BUBBLE_NOTIF + userId, since_id);
- editor.apply();
- }else if(!displayNotificationsFragment.getUserVisibleHint()){
- //The refresh was done automatically, but the fragment was not displayed in viewpager
- //So the bubble counter will be displayed
- int countData = 0;
- //Retrieves new notification count
- if( bubble_max_id != null) {
- for (Notification nt : notifications) {
- if (nt.getId().trim().equals(bubble_max_id.trim()))
- break;
- countData++;
- }
- }
- ((MainActivity)context).updateNotifCounter(countData);
- }
- }else { //Here, new values have been retrieved on the onResume call (forced mode)
- int countData = 0;
- if( bubble_max_id != null) {
- for (Notification nt : notifications) {
- if (nt.getId().trim().equals(bubble_max_id.trim()))
- break;
- countData++;
- }
- }
- if( notifications != null && notifications.size() > 0 && countData > 0) {
- max_id = null;
- firstLoad = true;
- notificationsTmp = new ArrayList<>();
- for (Notification tmpNotification : notifications) {
- this.notificationsTmp.add(tmpNotification);
- }
- //New notifications will be counted
- //The fragment is not displayed, so the bubble counter should be shown
- if (!displayNotificationsFragment.getUserVisibleHint()) {
- ((MainActivity) context).updateNotifCounter(countData);
- } else { //The current fragment is visible, but for avoiding to populate with new values
- // a message will be displayed at the bottom requiring a click to display these new values
- new_data.setVisibility(View.VISIBLE);
- }
- }
- }
- }
-
- private void manageNotifications(List notifications, String max_id, String since_id){
flag_loading = (max_id == null );
- final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
if( !swiped && firstLoad && (notifications == null || notifications.size() == 0))
textviewNoAction.setVisibility(View.VISIBLE);
else
@@ -284,11 +225,10 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
//Store last notification id to avoid to notify for those that have been already seen
if( notifications != null && notifications.size() > 0) {
//acct is null as userId when used in Fragment, data need to be retrieved via shared preferences and db
- String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
+ userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
Account currentAccount = new AccountDAO(context, db).getAccountByID(userId);
if( currentAccount != null && firstLoad && since_id != null){
- SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + currentAccount.getId(), since_id);
editor.apply();
}
@@ -296,40 +236,40 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
firstLoad = false;
}
+
public void scrollToTop(){
if( lv_notifications != null)
lv_notifications.setAdapter(notificationsListAdapter);
}
- public void update(){
- if( context != null){
- asyncTask = new RetrieveNotificationsAsyncTask(context, null, null, null, null, null, false, DisplayNotificationsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+
+ public void updateData(Notification notification){
+ if( notificationsTmp != null && notificationsTmp.size() > 0){
+ notificationsTmp.add(0,notification);
+ }else {
+ notificationsTmp = new ArrayList<>();
+ for(Notification notificationTmp: this.notifications){
+ notificationsTmp.add(notificationTmp);
+ }
+ notificationsTmp.add(0,notification);
}
- }
-
- public void refreshData(){
-
- final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
-
- if(context != null && this.notificationsTmp != null && this.notificationsTmp.size() > 0){
- boolean isOnWifi = Helper.isOnWIFI(context);
- int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
- notifications = new ArrayList<>();
- for(Notification notification: this.notificationsTmp){
- notifications.add(notification);
- }
- if( textviewNoAction.getVisibility() == View.VISIBLE)
- textviewNoAction.setVisibility(View.GONE);
- notificationsListAdapter = new NotificationsListAdapter(context,isOnWifi, behaviorWithAttachments, notifications);
- lv_notifications.setAdapter(notificationsListAdapter);
- this.notificationsTmp = new ArrayList<>();
- }
- if( since_id != null){
- //The user clicked on the tab to refresh values so, the pointer is changed
- SharedPreferences.Editor editor = sharedpreferences.edit();
- String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
- editor.putString(Helper.LAST_MAX_ID_BUBBLE_NOTIF + userId, since_id);
- editor.apply();
- }
- }
+ new_data.setVisibility(View.VISIBLE);
+ }
+ public void refresh(){
+ if( notificationsTmp != null){
+ boolean isOnWifi = Helper.isOnWIFI(context);
+ final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
+ int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
+ notifications = new ArrayList<>();
+ for(Notification notification: notificationsTmp){
+ notifications.add(notification);
+ }
+ notificationsListAdapter = new NotificationsListAdapter(context,isOnWifi, behaviorWithAttachments, notifications);
+ lv_notifications.setAdapter(notificationsListAdapter);
+ if( notificationsTmp.size() > 0 && textviewNoAction.getVisibility() == View.VISIBLE)
+ textviewNoAction.setVisibility(View.GONE);
+ }
+ new_data.setVisibility(View.GONE);
+ notificationsTmp = new ArrayList<>();
+ }
}
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayStatusFragment.java b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayStatusFragment.java
index 3aa2e1e6b..400df36f5 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayStatusFragment.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayStatusFragment.java
@@ -229,13 +229,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
for(Status status: statusesTmp){
statuses.add(status);
}
- //The user clicked on the banner to refresh values so, the pointer is changed
- if( statusesTmp.size() > 0 ) {
- SharedPreferences.Editor editor = sharedpreferences.edit();
- String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
- editor.putString(Helper.LAST_MAX_ID_BUBBLE_HOME + userId, statusesTmp.get(0).getId());
- editor.apply();
- }
if( statusesTmp.size() > 0 && textviewNoAction.getVisibility() == View.VISIBLE)
textviewNoAction.setVisibility(View.GONE);
statusListAdapter = new StatusListAdapter(context, type, targetedId, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, statuses);
@@ -271,11 +264,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
for(Status status: statusesTmp){
statuses.add(status);
}
- //The user clicked on the tab to refresh values so, the pointer is changed
- SharedPreferences.Editor editor = sharedpreferences.edit();
- String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
- editor.putString(Helper.LAST_MAX_ID_BUBBLE_HOME + userId, statusesTmp.get(0).getId());
- editor.apply();
statusListAdapter = new StatusListAdapter(context, type, targetedId, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, statuses);
lv_status.setAdapter(statusListAdapter);
statusesTmp = new ArrayList<>();
@@ -315,72 +303,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
List statuses = apiResponse.getStatuses();
since_id = apiResponse.getSince_id();
max_id = apiResponse.getMax_id();
- //Special case for home timeline
- if( type == RetrieveFeedsAsyncTask.Type.HOME){
- //Retrieves some values
- SharedPreferences.Editor editor = sharedpreferences.edit();
- String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
- String bubble_max_id = sharedpreferences.getString(Helper.LAST_MAX_ID_BUBBLE_HOME + userId, null);
- //The initial call comes from a classic tab refresh
- if( refreshData ) {
-
- manageStatus(statuses, max_id, since_id);
- //The current tab is displayed, so user is supposed to have seen status
- if( since_id != null && displayStatusFragment.getUserVisibleHint() && firstLoad) {
- editor.putString(Helper.LAST_MAX_ID_BUBBLE_HOME + userId, since_id);
- editor.apply();
- }else if(!displayStatusFragment.getUserVisibleHint()){
- //Current fragment was loaded but not displayed to the user.
- //So the bubble counter will be displayed
- int countData = 0;
- //Retrieves new status count
- if( bubble_max_id != null) {
- for (Status st : statuses) {
- if (st.getId().trim().equals(bubble_max_id.trim()))
- break;
- countData++;
- }
- }
- ((MainActivity)context).updateHomeCounter(countData);
- }
- }else { //Here, new values have been retrieved on the onResume call (forced mode)
- int countData = 0;
- if( bubble_max_id != null) {
- for (Status st : statuses) {
- if (st.getId().trim().equals(bubble_max_id.trim()))
- break;
- countData++;
- }
- }
-
- if( statuses != null && statuses.size() > 0 && countData > 0) {
- max_id = null;
- firstLoad = true;
- statusesTmp = new ArrayList<>();
- for (Status tmpStatus : statuses) {
- this.statusesTmp.add(tmpStatus);
- }
- //New status will be counted
- //The fragment is not displayed, so the bubble counter should be shown
- if (!displayStatusFragment.getUserVisibleHint()) {
- ((MainActivity) context).updateHomeCounter(countData);
- } else {
- //The current fragment is visible, but for avoiding to populate with new values
- //Values are put in temp and the banned is displayed
- new_data.setVisibility(View.VISIBLE);
- }
- }
- }
- }else {
- manageStatus(statuses, max_id, since_id);
- }
-
-
-
- }
-
- private void manageStatus(List statuses, String max_id, String since_id){
flag_loading = (max_id == null );
if( !swiped && firstLoad && (statuses == null || statuses.size() == 0))
textviewNoAction.setVisibility(View.VISIBLE);
@@ -401,7 +324,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
//Store last toot id for home timeline to avoid to notify for those that have been already seen
if(statuses != null && statuses.size() > 0 && type == RetrieveFeedsAsyncTask.Type.HOME ){
- final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
//acct is null when used in Fragment, data need to be retrieved via shared preferences and db
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
@@ -416,7 +338,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
//Retrieves replies
if(statuses != null && statuses.size() > 0 && type == RetrieveFeedsAsyncTask.Type.HOME ) {
- final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean showPreview = sharedpreferences.getBoolean(Helper.SET_PREVIEW_REPLIES, true);
//Retrieves attached replies to a toot
if (showPreview) {
@@ -425,6 +346,37 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
}
}
+ public void updateData(Status status){
+ if( statusesTmp != null && statusesTmp.size() > 0){
+ statusesTmp.add(0,status);
+ }else {
+ statusesTmp = new ArrayList<>();
+ for(Status statusTmp: this.statuses){
+ statusesTmp.add(statusTmp);
+ }
+ statusesTmp.add(0,status);
+ }
+ new_data.setVisibility(View.VISIBLE);
+ }
+
+ public void refresh(){
+ if( statusesTmp != null){
+ boolean isOnWifi = Helper.isOnWIFI(context);
+ final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
+ int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
+ statuses = new ArrayList<>();
+ for(Status status: statusesTmp){
+ statuses.add(status);
+ }
+ if( statusesTmp.size() > 0 && textviewNoAction.getVisibility() == View.VISIBLE)
+ textviewNoAction.setVisibility(View.GONE);
+ statusListAdapter = new StatusListAdapter(context, type, targetedId, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, statuses);
+ lv_status.setAdapter(statusListAdapter);
+ statusesTmp = new ArrayList<>();
+ }
+ new_data.setVisibility(View.GONE);
+ }
+
public void scrollToTop(){
if( lv_status != null)
lv_status.setAdapter(statusListAdapter);
@@ -444,36 +396,4 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
}
statusListAdapter.notifyDataSetChanged();
}
- public void update() {
- if( context != null) {
- asyncTask = new RetrieveFeedsAsyncTask(context, type, null, false, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- }
-
- public void refreshData(){
- final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
- if(context != null && this.statusesTmp != null && this.statusesTmp.size() > 0){
-
- boolean isOnWifi = Helper.isOnWIFI(context);
- int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS);
- int positionSpinnerTrans = sharedpreferences.getInt(Helper.SET_TRANSLATOR, Helper.TRANS_YANDEX);
-
- statuses = new ArrayList<>();
- for(Status status: statusesTmp){
- statuses.add(status);
- }
- if( textviewNoAction.getVisibility() == View.VISIBLE)
- textviewNoAction.setVisibility(View.GONE);
- statusListAdapter = new StatusListAdapter(context, type, targetedId, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, statuses);
- lv_status.setAdapter(statusListAdapter);
- statusesTmp = new ArrayList<>();
- }
- if( since_id != null){
- //The user clicked on the tab to refresh values so, the pointer is changed
- SharedPreferences.Editor editor = sharedpreferences.edit();
- String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
- editor.putString(Helper.LAST_MAX_ID_BUBBLE_HOME + userId, since_id);
- editor.apply();
- }
- }
}
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/SettingsFragment.java b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/SettingsFragment.java
index 2783602f9..5907cb623 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/SettingsFragment.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/SettingsFragment.java
@@ -94,19 +94,6 @@ public class SettingsFragment extends Fragment {
}
});
- boolean bubble_counter = sharedpreferences.getBoolean(Helper.SET_BUBBLE_COUNTER, true);
-
- final CheckBox set_bubble_counter = (CheckBox) rootView.findViewById(R.id.set_bubble_counter);
- set_bubble_counter.setChecked(bubble_counter);
- set_bubble_counter.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- SharedPreferences.Editor editor = sharedpreferences.edit();
- editor.putBoolean(Helper.SET_BUBBLE_COUNTER, set_bubble_counter.isChecked());
- editor.apply();
- }
- });
-
boolean show_error_messages = sharedpreferences.getBoolean(Helper.SET_SHOW_ERROR_MESSAGES, true);
final CheckBox set_show_error_messages = (CheckBox) rootView.findViewById(R.id.set_show_error_messages);
set_show_error_messages.setChecked(show_error_messages);
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java
index 97d89f078..a703e0db7 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java
@@ -178,10 +178,6 @@ public class Helper {
public static final String SHOW_BATTERY_SAVER_MESSAGE = "show_battery_saver_message";
public static final String LAST_NOTIFICATION_MAX_ID = "last_notification_max_id";
public static final String LAST_HOMETIMELINE_MAX_ID = "last_hometimeline_max_id";
- public static final String LAST_BUBBLE_REFRESH_NOTIF = "last_bubble_refresh_notif";
- public static final String LAST_BUBBLE_REFRESH_HOME = "last_bubble_refresh_home";
- public static final String LAST_MAX_ID_BUBBLE_NOTIF = "last_max_id_bubble_notif";
- public static final String LAST_MAX_ID_BUBBLE_HOME = "last_max_id_bubble_home";
public static final String CLIP_BOARD = "clipboard";
//Notifications
public static final int NOTIFICATION_INTENT = 1;
@@ -205,7 +201,6 @@ public class Helper {
public static final String SET_ICON_SIZE = "set_icon_size";
public static final String SET_PREVIEW_REPLIES = "set_preview_replies";
public static final String SET_PREVIEW_REPLIES_PP = "set_preview_replies_pp";
- public static final String SET_BUBBLE_COUNTER = "set_bubble_counter";
public static final String SET_TRANSLATOR = "set_translator";
public static final int ATTACHMENT_ALWAYS = 1;
@@ -242,8 +237,7 @@ public class Helper {
//Refresh job
- public static final int MINUTES_BETWEEN_NOTIFICATIONS_REFRESH = 15;
- public static final int MINUTES_BETWEEN_HOME_TIMELINE = 30;
+ public static final int MINUTES_BETWEEN_STREAMING_CHECK_ALIVE = 15;
//Intent
public static final String INTENT_ACTION = "intent_action";
@@ -251,6 +245,7 @@ public class Helper {
//Receiver
public static final String SEARCH_VALIDATE_ACCOUNT = "search_validate_account";
public static final String HEADER_ACCOUNT = "header_account";
+ public static final String RECEIVE_DATA = "receive_data";
//User agent
public static final String USER_AGENT = "Mastalab/"+ BuildConfig.VERSION_NAME + " Android/"+ Build.VERSION.RELEASE;
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveStreamingInterface.java b/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveStreamingInterface.java
new file mode 100644
index 000000000..43d5dd8cc
--- /dev/null
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveStreamingInterface.java
@@ -0,0 +1,28 @@
+/* Copyright 2017 Thomas Schneider
+ *
+ * This file is a part of Mastalab
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with Mastalab; if not,
+ * see . */
+package fr.gouv.etalab.mastodon.interfaces;
+
+import org.json.JSONObject;
+
+import fr.gouv.etalab.mastodon.asynctasks.StreamingUserAsyncTask;
+
+
+/**
+ * Created by Thomas on 28/08/2017.
+ * Interface when event from streaming api has been retrieved
+ */
+public interface OnRetrieveStreamingInterface {
+ void onRetrieveStreaming(StreamingUserAsyncTask.EventStreaming event, JSONObject response, String acct, String userId);
+}
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ApplicationJob.java b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ApplicationJob.java
index c087b520f..61b7159bf 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ApplicationJob.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ApplicationJob.java
@@ -26,10 +26,8 @@ public class ApplicationJob implements JobCreator {
@Override
public Job create(String tag) {
switch (tag) {
- case NotificationsSyncJob.NOTIFICATION_REFRESH:
- return new NotificationsSyncJob();
- case HomeTimelineSyncJob.HOME_TIMELINE:
- return new HomeTimelineSyncJob();
+ case StreamingSyncJob.STREAMING:
+ return new StreamingSyncJob();
case ScheduledTootsSyncJob.SCHEDULED_TOOT:
return new ScheduledTootsSyncJob();
default:
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/HomeTimelineSyncJob.java b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/HomeTimelineSyncJob.java
deleted file mode 100644
index 19cd2d843..000000000
--- a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/HomeTimelineSyncJob.java
+++ /dev/null
@@ -1,204 +0,0 @@
-package fr.gouv.etalab.mastodon.jobs;
-/* Copyright 2017 Thomas Schneider
- *
- * This file is a part of Mastalab
- *
- * This program is free software; you can redistribute it and/or modify it under the terms of the
- * GNU General Public License as published by the Free Software Foundation; either version 3 of the
- * License, or (at your option) any later version.
- *
- * Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
- * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- * Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with Mastalab; if not,
- * see . */
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.database.sqlite.SQLiteDatabase;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.os.AsyncTask;
-import android.support.annotation.NonNull;
-import android.view.View;
-
-import com.evernote.android.job.Job;
-import com.evernote.android.job.JobManager;
-import com.evernote.android.job.JobRequest;
-import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
-import com.nostra13.universalimageloader.core.DisplayImageOptions;
-import com.nostra13.universalimageloader.core.ImageLoader;
-import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
-import com.nostra13.universalimageloader.core.assist.FailReason;
-import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
-import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
-
-import java.io.File;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-import fr.gouv.etalab.mastodon.activities.MainActivity;
-import fr.gouv.etalab.mastodon.asynctasks.RetrieveHomeTimelineServiceAsyncTask;
-import fr.gouv.etalab.mastodon.client.APIResponse;
-import fr.gouv.etalab.mastodon.client.Entities.Account;
-import fr.gouv.etalab.mastodon.client.Entities.Status;
-import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
-import fr.gouv.etalab.mastodon.helper.Helper;
-import fr.gouv.etalab.mastodon.interfaces.OnRetrieveHomeTimelineServiceInterface;
-import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
-import fr.gouv.etalab.mastodon.sqlite.Sqlite;
-import mastodon.etalab.gouv.fr.mastodon.R;
-
-import static fr.gouv.etalab.mastodon.helper.Helper.HOME_TIMELINE_INTENT;
-import static fr.gouv.etalab.mastodon.helper.Helper.INTENT_ACTION;
-import static fr.gouv.etalab.mastodon.helper.Helper.PREF_KEY_ID;
-import static fr.gouv.etalab.mastodon.helper.Helper.canNotify;
-import static fr.gouv.etalab.mastodon.helper.Helper.notify_user;
-
-
-/**
- * Created by Thomas on 20/05/2017.
- * Notifications for home timeline job
- */
-
-public class HomeTimelineSyncJob extends Job implements OnRetrieveHomeTimelineServiceInterface{
-
- static final String HOME_TIMELINE = "home_timeline";
-
- @NonNull
- @Override
- protected Result onRunJob(Params params) {
- callAsynchronousTask();
- return Result.SUCCESS;
- }
-
-
- public static int schedule(boolean updateCurrent){
-
- Set jobRequests = JobManager.instance().getAllJobRequestsForTag(HOME_TIMELINE);
- if (!jobRequests.isEmpty() && !updateCurrent) {
- return jobRequests.iterator().next().getJobId();
- }
- return new JobRequest.Builder(HomeTimelineSyncJob.HOME_TIMELINE)
- .setPeriodic(TimeUnit.MINUTES.toMillis(Helper.MINUTES_BETWEEN_HOME_TIMELINE), TimeUnit.MINUTES.toMillis(5))
- .setPersisted(true)
- .setUpdateCurrent(updateCurrent)
- .setRequiredNetworkType(JobRequest.NetworkType.CONNECTED)
- .setRequirementsEnforced(false)
- .build()
- .schedule();
- }
-
-
- /**
- * Task in background starts here.
- */
- private void callAsynchronousTask() {
-
- if( !canNotify(getContext()))
- return;
- final SharedPreferences sharedpreferences = getContext().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
- boolean notif_hometimeline = sharedpreferences.getBoolean(Helper.SET_NOTIF_HOMETIMELINE, true);
- //User disagree with home timeline refresh
- if( !notif_hometimeline)
- return; //Nothing is done
- //No account connected, the service is stopped
- if(!Helper.isLoggedIn(getContext()))
- return;
- SQLiteDatabase db = Sqlite.getInstance(getContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
- //If an Internet connection and user agrees with notification refresh
- //If WIFI only and on WIFI OR user defined any connections to use the service.
- if(!sharedpreferences.getBoolean(Helper.SET_WIFI_ONLY, false) || Helper.isOnWIFI(getContext())) {
- List accounts = new AccountDAO(getContext(),db).getAllAccount();
- //It means there is no user in DB.
- if( accounts == null )
- return;
- //Retrieve users in db that owner has.
- for (Account account: accounts) {
- String since_id = sharedpreferences.getString(Helper.LAST_HOMETIMELINE_MAX_ID + account.getId(), null);
- new RetrieveHomeTimelineServiceAsyncTask(getContext(), account.getInstance(), account.getToken(), since_id, account.getAcct(), account.getId(), HomeTimelineSyncJob.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-
- }
- }
- }
-
-
- @Override
- public void onRetrieveHomeTimelineService(APIResponse apiResponse, String acct, String userId) {
- List statuses = apiResponse.getStatuses();
- if( apiResponse.getError() != null || statuses == null || statuses.size() == 0)
- return;
- final SharedPreferences sharedpreferences = getContext().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
-
- final String max_id = sharedpreferences.getString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, null);
- if( max_id == null){
- SharedPreferences.Editor editor = sharedpreferences.edit();
- editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, apiResponse.getSince_id());
- editor.apply();
- return;
- }
- //No previous notifications in cache, so no notification will be sent
- String message;
- SharedPreferences.Editor editor = sharedpreferences.edit();
- editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, apiResponse.getSince_id());
- editor.apply();
- for(Status status: statuses){
- //The notification associated to max_id is discarded as it is supposed to have already been sent
- //Also, if the toot comes from the owner, we will avoid to warn him/her...
- if( (status.getId().equals(max_id)) || (acct != null && status.getAccount().getAcct().trim().equals(acct.trim()) ))
- continue;
- String notificationUrl = status.getAccount().getAvatar();
-
- if(statuses.size() > 0 )
- message = getContext().getResources().getQuantityString(R.plurals.other_notif_hometimeline, statuses.size(), statuses.size());
- else
- message = "";
- final Intent intent = new Intent(getContext(), MainActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK );
- intent.putExtra(INTENT_ACTION, HOME_TIMELINE_INTENT);
- intent.putExtra(PREF_KEY_ID, userId);
- long notif_id = Long.parseLong(userId);
- final int notificationId = ((notif_id + 2) > 2147483647) ? (int) (2147483647 - notif_id - 2) : (int) (notif_id + 2);
-
- if( notificationUrl != null){
- ImageLoader imageLoaderNoty = ImageLoader.getInstance();
- File cacheDir = new File(getContext().getCacheDir(), getContext().getString(R.string.app_name));
- ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getContext())
- .imageDownloader(new PatchBaseImageDownloader(getContext()))
- .threadPoolSize(5)
- .threadPriority(Thread.MIN_PRIORITY + 3)
- .denyCacheImageMultipleSizesInMemory()
- .diskCache(new UnlimitedDiskCache(cacheDir))
- .build();
- imageLoaderNoty.init(config);
- DisplayImageOptions options = new DisplayImageOptions.Builder().displayer(new SimpleBitmapDisplayer()).cacheInMemory(false)
- .cacheOnDisk(true).resetViewBeforeLoading(true).build();
- final String finalMessage = message;
- String title;
- if( status.getAccount().getDisplay_name() != null && status.getAccount().getDisplay_name().length() > 0 )
- title = getContext().getResources().getString(R.string.notif_pouet, Helper.shortnameToUnicode(status.getAccount().getDisplay_name(), true));
- else
- title = getContext().getResources().getString(R.string.notif_pouet, status.getAccount().getUsername());
- final String finalTitle = title;
-
- imageLoaderNoty.loadImage(notificationUrl, options, new SimpleImageLoadingListener(){
- @Override
- public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
- super.onLoadingComplete(imageUri, view, loadedImage);
- notify_user(getContext(), intent, notificationId, loadedImage, finalTitle, finalMessage);
- }
- @Override
- public void onLoadingFailed(java.lang.String imageUri, android.view.View view, FailReason failReason){
- notify_user(getContext(), intent, notificationId, BitmapFactory.decodeResource(getContext().getResources(),
- R.drawable.mastodonlogo), finalTitle, finalMessage);
- }});
-
- }
- }
-
- }
-
-}
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/NotificationsSyncJob.java b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/NotificationsSyncJob.java
deleted file mode 100644
index 49603c1c1..000000000
--- a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/NotificationsSyncJob.java
+++ /dev/null
@@ -1,271 +0,0 @@
-package fr.gouv.etalab.mastodon.jobs;
-/* Copyright 2017 Thomas Schneider
- *
- * This file is a part of Mastalab
- *
- * This program is free software; you can redistribute it and/or modify it under the terms of the
- * GNU General Public License as published by the Free Software Foundation; either version 3 of the
- * License, or (at your option) any later version.
- *
- * Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
- * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- * Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with Mastalab; if not,
- * see . */
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.database.sqlite.SQLiteDatabase;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.os.AsyncTask;
-import android.support.annotation.NonNull;
-import android.view.View;
-
-import com.evernote.android.job.Job;
-import com.evernote.android.job.JobManager;
-import com.evernote.android.job.JobRequest;
-import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
-import com.nostra13.universalimageloader.core.DisplayImageOptions;
-import com.nostra13.universalimageloader.core.ImageLoader;
-import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
-import com.nostra13.universalimageloader.core.assist.FailReason;
-import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
-import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
-
-import java.io.File;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import fr.gouv.etalab.mastodon.activities.MainActivity;
-import fr.gouv.etalab.mastodon.client.APIResponse;
-import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
-import fr.gouv.etalab.mastodon.helper.Helper;
-import mastodon.etalab.gouv.fr.mastodon.R;
-import fr.gouv.etalab.mastodon.asynctasks.RetrieveNotificationsAsyncTask;
-import fr.gouv.etalab.mastodon.client.Entities.Account;
-import fr.gouv.etalab.mastodon.client.Entities.Notification;
-import fr.gouv.etalab.mastodon.interfaces.OnRetrieveNotificationsInterface;
-import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
-import fr.gouv.etalab.mastodon.sqlite.Sqlite;
-
-import static fr.gouv.etalab.mastodon.helper.Helper.INTENT_ACTION;
-import static fr.gouv.etalab.mastodon.helper.Helper.NOTIFICATION_INTENT;
-import static fr.gouv.etalab.mastodon.helper.Helper.PREF_KEY_ID;
-import static fr.gouv.etalab.mastodon.helper.Helper.canNotify;
-import static fr.gouv.etalab.mastodon.helper.Helper.notify_user;
-
-
-/**
- * Created by Thomas on 29/04/2017.
- * Notifications refresh job
- */
-
-public class NotificationsSyncJob extends Job implements OnRetrieveNotificationsInterface{
-
- static final String NOTIFICATION_REFRESH = "job_notification";
-
- @NonNull
- @Override
- protected Result onRunJob(Params params) {
- //Code refresh here
- callAsynchronousTask();
- return Result.SUCCESS;
- }
-
-
- public static int schedule(boolean updateCurrent){
-
- Set jobRequests = JobManager.instance().getAllJobRequestsForTag(NOTIFICATION_REFRESH);
- if (!jobRequests.isEmpty() && !updateCurrent) {
- return jobRequests.iterator().next().getJobId();
- }
-
- return new JobRequest.Builder(NotificationsSyncJob.NOTIFICATION_REFRESH)
- .setPeriodic(TimeUnit.MINUTES.toMillis(Helper.MINUTES_BETWEEN_NOTIFICATIONS_REFRESH), TimeUnit.MINUTES.toMillis(5))
- .setPersisted(true)
- .setUpdateCurrent(updateCurrent)
- .setRequiredNetworkType(JobRequest.NetworkType.CONNECTED)
- .setRequirementsEnforced(false)
- .build()
- .schedule();
- }
-
-
-
- /**
- * Task in background starts here.
- */
- private void callAsynchronousTask() {
- if( !canNotify(getContext()))
- return;
- SQLiteDatabase db = Sqlite.getInstance(getContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
- //If an Internet connection and user agrees with notification refresh
- final SharedPreferences sharedpreferences = getContext().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
- //Check which notifications the user wants to see
- boolean notif_follow = sharedpreferences.getBoolean(Helper.SET_NOTIF_FOLLOW, true);
- boolean notif_add = sharedpreferences.getBoolean(Helper.SET_NOTIF_ADD, true);
- boolean notif_ask = sharedpreferences.getBoolean(Helper.SET_NOTIF_ASK, true);
- boolean notif_mention = sharedpreferences.getBoolean(Helper.SET_NOTIF_MENTION, true);
- boolean notif_share = sharedpreferences.getBoolean(Helper.SET_NOTIF_SHARE, true);
- //User disagree with all notifications
- if( !notif_follow && !notif_add && !notif_ask && !notif_mention && !notif_share)
- return; //Nothing is done
- //No account connected, the service is stopped
- if(!Helper.isLoggedIn(getContext()))
- return;
- //If WIFI only and on WIFI OR user defined any connections to use the service.
- if(!sharedpreferences.getBoolean(Helper.SET_WIFI_ONLY, false) || Helper.isOnWIFI(getContext())) {
- List accounts = new AccountDAO(getContext(),db).getAllAccount();
- //It means there is no user in DB.
- if( accounts == null )
- return;
- //Retrieve users in db that owner has.
- for (Account account: accounts) {
- String max_id = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId(), null);
- new RetrieveNotificationsAsyncTask(getContext(), account.getInstance(), account.getToken(), max_id, account.getAcct(), account.getId(), NotificationsSyncJob.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- }
- }
-
-
-
- @Override
- public void onRetrieveNotifications(APIResponse apiResponse, String acct, String userId, boolean refreshData) {
- List notifications = apiResponse.getNotifications();
- if( apiResponse.getError() != null || notifications == null || notifications.size() == 0)
- return;
- Bitmap icon_notification = null;
- final SharedPreferences sharedpreferences = getContext().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
- boolean notif_follow = sharedpreferences.getBoolean(Helper.SET_NOTIF_FOLLOW, true);
- boolean notif_add = sharedpreferences.getBoolean(Helper.SET_NOTIF_ADD, true);
- boolean notif_mention = sharedpreferences.getBoolean(Helper.SET_NOTIF_MENTION, true);
- boolean notif_share = sharedpreferences.getBoolean(Helper.SET_NOTIF_SHARE, true);
- final String max_id = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + userId, null);
- if( max_id == null){
- SharedPreferences.Editor editor = sharedpreferences.edit();
- editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, apiResponse.getSince_id());
- editor.apply();
- return;
- }
-
- //No previous notifications in cache, so no notification will be sent
- int newFollows = 0;
- int newAdds = 0;
- int newAsks = 0;
- int newMentions = 0;
- int newShare = 0;
- String notificationUrl = null;
- String title = null;
- final String message;
- for(Notification notification: notifications){
- //The notification associated to max_id is discarded as it is supposed to have already been sent
- if( max_id != null && notification.getId().equals(max_id))
- continue;
- switch (notification.getType()){
- case "mention":
- if(notif_mention){
- newMentions++;
- if( notificationUrl == null){
- notificationUrl = notification.getAccount().getAvatar();
- if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0 )
- title = String.format("@%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),getContext().getString(R.string.notif_mention));
- else
- title = String.format("@%s %s", notification.getAccount().getUsername(),getContext().getString(R.string.notif_mention));
- }
- }
- break;
- case "reblog":
- if(notif_share){
- newShare++;
- if( notificationUrl == null){
- notificationUrl = notification.getAccount().getAvatar();
- if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0 )
- title = String.format("@%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),getContext().getString(R.string.notif_reblog));
- else
- title = String.format("@%s %s", notification.getAccount().getUsername(),getContext().getString(R.string.notif_reblog));
-
- }
- }
- break;
- case "favourite":
- if(notif_add){
- newAdds++;
- if( notificationUrl == null){
- notificationUrl = notification.getAccount().getAvatar();
- if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0 )
- title = String.format("@%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),getContext().getString(R.string.notif_favourite));
- else
- title = String.format("@%s %s", notification.getAccount().getUsername(),getContext().getString(R.string.notif_favourite));
- }
- }
- break;
- case "follow":
- if(notif_follow){
- newFollows++;
- if( notificationUrl == null){
- notificationUrl = notification.getAccount().getAvatar();
- if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0 )
- title = String.format("@%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),getContext().getString(R.string.notif_follow));
- else
- title = String.format("@%s %s", notification.getAccount().getUsername(),getContext().getString(R.string.notif_follow));
- }
- }
- break;
- default:
- }
- }
- SharedPreferences.Editor editor = sharedpreferences.edit();
- editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, apiResponse.getSince_id());
- editor.apply();
- int allNotifCount = newFollows + newAdds + newAsks + newMentions + newShare;
- if( allNotifCount > 0){
- //Some others notification
- int other = allNotifCount -1;
- if(other > 0 )
- message = getContext().getResources().getQuantityString(R.plurals.other_notifications, other, other);
- else
- message = "";
- final Intent intent = new Intent(getContext(), MainActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK );
- intent.putExtra(INTENT_ACTION, NOTIFICATION_INTENT);
- intent.putExtra(PREF_KEY_ID, userId);
- long notif_id = Long.parseLong(userId);
- final int notificationId = ((notif_id + 1) > 2147483647) ? (int) (2147483647 - notif_id - 1) : (int) (notif_id + 1);
-
- if( notificationUrl != null && icon_notification == null){
- ImageLoader imageLoaderNoty = ImageLoader.getInstance();
- File cacheDir = new File(getContext().getCacheDir(), getContext().getString(R.string.app_name));
- ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getContext())
- .imageDownloader(new PatchBaseImageDownloader(getContext()))
- .threadPoolSize(5)
- .threadPriority(Thread.MIN_PRIORITY + 3)
- .denyCacheImageMultipleSizesInMemory()
- .diskCache(new UnlimitedDiskCache(cacheDir))
- .build();
- imageLoaderNoty.init(config);
- DisplayImageOptions options = new DisplayImageOptions.Builder().displayer(new SimpleBitmapDisplayer()).cacheInMemory(false)
- .cacheOnDisk(true).resetViewBeforeLoading(true).build();
-
- final String finalTitle = title;
- imageLoaderNoty.loadImage(notificationUrl, options, new SimpleImageLoadingListener(){
- @Override
- public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
- super.onLoadingComplete(imageUri, view, loadedImage);
- if( max_id != null)
- notify_user(getContext(), intent, notificationId, loadedImage, finalTitle, message);
- }
- @Override
- public void onLoadingFailed(java.lang.String imageUri, android.view.View view, FailReason failReason){
- if( max_id != null)
- notify_user(getContext(), intent, notificationId, BitmapFactory.decodeResource(getContext().getResources(),
- R.drawable.mastodonlogo), finalTitle, message);
- }});
- }
-
- }
- }
-
-}
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ScheduledTootsSyncJob.java b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ScheduledTootsSyncJob.java
index 5bc7eb5bf..a995d5b1e 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ScheduledTootsSyncJob.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ScheduledTootsSyncJob.java
@@ -17,7 +17,6 @@ package fr.gouv.etalab.mastodon.jobs;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.NonNull;
-import android.util.Log;
import com.evernote.android.job.Job;
import com.evernote.android.job.JobRequest;
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/StreamingSyncJob.java b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/StreamingSyncJob.java
new file mode 100644
index 000000000..b1b093de3
--- /dev/null
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/StreamingSyncJob.java
@@ -0,0 +1,63 @@
+package fr.gouv.etalab.mastodon.jobs;
+/* Copyright 2017 Thomas Schneider
+ *
+ * This file is a part of Mastalab
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with Mastalab; if not,
+ * see . */
+
+import android.content.Intent;
+import android.support.annotation.NonNull;
+import com.evernote.android.job.Job;
+import com.evernote.android.job.JobManager;
+import com.evernote.android.job.JobRequest;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import fr.gouv.etalab.mastodon.helper.Helper;
+import fr.gouv.etalab.mastodon.services.StreamingService;
+
+
+/**
+ * Created by Thomas on 29/04/2017.
+ * Notifications refresh job
+ */
+
+public class StreamingSyncJob extends Job {
+
+ static final String STREAMING = "job_streaming";
+
+
+ @NonNull
+ @Override
+ protected Result onRunJob(Params params) {
+ //Code refresh here
+ getContext().startService(new Intent(getContext(), StreamingService.class));
+ return Result.SUCCESS;
+ }
+
+
+ public static int schedule(boolean updateCurrent){
+
+ Set jobRequests = JobManager.instance().getAllJobRequestsForTag(STREAMING);
+ if (!jobRequests.isEmpty() && !updateCurrent) {
+ return jobRequests.iterator().next().getJobId();
+ }
+ return new JobRequest.Builder(StreamingSyncJob.STREAMING)
+ .setPeriodic(TimeUnit.MINUTES.toMillis(Helper.MINUTES_BETWEEN_STREAMING_CHECK_ALIVE), TimeUnit.MINUTES.toMillis(5))
+ .setPersisted(true)
+ .setUpdateCurrent(updateCurrent)
+ .setRequiredNetworkType(JobRequest.NetworkType.CONNECTED)
+ .setRequirementsEnforced(false)
+ .build()
+ .schedule();
+ }
+
+}
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/services/StreamingService.java b/app/src/main/java/fr/gouv/etalab/mastodon/services/StreamingService.java
new file mode 100644
index 000000000..7144da304
--- /dev/null
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/services/StreamingService.java
@@ -0,0 +1,314 @@
+package fr.gouv.etalab.mastodon.services;
+/* Copyright 2017 Thomas Schneider
+ *
+ * This file is a part of Mastalab
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with Mastalab; if not,
+ * see . */
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.support.annotation.Nullable;
+import android.support.v4.content.LocalBroadcastManager;
+import android.text.Html;
+import android.view.View;
+
+import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
+import com.nostra13.universalimageloader.core.DisplayImageOptions;
+import com.nostra13.universalimageloader.core.ImageLoader;
+import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
+import com.nostra13.universalimageloader.core.assist.FailReason;
+import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
+import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.File;
+import java.util.List;
+
+import fr.gouv.etalab.mastodon.activities.MainActivity;
+import fr.gouv.etalab.mastodon.asynctasks.StreamingUserAsyncTask;
+import fr.gouv.etalab.mastodon.client.API;
+import fr.gouv.etalab.mastodon.client.Entities.Account;
+import fr.gouv.etalab.mastodon.client.Entities.Notification;
+import fr.gouv.etalab.mastodon.client.Entities.Status;
+import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
+import fr.gouv.etalab.mastodon.helper.Helper;
+import fr.gouv.etalab.mastodon.interfaces.OnRetrieveStreamingInterface;
+import fr.gouv.etalab.mastodon.jobs.StreamingSyncJob;
+import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
+import fr.gouv.etalab.mastodon.sqlite.Sqlite;
+import mastodon.etalab.gouv.fr.mastodon.R;
+
+import static fr.gouv.etalab.mastodon.helper.Helper.HOME_TIMELINE_INTENT;
+import static fr.gouv.etalab.mastodon.helper.Helper.INTENT_ACTION;
+import static fr.gouv.etalab.mastodon.helper.Helper.NOTIFICATION_INTENT;
+import static fr.gouv.etalab.mastodon.helper.Helper.PREF_KEY_ID;
+import static fr.gouv.etalab.mastodon.helper.Helper.notify_user;
+
+/**
+ * Created by Thomas on 28/08/2017.
+ */
+
+public class StreamingService extends Service implements OnRetrieveStreamingInterface {
+
+ private String message;
+ private int notificationId;
+ private Intent intent;
+
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ callAsynchronousTask();
+ return START_NOT_STICKY;
+ }
+
+ @Nullable
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+
+ /**
+ * Task in background starts here.
+ */
+ private void callAsynchronousTask() {
+ SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
+ //If an Internet connection and user agrees with notification refresh
+ final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
+ //Check which notifications the user wants to see
+ boolean notif_follow = sharedpreferences.getBoolean(Helper.SET_NOTIF_FOLLOW, true);
+ boolean notif_add = sharedpreferences.getBoolean(Helper.SET_NOTIF_ADD, true);
+ boolean notif_ask = sharedpreferences.getBoolean(Helper.SET_NOTIF_ASK, true);
+ boolean notif_mention = sharedpreferences.getBoolean(Helper.SET_NOTIF_MENTION, true);
+ boolean notif_share = sharedpreferences.getBoolean(Helper.SET_NOTIF_SHARE, true);
+ //User disagree with all notifications
+ if( !notif_follow && !notif_add && !notif_ask && !notif_mention && !notif_share)
+ return; //Nothing is done
+ //No account connected, the service is stopped
+ if(!Helper.isLoggedIn(getApplicationContext()))
+ return;
+ //If WIFI only and on WIFI OR user defined any connections to use the service.
+ if(!sharedpreferences.getBoolean(Helper.SET_WIFI_ONLY, false) || Helper.isOnWIFI(getApplicationContext())) {
+ List accounts = new AccountDAO(getApplicationContext(),db).getAllAccount();
+ //It means there is no user in DB.
+ if( accounts == null )
+ return;
+ //Retrieve users in db that owner has.
+ for (Account account: accounts) {
+ new StreamingUserAsyncTask(account.getInstance(), account.getToken(), account.getAcct(), account.getId(), StreamingService.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+ }
+ }
+
+
+ @Override
+ public void onRetrieveStreaming(StreamingUserAsyncTask.EventStreaming event, JSONObject response, String acct, String userId) {
+ if( response == null )
+ return;
+ String max_id = null;
+ final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
+ boolean notif_follow = sharedpreferences.getBoolean(Helper.SET_NOTIF_FOLLOW, true);
+ boolean notif_add = sharedpreferences.getBoolean(Helper.SET_NOTIF_ADD, true);
+ boolean notif_mention = sharedpreferences.getBoolean(Helper.SET_NOTIF_MENTION, true);
+ boolean notif_share = sharedpreferences.getBoolean(Helper.SET_NOTIF_SHARE, true);
+
+ //No previous notifications in cache, so no notification will be sent
+ boolean notify = false;
+
+ String notificationUrl = null;
+ String title = null;
+ Status status = null;
+ Notification notification = null;
+ String dataId = null;
+ if( event == StreamingUserAsyncTask.EventStreaming.NOTIFICATION){
+ notification = API.parseNotificationResponse(getApplicationContext(), response);
+ max_id = notification.getId();
+ switch (notification.getType()){
+ case "mention":
+ if(notif_mention){
+ notify = true;
+ notificationUrl = notification.getAccount().getAvatar();
+ if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0 )
+ title = String.format("@%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),getString(R.string.notif_mention));
+ else
+ title = String.format("@%s %s", notification.getAccount().getUsername(),getString(R.string.notif_mention));
+ }
+ break;
+ case "reblog":
+ if(notif_share){
+ notify = true;
+ notificationUrl = notification.getAccount().getAvatar();
+ if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0 )
+ title = String.format("@%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),getString(R.string.notif_reblog));
+ else
+ title = String.format("@%s %s", notification.getAccount().getUsername(),getString(R.string.notif_reblog));
+ }
+ break;
+ case "favourite":
+ if(notif_add){
+ notify = true;
+ notificationUrl = notification.getAccount().getAvatar();
+ if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0 )
+ title = String.format("@%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),getString(R.string.notif_favourite));
+ else
+ title = String.format("@%s %s", notification.getAccount().getUsername(),getString(R.string.notif_favourite));
+ }
+ break;
+ case "follow":
+ if(notif_follow){
+ notify = true;
+ notificationUrl = notification.getAccount().getAvatar();
+ if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0 )
+ title = String.format("@%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),getString(R.string.notif_follow));
+ else
+ title = String.format("@%s %s", notification.getAccount().getUsername(),getString(R.string.notif_follow));
+ }
+ break;
+ default:
+ break;
+ }
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, notification.getId());
+ editor.apply();
+ if( notification.getStatus().getContent()!= null) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ message = Html.fromHtml(notification.getStatus().getContent(), Html.FROM_HTML_MODE_LEGACY).toString();
+ else
+ //noinspection deprecation
+ message = Html.fromHtml(notification.getStatus().getContent()).toString();
+ message = message.substring(0, message.length()>49?49:message.length());
+ message = message + "…";
+ }else{
+ message = "";
+ }
+ }else if ( event == StreamingUserAsyncTask.EventStreaming.UPDATE){
+ status = API.parseStatuses(getApplicationContext(), response);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, status.getId());
+ editor.apply();
+ if( status.getContent() != null) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
+ message = Html.fromHtml(status.getContent(), Html.FROM_HTML_MODE_LEGACY).toString();
+ else
+ //noinspection deprecation
+ message = Html.fromHtml(status.getContent()).toString();
+ message = message.substring(0, message.length()>49?49:message.length());
+ message = message + "…";
+ }else{
+ message = "";
+ }
+ title = getString(R.string.notif_pouet, status.getAccount().getUsername());
+ notificationUrl = status.getAccount().getAvatar();
+ }else if( event == StreamingUserAsyncTask.EventStreaming.DELETE){
+ try {
+ dataId = response.getString("id");
+
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+
+ }
+ if( max_id != null){
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, max_id);
+ editor.apply();
+ return;
+ }
+
+ //Check which user is connected and if activity is to front
+ boolean activityVisible = false;
+ try{
+ activityVisible = MainActivity.isActivityVisible();
+ }catch (Exception ignored){}
+ String userconnected = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
+ SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
+ Account account = new AccountDAO(getApplicationContext(), db).getAccountByID(userconnected);
+ //User receiving the notification is connected and application is to front, notification won't be pushed
+ //Instead, the interaction is done in the activity
+ if( activityVisible && account != null && !account.getAcct().trim().equals(acct.trim()) && !account.getId().trim().equals(userId.trim())){
+ notify = false;
+ Intent intentBC = new Intent(Helper.RECEIVE_DATA);
+ intentBC.putExtra("eventStreaming", event);
+ Bundle b = new Bundle();
+ if( event == StreamingUserAsyncTask.EventStreaming.UPDATE)
+ b.putParcelable("data", status);
+ else if(event == StreamingUserAsyncTask.EventStreaming.NOTIFICATION)
+ b.putParcelable("data", notification);
+ else if(event == StreamingUserAsyncTask.EventStreaming.DELETE)
+ b.putString("id", dataId);
+ intentBC.putExtras(b);
+ LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intentBC);
+ }else if(event == StreamingUserAsyncTask.EventStreaming.NOTIFICATION ){
+ notify = true;
+ intent = new Intent(getApplicationContext(), MainActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK );
+ intent.putExtra(INTENT_ACTION, NOTIFICATION_INTENT);
+ intent.putExtra(PREF_KEY_ID, userId);
+ long notif_id = Long.parseLong(userId);
+ notificationId = ((notif_id + 1) > 2147483647) ? (int) (2147483647 - notif_id - 1) : (int) (notif_id + 1);
+
+
+ }else if(event == StreamingUserAsyncTask.EventStreaming.UPDATE ){
+ if(account.getAcct().trim().equals(acct.trim()) && account.getId().trim().equals(userId.trim())){
+ notify = false;
+ }else {
+ notify = true;
+ intent = new Intent(getApplicationContext(), MainActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.putExtra(INTENT_ACTION, HOME_TIMELINE_INTENT);
+ intent.putExtra(PREF_KEY_ID, userId);
+ long notif_id = Long.parseLong(userId);
+ notificationId = ((notif_id + 2) > 2147483647) ? (int) (2147483647 - notif_id - 2) : (int) (notif_id + 2);
+ }
+ }
+ if( notify){
+ if( notificationUrl != null){
+ ImageLoader imageLoaderNoty = ImageLoader.getInstance();
+ File cacheDir = new File(getApplicationContext().getCacheDir(), getString(R.string.app_name));
+ ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
+ .imageDownloader(new PatchBaseImageDownloader(getApplicationContext()))
+ .threadPoolSize(5)
+ .threadPriority(Thread.MIN_PRIORITY + 3)
+ .denyCacheImageMultipleSizesInMemory()
+ .diskCache(new UnlimitedDiskCache(cacheDir))
+ .build();
+ imageLoaderNoty.init(config);
+ DisplayImageOptions options = new DisplayImageOptions.Builder().displayer(new SimpleBitmapDisplayer()).cacheInMemory(false)
+ .cacheOnDisk(true).resetViewBeforeLoading(true).build();
+
+ final String finalTitle = title;
+ imageLoaderNoty.loadImage(notificationUrl, options, new SimpleImageLoadingListener(){
+ @Override
+ public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
+ super.onLoadingComplete(imageUri, view, loadedImage);
+ notify_user(getApplicationContext(), intent, notificationId, loadedImage, finalTitle, message);
+
+ }
+ @Override
+ public void onLoadingFailed(String imageUri, View view, FailReason failReason){
+ notify_user(getApplicationContext(), intent, notificationId, BitmapFactory.decodeResource(getApplicationContext().getResources(),
+ R.drawable.mastodonlogo), finalTitle, message);
+ }});
+ }
+ }
+ }
+}
diff --git a/app/src/main/res/layout-sw600dp/fragment_settings.xml b/app/src/main/res/layout-sw600dp/fragment_settings.xml
index 73c3fd3d0..9e104537d 100644
--- a/app/src/main/res/layout-sw600dp/fragment_settings.xml
+++ b/app/src/main/res/layout-sw600dp/fragment_settings.xml
@@ -58,11 +58,6 @@
android:text="@string/set_auto_store_toot"
android:layout_height="wrap_content" />
-
-
= TimeUnit.SECONDS.toMillis(60)) {
-
- if( notificationsFragment != null ){
- notificationsFragment.update();
- SharedPreferences.Editor editor = sharedpreferences.edit();
- editor.putString(Helper.LAST_BUBBLE_REFRESH_NOTIF+ account.getId(),Helper.dateToString(getApplicationContext(), new Date()));
- editor.apply();
- }
- }
-
- last_refresh = sharedpreferences.getString(Helper.LAST_BUBBLE_REFRESH_HOME + account.getId(), null);
- last_refresh_date = Helper.stringToDate(getApplicationContext(), last_refresh);
-
- if (last_refresh_date == null || (new Date().getTime() - last_refresh_date.getTime()) >= TimeUnit.SECONDS.toMillis(60)) {
- if( homeFragment != null ){
- homeFragment.update();
- SharedPreferences.Editor editor = sharedpreferences.edit();
- editor.putString(Helper.LAST_BUBBLE_REFRESH_HOME+ account.getId(),Helper.dateToString(getApplicationContext(), new Date()));
- editor.apply();
- }
- }
- }
- }
-
- public void updateHomeCounter(int newHomeCount){
+ public void updateHomeCounter(){
if( tabLayout.getTabAt(0) == null )
return;
//noinspection ConstantConditions
@@ -1101,8 +1121,8 @@ public class MainActivity extends AppCompatActivity
if( tabHome == null)
return;
TextView tabCounterHome = (TextView) tabHome.findViewById(R.id.tab_counter);
- tabCounterHome.setText(String.valueOf(newHomeCount));
- if( newHomeCount > 0){
+ tabCounterHome.setText(String.valueOf(newHome));
+ if( newHome > 0){
//New data are available
//The fragment is not displayed, so the counter is displayed
if( tabLayout.getSelectedTabPosition() != 0)
@@ -1114,7 +1134,7 @@ public class MainActivity extends AppCompatActivity
}
}
- public void updateNotifCounter(int newNotifCount){
+ public void updateNotifCounter(){
if(tabLayout.getTabAt(1) == null)
return;
//noinspection ConstantConditions
@@ -1122,8 +1142,8 @@ public class MainActivity extends AppCompatActivity
if( tabNotif == null)
return;
TextView tabCounterNotif = (TextView) tabNotif.findViewById(R.id.tab_counter);
- tabCounterNotif.setText(String.valueOf(newNotifCount));
- if( newNotifCount > 0){
+ tabCounterNotif.setText(String.valueOf(newNotif));
+ if( newNotif > 0){
if( tabLayout.getSelectedTabPosition() != 1)
tabCounterNotif.setVisibility(View.VISIBLE);
else
@@ -1133,4 +1153,21 @@ public class MainActivity extends AppCompatActivity
}
}
+
+
+
+
+ public static boolean isActivityVisible() {
+ return activityVisible;
+ }
+
+ private static void activityResumed() {
+ activityVisible = true;
+ }
+
+ private static void activityPaused() {
+ activityVisible = false;
+ }
+
+ private static boolean activityVisible;
}