Improvements

This commit is contained in:
stom79 2018-12-19 15:12:46 +01:00
parent 09d01a06b9
commit 13181f0bf0
7 changed files with 90 additions and 316 deletions

View File

@ -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)

View File

@ -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 {

View File

@ -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());

View File

@ -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();
}
}
}

View File

@ -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";

View File

@ -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:

View File

@ -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);
}
}
}
}