Improvements
This commit is contained in:
parent
09d01a06b9
commit
13181f0bf0
|
@ -195,7 +195,6 @@ public abstract class BaseMainActivity extends BaseActivity
|
|||
boolean notif_follow, notif_add, notif_mention, notif_share, show_boosts, show_replies , show_nsfw;
|
||||
String show_filtered;
|
||||
private AppBarLayout appBar;
|
||||
private String bookmark;
|
||||
private String userId;
|
||||
private String instance;
|
||||
public int countPage;
|
||||
|
@ -1222,10 +1221,7 @@ public abstract class BaseMainActivity extends BaseActivity
|
|||
userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
instance = sharedpreferences.getString(Helper.PREF_INSTANCE, Helper.getLiveInstance(getApplicationContext()));
|
||||
|
||||
//Get the previous bookmark value
|
||||
//If null try to use the LAST_HOMETIMELINE_MAX_ID
|
||||
String lastHomeTimeline = sharedpreferences.getString(Helper.LAST_HOMETIMELINE_MAX_ID + userId + instance, null);
|
||||
bookmark = sharedpreferences.getString(Helper.BOOKMARK_ID + userId + instance, lastHomeTimeline);
|
||||
|
||||
Account account = new AccountDAO(getApplicationContext(), db).getAccountByID(userId);
|
||||
if( account == null){
|
||||
Helper.logout(getApplicationContext());
|
||||
|
@ -2331,14 +2327,6 @@ public abstract class BaseMainActivity extends BaseActivity
|
|||
Helper.canPin = (currentVersion.compareTo(minVersion) == 1 || currentVersion.equals(minVersion));
|
||||
}
|
||||
|
||||
public String getBookmark() {
|
||||
return bookmark;
|
||||
}
|
||||
|
||||
public void setBookmark(@SuppressWarnings("SameParameterValue") String bookmark) {
|
||||
this.bookmark = bookmark;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRetrieveRemoteAccount(Results results) {
|
||||
if (results == null)
|
||||
|
|
|
@ -30,7 +30,6 @@ import java.util.Locale;
|
|||
import es.dmoral.toasty.Toasty;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.jobs.ApplicationJob;
|
||||
import fr.gouv.etalab.mastodon.jobs.HomeTimelineSyncJob;
|
||||
import fr.gouv.etalab.mastodon.jobs.NotificationsSyncJob;
|
||||
|
||||
/**
|
||||
|
@ -47,7 +46,6 @@ public class MainApplication extends MultiDexApplication {
|
|||
super.onCreate();
|
||||
JobManager.create(this).addJobCreator(new ApplicationJob());
|
||||
NotificationsSyncJob.schedule(false);
|
||||
HomeTimelineSyncJob.schedule(false);
|
||||
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
|
||||
StrictMode.setVmPolicy(builder.build());
|
||||
try {
|
||||
|
|
|
@ -997,22 +997,22 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
|
|||
if( status.isFetchMore()) {
|
||||
holder.fetch_more.setVisibility(View.VISIBLE);
|
||||
holder.fetch_more.setEnabled(true);
|
||||
}else {
|
||||
holder.fetch_more.setVisibility(View.GONE);
|
||||
|
||||
}
|
||||
|
||||
holder.fetch_more.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
holder.fetch_more.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
status.setFetchMore(false);
|
||||
holder.fetch_more.setEnabled(false);
|
||||
holder.fetch_more.setVisibility(View.GONE);
|
||||
DisplayStatusFragment homeFragment = ((BaseMainActivity) context).getHomeFragment();
|
||||
if( homeFragment != null)
|
||||
homeFragment.fetchMore(status.getId());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}else {
|
||||
holder.fetch_more.setVisibility(View.GONE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
holder.status_mention_spoiler.setText(Helper.makeMentionsClick(context,status.getMentions()), TextView.BufferType.SPANNABLE);
|
||||
holder.status_mention_spoiler.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
|
|
|
@ -105,6 +105,9 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
private boolean fetchMoreButtonDisplayed;
|
||||
private TagTimeline tagTimeline;
|
||||
|
||||
private String updatedBookMark;
|
||||
private String lastReadToot;
|
||||
|
||||
public DisplayStatusFragment(){
|
||||
}
|
||||
|
||||
|
@ -117,7 +120,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
Bundle bundle = this.getArguments();
|
||||
showMediaOnly = false;
|
||||
//Will allow to load first toots if bookmark != null
|
||||
firstTootsLoaded = true;
|
||||
firstTootsLoaded = false;
|
||||
fetchMoreButtonDisplayed = false;
|
||||
showPinned = false;
|
||||
showReply = false;
|
||||
|
@ -144,6 +147,8 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
max_id = null;
|
||||
flag_loading = true;
|
||||
firstLoad = true;
|
||||
initialBookMark = null;
|
||||
|
||||
assert context != null;
|
||||
sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
boolean isOnWifi = Helper.isOnWIFI(context);
|
||||
|
@ -156,9 +161,15 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
nextElementLoader.setVisibility(View.GONE);
|
||||
|
||||
userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
instance = sharedpreferences.getString(Helper.PREF_INSTANCE, context!=null?Helper.getLiveInstance(context):null);
|
||||
Account account = new AccountDAO(context, db).getAccountByID(userId);
|
||||
mutedAccount = new TempMuteDAO(context, db).getAllTimeMuted(account);
|
||||
|
||||
//For Home timeline, fetch stored values for bookmark and last read toot
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME) {
|
||||
initialBookMark = sharedpreferences.getString(Helper.BOOKMARK_ID + userId + instance, null);
|
||||
lastReadToot = sharedpreferences.getString(Helper.LAST_READ_TOOT_ID + userId + instance, null);
|
||||
}
|
||||
if( type == RetrieveFeedsAsyncTask.Type.TAG && tag != null) {
|
||||
BaseMainActivity.displayPeertube = null;
|
||||
List<TagTimeline> tagTimelines = new SearchDAO(context, db).getTimelineInfo(tag);
|
||||
|
@ -180,7 +191,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
lv_status.setLayoutManager(mLayoutManager);
|
||||
|
||||
|
||||
instance = sharedpreferences.getString(Helper.PREF_INSTANCE, context!=null?Helper.getLiveInstance(context):null);
|
||||
|
||||
if( type == RetrieveFeedsAsyncTask.Type.REMOTE_INSTANCE && search_peertube != null)
|
||||
((Activity)context).setTitle(remoteInstance + " - " + search_peertube);
|
||||
|
@ -228,13 +238,12 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
nextElementLoader.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
if(type == RetrieveFeedsAsyncTask.Type.HOME && statuses != null && statuses.size() > firstVisibleItem && firstVisibleItem >= 0)
|
||||
if( context instanceof BaseMainActivity){
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
Long bookmarkL = Long.parseLong(statuses.get(firstVisibleItem).getId()) + 1;
|
||||
editor.putString(Helper.BOOKMARK_ID + userId + instance, String.valueOf(bookmarkL));
|
||||
editor.apply();
|
||||
}
|
||||
if(type == RetrieveFeedsAsyncTask.Type.HOME && statuses != null && statuses.size() > firstVisibleItem && firstVisibleItem >= 0) {
|
||||
Long bookmarkL = Long.parseLong(statuses.get(firstVisibleItem).getId()) + 1;
|
||||
updatedBookMark = String.valueOf(bookmarkL);
|
||||
if( lastReadToot == null || bookmarkL > Long.parseLong(lastReadToot)) //Last read toot, only incremented if the id of the toot is greater than the recorded one
|
||||
lastReadToot = String.valueOf(bookmarkL);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -306,9 +315,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
asyncTask = new RetrievePeertubeSearchAsyncTask(context, remoteInstance, search_peertube, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}else {
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME ){
|
||||
firstTootsLoaded = false;
|
||||
if( context instanceof BaseMainActivity){
|
||||
initialBookMark = ((BaseMainActivity) context).getBookmark();
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, initialBookMark, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}else {
|
||||
|
@ -335,9 +342,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
asyncTask = new RetrievePeertubeSearchAsyncTask(context, remoteInstance, search_peertube, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}else {
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME ){
|
||||
firstTootsLoaded = false;
|
||||
if( context instanceof BaseMainActivity){
|
||||
initialBookMark = ((BaseMainActivity) context).getBookmark();
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, initialBookMark,DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}else {
|
||||
|
@ -352,6 +357,21 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
return rootView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause(){
|
||||
super.onPause();
|
||||
//Store bookmark on pause
|
||||
if (context instanceof BaseMainActivity && type == RetrieveFeedsAsyncTask.Type.HOME) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
if(updatedBookMark != null)
|
||||
editor.putString(Helper.BOOKMARK_ID + userId + instance, updatedBookMark);
|
||||
if( lastReadToot != null)
|
||||
editor.putString(Helper.LAST_READ_TOOT_ID + userId + instance, lastReadToot);
|
||||
if( lastReadToot != null || updatedBookMark != null)
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle saveInstance)
|
||||
|
@ -378,9 +398,10 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
|
||||
@Override
|
||||
public void onRetrieveFeeds(APIResponse apiResponse) {
|
||||
//hide loaders
|
||||
mainLoader.setVisibility(View.GONE);
|
||||
nextElementLoader.setVisibility(View.GONE);
|
||||
//Discards 404 - error which can often happen due to toots which have been deleted
|
||||
//handle other API error but discards 404 - error which can often happen due to toots which have been deleted
|
||||
if( apiResponse == null || (apiResponse.getError() != null && apiResponse.getError().getStatusCode() != 404) ){
|
||||
if( apiResponse == null)
|
||||
Toasty.error(context, context.getString(R.string.toast_error),Toast.LENGTH_LONG).show();
|
||||
|
@ -390,25 +411,30 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
flag_loading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
//For remote Peertube remote instances
|
||||
if( type == RetrieveFeedsAsyncTask.Type.REMOTE_INSTANCE && peertubeAdapater != null){
|
||||
int previousPosition = this.peertubes.size();
|
||||
if( max_id == null)
|
||||
max_id = "0";
|
||||
//max_id needs to work like an offset
|
||||
max_id = String.valueOf(Integer.valueOf(max_id) + 50);
|
||||
this.peertubes.addAll(apiResponse.getPeertubes());
|
||||
//If no item were inserted previously the adapter is created
|
||||
if( previousPosition == 0) {
|
||||
peertubeAdapater = new PeertubeAdapter(context, remoteInstance, this.peertubes);
|
||||
lv_status.setAdapter(peertubeAdapater);
|
||||
}else
|
||||
peertubeAdapater.notifyItemRangeInserted(previousPosition, apiResponse.getPeertubes().size());
|
||||
//remove handlers
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
firstLoad = false;
|
||||
flag_loading = false;
|
||||
}else {
|
||||
//Add conversation in status
|
||||
if( type == RetrieveFeedsAsyncTask.Type.CONVERSATION ){
|
||||
//When Mastodon statuses have been fetched.
|
||||
if( type == RetrieveFeedsAsyncTask.Type.CONVERSATION ){ //Conversation timeline
|
||||
//this timeline is dealt differently because it is embedded in Conversation entity and not directly in statuses
|
||||
List<Conversation> conversations = apiResponse.getConversations();
|
||||
//Statuses from conversation entity are retrieved
|
||||
List<Status> statusesConversations = new ArrayList<>();
|
||||
if( conversations != null) {
|
||||
for (Conversation conversation : conversations) {
|
||||
|
@ -427,48 +453,55 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
}
|
||||
int previousPosition = this.statuses.size();
|
||||
List<Status> statuses = apiResponse.getStatuses();
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME) {
|
||||
if (max_id == null || (apiResponse.getMax_id() != null && Long.parseLong(max_id) > Long.parseLong(apiResponse.getMax_id())))
|
||||
max_id = apiResponse.getMax_id();
|
||||
}else {
|
||||
max_id = apiResponse.getMax_id();
|
||||
}
|
||||
//At this point all statuses are in "List<Status> statuses"
|
||||
max_id = apiResponse.getMax_id();
|
||||
//while max_id is different from null, there are some more toots to load when scrolling
|
||||
flag_loading = (max_id == null );
|
||||
if( firstLoad && (statuses == null || statuses.size() == 0))
|
||||
//If it's the first load and the reply doesn't contain any toots, a message is displayed.
|
||||
if( firstLoad && (statuses == null || statuses.size() == 0)) {
|
||||
textviewNoAction.setVisibility(View.VISIBLE);
|
||||
else
|
||||
lv_status.setVisibility(View.GONE);
|
||||
}else {
|
||||
lv_status.setVisibility(View.VISIBLE);
|
||||
textviewNoAction.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
//First toot are loaded as soon as the bookmark has been retrieved
|
||||
//Only for the Home timeline
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME && !firstTootsLoaded){
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, null, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
firstTootsLoaded = true;
|
||||
}
|
||||
|
||||
//Let's deal with statuses
|
||||
if( statuses != null && statuses.size() > 0) {
|
||||
if (type == RetrieveFeedsAsyncTask.Type.HOME) {
|
||||
//Toots are older than the bookmark -> no special treatment with them
|
||||
//Toots are older than the bookmark:
|
||||
//Bookmark is null or greater id of returned status is lower than the bookmark id (+1 to exclude the bookmarked status).
|
||||
//The initialBookMark will be only set once for Home timeline when the fragment is created
|
||||
if( initialBookMark == null || Long.parseLong(statuses.get(0).getId()) + 1 < Long.parseLong(initialBookMark)){
|
||||
this.statuses.addAll(statuses);
|
||||
statusListAdapter.notifyItemRangeInserted(previousPosition, statuses.size());
|
||||
}else { //Toots are younger than the bookmark
|
||||
String currentMaxId = sharedpreferences.getString(Helper.LAST_HOMETIMELINE_MAX_ID + userId + instance, null);
|
||||
//Find the position of toots between those already present
|
||||
int position = 0;
|
||||
while (position < this.statuses.size() && Long.parseLong(statuses.get(0).getId()) < Long.parseLong(this.statuses.get(position).getId())) {
|
||||
position++;
|
||||
}
|
||||
ArrayList<Status> tmpStatuses = new ArrayList<>();
|
||||
for (Status tmpStatus : statuses) {
|
||||
//Mark status at new ones when their id is greater than the bookmark id / Also increments counter
|
||||
if (currentMaxId != null && Long.parseLong(tmpStatus.getId()) > Long.parseLong(currentMaxId)) {
|
||||
tmpStatus.setNew(true);
|
||||
MainActivity.countNewStatus++;
|
||||
}
|
||||
//Put the toot at its place in the list (id desc)
|
||||
if( !this.statuses.contains(tmpStatus) ) { //Element not already addeds
|
||||
if( !this.statuses.contains(tmpStatus) ) { //Element not already added
|
||||
//Mark status at new ones when their id is greater than the last read toot id
|
||||
if (lastReadToot != null && Long.parseLong(tmpStatus.getId()) > Long.parseLong(lastReadToot)) {
|
||||
tmpStatus.setNew(true);
|
||||
MainActivity.countNewStatus++;
|
||||
}
|
||||
tmpStatuses.add(tmpStatus);
|
||||
}
|
||||
}
|
||||
int tootPerPage = sharedpreferences.getInt(Helper.SET_TOOTS_PER_PAGE, 40);
|
||||
//Display the fetch more toot button
|
||||
if( tmpStatuses.size() >= tootPerPage) {
|
||||
if (!fetchMoreButtonDisplayed && tmpStatuses.size() > 0 && Long.parseLong(tmpStatuses.get(tmpStatuses.size() - 1).getId()) > Long.parseLong(initialBookMark)) {
|
||||
tmpStatuses.get(tmpStatuses.size() - 1).setFetchMore(true);
|
||||
|
@ -484,6 +517,14 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
}
|
||||
}
|
||||
|
||||
//Update the id of the last toot retrieved
|
||||
if( MainActivity.lastHomeId == null || Long.parseLong(statuses.get(0).getId()) > Long.parseLong(MainActivity.lastHomeId))
|
||||
MainActivity.lastHomeId = statuses.get(0).getId();
|
||||
//Display new value in counter
|
||||
try {
|
||||
((MainActivity) context).updateHomeCounter();
|
||||
}catch (Exception ignored){}
|
||||
|
||||
}else if ( statusListAdapter != null){
|
||||
if( tagTimeline == null || !tagTimeline.isART() || (tagTimeline.isART() && tagTimeline.isNSFW())) {
|
||||
this.statuses.addAll(statuses);
|
||||
|
@ -499,18 +540,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
statusListAdapter.notifyItemRangeInserted(previousPosition, safeStatuses.size());
|
||||
}
|
||||
}
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME ) {
|
||||
//Update the id of the last toot retrieved
|
||||
if( MainActivity.lastHomeId == null || Long.parseLong(statuses.get(0).getId()) > Long.parseLong(MainActivity.lastHomeId))
|
||||
MainActivity.lastHomeId = statuses.get(0).getId();
|
||||
if( firstLoad )
|
||||
updateStatusLastId(statuses.get(0).getId());
|
||||
}
|
||||
if( type == RetrieveFeedsAsyncTask.Type.HOME)
|
||||
//Display new value in counter
|
||||
try {
|
||||
((MainActivity) context).updateHomeCounter();
|
||||
}catch (Exception ignored){}
|
||||
|
||||
}
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
firstLoad = false;
|
||||
|
@ -541,12 +571,14 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
statuses.add(0, status);
|
||||
if (!status.getAccount().getId().equals(userId))
|
||||
MainActivity.countNewStatus++;
|
||||
try {
|
||||
((MainActivity) context).updateHomeCounter();
|
||||
}catch (Exception ignored){}
|
||||
statusListAdapter.notifyItemInserted(0);
|
||||
if (textviewNoAction.getVisibility() == View.VISIBLE)
|
||||
textviewNoAction.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
|
||||
} else if (type == RetrieveFeedsAsyncTask.Type.PUBLIC || type == RetrieveFeedsAsyncTask.Type.LOCAL|| type == RetrieveFeedsAsyncTask.Type.DIRECT) {
|
||||
|
||||
status.setNew(false);
|
||||
|
@ -664,8 +696,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 (type == RetrieveFeedsAsyncTask.Type.HOME ) {
|
||||
|
||||
if(visible && statuses != null && statuses.size() > 0)
|
||||
updateStatusLastId(statuses.get(0).getId());
|
||||
if (visible) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(Helper.SHOULD_CONTINUE_STREAMING_HOME + userId + instance, true);
|
||||
|
@ -755,10 +785,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
public void scrollToTop(){
|
||||
if( lv_status != null) {
|
||||
lv_status.setAdapter(statusListAdapter);
|
||||
//Store last toot id for home timeline to avoid to notify for those that have been already seen
|
||||
if (type == RetrieveFeedsAsyncTask.Type.HOME && statuses != null && statuses.size() > 0) {
|
||||
updateStatusLastId(statuses.get(0).getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -832,20 +858,4 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
|
|||
fetchMoreButtonDisplayed = false;
|
||||
asyncTask = new RetrieveFeedsAsyncTask(context, type, max_id, DisplayStatusFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Records the id of the status only if its greater than the previous one.
|
||||
* @param statusId String current status id to check
|
||||
*/
|
||||
private void updateStatusLastId(String statusId){
|
||||
|
||||
String lastNotif = sharedpreferences.getString(Helper.LAST_HOMETIMELINE_MAX_ID + userId + instance, null);
|
||||
if( lastNotif == null || Long.parseLong(statusId) > Long.parseLong(lastNotif)){
|
||||
MainActivity.countNewStatus = 0;
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId + instance, statusId);
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -222,6 +222,7 @@ public class Helper {
|
|||
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 BOOKMARK_ID = "bookmark_id";
|
||||
public static final String LAST_READ_TOOT_ID = "last_read_toot_id";
|
||||
public static final String LAST_HOMETIMELINE_NOTIFICATION_MAX_ID = "last_hometimeline_notification_max_id";
|
||||
public static final String SHOULD_CONTINUE_STREAMING = "should_continue_streaming";
|
||||
public static final String SHOULD_CONTINUE_STREAMING_HOME = "should_continue_streaming_home";
|
||||
|
|
|
@ -30,8 +30,6 @@ public class ApplicationJob implements JobCreator {
|
|||
switch (tag) {
|
||||
case NotificationsSyncJob.NOTIFICATION_REFRESH:
|
||||
return new NotificationsSyncJob();
|
||||
case HomeTimelineSyncJob.HOME_TIMELINE:
|
||||
return new HomeTimelineSyncJob();
|
||||
case ScheduledTootsSyncJob.SCHEDULED_TOOT:
|
||||
return new ScheduledTootsSyncJob();
|
||||
case ScheduledBoostsSyncJob.SCHEDULED_BOOST:
|
||||
|
|
|
@ -1,221 +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 <http://www.gnu.org/licenses>. */
|
||||
|
||||
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.Handler;
|
||||
import android.os.Looper;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
import com.bumptech.glide.load.engine.GlideException;
|
||||
import com.bumptech.glide.request.RequestListener;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.evernote.android.job.Job;
|
||||
import com.evernote.android.job.JobManager;
|
||||
import com.evernote.android.job.JobRequest;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import fr.gouv.etalab.mastodon.R;
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
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.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
|
||||
|
||||
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_INSTANCE;
|
||||
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 {
|
||||
|
||||
static final String HOME_TIMELINE = "home_timeline";
|
||||
static {
|
||||
Helper.installProvider();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Result onRunJob(@NonNull Params params) {
|
||||
callAsynchronousTask();
|
||||
return Result.SUCCESS;
|
||||
}
|
||||
public static int schedule(boolean updateCurrent){
|
||||
|
||||
Set<JobRequest> 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))
|
||||
.setUpdateCurrent(updateCurrent)
|
||||
.setRequiredNetworkType(JobRequest.NetworkType.METERED)
|
||||
.setRequiresBatteryNotLow(true)
|
||||
.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, false);
|
||||
//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<Account> 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_HOMETIMELINE_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), null);
|
||||
String lastHomeSeen = sharedpreferences.getString(Helper.LAST_HOMETIMELINE_MAX_ID + account.getId() + account.getInstance(), null);
|
||||
if( lastHomeSeen != null && max_id != null){
|
||||
if( Long.parseLong(lastHomeSeen) > Long.parseLong(max_id)){
|
||||
max_id = lastHomeSeen;
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_HOMETIMELINE_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), max_id);
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
API api = new API(getContext(), account.getInstance(), account.getToken());
|
||||
APIResponse apiResponse = api.getHomeTimelineSinceId(max_id);
|
||||
onRetrieveHomeTimelineService(apiResponse, account);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onRetrieveHomeTimelineService(APIResponse apiResponse, final Account account) {
|
||||
final List<Status> statuses = apiResponse.getStatuses();
|
||||
if( apiResponse.getError() != null || statuses == null || statuses.size() == 0 || account == null)
|
||||
return;
|
||||
|
||||
final SharedPreferences sharedpreferences = getContext().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
|
||||
final String max_id = sharedpreferences.getString(Helper.LAST_HOMETIMELINE_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), null);
|
||||
//No previous notifications in cache, so no notification will be sent
|
||||
String message;
|
||||
|
||||
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( max_id != null && (status.getId().equals(max_id)) || (account.getAcct() != null && status.getAccount().getAcct().trim().equals(account.getAcct().trim()) ))
|
||||
continue;
|
||||
final 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, account.getId());
|
||||
intent.putExtra(PREF_INSTANCE, account.getInstance());
|
||||
long notif_id = Long.parseLong(account.getId());
|
||||
final int notificationId = ((notif_id + 2) > 2147483647) ? (int) (2147483647 - notif_id - 2) : (int) (notif_id + 2);
|
||||
if( notificationUrl != null){
|
||||
|
||||
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;
|
||||
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
Runnable myRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {Glide.with(getContext())
|
||||
.asBitmap()
|
||||
.load(notificationUrl)
|
||||
.listener(new RequestListener<Bitmap>(){
|
||||
|
||||
@Override
|
||||
public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
|
||||
notify_user(getContext(), intent, notificationId, BitmapFactory.decodeResource(getContext().getResources(),
|
||||
R.drawable.mastodonlogo), Helper.NotifType.TOOT, finalTitle, finalMessage);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_HOMETIMELINE_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), statuses.get(0).getId());
|
||||
editor.apply();
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.into(new SimpleTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
|
||||
notify_user(getContext(), intent, notificationId, resource, Helper.NotifType.TOOT, finalTitle, finalMessage);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_HOMETIMELINE_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), statuses.get(0).getId());
|
||||
editor.apply();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
mainHandler.post(myRunnable);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue