From b842520d53e3353b1dceab495545f59f92f15403 Mon Sep 17 00:00:00 2001 From: Mariotaku Lee Date: Wed, 14 Dec 2016 16:02:50 +0800 Subject: [PATCH] code cleanup --- twidere/src/debug/res/values/config.xml | 4 + twidere/src/debug/res/values/defaults.xml | 1 - twidere/src/main/AndroidManifest.xml | 7 + .../twidere/service/BackgroundJobService.java | 43 -- .../twidere/service/RefreshService.java | 411 ------------------ .../twidere/task/GetDirectMessagesTask.java | 156 ------- .../twidere/task/GetLocalTrendsTask.java | 37 -- .../twidere/task/GetSavedSearchesTask.java | 57 --- .../mariotaku/twidere/task/GetTrendsTask.java | 89 ---- .../twidere/task/SaveMediaToGalleryTask.java | 82 ---- .../twidere/util/AsyncTwitterWrapper.java | 60 +-- .../org/mariotaku/twidere/util/Utils.java | 1 + .../twidere/activity/MediaViewerActivity.kt | 14 +- .../twidere/app/TwidereApplication.kt | 41 +- .../twidere/constant/PreferenceKeys.kt | 6 +- .../fragment/AccountsDashboardFragment.kt | 55 +-- .../twidere/service/JobRefreshService.kt | 101 +++++ .../twidere/service/RefreshService.kt | 304 +++++++++++++ .../twidere/task/GetActivitiesAboutMeTask.kt | 4 +- .../twidere/task/GetDirectMessagesTask.kt | 132 ++++++ .../twidere/task/GetLocalTrendsTask.kt | 24 + .../task/GetReceivedDirectMessagesTask.kt | 27 ++ .../twidere/task/GetSavedSearchesTask.kt | 43 ++ .../twidere/task/GetSentDirectMessagesTask.kt | 26 ++ .../mariotaku/twidere/task/GetTrendsTask.kt | 77 ++++ .../twidere/task/SaveMediaToGalleryTask.kt | 69 +++ .../twidere/task/twitter/GetActivitiesTask.kt | 23 +- .../twidere/task/twitter/GetStatusesTask.kt | 6 +- .../twidere/util/dagger/GeneralComponent.kt | 3 + .../main/res/menu/menu_account_dashboard.xml | 6 + twidere/src/main/res/values-v21/config.xml | 5 + twidere/src/main/res/values/config.xml | 6 + twidere/src/main/res/values/defaults.xml | 1 - twidere/src/main/res/values/ids.xml | 1 + 34 files changed, 901 insertions(+), 1021 deletions(-) create mode 100644 twidere/src/debug/res/values/config.xml delete mode 100644 twidere/src/main/java/org/mariotaku/twidere/service/BackgroundJobService.java delete mode 100644 twidere/src/main/java/org/mariotaku/twidere/service/RefreshService.java delete mode 100644 twidere/src/main/java/org/mariotaku/twidere/task/GetDirectMessagesTask.java delete mode 100644 twidere/src/main/java/org/mariotaku/twidere/task/GetLocalTrendsTask.java delete mode 100644 twidere/src/main/java/org/mariotaku/twidere/task/GetSavedSearchesTask.java delete mode 100644 twidere/src/main/java/org/mariotaku/twidere/task/GetTrendsTask.java delete mode 100644 twidere/src/main/java/org/mariotaku/twidere/task/SaveMediaToGalleryTask.java create mode 100644 twidere/src/main/kotlin/org/mariotaku/twidere/service/JobRefreshService.kt create mode 100644 twidere/src/main/kotlin/org/mariotaku/twidere/service/RefreshService.kt create mode 100644 twidere/src/main/kotlin/org/mariotaku/twidere/task/GetDirectMessagesTask.kt create mode 100644 twidere/src/main/kotlin/org/mariotaku/twidere/task/GetLocalTrendsTask.kt create mode 100644 twidere/src/main/kotlin/org/mariotaku/twidere/task/GetReceivedDirectMessagesTask.kt create mode 100644 twidere/src/main/kotlin/org/mariotaku/twidere/task/GetSavedSearchesTask.kt create mode 100644 twidere/src/main/kotlin/org/mariotaku/twidere/task/GetSentDirectMessagesTask.kt create mode 100644 twidere/src/main/kotlin/org/mariotaku/twidere/task/GetTrendsTask.kt create mode 100644 twidere/src/main/kotlin/org/mariotaku/twidere/task/SaveMediaToGalleryTask.kt create mode 100644 twidere/src/main/res/values-v21/config.xml create mode 100644 twidere/src/main/res/values/config.xml diff --git a/twidere/src/debug/res/values/config.xml b/twidere/src/debug/res/values/config.xml new file mode 100644 index 000000000..37072036f --- /dev/null +++ b/twidere/src/debug/res/values/config.xml @@ -0,0 +1,4 @@ + + + true + \ No newline at end of file diff --git a/twidere/src/debug/res/values/defaults.xml b/twidere/src/debug/res/values/defaults.xml index 57d4eed51..670c84887 100644 --- a/twidere/src/debug/res/values/defaults.xml +++ b/twidere/src/debug/res/values/defaults.xml @@ -1,5 +1,4 @@ 10 - true \ No newline at end of file diff --git a/twidere/src/main/AndroidManifest.xml b/twidere/src/main/AndroidManifest.xml index b2fcf5060..fe0a44aea 100644 --- a/twidere/src/main/AndroidManifest.xml +++ b/twidere/src/main/AndroidManifest.xml @@ -461,7 +461,14 @@ + diff --git a/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundJobService.java b/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundJobService.java deleted file mode 100644 index fd62ef6ec..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/service/BackgroundJobService.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2014 Mariotaku Lee - * - * 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. - * - * This program 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 this program. If not, see . - */ - -package org.mariotaku.twidere.service; - -import android.annotation.SuppressLint; -import android.annotation.TargetApi; -import android.app.job.JobParameters; -import android.app.job.JobService; -import android.os.Build; - -/** - * Created by mariotaku on 14/12/12. - */ -@SuppressLint("Registered") -@TargetApi(Build.VERSION_CODES.LOLLIPOP) -public class BackgroundJobService extends JobService { - @Override - public boolean onStartJob(JobParameters params) { - return false; - } - - @Override - public boolean onStopJob(JobParameters params) { - return false; - } -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/service/RefreshService.java b/twidere/src/main/java/org/mariotaku/twidere/service/RefreshService.java deleted file mode 100644 index 53b4bd999..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/service/RefreshService.java +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2014 Mariotaku Lee - * - * 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. - * - * This program 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 this program. If not, see . - */ - -package org.mariotaku.twidere.service; - -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.app.Service; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.IBinder; -import android.os.SystemClock; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.util.Log; - -import org.apache.commons.lang3.math.NumberUtils; -import org.mariotaku.twidere.BuildConfig; -import org.mariotaku.twidere.Constants; -import org.mariotaku.twidere.model.AccountPreferences; -import org.mariotaku.twidere.model.SimpleRefreshTaskParam; -import org.mariotaku.twidere.model.UserKey; -import org.mariotaku.twidere.provider.TwidereDataStore.Activities; -import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages; -import org.mariotaku.twidere.provider.TwidereDataStore.Statuses; -import org.mariotaku.twidere.receiver.PowerStateReceiver; -import org.mariotaku.twidere.util.AsyncTwitterWrapper; -import org.mariotaku.twidere.util.DataStoreUtils; -import org.mariotaku.twidere.util.SharedPreferencesWrapper; -import org.mariotaku.twidere.util.Utils; -import org.mariotaku.twidere.util.dagger.GeneralComponentHelper; - -import java.util.Arrays; - -import javax.inject.Inject; - -import edu.tsinghua.hotmobi.model.BatteryRecord; -import edu.tsinghua.hotmobi.model.ScreenEvent; - -public class RefreshService extends Service implements Constants { - - @Inject - SharedPreferencesWrapper mPreferences; - - private AlarmManager mAlarmManager; - @Inject - AsyncTwitterWrapper mTwitterWrapper; - private PendingIntent mPendingRefreshHomeTimelineIntent, mPendingRefreshMentionsIntent, - mPendingRefreshDirectMessagesIntent, mPendingRefreshTrendsIntent; - - private final BroadcastReceiver mStateReceiver = new BroadcastReceiver() { - - @Override - public void onReceive(final Context context, final Intent intent) { - final String action = intent.getAction(); - if (BuildConfig.DEBUG) { - Log.d(LOGTAG, String.format("Refresh service received action %s", action)); - } - switch (action) { - case BROADCAST_RESCHEDULE_HOME_TIMELINE_REFRESHING: { - rescheduleHomeTimelineRefreshing(); - break; - } - case BROADCAST_RESCHEDULE_MENTIONS_REFRESHING: { - rescheduleMentionsRefreshing(); - break; - } - case BROADCAST_RESCHEDULE_DIRECT_MESSAGES_REFRESHING: { - rescheduleDirectMessagesRefreshing(); - break; - } - case BROADCAST_RESCHEDULE_TRENDS_REFRESHING: { - rescheduleTrendsRefreshing(); - break; - } - case BROADCAST_REFRESH_HOME_TIMELINE: { - if (isAutoRefreshAllowed()) { - mTwitterWrapper.getHomeTimelineAsync(new SimpleRefreshTaskParam() { - private UserKey[] accountIds; - - @NonNull - @Override - public UserKey[] getAccountKeysWorker() { - if (accountIds != null) return accountIds; - final AccountPreferences[] prefs = AccountPreferences.getAccountPreferences(context, - DataStoreUtils.getAccountKeys(context)); - return accountIds = getRefreshableIds(prefs, HomeRefreshableFilter.INSTANCE); - } - - @Nullable - @Override - public String[] getSinceIds() { - return DataStoreUtils.getNewestStatusIds(context, - Statuses.CONTENT_URI, getAccountKeys()); - } - }); - } - break; - } - case BROADCAST_REFRESH_NOTIFICATIONS: { - if (isAutoRefreshAllowed()) { - mTwitterWrapper.getActivitiesAboutMeAsync(new SimpleRefreshTaskParam() { - private UserKey[] accountIds; - - @NonNull - @Override - public UserKey[] getAccountKeysWorker() { - if (accountIds != null) return accountIds; - final AccountPreferences[] prefs = AccountPreferences.getAccountPreferences(context, - DataStoreUtils.getAccountKeys(context)); - return accountIds = getRefreshableIds(prefs, MentionsRefreshableFilter.INSTANCE); - } - - @Nullable - @Override - public String[] getSinceIds() { - return DataStoreUtils.getNewestActivityMaxPositions(context, - Activities.AboutMe.CONTENT_URI, getAccountKeys()); - } - }); - } - break; - } - case BROADCAST_REFRESH_DIRECT_MESSAGES: { - if (isAutoRefreshAllowed()) { - mTwitterWrapper.getReceivedDirectMessagesAsync(new SimpleRefreshTaskParam() { - private UserKey[] accountIds; - - @NonNull - @Override - public UserKey[] getAccountKeysWorker() { - if (accountIds != null) return accountIds; - final AccountPreferences[] prefs = AccountPreferences.getAccountPreferences(context, - DataStoreUtils.getAccountKeys(context)); - return accountIds = getRefreshableIds(prefs, MessagesRefreshableFilter.INSTANCE); - } - - @Nullable - @Override - public String[] getSinceIds() { - return DataStoreUtils.getNewestMessageIds(context, - DirectMessages.Inbox.CONTENT_URI, getAccountKeys()); - } - }); - } - break; - } - case BROADCAST_REFRESH_TRENDS: { - if (isAutoRefreshAllowed()) { - final AccountPreferences[] prefs = AccountPreferences.getAccountPreferences(context, - DataStoreUtils.getAccountKeys(context)); - final UserKey[] refreshIds = getRefreshableIds(prefs, TrendsRefreshableFilter.INSTANCE); - if (BuildConfig.DEBUG) { - Log.d(LOGTAG, String.format("Auto refreshing trends for %s", Arrays.toString(refreshIds))); - } - getLocalTrends(refreshIds); - break; - } - } - } - } - - }; - - private final BroadcastReceiver mPowerStateReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - switch (intent.getAction()) { - case Intent.ACTION_BATTERY_CHANGED: { - BatteryRecord.log(context, intent); - break; - } - default: { - BatteryRecord.log(context); - break; - } - } - } - }; - - private final BroadcastReceiver mScreenStateReceiver = new BroadcastReceiver() { - public long mPresentTime = -1; - - @Override - public void onReceive(Context context, Intent intent) { - switch (intent.getAction()) { - case Intent.ACTION_SCREEN_ON: { - ScreenEvent.log(context, ScreenEvent.Action.ON, getPresentDuration()); - break; - } - case Intent.ACTION_SCREEN_OFF: { - ScreenEvent.log(context, ScreenEvent.Action.OFF, getPresentDuration()); - mPresentTime = -1; - break; - } - case Intent.ACTION_USER_PRESENT: { - mPresentTime = SystemClock.elapsedRealtime(); - ScreenEvent.log(context, ScreenEvent.Action.PRESENT, -1); - break; - } - } - } - - private long getPresentDuration() { - if (mPresentTime < 0) return -1; - return SystemClock.elapsedRealtime() - mPresentTime; - } - }; - - @Override - public IBinder onBind(final Intent intent) { - return null; - } - - @Override - public void onCreate() { - super.onCreate(); - GeneralComponentHelper.build(this).inject(this); - mAlarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); - mPendingRefreshHomeTimelineIntent = PendingIntent.getBroadcast(this, 0, new Intent( - BROADCAST_REFRESH_HOME_TIMELINE), 0); - mPendingRefreshMentionsIntent = PendingIntent.getBroadcast(this, 0, new Intent(BROADCAST_REFRESH_NOTIFICATIONS), 0); - mPendingRefreshDirectMessagesIntent = PendingIntent.getBroadcast(this, 0, new Intent( - BROADCAST_REFRESH_DIRECT_MESSAGES), 0); - mPendingRefreshTrendsIntent = PendingIntent.getBroadcast(this, 0, new Intent(BROADCAST_REFRESH_TRENDS), 0); - final IntentFilter refreshFilter = new IntentFilter(BROADCAST_NOTIFICATION_DELETED); - refreshFilter.addAction(BROADCAST_REFRESH_HOME_TIMELINE); - refreshFilter.addAction(BROADCAST_REFRESH_NOTIFICATIONS); - refreshFilter.addAction(BROADCAST_REFRESH_DIRECT_MESSAGES); - refreshFilter.addAction(BROADCAST_RESCHEDULE_HOME_TIMELINE_REFRESHING); - refreshFilter.addAction(BROADCAST_RESCHEDULE_MENTIONS_REFRESHING); - refreshFilter.addAction(BROADCAST_RESCHEDULE_DIRECT_MESSAGES_REFRESHING); - registerReceiver(mStateReceiver, refreshFilter); - final IntentFilter batteryFilter = new IntentFilter(); - batteryFilter.addAction(Intent.ACTION_BATTERY_CHANGED); - batteryFilter.addAction(Intent.ACTION_BATTERY_OKAY); - batteryFilter.addAction(Intent.ACTION_BATTERY_LOW); - batteryFilter.addAction(Intent.ACTION_POWER_CONNECTED); - batteryFilter.addAction(Intent.ACTION_POWER_DISCONNECTED); - final IntentFilter screenFilter = new IntentFilter(); - screenFilter.addAction(Intent.ACTION_SCREEN_ON); - screenFilter.addAction(Intent.ACTION_SCREEN_OFF); - screenFilter.addAction(Intent.ACTION_USER_PRESENT); - registerReceiver(mPowerStateReceiver, batteryFilter); - registerReceiver(mScreenStateReceiver, screenFilter); - PowerStateReceiver.Companion.setServiceReceiverStarted(true); - if (Utils.hasAutoRefreshAccounts(this)) { - startAutoRefresh(); - } else { - stopSelf(); - } - } - - @Override - public void onDestroy() { - PowerStateReceiver.Companion.setServiceReceiverStarted(false); - unregisterReceiver(mScreenStateReceiver); - unregisterReceiver(mPowerStateReceiver); - unregisterReceiver(mStateReceiver); - if (Utils.hasAutoRefreshAccounts(this)) { - // Auto refresh enabled, so I will try to start service after it was - // stopped. - startService(new Intent(this, getClass())); - } - super.onDestroy(); - } - - protected boolean isAutoRefreshAllowed() { - return Utils.isNetworkAvailable(this) && (Utils.isBatteryOkay(this) || !Utils.shouldStopAutoRefreshOnBatteryLow(this)); - } - - private void getLocalTrends(final UserKey[] accountIds) { - final UserKey account_id = Utils.getDefaultAccountKey(this); - final int woeid = mPreferences.getInt(KEY_LOCAL_TRENDS_WOEID, 1); - mTwitterWrapper.getLocalTrendsAsync(account_id, woeid); - } - - private UserKey[] getRefreshableIds(final AccountPreferences[] prefs, final RefreshableAccountFilter filter) { - if (prefs == null) return null; - final UserKey[] temp = new UserKey[prefs.length]; - int i = 0; - for (final AccountPreferences pref : prefs) { - if (pref.isAutoRefreshEnabled() && filter.isRefreshable(pref)) { - temp[i++] = pref.getAccountKey(); - } - } - final UserKey[] result = new UserKey[i]; - System.arraycopy(temp, 0, result, 0, i); - return result; - } - - private long getRefreshInterval() { - if (mPreferences == null) return 0; - final int prefValue = NumberUtils.toInt(mPreferences.getString(KEY_REFRESH_INTERVAL, DEFAULT_REFRESH_INTERVAL), -1); - return Math.max(prefValue, 3) * 60 * 1000; - } - - private void rescheduleDirectMessagesRefreshing() { - mAlarmManager.cancel(mPendingRefreshDirectMessagesIntent); - final long refreshInterval = getRefreshInterval(); - if (refreshInterval > 0) { - mAlarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + refreshInterval, - refreshInterval, mPendingRefreshDirectMessagesIntent); - } - } - - private void rescheduleHomeTimelineRefreshing() { - mAlarmManager.cancel(mPendingRefreshHomeTimelineIntent); - final long refreshInterval = getRefreshInterval(); - if (refreshInterval > 0) { - mAlarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + refreshInterval, - refreshInterval, mPendingRefreshHomeTimelineIntent); - } - } - - private void rescheduleMentionsRefreshing() { - mAlarmManager.cancel(mPendingRefreshMentionsIntent); - final long refreshInterval = getRefreshInterval(); - if (refreshInterval > 0) { - mAlarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + refreshInterval, - refreshInterval, mPendingRefreshMentionsIntent); - } - } - - private void rescheduleTrendsRefreshing() { - mAlarmManager.cancel(mPendingRefreshTrendsIntent); - final long refreshInterval = getRefreshInterval(); - if (refreshInterval > 0) { - mAlarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + refreshInterval, - refreshInterval, mPendingRefreshTrendsIntent); - } - } - - private boolean startAutoRefresh() { - stopAutoRefresh(); - final long refreshInterval = getRefreshInterval(); - if (refreshInterval <= 0) return false; - rescheduleHomeTimelineRefreshing(); - rescheduleMentionsRefreshing(); - rescheduleDirectMessagesRefreshing(); - rescheduleTrendsRefreshing(); - return true; - } - - private void stopAutoRefresh() { - mAlarmManager.cancel(mPendingRefreshHomeTimelineIntent); - mAlarmManager.cancel(mPendingRefreshMentionsIntent); - mAlarmManager.cancel(mPendingRefreshDirectMessagesIntent); - mAlarmManager.cancel(mPendingRefreshTrendsIntent); - } - - private interface RefreshableAccountFilter { - boolean isRefreshable(AccountPreferences pref); - } - - private static class HomeRefreshableFilter implements RefreshableAccountFilter { - public static final RefreshableAccountFilter INSTANCE = new HomeRefreshableFilter(); - - @Override - public boolean isRefreshable(final AccountPreferences pref) { - return pref.isAutoRefreshHomeTimelineEnabled(); - } - } - - private static class MentionsRefreshableFilter implements RefreshableAccountFilter { - - static final RefreshableAccountFilter INSTANCE = new MentionsRefreshableFilter(); - - @Override - public boolean isRefreshable(final AccountPreferences pref) { - return pref.isAutoRefreshMentionsEnabled(); - } - - } - - private static class MessagesRefreshableFilter implements RefreshableAccountFilter { - public static final RefreshableAccountFilter INSTANCE = new MentionsRefreshableFilter(); - - @Override - public boolean isRefreshable(final AccountPreferences pref) { - return pref.isAutoRefreshDirectMessagesEnabled(); - } - } - - private static class TrendsRefreshableFilter implements RefreshableAccountFilter { - public static final RefreshableAccountFilter INSTANCE = new TrendsRefreshableFilter(); - - @Override - public boolean isRefreshable(final AccountPreferences pref) { - return pref.isAutoRefreshTrendsEnabled(); - } - } -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/GetDirectMessagesTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/GetDirectMessagesTask.java deleted file mode 100644 index 79a0ab487..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/task/GetDirectMessagesTask.java +++ /dev/null @@ -1,156 +0,0 @@ -package org.mariotaku.twidere.task; - -import android.content.ContentValues; -import android.content.Context; -import android.net.Uri; -import android.util.Log; - -import com.squareup.otto.Bus; - -import org.apache.commons.lang3.math.NumberUtils; -import org.mariotaku.abstask.library.AbstractTask; -import org.mariotaku.microblog.library.MicroBlog; -import org.mariotaku.microblog.library.MicroBlogException; -import org.mariotaku.microblog.library.twitter.model.DirectMessage; -import org.mariotaku.microblog.library.twitter.model.ErrorInfo; -import org.mariotaku.microblog.library.twitter.model.Paging; -import org.mariotaku.microblog.library.twitter.model.ResponseList; -import org.mariotaku.twidere.BuildConfig; -import org.mariotaku.twidere.Constants; -import org.mariotaku.twidere.TwidereConstants; -import org.mariotaku.twidere.model.RefreshTaskParam; -import org.mariotaku.twidere.model.UserKey; -import org.mariotaku.twidere.model.message.GetMessagesTaskEvent; -import org.mariotaku.twidere.util.AsyncTwitterWrapper; -import org.mariotaku.twidere.util.ContentValuesCreator; -import org.mariotaku.twidere.util.ErrorInfoStore; -import org.mariotaku.twidere.util.MicroBlogAPIFactory; -import org.mariotaku.twidere.util.SharedPreferencesWrapper; -import org.mariotaku.twidere.util.TwitterWrapper; -import org.mariotaku.twidere.util.UriUtils; -import org.mariotaku.twidere.util.content.ContentResolverUtils; -import org.mariotaku.twidere.util.dagger.GeneralComponentHelper; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import javax.inject.Inject; - -/** - * Created by mariotaku on 16/2/14. - */ -public abstract class GetDirectMessagesTask extends AbstractTask, Object> implements Constants { - - protected final Context context; - @Inject - protected ErrorInfoStore errorInfoStore; - @Inject - protected SharedPreferencesWrapper preferences; - @Inject - protected Bus bus; - - public GetDirectMessagesTask(Context context) { - this.context = context; - GeneralComponentHelper.build(context).inject(this); - } - - public abstract ResponseList getDirectMessages(MicroBlog twitter, Paging paging) - throws MicroBlogException; - - protected abstract Uri getDatabaseUri(); - - protected abstract boolean isOutgoing(); - - @Override - public List doLongOperation(final RefreshTaskParam param) { - final UserKey[] accountKeys = param.getAccountKeys(); - final String[] sinceIds = param.getSinceIds(), maxIds = param.getMaxIds(); - final List result = new ArrayList<>(); - int idx = 0; - final int loadItemLimit = preferences.getInt(KEY_LOAD_ITEM_LIMIT, DEFAULT_LOAD_ITEM_LIMIT); - for (final UserKey accountKey : accountKeys) { - final MicroBlog twitter = MicroBlogAPIFactory.getInstance(context, accountKey); - if (twitter == null) continue; - try { - final Paging paging = new Paging(); - paging.setCount(loadItemLimit); - String maxId = null, sinceId = null; - if (maxIds != null && maxIds[idx] != null) { - maxId = maxIds[idx]; - paging.setMaxId(maxId); - } - if (sinceIds != null && sinceIds[idx] != null) { - sinceId = sinceIds[idx]; - long sinceIdLong = NumberUtils.toLong(sinceId, -1); - //TODO handle non-twitter case - if (sinceIdLong != -1) { - paging.sinceId(String.valueOf(sinceIdLong - 1)); - } else { - paging.sinceId(sinceId); - } - if (maxIds == null || sinceIds[idx] == null) { - paging.setLatestResults(true); - } - } - final List messages = getDirectMessages(twitter, paging); - result.add(new TwitterWrapper.MessageListResponse(accountKey, maxId, sinceId, messages)); - storeMessages(accountKey, messages, isOutgoing(), true); - errorInfoStore.remove(ErrorInfoStore.KEY_DIRECT_MESSAGES, accountKey); - } catch (final MicroBlogException e) { - if (e.getErrorCode() == ErrorInfo.NO_DIRECT_MESSAGE_PERMISSION) { - errorInfoStore.put(ErrorInfoStore.KEY_DIRECT_MESSAGES, accountKey, - ErrorInfoStore.CODE_NO_DM_PERMISSION); - } else if (e.isCausedByNetworkIssue()) { - errorInfoStore.put(ErrorInfoStore.KEY_DIRECT_MESSAGES, accountKey, - ErrorInfoStore.CODE_NETWORK_ERROR); - } - if (BuildConfig.DEBUG) { - Log.w(TwidereConstants.LOGTAG, e); - } - result.add(new TwitterWrapper.MessageListResponse(accountKey, e)); - } - idx++; - } - return result; - - } - - private boolean storeMessages(UserKey accountKey, List messages, boolean isOutgoing, boolean notify) { - if (messages == null) return true; - final Uri uri = getDatabaseUri(); - final ContentValues[] valuesArray = new ContentValues[messages.size()]; - - for (int i = 0, j = messages.size(); i < j; i++) { - final DirectMessage message = messages.get(i); - try { - valuesArray[i] = ContentValuesCreator.createDirectMessage(message, accountKey, isOutgoing); - } catch (IOException e) { - return false; - } - } - - // Delete all rows conflicting before new data inserted. -// final Expression deleteWhere = Expression.and(Expression.equals(DirectMessages.ACCOUNT_ID, accountKey), -// Expression.in(new Column(DirectMessages.MESSAGE_ID), new RawItemArray(messageIds))); -// final Uri deleteUri = UriUtils.appendQueryParameters(uri, QUERY_PARAM_NOTIFY, false); -// mResolver.delete(deleteUri, deleteWhere.getSQL(), null); - - - // Insert previously fetched items. - final Uri insertUri = UriUtils.appendQueryParameters(uri, TwidereConstants.QUERY_PARAM_NOTIFY, notify); - ContentResolverUtils.bulkInsert(context.getContentResolver(), insertUri, valuesArray); - return false; - } - - - public void beforeExecute(RefreshTaskParam params) { - bus.post(new GetMessagesTaskEvent(getDatabaseUri(), true, null)); - } - - @Override - protected void afterExecute(Object handler, List result) { - bus.post(new GetMessagesTaskEvent(getDatabaseUri(), false, AsyncTwitterWrapper.getException(result))); - } -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/GetLocalTrendsTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/GetLocalTrendsTask.java deleted file mode 100644 index 50facaa33..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/task/GetLocalTrendsTask.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.mariotaku.twidere.task; - -import android.content.Context; -import android.net.Uri; -import android.support.annotation.NonNull; - -import org.mariotaku.microblog.library.MicroBlog; -import org.mariotaku.microblog.library.MicroBlogException; -import org.mariotaku.microblog.library.twitter.model.Trends; -import org.mariotaku.twidere.model.UserKey; -import org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends; - -import java.util.List; - -/** - * Created by mariotaku on 16/2/24. - */ -public class GetLocalTrendsTask extends GetTrendsTask { - - private final int woeid; - - public GetLocalTrendsTask(final Context context, final UserKey accountKey, final int woeid) { - super(context, accountKey); - this.woeid = woeid; - } - - @Override - public List getTrends(@NonNull final MicroBlog twitter) throws MicroBlogException { - return twitter.getLocationTrends(woeid); - } - - @Override - protected Uri getContentUri() { - return CachedTrends.Local.CONTENT_URI; - } - -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/GetSavedSearchesTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/GetSavedSearchesTask.java deleted file mode 100644 index b607b443a..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/task/GetSavedSearchesTask.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.mariotaku.twidere.task; - -import android.content.ContentResolver; -import android.content.ContentValues; -import android.content.Context; -import android.util.Log; - -import org.mariotaku.abstask.library.AbstractTask; -import org.mariotaku.microblog.library.MicroBlog; -import org.mariotaku.microblog.library.MicroBlogException; -import org.mariotaku.microblog.library.twitter.model.ResponseList; -import org.mariotaku.microblog.library.twitter.model.SavedSearch; -import org.mariotaku.sqliteqb.library.Expression; -import org.mariotaku.twidere.BuildConfig; -import org.mariotaku.twidere.model.SingleResponse; -import org.mariotaku.twidere.model.UserKey; -import org.mariotaku.twidere.provider.TwidereDataStore.SavedSearches; -import org.mariotaku.twidere.util.ContentValuesCreator; -import org.mariotaku.twidere.util.MicroBlogAPIFactory; -import org.mariotaku.twidere.util.content.ContentResolverUtils; - -import static org.mariotaku.twidere.TwidereConstants.LOGTAG; - -/** - * Created by mariotaku on 16/2/13. - */ -public class GetSavedSearchesTask extends AbstractTask, Object> { - - private final Context mContext; - - public GetSavedSearchesTask(Context context) { - this.mContext = context; - } - - @Override - public SingleResponse doLongOperation(UserKey[] params) { - final ContentResolver cr = mContext.getContentResolver(); - for (UserKey accountKey : params) { - final MicroBlog twitter = MicroBlogAPIFactory.getInstance(mContext, accountKey); - if (twitter == null) continue; - try { - final ResponseList searches = twitter.getSavedSearches(); - final ContentValues[] values = ContentValuesCreator.createSavedSearches(searches, - accountKey); - final Expression where = Expression.equalsArgs(SavedSearches.ACCOUNT_KEY); - final String[] whereArgs = {accountKey.toString()}; - cr.delete(SavedSearches.CONTENT_URI, where.getSQL(), whereArgs); - ContentResolverUtils.bulkInsert(cr, SavedSearches.CONTENT_URI, values); - } catch (MicroBlogException e) { - if (BuildConfig.DEBUG) { - Log.w(LOGTAG, e); - } - } - } - return SingleResponse.Companion.getInstance(); - } -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/GetTrendsTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/GetTrendsTask.java deleted file mode 100644 index 5304f33c7..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/task/GetTrendsTask.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.mariotaku.twidere.task; - -import android.content.ContentResolver; -import android.content.ContentValues; -import android.content.Context; -import android.net.Uri; -import android.support.annotation.NonNull; - -import com.squareup.otto.Bus; - -import org.mariotaku.abstask.library.AbstractTask; -import org.mariotaku.microblog.library.MicroBlog; -import org.mariotaku.microblog.library.MicroBlogException; -import org.mariotaku.microblog.library.twitter.model.Trends; -import org.mariotaku.twidere.model.UserKey; -import org.mariotaku.twidere.model.message.TrendsRefreshedEvent; -import org.mariotaku.twidere.provider.TwidereDataStore; -import org.mariotaku.twidere.util.ContentValuesCreator; -import org.mariotaku.twidere.util.MicroBlogAPIFactory; -import org.mariotaku.twidere.util.content.ContentResolverUtils; -import org.mariotaku.twidere.util.dagger.GeneralComponentHelper; - -import java.util.ArrayList; -import java.util.List; - -import javax.inject.Inject; - -/** - * Created by mariotaku on 16/2/24. - */ -public abstract class GetTrendsTask extends AbstractTask { - - private final Context mContext; - private final UserKey mAccountId; - - @Inject - protected Bus mBus; - - public GetTrendsTask(Context context, final UserKey accountKey) { - GeneralComponentHelper.build(context).inject(this); - this.mContext = context; - this.mAccountId = accountKey; - } - - public abstract List getTrends(@NonNull MicroBlog twitter) throws MicroBlogException; - - @Override - public Object doLongOperation(final Object param) { - final MicroBlog twitter = MicroBlogAPIFactory.getInstance(mContext, mAccountId); - if (twitter == null) return null; - try { - final List trends = getTrends(twitter); - storeTrends(mContext.getContentResolver(), getContentUri(), trends); - return null; - } catch (final MicroBlogException e) { - return null; - } - } - - @Override - protected void afterExecute(Object handler, Object result) { - mBus.post(new TrendsRefreshedEvent()); - } - - protected abstract Uri getContentUri(); - - private static void storeTrends(ContentResolver cr, Uri uri, List trendsList) { - final ArrayList hashtags = new ArrayList<>(); - final ArrayList hashtagValues = new ArrayList<>(); - if (trendsList != null && trendsList.size() > 0) { - final ContentValues[] valuesArray = ContentValuesCreator.createTrends(trendsList); - for (final ContentValues values : valuesArray) { - final String hashtag = values.getAsString(TwidereDataStore.CachedTrends.NAME).replaceFirst("#", ""); - if (hashtags.contains(hashtag)) { - continue; - } - hashtags.add(hashtag); - final ContentValues hashtagValue = new ContentValues(); - hashtagValue.put(TwidereDataStore.CachedHashtags.NAME, hashtag); - hashtagValues.add(hashtagValue); - } - cr.delete(uri, null, null); - ContentResolverUtils.bulkInsert(cr, uri, valuesArray); - ContentResolverUtils.bulkDelete(cr, TwidereDataStore.CachedHashtags.CONTENT_URI, TwidereDataStore.CachedHashtags.NAME, hashtags, null); - ContentResolverUtils.bulkInsert(cr, TwidereDataStore.CachedHashtags.CONTENT_URI, - hashtagValues.toArray(new ContentValues[hashtagValues.size()])); - } - } -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/SaveMediaToGalleryTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/SaveMediaToGalleryTask.java deleted file mode 100644 index d7af93a04..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/task/SaveMediaToGalleryTask.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2015 Mariotaku Lee - * - * 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. - * - * This program 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 this program. If not, see . - */ - -package org.mariotaku.twidere.task; - -import android.app.Activity; -import android.content.Context; -import android.media.MediaScannerConnection; -import android.net.Uri; -import android.os.Environment; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.widget.Toast; - -import org.mariotaku.twidere.R; -import org.mariotaku.twidere.provider.CacheProvider; - -import java.io.File; - -/** - * Created by mariotaku on 15/12/28. - */ -public class SaveMediaToGalleryTask extends ProgressSaveFileTask { - - public SaveMediaToGalleryTask(@NonNull Activity activity, @NonNull Uri source, @NonNull File destination, String type) { - super(activity, source, destination, new CacheProvider.CacheFileTypeCallback(activity, type)); - } - - public static SaveFileTask create(final Activity activity, final Uri source, - @NonNull @CacheProvider.Type final String type) { - final File pubDir; - switch (type) { - case CacheProvider.Type.VIDEO: { - pubDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES); - break; - } - case CacheProvider.Type.IMAGE: { - pubDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); - break; - } - default: { - pubDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); - break; - } - } - final File saveDir = new File(pubDir, "Twidere"); - return new SaveMediaToGalleryTask(activity, source, saveDir, type); - } - - @Override - protected void onFileSaved(@NonNull File savedFile, @Nullable String mimeType) { - final Context context = getContext(); - if (context == null) return; - MediaScannerConnection.scanFile(context, new String[]{savedFile.getPath()}, - new String[]{mimeType}, null); - Toast.makeText(context, R.string.saved_to_gallery, Toast.LENGTH_SHORT).show(); - } - - @Override - protected void onFileSaveFailed() { - final Context context = getContext(); - if (context == null) return; - Toast.makeText(context, R.string.error_occurred, Toast.LENGTH_SHORT).show(); - } - -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java b/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java index 08ab597dd..e83fae1e1 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/AsyncTwitterWrapper.java @@ -47,9 +47,7 @@ import org.mariotaku.microblog.library.twitter.http.HttpResponseCode; import org.mariotaku.microblog.library.twitter.model.DirectMessage; import org.mariotaku.microblog.library.twitter.model.ErrorInfo; import org.mariotaku.microblog.library.twitter.model.FriendshipUpdate; -import org.mariotaku.microblog.library.twitter.model.Paging; import org.mariotaku.microblog.library.twitter.model.Relationship; -import org.mariotaku.microblog.library.twitter.model.ResponseList; import org.mariotaku.microblog.library.twitter.model.SavedSearch; import org.mariotaku.microblog.library.twitter.model.User; import org.mariotaku.microblog.library.twitter.model.UserList; @@ -106,10 +104,11 @@ import org.mariotaku.twidere.task.DestroyStatusTask; import org.mariotaku.twidere.task.DestroyUserBlockTask; import org.mariotaku.twidere.task.DestroyUserMuteTask; import org.mariotaku.twidere.task.GetActivitiesAboutMeTask; -import org.mariotaku.twidere.task.GetDirectMessagesTask; import org.mariotaku.twidere.task.GetHomeTimelineTask; import org.mariotaku.twidere.task.GetLocalTrendsTask; +import org.mariotaku.twidere.task.GetReceivedDirectMessagesTask; import org.mariotaku.twidere.task.GetSavedSearchesTask; +import org.mariotaku.twidere.task.GetSentDirectMessagesTask; import org.mariotaku.twidere.task.ManagedAsyncTask; import org.mariotaku.twidere.task.ReportSpamAndBlockTask; import org.mariotaku.twidere.task.twitter.GetActivitiesTask; @@ -1325,61 +1324,6 @@ public class AsyncTwitterWrapper extends TwitterWrapper { } - static class GetReceivedDirectMessagesTask extends GetDirectMessagesTask { - - public GetReceivedDirectMessagesTask(Context context) { - super(context); - } - - @Override - public ResponseList getDirectMessages(final MicroBlog twitter, final Paging paging) - throws MicroBlogException { - return twitter.getDirectMessages(paging); - } - - @Override - protected Uri getDatabaseUri() { - return Inbox.CONTENT_URI; - } - - - @Override - protected boolean isOutgoing() { - return false; - } - - @Override - public void beforeExecute(RefreshTaskParam params) { - final Intent intent = new Intent(BROADCAST_RESCHEDULE_DIRECT_MESSAGES_REFRESHING); - context.sendBroadcast(intent); - super.beforeExecute(params); - } - } - - static class GetSentDirectMessagesTask extends GetDirectMessagesTask { - - public GetSentDirectMessagesTask(Context context) { - super(context); - } - - @Override - public ResponseList getDirectMessages(final MicroBlog twitter, final Paging paging) - throws MicroBlogException { - return twitter.getSentDirectMessages(paging); - } - - @Override - protected boolean isOutgoing() { - return true; - } - - @Override - protected Uri getDatabaseUri() { - return Outbox.CONTENT_URI; - } - - } - public SharedPreferencesWrapper getPreferences() { return preferences; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java b/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java index 7b98c3226..87b0d258f 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java @@ -1187,6 +1187,7 @@ public final class Utils implements Constants { public static void startRefreshServiceIfNeeded(@NonNull final Context context) { final Context appContext = context.getApplicationContext(); if (appContext == null) return; + if (!appContext.getResources().getBoolean(R.bool.use_legacy_refresh_service)) return; final Intent refreshServiceIntent = new Intent(appContext, RefreshService.class); AsyncTask.execute(new Runnable() { @Override diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/MediaViewerActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/MediaViewerActivity.kt index 4d03c03aa..7711d1dad 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/MediaViewerActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/MediaViewerActivity.kt @@ -396,15 +396,11 @@ class MediaViewerActivity : BaseActivity(), IExtendedActivity, ATEToolbarCustomi val viewPager = findViewPager() val adapter = viewPager.adapter val f = adapter.instantiateItem(viewPager, saveToStoragePosition) as? CacheDownloadMediaViewerFragment ?: return - val result = f.downloadResult ?: return - val cacheUri = result.cacheUri - val hasMedia = cacheUri != null - if (!hasMedia) return - val task: SaveFileTask - when (f) { - is ImagePageFragment -> task = SaveMediaToGalleryTask.create(this, cacheUri, CacheProvider.Type.IMAGE) - is VideoPageFragment -> task = SaveMediaToGalleryTask.create(this, cacheUri, CacheProvider.Type.VIDEO) - is GifPageFragment -> task = SaveMediaToGalleryTask.create(this, cacheUri, CacheProvider.Type.IMAGE) + val cacheUri = f.downloadResult?.cacheUri ?: return + val task: SaveFileTask = when (f) { + is ImagePageFragment -> SaveMediaToGalleryTask.create(this, cacheUri, CacheProvider.Type.IMAGE) + is VideoPageFragment -> SaveMediaToGalleryTask.create(this, cacheUri, CacheProvider.Type.VIDEO) + is GifPageFragment -> SaveMediaToGalleryTask.create(this, cacheUri, CacheProvider.Type.IMAGE) else -> throw UnsupportedOperationException() } AsyncTaskUtils.executeTask(task) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/app/TwidereApplication.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/app/TwidereApplication.kt index dd3ce3b44..930b9b276 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/app/TwidereApplication.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/app/TwidereApplication.kt @@ -27,7 +27,6 @@ import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteOpenHelper import android.graphics.Color import android.os.AsyncTask -import android.os.Handler import android.support.design.widget.FloatingActionButton import android.support.multidex.MultiDex import android.support.v4.content.ContextCompat @@ -46,6 +45,8 @@ import nl.komponents.kovenant.android.stopKovenant import nl.komponents.kovenant.task import org.apache.commons.lang3.ArrayUtils import org.mariotaku.kpreferences.KPreferences +import org.mariotaku.kpreferences.get +import org.mariotaku.kpreferences.set import org.mariotaku.ktextension.configure import org.mariotaku.mediaviewer.library.MediaDownloader import org.mariotaku.restfu.http.RestHttpClient @@ -56,6 +57,8 @@ import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.activity.AssistLauncherActivity import org.mariotaku.twidere.activity.MainActivity import org.mariotaku.twidere.activity.MainHondaJOJOActivity +import org.mariotaku.twidere.constant.apiLastChangeKey +import org.mariotaku.twidere.constant.bugReportsKey import org.mariotaku.twidere.constant.defaultFeatureLastUpdated import org.mariotaku.twidere.model.DefaultFeatures import org.mariotaku.twidere.service.RefreshService @@ -89,25 +92,14 @@ class TwidereApplication : Application(), Constants, OnSharedPreferenceChangeLis @Inject lateinit internal var kPreferences: KPreferences - var handler: Handler? = null - private set - - private var profileImageViewViewProcessor: ProfileImageViewViewProcessor? = null - private var fontFamilyTagProcessor: FontFamilyTagProcessor? = null + private lateinit var profileImageViewViewProcessor: ProfileImageViewViewProcessor + private lateinit var fontFamilyTagProcessor: FontFamilyTagProcessor override fun attachBaseContext(base: Context) { super.attachBaseContext(base) MultiDex.install(this) } - fun initKeyboardShortcuts() { - val preferences = sharedPreferences - if (!preferences.getBoolean(KEY_KEYBOARD_SHORTCUT_INITIALIZED, false)) { - // getApplicationModule().getKeyboardShortcutsHandler().reset(); - preferences.edit().putBoolean(KEY_KEYBOARD_SHORTCUT_INITIALIZED, true).apply() - } - } - val sqLiteDatabase: SQLiteDatabase by lazy { StrictModeUtils.checkDiskIO() @@ -131,12 +123,14 @@ class TwidereApplication : Application(), Constants, OnSharedPreferenceChangeLis initializeAsyncTask() initDebugMode() initBugReport() - handler = Handler() updateEasterEggIcon() migrateUsageStatisticsPreferences() - Utils.startRefreshServiceIfNeeded(this) + if (resources.getBoolean(R.bool.use_job_refresh_service)) { + } else { + Utils.startRefreshServiceIfNeeded(this) + } GeneralComponentHelper.build(this).inject(this) @@ -225,9 +219,9 @@ class TwidereApplication : Application(), Constants, OnSharedPreferenceChangeLis ATE.registerViewProcessor(ImageView::class.java, ImageViewViewProcessor()) ATE.registerViewProcessor(MaterialEditText::class.java, MaterialEditTextViewProcessor()) ATE.registerViewProcessor(ProgressWheel::class.java, ProgressWheelViewProcessor()) - ATE.registerViewProcessor(ProfileImageView::class.java, profileImageViewViewProcessor!!) + ATE.registerViewProcessor(ProfileImageView::class.java, profileImageViewViewProcessor) ATE.registerTagProcessor(OptimalLinkColorTagProcessor.TAG, OptimalLinkColorTagProcessor()) - ATE.registerTagProcessor(FontFamilyTagProcessor.TAG, fontFamilyTagProcessor!!) + ATE.registerTagProcessor(FontFamilyTagProcessor.TAG, fontFamilyTagProcessor) ATE.registerTagProcessor(IconActionButtonTagProcessor.PREFIX_COLOR, IconActionButtonTagProcessor(IconActionButtonTagProcessor.PREFIX_COLOR)) ATE.registerTagProcessor(IconActionButtonTagProcessor.PREFIX_COLOR_ACTIVATED, @@ -256,8 +250,7 @@ class TwidereApplication : Application(), Constants, OnSharedPreferenceChangeLis } private fun initBugReport() { - val preferences = sharedPreferences - if (!preferences.getBoolean(KEY_BUG_REPORTS, BuildConfig.DEBUG)) return + if (!sharedPreferences[bugReportsKey]) return BugReporter.setImplementation(TwidereBugReporter()) BugReporter.init(this) } @@ -305,9 +298,7 @@ class TwidereApplication : Application(), Constants, OnSharedPreferenceChangeLis } KEY_CONSUMER_KEY, KEY_CONSUMER_SECRET, KEY_API_URL_FORMAT, KEY_CREDENTIALS_TYPE, KEY_SAME_OAUTH_SIGNING_URL, KEY_THUMBOR_ENABLED, KEY_THUMBOR_ADDRESS, KEY_THUMBOR_SECURITY_KEY -> { - val editor = preferences.edit() - editor.putLong(KEY_API_LAST_CHANGE, System.currentTimeMillis()) - editor.apply() + preferences[apiLastChangeKey] = System.currentTimeMillis() } KEY_EMOJI_SUPPORT -> { externalThemeManager.reloadEmojiPreferences() @@ -321,11 +312,11 @@ class TwidereApplication : Application(), Constants, OnSharedPreferenceChangeLis } KEY_PROFILE_IMAGE_STYLE -> { Config.markChanged(this, VALUE_THEME_NAME_LIGHT, VALUE_THEME_NAME_DARK) - profileImageViewViewProcessor!!.setStyle(Utils.getProfileImageStyle(preferences.getString(key, null))) + profileImageViewViewProcessor.setStyle(Utils.getProfileImageStyle(preferences.getString(key, null))) } KEY_THEME_FONT_FAMILY -> { Config.markChanged(this, VALUE_THEME_NAME_LIGHT, VALUE_THEME_NAME_DARK) - fontFamilyTagProcessor!!.setFontFamily(ThemeUtils.getThemeFontFamily(preferences)) + fontFamilyTagProcessor.setFontFamily(ThemeUtils.getThemeFontFamily(preferences)) } KEY_THEME_COLOR -> { val themeColor = preferences.getInt(key, ContextCompat.getColor(this, diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/constant/PreferenceKeys.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/constant/PreferenceKeys.kt index 09950887e..d25953f9e 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/constant/PreferenceKeys.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/constant/PreferenceKeys.kt @@ -4,10 +4,9 @@ import android.content.SharedPreferences import android.os.Build import android.text.TextUtils import org.mariotaku.kpreferences.* +import org.mariotaku.twidere.BuildConfig import org.mariotaku.twidere.Constants.KEY_NO_CLOSE_AFTER_TWEET_SENT import org.mariotaku.twidere.TwidereConstants.* -import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_ATTACH_PRECISE_LOCATION -import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_SETTINGS_WIZARD_COMPLETED import org.mariotaku.twidere.extension.getNonEmptyString import org.mariotaku.twidere.model.CustomAPIConfig import org.mariotaku.twidere.model.account.cred.Credentials @@ -37,6 +36,9 @@ val noCloseAfterTweetSentKey = KBooleanKey(KEY_NO_CLOSE_AFTER_TWEET_SENT, false) val loadItemLimitKey = KIntKey(KEY_LOAD_ITEM_LIMIT, DEFAULT_LOAD_ITEM_LIMIT) val defaultFeatureLastUpdated = KLongKey("default_feature_last_updated", -1) val drawerTutorialCompleted = KBooleanKey(KEY_SETTINGS_WIZARD_COMPLETED, false) +val stopAutoRefreshWhenBatteryLowKey = KBooleanKey(KEY_STOP_AUTO_REFRESH_WHEN_BATTERY_LOW, true) +val apiLastChangeKey = KLongKey(KEY_API_LAST_CHANGE, -1) +val bugReportsKey = KBooleanKey(KEY_BUG_REPORTS, BuildConfig.DEBUG) object defaultAPIConfigKey : KPreferenceKey { override fun contains(preferences: SharedPreferences): Boolean { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AccountsDashboardFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AccountsDashboardFragment.kt index aac8c4241..1fed02a76 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AccountsDashboardFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AccountsDashboardFragment.kt @@ -41,9 +41,7 @@ import android.os.Looper import android.support.design.widget.NavigationView import android.support.v4.app.LoaderManager.LoaderCallbacks import android.support.v4.content.AsyncTaskLoader -import android.support.v4.content.ContextCompat import android.support.v4.content.Loader -import android.support.v4.graphics.drawable.DrawableCompat import android.support.v4.view.MenuItemCompat import android.support.v4.view.ViewPager import android.support.v7.view.SupportMenuInflater @@ -55,7 +53,10 @@ import android.view.View.OnClickListener import android.view.animation.DecelerateInterpolator import android.widget.ImageView import kotlinx.android.synthetic.main.header_drawer_account_selector.view.* -import org.mariotaku.ktextension.* +import org.mariotaku.ktextension.addOnAccountsUpdatedListenerSafe +import org.mariotaku.ktextension.convert +import org.mariotaku.ktextension.removeOnAccountsUpdatedListenerSafe +import org.mariotaku.ktextension.setItemAvailability import org.mariotaku.twidere.R import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.activity.* @@ -79,9 +80,9 @@ import java.util.* class AccountsDashboardFragment : BaseSupportFragment(), LoaderCallbacks, OnSharedPreferenceChangeListener, OnClickListener, KeyboardShortcutCallback, NavigationView.OnNavigationItemSelectedListener { - private val mSystemWindowsInsets = Rect() + private val systemWindowsInsets = Rect() - private var accountsAdapter: AccountSelectorAdapter? = null + private lateinit var accountsAdapter: AccountSelectorAdapter private val hasNextAccountIndicator by lazy { accountsHeader.hasNextAccountIndicator } private val hasPrevAccountIndicator by lazy { accountsHeader.hasPrevAccountIndicator } @@ -113,7 +114,7 @@ class AccountsDashboardFragment : BaseSupportFragment(), LoaderCallbacks { - val account = accountsAdapter!!.selectedAccount ?: return@OnMenuItemClickListener true + val account = accountsAdapter.selectedAccount ?: return@OnMenuItemClickListener true val composeIntent = Intent(INTENT_ACTION_COMPOSE) composeIntent.setClass(activity, ComposeActivity::class.java) composeIntent.putExtra(EXTRA_ACCOUNT_KEY, account.key) @@ -225,7 +226,7 @@ class AccountsDashboardFragment : BaseSupportFragment(), LoaderCallbacks { - val account = accountsAdapter!!.selectedAccount ?: return + val account = accountsAdapter.selectedAccount ?: return val activity = activity if (account.user != null) { IntentUtils.openUserProfile(activity, account.user!!, null, @@ -262,18 +263,18 @@ class AccountsDashboardFragment : BaseSupportFragment(), LoaderCallbacks { if (!hasDmTab) { @@ -338,17 +338,8 @@ class AccountsDashboardFragment : BaseSupportFragment(), LoaderCallbacks { val intent = Intent(activity, QuickSearchBarActivity::class.java) @@ -520,9 +511,9 @@ class AccountsDashboardFragment : BaseSupportFragment(), LoaderCallbacks { - IntentUtils.openUserFavorites(activity, account.key, - account.key, account.user.screen_name) + R.id.likes, R.id.favorites -> { + IntentUtils.openUserFavorites(activity, account.key, account.key, + account.user.screen_name) } R.id.lists -> { IntentUtils.openUserLists(activity, account.key, diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/service/JobRefreshService.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/service/JobRefreshService.kt new file mode 100644 index 000000000..6e2d50e4e --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/service/JobRefreshService.kt @@ -0,0 +1,101 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2014 Mariotaku Lee + * + * 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. + * + * This program 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 this program. If not, see . + */ + +package org.mariotaku.twidere.service + +import android.annotation.SuppressLint +import android.annotation.TargetApi +import android.app.job.JobParameters +import android.app.job.JobService +import android.os.Build +import org.mariotaku.abstask.library.AbstractTask +import org.mariotaku.abstask.library.TaskStarter +import org.mariotaku.kpreferences.KPreferences +import org.mariotaku.twidere.constant.IntentConstants.* +import org.mariotaku.twidere.constant.stopAutoRefreshWhenBatteryLowKey +import org.mariotaku.twidere.model.AccountPreferences +import org.mariotaku.twidere.provider.TwidereDataStore.* +import org.mariotaku.twidere.task.GetActivitiesAboutMeTask +import org.mariotaku.twidere.task.GetHomeTimelineTask +import org.mariotaku.twidere.task.GetReceivedDirectMessagesTask +import org.mariotaku.twidere.util.DataStoreUtils +import org.mariotaku.twidere.util.Utils +import org.mariotaku.twidere.util.dagger.GeneralComponentHelper +import javax.inject.Inject + +/** + * Created by mariotaku on 14/12/12. + */ +@SuppressLint("Registered") +@TargetApi(Build.VERSION_CODES.LOLLIPOP) +class JobRefreshService : JobService() { + + @Inject + internal lateinit var preferences: KPreferences + + override fun onCreate() { + super.onCreate() + GeneralComponentHelper.build(this).inject(this) + } + + override fun onStartJob(params: JobParameters): Boolean { + if (!Utils.isBatteryOkay(this) && preferences[stopAutoRefreshWhenBatteryLowKey]) { + // Low battery, don't refresh + return false + } + + val task = createJobTask(params) ?: return false + task.callback = { + this.jobFinished(params, true) + } + TaskStarter.execute(task) + return true + } + + override fun onStopJob(params: JobParameters): Boolean { + return false + } + + internal fun createJobTask(params: JobParameters): AbstractTask<*, *, () -> Unit>? { + when (params.extras?.getString(EXTRA_ACTION)) { + BROADCAST_REFRESH_HOME_TIMELINE -> { + val task = GetHomeTimelineTask(this) + task.params = RefreshService.AutoRefreshTaskParam(this, AccountPreferences::isAutoRefreshHomeTimelineEnabled) { accountKeys -> + DataStoreUtils.getNewestStatusIds(this, Statuses.CONTENT_URI, accountKeys) + } + return task + } + BROADCAST_REFRESH_NOTIFICATIONS -> { + val task = GetActivitiesAboutMeTask(this) + task.params = RefreshService.AutoRefreshTaskParam(this, AccountPreferences::isAutoRefreshMentionsEnabled) { accountKeys -> + DataStoreUtils.getNewestActivityMaxPositions(this, Activities.AboutMe.CONTENT_URI, accountKeys) + } + return task + } + BROADCAST_REFRESH_DIRECT_MESSAGES -> { + val task = GetReceivedDirectMessagesTask(this) + task.params = RefreshService.AutoRefreshTaskParam(this, AccountPreferences::isAutoRefreshDirectMessagesEnabled) { accountKeys -> + DataStoreUtils.getNewestMessageIds(this, DirectMessages.Inbox.CONTENT_URI, accountKeys) + } + return task + } + } + return null + } +} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/service/RefreshService.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/service/RefreshService.kt new file mode 100644 index 000000000..277e6eaa5 --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/service/RefreshService.kt @@ -0,0 +1,304 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2014 Mariotaku Lee + * + * 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. + * + * This program 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 this program. If not, see . + */ + +package org.mariotaku.twidere.service + +import android.app.AlarmManager +import android.app.PendingIntent +import android.app.Service +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.os.IBinder +import android.os.SystemClock +import android.util.Log +import edu.tsinghua.hotmobi.model.BatteryRecord +import edu.tsinghua.hotmobi.model.ScreenEvent +import org.apache.commons.lang3.math.NumberUtils +import org.mariotaku.twidere.BuildConfig +import org.mariotaku.twidere.Constants +import org.mariotaku.twidere.TwidereConstants.LOGTAG +import org.mariotaku.twidere.constant.IntentConstants.* +import org.mariotaku.twidere.constant.SharedPreferenceConstants.* +import org.mariotaku.twidere.model.AccountPreferences +import org.mariotaku.twidere.model.SimpleRefreshTaskParam +import org.mariotaku.twidere.model.UserKey +import org.mariotaku.twidere.provider.TwidereDataStore.* +import org.mariotaku.twidere.receiver.PowerStateReceiver +import org.mariotaku.twidere.util.AsyncTwitterWrapper +import org.mariotaku.twidere.util.DataStoreUtils +import org.mariotaku.twidere.util.SharedPreferencesWrapper +import org.mariotaku.twidere.util.Utils +import org.mariotaku.twidere.util.dagger.GeneralComponentHelper +import javax.inject.Inject + +class RefreshService : Service(), Constants { + + @Inject + internal lateinit var preferences: SharedPreferencesWrapper + @Inject + internal lateinit var twitterWrapper: AsyncTwitterWrapper + + private lateinit var alarmManager: AlarmManager + private var pendingRefreshHomeTimelineIntent: PendingIntent? = null + private var pendingRefreshMentionsIntent: PendingIntent? = null + private var pendingRefreshDirectMessagesIntent: PendingIntent? = null + private var pendingRefreshTrendsIntent: PendingIntent? = null + + private val mStateReceiver = object : BroadcastReceiver() { + + override fun onReceive(context: Context, intent: Intent) { + val action = intent.action + if (BuildConfig.DEBUG) { + Log.d(LOGTAG, String.format("Refresh service received action %s", action)) + } + when (action) { + BROADCAST_RESCHEDULE_HOME_TIMELINE_REFRESHING -> { + rescheduleHomeTimelineRefreshing() + } + BROADCAST_RESCHEDULE_MENTIONS_REFRESHING -> { + rescheduleMentionsRefreshing() + } + BROADCAST_RESCHEDULE_DIRECT_MESSAGES_REFRESHING -> { + rescheduleDirectMessagesRefreshing() + } + BROADCAST_RESCHEDULE_TRENDS_REFRESHING -> { + rescheduleTrendsRefreshing() + } + BROADCAST_REFRESH_HOME_TIMELINE -> { + if (isAutoRefreshAllowed) { + twitterWrapper.getHomeTimelineAsync(AutoRefreshTaskParam(context, + AccountPreferences::isAutoRefreshHomeTimelineEnabled) { accountKeys -> + DataStoreUtils.getNewestStatusIds(context, Statuses.CONTENT_URI, accountKeys) + }) + } + } + BROADCAST_REFRESH_NOTIFICATIONS -> { + if (isAutoRefreshAllowed) { + twitterWrapper.getActivitiesAboutMeAsync(AutoRefreshTaskParam(context, + AccountPreferences::isAutoRefreshMentionsEnabled) { accountKeys -> + DataStoreUtils.getNewestActivityMaxPositions(context, + Activities.AboutMe.CONTENT_URI, accountKeys) + }) + } + } + BROADCAST_REFRESH_DIRECT_MESSAGES -> { + if (isAutoRefreshAllowed) { + twitterWrapper.getReceivedDirectMessagesAsync(AutoRefreshTaskParam(context, + AccountPreferences::isAutoRefreshDirectMessagesEnabled) { accountKeys -> + DataStoreUtils.getNewestMessageIds(context, + DirectMessages.Inbox.CONTENT_URI, accountKeys) + }) + } + } + BROADCAST_REFRESH_TRENDS -> { + if (isAutoRefreshAllowed) { + val prefs = AccountPreferences.getAccountPreferences(context, + DataStoreUtils.getAccountKeys(context)).filter(AccountPreferences::isAutoRefreshEnabled) + getLocalTrends(prefs.filter(AccountPreferences::isAutoRefreshTrendsEnabled) + .map(AccountPreferences::getAccountKey).toTypedArray()) + } + } + } + } + + } + + private val mPowerStateReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + when (intent.action) { + Intent.ACTION_BATTERY_CHANGED -> { + BatteryRecord.log(context, intent) + } + else -> { + BatteryRecord.log(context) + } + } + } + } + + private val mScreenStateReceiver = object : BroadcastReceiver() { + var mPresentTime: Long = -1 + + override fun onReceive(context: Context, intent: Intent) { + when (intent.action) { + Intent.ACTION_SCREEN_ON -> { + ScreenEvent.log(context, ScreenEvent.Action.ON, presentDuration) + } + Intent.ACTION_SCREEN_OFF -> { + ScreenEvent.log(context, ScreenEvent.Action.OFF, presentDuration) + mPresentTime = -1 + } + Intent.ACTION_USER_PRESENT -> { + mPresentTime = SystemClock.elapsedRealtime() + ScreenEvent.log(context, ScreenEvent.Action.PRESENT, -1) + } + } + } + + private val presentDuration: Long + get() { + if (mPresentTime < 0) return -1 + return SystemClock.elapsedRealtime() - mPresentTime + } + } + + override fun onBind(intent: Intent): IBinder? { + return null + } + + override fun onCreate() { + super.onCreate() + GeneralComponentHelper.build(this).inject(this) + alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager + pendingRefreshHomeTimelineIntent = PendingIntent.getBroadcast(this, 0, Intent( + BROADCAST_REFRESH_HOME_TIMELINE), 0) + pendingRefreshMentionsIntent = PendingIntent.getBroadcast(this, 0, Intent(BROADCAST_REFRESH_NOTIFICATIONS), 0) + pendingRefreshDirectMessagesIntent = PendingIntent.getBroadcast(this, 0, Intent( + BROADCAST_REFRESH_DIRECT_MESSAGES), 0) + pendingRefreshTrendsIntent = PendingIntent.getBroadcast(this, 0, Intent(BROADCAST_REFRESH_TRENDS), 0) + val refreshFilter = IntentFilter(BROADCAST_NOTIFICATION_DELETED) + refreshFilter.addAction(BROADCAST_REFRESH_HOME_TIMELINE) + refreshFilter.addAction(BROADCAST_REFRESH_NOTIFICATIONS) + refreshFilter.addAction(BROADCAST_REFRESH_DIRECT_MESSAGES) + refreshFilter.addAction(BROADCAST_RESCHEDULE_HOME_TIMELINE_REFRESHING) + refreshFilter.addAction(BROADCAST_RESCHEDULE_MENTIONS_REFRESHING) + refreshFilter.addAction(BROADCAST_RESCHEDULE_DIRECT_MESSAGES_REFRESHING) + registerReceiver(mStateReceiver, refreshFilter) + val batteryFilter = IntentFilter() + batteryFilter.addAction(Intent.ACTION_BATTERY_CHANGED) + batteryFilter.addAction(Intent.ACTION_BATTERY_OKAY) + batteryFilter.addAction(Intent.ACTION_BATTERY_LOW) + batteryFilter.addAction(Intent.ACTION_POWER_CONNECTED) + batteryFilter.addAction(Intent.ACTION_POWER_DISCONNECTED) + val screenFilter = IntentFilter() + screenFilter.addAction(Intent.ACTION_SCREEN_ON) + screenFilter.addAction(Intent.ACTION_SCREEN_OFF) + screenFilter.addAction(Intent.ACTION_USER_PRESENT) + registerReceiver(mPowerStateReceiver, batteryFilter) + registerReceiver(mScreenStateReceiver, screenFilter) + PowerStateReceiver.serviceReceiverStarted = true + if (Utils.hasAutoRefreshAccounts(this)) { + startAutoRefresh() + } else { + stopSelf() + } + } + + override fun onDestroy() { + PowerStateReceiver.serviceReceiverStarted = false + unregisterReceiver(mScreenStateReceiver) + unregisterReceiver(mPowerStateReceiver) + unregisterReceiver(mStateReceiver) + if (Utils.hasAutoRefreshAccounts(this)) { + // Auto refresh enabled, so I will try to start service after it was + // stopped. + startService(Intent(this, javaClass)) + } + super.onDestroy() + } + + protected val isAutoRefreshAllowed: Boolean + get() = Utils.isNetworkAvailable(this) && (Utils.isBatteryOkay(this) || !Utils.shouldStopAutoRefreshOnBatteryLow(this)) + + private fun getLocalTrends(accountIds: Array) { + val account_id = Utils.getDefaultAccountKey(this) + val woeid = preferences.getInt(KEY_LOCAL_TRENDS_WOEID, 1) + twitterWrapper.getLocalTrendsAsync(account_id, woeid) + } + + private val refreshInterval: Long + get() { + val prefValue = NumberUtils.toInt(preferences.getString(KEY_REFRESH_INTERVAL, DEFAULT_REFRESH_INTERVAL), -1) + return (Math.max(prefValue, 3) * 60 * 1000).toLong() + } + + private fun rescheduleDirectMessagesRefreshing() { + alarmManager.cancel(pendingRefreshDirectMessagesIntent) + val refreshInterval = refreshInterval + if (refreshInterval > 0) { + alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + refreshInterval, + refreshInterval, pendingRefreshDirectMessagesIntent) + } + } + + private fun rescheduleHomeTimelineRefreshing() { + alarmManager.cancel(pendingRefreshHomeTimelineIntent) + val refreshInterval = refreshInterval + if (refreshInterval > 0) { + alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + refreshInterval, + refreshInterval, pendingRefreshHomeTimelineIntent) + } + } + + private fun rescheduleMentionsRefreshing() { + alarmManager.cancel(pendingRefreshMentionsIntent) + val refreshInterval = refreshInterval + if (refreshInterval > 0) { + alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + refreshInterval, + refreshInterval, pendingRefreshMentionsIntent) + } + } + + private fun rescheduleTrendsRefreshing() { + alarmManager.cancel(pendingRefreshTrendsIntent) + val refreshInterval = refreshInterval + if (refreshInterval > 0) { + alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + refreshInterval, + refreshInterval, pendingRefreshTrendsIntent) + } + } + + private fun startAutoRefresh(): Boolean { + stopAutoRefresh() + val refreshInterval = refreshInterval + if (refreshInterval <= 0) return false + rescheduleHomeTimelineRefreshing() + rescheduleMentionsRefreshing() + rescheduleDirectMessagesRefreshing() + rescheduleTrendsRefreshing() + return true + } + + private fun stopAutoRefresh() { + alarmManager.cancel(pendingRefreshHomeTimelineIntent) + alarmManager.cancel(pendingRefreshMentionsIntent) + alarmManager.cancel(pendingRefreshDirectMessagesIntent) + alarmManager.cancel(pendingRefreshTrendsIntent) + } + + class AutoRefreshTaskParam( + val context: Context, + val refreshable: (AccountPreferences) -> Boolean, + val getSinceIds: (Array) -> Array? + ) : SimpleRefreshTaskParam() { + + override fun getAccountKeysWorker(): Array { + val prefs = AccountPreferences.getAccountPreferences(context, + DataStoreUtils.getAccountKeys(context)).filter(AccountPreferences::isAutoRefreshEnabled) + return prefs.filter(refreshable) + .map(AccountPreferences::getAccountKey).toTypedArray() + } + + override val sinceIds: Array? + get() = getSinceIds(accountKeys) + } + +} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetActivitiesAboutMeTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetActivitiesAboutMeTask.kt index af5c96769..2b4e3f3c1 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetActivitiesAboutMeTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetActivitiesAboutMeTask.kt @@ -40,9 +40,7 @@ class GetActivitiesAboutMeTask(context: Context) : GetActivitiesTask(context) { } @Throws(MicroBlogException::class) - override fun getActivities(twitter: MicroBlog, - details: AccountDetails, - paging: Paging): ResponseList { + override fun getActivities(twitter: MicroBlog, details: AccountDetails, paging: Paging): ResponseList { if (details.isOfficial(context)) { return twitter.getActivitiesAboutMe(paging) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetDirectMessagesTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetDirectMessagesTask.kt new file mode 100644 index 000000000..d010e8e2b --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetDirectMessagesTask.kt @@ -0,0 +1,132 @@ +package org.mariotaku.twidere.task + +import android.content.Context +import android.net.Uri +import android.util.Log +import com.squareup.otto.Bus +import org.apache.commons.lang3.math.NumberUtils +import org.mariotaku.abstask.library.AbstractTask +import org.mariotaku.kpreferences.get +import org.mariotaku.microblog.library.MicroBlog +import org.mariotaku.microblog.library.MicroBlogException +import org.mariotaku.microblog.library.twitter.model.DirectMessage +import org.mariotaku.microblog.library.twitter.model.ErrorInfo +import org.mariotaku.microblog.library.twitter.model.Paging +import org.mariotaku.microblog.library.twitter.model.ResponseList +import org.mariotaku.twidere.BuildConfig +import org.mariotaku.twidere.Constants +import org.mariotaku.twidere.TwidereConstants +import org.mariotaku.twidere.constant.loadItemLimitKey +import org.mariotaku.twidere.model.RefreshTaskParam +import org.mariotaku.twidere.model.UserKey +import org.mariotaku.twidere.model.message.GetMessagesTaskEvent +import org.mariotaku.twidere.util.* +import org.mariotaku.twidere.util.content.ContentResolverUtils +import org.mariotaku.twidere.util.dagger.GeneralComponentHelper +import java.util.* +import javax.inject.Inject + +/** + * Created by mariotaku on 16/2/14. + */ +abstract class GetDirectMessagesTask(protected val context: Context) : AbstractTask, () -> Unit>(), Constants { + @Inject + protected lateinit var errorInfoStore: ErrorInfoStore + @Inject + protected lateinit var preferences: SharedPreferencesWrapper + @Inject + protected lateinit var bus: Bus + + init { + GeneralComponentHelper.build(context).inject(this) + } + + @Throws(MicroBlogException::class) + abstract fun getDirectMessages(twitter: MicroBlog, paging: Paging): ResponseList + + protected abstract val databaseUri: Uri + + protected abstract val isOutgoing: Boolean + + public override fun doLongOperation(param: RefreshTaskParam): List { + val accountKeys = param.accountKeys + val sinceIds = param.sinceIds + val maxIds = param.maxIds + val result = ArrayList() + var idx = 0 + val loadItemLimit = preferences[loadItemLimitKey] + for (accountKey in accountKeys) { + val twitter = MicroBlogAPIFactory.getInstance(context, accountKey) ?: continue + try { + val paging = Paging() + paging.setCount(loadItemLimit) + var maxId: String? = null + var sinceId: String? = null + if (maxIds != null && maxIds[idx] != null) { + maxId = maxIds[idx] + paging.setMaxId(maxId) + } + if (sinceIds != null && sinceIds[idx] != null) { + sinceId = sinceIds[idx] + val sinceIdLong = NumberUtils.toLong(sinceId, -1) + //TODO handle non-twitter case + if (sinceIdLong != -1L) { + paging.sinceId((sinceIdLong - 1).toString()) + } else { + paging.sinceId(sinceId) + } + if (maxIds == null || sinceIds[idx] == null) { + paging.setLatestResults(true) + } + } + val messages = getDirectMessages(twitter, paging) + result.add(TwitterWrapper.MessageListResponse(accountKey, maxId, sinceId, messages)) + storeMessages(accountKey, messages, isOutgoing, true) + errorInfoStore.remove(ErrorInfoStore.KEY_DIRECT_MESSAGES, accountKey) + } catch (e: MicroBlogException) { + if (e.errorCode == ErrorInfo.NO_DIRECT_MESSAGE_PERMISSION) { + errorInfoStore.put(ErrorInfoStore.KEY_DIRECT_MESSAGES, accountKey, + ErrorInfoStore.CODE_NO_DM_PERMISSION) + } else if (e.isCausedByNetworkIssue) { + errorInfoStore.put(ErrorInfoStore.KEY_DIRECT_MESSAGES, accountKey, + ErrorInfoStore.CODE_NETWORK_ERROR) + } + if (BuildConfig.DEBUG) { + Log.w(TwidereConstants.LOGTAG, e) + } + result.add(TwitterWrapper.MessageListResponse(accountKey, e)) + } + + idx++ + } + return result + + } + + private fun storeMessages(accountKey: UserKey, messages: List?, isOutgoing: Boolean, notify: Boolean): Boolean { + if (messages == null) return true + val uri = databaseUri + val valuesArray = messages.map { ContentValuesCreator.createDirectMessage(it, accountKey, isOutgoing) } + + // Delete all rows conflicting before new data inserted. + // final Expression deleteWhere = Expression.and(Expression.equals(DirectMessages.ACCOUNT_ID, accountKey), + // Expression.in(new Column(DirectMessages.MESSAGE_ID), new RawItemArray(messageIds))); + // final Uri deleteUri = UriUtils.appendQueryParameters(uri, QUERY_PARAM_NOTIFY, false); + // mResolver.delete(deleteUri, deleteWhere.getSQL(), null); + + + // Insert previously fetched items. + val insertUri = UriUtils.appendQueryParameters(uri, TwidereConstants.QUERY_PARAM_NOTIFY, notify) + ContentResolverUtils.bulkInsert(context.contentResolver, insertUri, valuesArray) + return false + } + + override fun beforeExecute() { + bus.post(GetMessagesTaskEvent(databaseUri, true, null)) + } + + override fun afterExecute(handler: (() -> Unit)?, result: List?) { + bus.post(GetMessagesTaskEvent(databaseUri, false, AsyncTwitterWrapper.getException(result))) + } +} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetLocalTrendsTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetLocalTrendsTask.kt new file mode 100644 index 000000000..81c5abb4a --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetLocalTrendsTask.kt @@ -0,0 +1,24 @@ +package org.mariotaku.twidere.task + +import android.content.Context +import android.net.Uri + +import org.mariotaku.microblog.library.MicroBlog +import org.mariotaku.microblog.library.MicroBlogException +import org.mariotaku.microblog.library.twitter.model.Trends +import org.mariotaku.twidere.model.UserKey +import org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends + +/** + * Created by mariotaku on 16/2/24. + */ +class GetLocalTrendsTask(context: Context, accountKey: UserKey, private val woeid: Int) : GetTrendsTask(context, accountKey) { + + @Throws(MicroBlogException::class) + override fun getTrends(twitter: MicroBlog): List { + return twitter.getLocationTrends(woeid) + } + + override val contentUri: Uri = CachedTrends.Local.CONTENT_URI + +} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetReceivedDirectMessagesTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetReceivedDirectMessagesTask.kt new file mode 100644 index 000000000..dbed4b094 --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetReceivedDirectMessagesTask.kt @@ -0,0 +1,27 @@ +package org.mariotaku.twidere.task + +import android.content.Context +import android.net.Uri +import org.mariotaku.microblog.library.MicroBlog +import org.mariotaku.microblog.library.MicroBlogException +import org.mariotaku.microblog.library.twitter.model.DirectMessage +import org.mariotaku.microblog.library.twitter.model.Paging +import org.mariotaku.microblog.library.twitter.model.ResponseList +import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages + +/** + * Created by mariotaku on 2016/12/14. + */ +class GetReceivedDirectMessagesTask(context: Context) : GetDirectMessagesTask(context) { + + @Throws(MicroBlogException::class) + override fun getDirectMessages(twitter: MicroBlog, paging: Paging): ResponseList { + return twitter.getDirectMessages(paging) + } + + override val isOutgoing: Boolean = false + + + override val databaseUri: Uri = DirectMessages.Inbox.CONTENT_URI + +} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetSavedSearchesTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetSavedSearchesTask.kt new file mode 100644 index 000000000..a79ae0346 --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetSavedSearchesTask.kt @@ -0,0 +1,43 @@ +package org.mariotaku.twidere.task + +import android.content.Context +import android.util.Log +import org.mariotaku.abstask.library.AbstractTask +import org.mariotaku.microblog.library.MicroBlogException +import org.mariotaku.sqliteqb.library.Expression +import org.mariotaku.twidere.BuildConfig +import org.mariotaku.twidere.TwidereConstants.LOGTAG +import org.mariotaku.twidere.model.SingleResponse +import org.mariotaku.twidere.model.UserKey +import org.mariotaku.twidere.provider.TwidereDataStore.SavedSearches +import org.mariotaku.twidere.util.ContentValuesCreator +import org.mariotaku.twidere.util.MicroBlogAPIFactory +import org.mariotaku.twidere.util.content.ContentResolverUtils + +/** + * Created by mariotaku on 16/2/13. + */ +class GetSavedSearchesTask(private val context: Context) : AbstractTask, SingleResponse, Any>() { + + public override fun doLongOperation(params: Array): SingleResponse { + val cr = context.contentResolver + for (accountKey in params) { + val twitter = MicroBlogAPIFactory.getInstance(context, accountKey) ?: continue + try { + val searches = twitter.savedSearches + val values = ContentValuesCreator.createSavedSearches(searches, + accountKey) + val where = Expression.equalsArgs(SavedSearches.ACCOUNT_KEY) + val whereArgs = arrayOf(accountKey.toString()) + cr.delete(SavedSearches.CONTENT_URI, where.sql, whereArgs) + ContentResolverUtils.bulkInsert(cr, SavedSearches.CONTENT_URI, values) + } catch (e: MicroBlogException) { + if (BuildConfig.DEBUG) { + Log.w(LOGTAG, e) + } + } + + } + return SingleResponse.getInstance() + } +} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetSentDirectMessagesTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetSentDirectMessagesTask.kt new file mode 100644 index 000000000..f944212cc --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetSentDirectMessagesTask.kt @@ -0,0 +1,26 @@ +package org.mariotaku.twidere.task + +import android.content.Context +import android.net.Uri +import org.mariotaku.microblog.library.MicroBlog +import org.mariotaku.microblog.library.MicroBlogException +import org.mariotaku.microblog.library.twitter.model.DirectMessage +import org.mariotaku.microblog.library.twitter.model.Paging +import org.mariotaku.microblog.library.twitter.model.ResponseList +import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages + +/** + * Created by mariotaku on 2016/12/14. + */ +class GetSentDirectMessagesTask(context: Context) : GetDirectMessagesTask(context) { + + @Throws(MicroBlogException::class) + override fun getDirectMessages(twitter: MicroBlog, paging: Paging): ResponseList { + return twitter.getSentDirectMessages(paging) + } + + override val isOutgoing: Boolean = true + + override val databaseUri: Uri = DirectMessages.Outbox.CONTENT_URI + +} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetTrendsTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetTrendsTask.kt new file mode 100644 index 000000000..b40d13ff4 --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/GetTrendsTask.kt @@ -0,0 +1,77 @@ +package org.mariotaku.twidere.task + +import android.content.ContentResolver +import android.content.ContentValues +import android.content.Context +import android.net.Uri +import com.squareup.otto.Bus +import org.mariotaku.abstask.library.AbstractTask +import org.mariotaku.microblog.library.MicroBlog +import org.mariotaku.microblog.library.MicroBlogException +import org.mariotaku.microblog.library.twitter.model.Trends +import org.mariotaku.twidere.model.UserKey +import org.mariotaku.twidere.model.message.TrendsRefreshedEvent +import org.mariotaku.twidere.provider.TwidereDataStore +import org.mariotaku.twidere.util.ContentValuesCreator +import org.mariotaku.twidere.util.MicroBlogAPIFactory +import org.mariotaku.twidere.util.content.ContentResolverUtils +import org.mariotaku.twidere.util.dagger.GeneralComponentHelper +import java.util.* +import javax.inject.Inject + +/** + * Created by mariotaku on 16/2/24. + */ +abstract class GetTrendsTask(private val context: Context, private val accountId: UserKey) : AbstractTask() { + + @Inject + lateinit var bus: Bus + + init { + GeneralComponentHelper.build(context).inject(this) + } + + @Throws(MicroBlogException::class) + abstract fun getTrends(twitter: MicroBlog): List + + public override fun doLongOperation(param: Any): Any? { + val twitter = MicroBlogAPIFactory.getInstance(context, accountId) ?: return null + try { + val trends = getTrends(twitter) + storeTrends(context.contentResolver, contentUri, trends) + return null + } catch (e: MicroBlogException) { + return null + } + + } + + override fun afterExecute(handler: Any?, result: Any?) { + bus.post(TrendsRefreshedEvent()) + } + + protected abstract val contentUri: Uri + + private fun storeTrends(cr: ContentResolver, uri: Uri, trendsList: List) { + val hashtags = ArrayList() + val hashtagValues = ArrayList() + if (trendsList.isNotEmpty()) { + val valuesArray = ContentValuesCreator.createTrends(trendsList) + for (values in valuesArray) { + val hashtag = values.getAsString(TwidereDataStore.CachedTrends.NAME).replaceFirst("#".toRegex(), "") + if (hashtags.contains(hashtag)) { + continue + } + hashtags.add(hashtag) + val hashtagValue = ContentValues() + hashtagValue.put(TwidereDataStore.CachedHashtags.NAME, hashtag) + hashtagValues.add(hashtagValue) + } + cr.delete(uri, null, null) + ContentResolverUtils.bulkInsert(cr, uri, valuesArray) + ContentResolverUtils.bulkDelete(cr, TwidereDataStore.CachedHashtags.CONTENT_URI, TwidereDataStore.CachedHashtags.NAME, hashtags, null) + ContentResolverUtils.bulkInsert(cr, TwidereDataStore.CachedHashtags.CONTENT_URI, + hashtagValues.toTypedArray()) + } + } +} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/SaveMediaToGalleryTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/SaveMediaToGalleryTask.kt new file mode 100644 index 000000000..ccf8902bb --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/SaveMediaToGalleryTask.kt @@ -0,0 +1,69 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2015 Mariotaku Lee + * + * 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. + * + * This program 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 this program. If not, see . + */ + +package org.mariotaku.twidere.task + +import android.app.Activity +import android.media.MediaScannerConnection +import android.net.Uri +import android.os.Environment +import android.widget.Toast +import org.mariotaku.twidere.R +import org.mariotaku.twidere.provider.CacheProvider +import java.io.File + +/** + * Created by mariotaku on 15/12/28. + */ +class SaveMediaToGalleryTask(activity: Activity, source: Uri, destination: File, type: String) : ProgressSaveFileTask(activity, source, destination, CacheProvider.CacheFileTypeCallback(activity, type)) { + + override fun onFileSaved(savedFile: File, mimeType: String?) { + val context = context ?: return + MediaScannerConnection.scanFile(context, arrayOf(savedFile.path), + arrayOf(mimeType), null) + Toast.makeText(context, R.string.saved_to_gallery, Toast.LENGTH_SHORT).show() + } + + override fun onFileSaveFailed() { + val context = context ?: return + Toast.makeText(context, R.string.error_occurred, Toast.LENGTH_SHORT).show() + } + + companion object { + + fun create(activity: Activity, source: Uri, + @CacheProvider.Type type: String): SaveFileTask { + val pubDir: File + when (type) { + CacheProvider.Type.VIDEO -> { + pubDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) + } + CacheProvider.Type.IMAGE -> { + pubDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + } + else -> { + pubDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + } + } + val saveDir = File(pubDir, "Twidere") + return SaveMediaToGalleryTask(activity, source, saveDir, type) + } + } + +} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetActivitiesTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetActivitiesTask.kt index bbfad9517..0f01b1add 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetActivitiesTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetActivitiesTask.kt @@ -9,6 +9,7 @@ import android.support.annotation.UiThread import android.util.Log import com.squareup.otto.Bus import org.mariotaku.abstask.library.AbstractTask +import org.mariotaku.kpreferences.KPreferences import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.twitter.model.Activity @@ -19,7 +20,7 @@ import org.mariotaku.twidere.BuildConfig import org.mariotaku.twidere.Constants import org.mariotaku.twidere.TwidereConstants.LOGTAG import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_NOTIFY -import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_LOAD_ITEM_LIMIT +import org.mariotaku.twidere.constant.loadItemLimitKey import org.mariotaku.twidere.extension.model.newMicroBlogInstance import org.mariotaku.twidere.model.AccountDetails import org.mariotaku.twidere.model.RefreshTaskParam @@ -37,9 +38,9 @@ import javax.inject.Inject /** * Created by mariotaku on 16/1/4. */ -abstract class GetActivitiesTask(protected val context: Context) : AbstractTask(), Constants { +abstract class GetActivitiesTask(protected val context: Context) : AbstractTask Unit>(), Constants { @Inject - lateinit var preferences: SharedPreferencesWrapper + lateinit var preferences: KPreferences @Inject lateinit var bus: Bus @Inject @@ -60,12 +61,11 @@ abstract class GetActivitiesTask(protected val context: Context) : AbstractTask< val maxSortIds = param.maxSortIds val sinceIds = param.sinceIds val cr = context.contentResolver - val loadItemLimit = preferences.getInt(KEY_LOAD_ITEM_LIMIT) + val loadItemLimit = preferences[loadItemLimitKey] var saveReadPosition = false for (i in accountIds.indices) { val accountKey = accountIds[i] - val noItemsBefore = DataStoreUtils.getActivitiesCount(context, contentUri, - accountKey) <= 0 + val noItemsBefore = DataStoreUtils.getActivitiesCount(context, contentUri, accountKey) <= 0 val credentials = AccountUtils.getAccountDetails(AccountManager.get(context), accountKey) ?: continue val microBlog = credentials.newMicroBlogInstance(context = context, cls = MicroBlog::class.java) val paging = Paging() @@ -123,7 +123,7 @@ abstract class GetActivitiesTask(protected val context: Context) : AbstractTask< private fun storeActivities(cr: ContentResolver, loadItemLimit: Int, details: AccountDetails, noItemsBefore: Boolean, activities: ResponseList, sinceId: String?, maxId: String?, notify: Boolean) { - val deleteBound = LongArray(2, { return@LongArray -1 }) + val deleteBound = LongArray(2) { -1 } val valuesList = ArrayList() var minIdx = -1 var minPositionKey: Long = -1 @@ -190,15 +190,12 @@ abstract class GetActivitiesTask(protected val context: Context) : AbstractTask< } } - protected abstract fun saveReadPosition(accountKey: UserKey, - details: AccountDetails, twitter: MicroBlog) + protected abstract fun saveReadPosition(accountKey: UserKey, details: AccountDetails, twitter: MicroBlog) @Throws(MicroBlogException::class) - protected abstract fun getActivities(twitter: MicroBlog, - details: AccountDetails, - paging: Paging): ResponseList + protected abstract fun getActivities(twitter: MicroBlog, details: AccountDetails, paging: Paging): ResponseList - public override fun afterExecute(handler: Any?, result: Any?) { + public override fun afterExecute(handler: (() -> Unit)?, result: Any?) { context.contentResolver.notifyChange(contentUri, null) bus.post(GetActivitiesTaskEvent(contentUri, false, null)) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetStatusesTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetStatusesTask.kt index f8ad10e4a..95f7c13a2 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetStatusesTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetStatusesTask.kt @@ -45,7 +45,8 @@ import javax.inject.Inject /** * Created by mariotaku on 16/1/2. */ -abstract class GetStatusesTask(protected val context: Context) : AbstractTask, Any>(), Constants { +abstract class GetStatusesTask(protected val context: Context) : + AbstractTask, () -> Unit>(), Constants { @Inject lateinit var preferences: KPreferences @Inject @@ -68,9 +69,10 @@ abstract class GetStatusesTask(protected val context: Context) : AbstractTask?) { + public override fun afterExecute(handler: (() -> Unit)?, result: List?) { context.contentResolver.notifyChange(contentUri, null) bus.post(GetStatusesTaskEvent(contentUri, false, AsyncTwitterWrapper.getException(result))) + handler?.invoke() } override fun beforeExecute() { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/dagger/GeneralComponent.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/dagger/GeneralComponent.kt index 4f66f8953..f9cb880ae 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/dagger/GeneralComponent.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/dagger/GeneralComponent.kt @@ -36,6 +36,7 @@ import org.mariotaku.twidere.preference.KeyboardShortcutPreference import org.mariotaku.twidere.provider.CacheProvider import org.mariotaku.twidere.provider.TwidereDataProvider import org.mariotaku.twidere.service.BackgroundOperationService +import org.mariotaku.twidere.service.JobRefreshService import org.mariotaku.twidere.service.RefreshService import org.mariotaku.twidere.task.* import org.mariotaku.twidere.task.twitter.GetActivitiesTask @@ -110,6 +111,8 @@ interface GeneralComponent { fun inject(task: GetStatusesTask) + fun inject(service: JobRefreshService) + fun inject(task: GetActivitiesTask) fun inject(task: GetDirectMessagesTask) diff --git a/twidere/src/main/res/menu/menu_account_dashboard.xml b/twidere/src/main/res/menu/menu_account_dashboard.xml index 2c3c6977c..b4976c616 100644 --- a/twidere/src/main/res/menu/menu_account_dashboard.xml +++ b/twidere/src/main/res/menu/menu_account_dashboard.xml @@ -17,6 +17,12 @@ android:title="@string/direct_messages"/> + + + true + false + \ No newline at end of file diff --git a/twidere/src/main/res/values/config.xml b/twidere/src/main/res/values/config.xml new file mode 100644 index 000000000..78be49792 --- /dev/null +++ b/twidere/src/main/res/values/config.xml @@ -0,0 +1,6 @@ + + + false + false + true + \ No newline at end of file diff --git a/twidere/src/main/res/values/defaults.xml b/twidere/src/main/res/values/defaults.xml index e4a824dd5..1c93a0dbc 100644 --- a/twidere/src/main/res/values/defaults.xml +++ b/twidere/src/main/res/values/defaults.xml @@ -6,6 +6,5 @@ round 1 50 - false \ No newline at end of file diff --git a/twidere/src/main/res/values/ids.xml b/twidere/src/main/res/values/ids.xml index 2993bb4e9..a875605d8 100644 --- a/twidere/src/main/res/values/ids.xml +++ b/twidere/src/main/res/values/ids.xml @@ -57,6 +57,7 @@ +