diff options
author | Alex Ning <chineseperson5@gmail.com> | 2019-08-19 03:44:19 +0000 |
---|---|---|
committer | Alex Ning <chineseperson5@gmail.com> | 2019-08-19 03:44:19 +0000 |
commit | 85d232c7f6254a8ed065637c6f7b21a55fe3f1b4 (patch) | |
tree | 767a2ccbe9ed63b4ba45eb59bff0edf1c215489b /app | |
parent | a83aaa671a1c930c4402345783839b0db66118b3 (diff) | |
download | infinity-for-reddit-85d232c7f6254a8ed065637c6f7b21a55fe3f1b4.tar infinity-for-reddit-85d232c7f6254a8ed065637c6f7b21a55fe3f1b4.tar.gz infinity-for-reddit-85d232c7f6254a8ed065637c6f7b21a55fe3f1b4.tar.bz2 infinity-for-reddit-85d232c7f6254a8ed065637c6f7b21a55fe3f1b4.tar.lz infinity-for-reddit-85d232c7f6254a8ed065637c6f7b21a55fe3f1b4.tar.xz infinity-for-reddit-85d232c7f6254a8ed065637c6f7b21a55fe3f1b4.tar.zst infinity-for-reddit-85d232c7f6254a8ed065637c6f7b21a55fe3f1b4.zip |
Fetch all users' messages in PullNotificationWorker. Update the access token in database instead of inserting an account in AccessTokenAuthenticator to hopefully fix the problem that subscriptions database is cleared implicitly.
Diffstat (limited to 'app')
10 files changed, 365 insertions, 161 deletions
diff --git a/app/src/main/java/Account/AccountDao.java b/app/src/main/java/Account/AccountDao.java index aa7b7f19..c05e5552 100644 --- a/app/src/main/java/Account/AccountDao.java +++ b/app/src/main/java/Account/AccountDao.java @@ -13,6 +13,9 @@ public interface AccountDao { @Insert(onConflict = OnConflictStrategy.REPLACE) void insert(Account account); + @Query("SELECT * FROM accounts") + List<Account> getAllAccounts(); + @Query("SELECT * FROM accounts WHERE is_current_user = 0") List<Account> getAllNonCurrentAccounts(); @@ -43,4 +46,7 @@ public interface AccountDao { @Query("UPDATE accounts SET is_current_user = 1 WHERE username = :username") void markAccountCurrent(String username); + + @Query("UPDATE accounts SET access_token = :accessToken WHERE username = :username") + void changeAccessToken(String username, String accessToken); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AccessTokenAuthenticator.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AccessTokenAuthenticator.java index 8d460c5e..609eee1f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AccessTokenAuthenticator.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AccessTokenAuthenticator.java @@ -68,17 +68,15 @@ class AccessTokenAuthenticator implements Authenticator { Call<String> accessTokenCall = api.getAccessToken(RedditUtils.getHttpBasicAuthHeader(), params); try { retrofit2.Response response = accessTokenCall.execute(); - if(response.body() == null) { - return ""; - } - - JSONObject jsonObject = new JSONObject((String) response.body()); - String newAccessToken = jsonObject.getString(RedditUtils.ACCESS_TOKEN_KEY); - account.setAccessToken(newAccessToken); - mRedditDataRoomDatabase.accountDao().insert(account); + if(response.isSuccessful() && response.body() != null) { + JSONObject jsonObject = new JSONObject((String) response.body()); + String newAccessToken = jsonObject.getString(RedditUtils.ACCESS_TOKEN_KEY); + mRedditDataRoomDatabase.accountDao().changeAccessToken(account.getUsername(), newAccessToken); - Log.i("access token", newAccessToken); - return newAccessToken; + Log.i("access token", newAccessToken); + return newAccessToken; + } + return ""; } catch (IOException | JSONException e) { e.printStackTrace(); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AppModule.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AppModule.java index 418b349a..26b5ede9 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AppModule.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AppModule.java @@ -29,6 +29,16 @@ class AppModule { .build(); } + @Provides @Named("oauth_without_authenticator") + @Singleton + Retrofit provideOauthWithoutAuthenticatorRetrofit(OkHttpClient okHttpClient) { + return new Retrofit.Builder() + .baseUrl(RedditUtils.OAUTH_API_BASE_URI) + .client(okHttpClient) + .addConverterFactory(ScalarsConverterFactory.create()) + .build(); + } + @Provides @Named("no_oauth") @Singleton Retrofit provideRetrofit() { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/LinkResolverActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/LinkResolverActivity.java index 1c6ee055..b095d3c0 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/LinkResolverActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/LinkResolverActivity.java @@ -17,6 +17,10 @@ import static androidx.browser.customtabs.CustomTabsService.ACTION_CUSTOM_TABS_C public class LinkResolverActivity extends AppCompatActivity { + static final String EXTRA_NOTIFICATION_FULLNAME = "ENF"; + static final String EXTRA_SWITCH_ACCOUNT = "ESA"; + static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; + private static final String POST_PATTERN = "/r/\\w+/comments/\\w+/{0,1}\\w+/{0,1}"; private static final String COMMENT_PATTERN = "/r/\\w+/comments/\\w+/{0,1}\\w+/\\w+/{0,1}"; private static final String SUBREDDIT_PATTERN = "/r/\\w+/*"; @@ -32,12 +36,18 @@ public class LinkResolverActivity extends AppCompatActivity { path = path.substring(0, path.length() - 1); } + String notificationFullname = getIntent().getStringExtra(EXTRA_NOTIFICATION_FULLNAME); + boolean switchAccount = getIntent().getBooleanExtra(EXTRA_SWITCH_ACCOUNT, false); + String newAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); + if(path.matches(POST_PATTERN)) { List<String> segments = uri.getPathSegments(); int commentsIndex = segments.lastIndexOf("comments"); if(commentsIndex >=0 && commentsIndex < segments.size() - 1) { Intent intent = new Intent(this, ViewPostDetailActivity.class); intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, segments.get(commentsIndex + 1)); + intent.putExtra(ViewPostDetailActivity.EXTRA_NOTIFICATION_FULLNAME, notificationFullname); + intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); startActivity(intent); } else { deepLinkError(uri); @@ -49,6 +59,8 @@ public class LinkResolverActivity extends AppCompatActivity { Intent intent = new Intent(this, ViewPostDetailActivity.class); intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, segments.get(commentsIndex + 1)); intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, segments.get(segments.size() - 1)); + intent.putExtra(ViewPostDetailActivity.EXTRA_NOTIFICATION_FULLNAME, notificationFullname); + intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); startActivity(intent); } else { deepLinkError(uri); @@ -58,15 +70,21 @@ public class LinkResolverActivity extends AppCompatActivity { if(subredditName.equals("popular") || subredditName.equals("all")) { Intent intent = new Intent(this, MainActivity.class); intent.putExtra(MainActivity.EXTRA_POST_TYPE, subredditName); + intent.putExtra(MainActivity.EXTRA_NOTIFICATION_FULLNAME, notificationFullname); + intent.putExtra(MainActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); startActivity(intent); } else { Intent intent = new Intent(this, ViewSubredditDetailActivity.class); intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, path.substring(3)); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_NOTIFICATION_FULLNAME, notificationFullname); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); startActivity(intent); } } else if(path.matches(USER_PATTERN)) { Intent intent = new Intent(this, ViewUserDetailActivity.class); intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, path.substring(6)); + intent.putExtra(ViewUserDetailActivity.EXTRA_NOTIFICATION_FULLNAME, notificationFullname); + intent.putExtra(ViewUserDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); startActivity(intent); } else { deepLinkError(uri); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java index f2c58214..eb665671 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java @@ -61,6 +61,8 @@ public class MainActivity extends AppCompatActivity implements SortTypeBottomShe PostTypeBottomSheetFragment.PostTypeSelectionCallback { static final String EXTRA_POST_TYPE = "EPT"; + static final String EXTRA_NOTIFICATION_FULLNAME = "ENF"; + static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; private static final String FETCH_USER_INFO_STATE = "FUIS"; private static final String DRAWER_ON_ACCOUNT_SWITCH_STATE = "DOASS"; @@ -71,6 +73,7 @@ public class MainActivity extends AppCompatActivity implements SortTypeBottomShe private static final String ACCOUNT_PROFILE_IMAGE_URL_STATE = "APIUS"; private static final String ACCOUNT_BANNER_IMAGE_URL_STATE = "ABIUS"; private static final String ACCOUNT_KARMA_STATE = "AKS"; + private static final String NEW_ACCOUNT_NAME_STATE = "NANS"; private static final int LOGIN_ACTIVITY_REQUEST_CODE = 0; @@ -117,6 +120,7 @@ public class MainActivity extends AppCompatActivity implements SortTypeBottomShe private int mKarma; private boolean mFetchUserInfoSuccess = false; private boolean mDrawerOnAccountSwitch = false; + private String mNewAccountName; private Menu mMenu; @@ -217,6 +221,7 @@ public class MainActivity extends AppCompatActivity implements SortTypeBottomShe mProfileImageUrl = savedInstanceState.getString(ACCOUNT_PROFILE_IMAGE_URL_STATE); mBannerImageUrl = savedInstanceState.getString(ACCOUNT_BANNER_IMAGE_URL_STATE); mKarma = savedInstanceState.getInt(ACCOUNT_KARMA_STATE); + mNewAccountName = savedInstanceState.getString(NEW_ACCOUNT_NAME_STATE); if(!mNullAccessToken && mAccessToken == null) { getCurrentAccountAndBindView(); @@ -224,6 +229,7 @@ public class MainActivity extends AppCompatActivity implements SortTypeBottomShe bindView(); } } else { + mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); getCurrentAccountAndBindView(); } @@ -231,32 +237,60 @@ public class MainActivity extends AppCompatActivity implements SortTypeBottomShe } private void getCurrentAccountAndBindView() { - mNullAccessToken = true; - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if(account == null) { - mNullAccessToken = true; - } else { - mNullAccessToken = false; - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - mProfileImageUrl = account.getProfileImageUrl(); - mBannerImageUrl = account.getBannerImageUrl(); - mKarma = account.getKarma(); - - Constraints constraints = new Constraints.Builder() - .setRequiredNetworkType(NetworkType.CONNECTED) - .build(); - - PeriodicWorkRequest pullNotificationRequest = - new PeriodicWorkRequest.Builder(PullNotificationWorker.class, 1, TimeUnit.HOURS) - .setConstraints(constraints) + if(mNewAccountName != null) { + new SwitchAccountAsyncTask(mRedditDataRoomDatabase, mNewAccountName, () -> { + mNewAccountName = null; + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if(account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + mProfileImageUrl = account.getProfileImageUrl(); + mBannerImageUrl = account.getBannerImageUrl(); + mKarma = account.getKarma(); + + Constraints constraints = new Constraints.Builder() + .setRequiredNetworkType(NetworkType.CONNECTED) .build(); - WorkManager.getInstance(this).enqueueUniquePeriodicWork(PullNotificationWorker.WORKER_TAG, - ExistingPeriodicWorkPolicy.KEEP, pullNotificationRequest); - } - bindView(); - }).execute(); + PeriodicWorkRequest pullNotificationRequest = + new PeriodicWorkRequest.Builder(PullNotificationWorker.class, 1, TimeUnit.HOURS) + .setConstraints(constraints) + .build(); + + WorkManager.getInstance(this).enqueueUniquePeriodicWork(PullNotificationWorker.WORKER_TAG, + ExistingPeriodicWorkPolicy.REPLACE, pullNotificationRequest); + } + bindView(); + }).execute(); + }).execute(); + } else { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if(account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + mProfileImageUrl = account.getProfileImageUrl(); + mBannerImageUrl = account.getBannerImageUrl(); + mKarma = account.getKarma(); + + Constraints constraints = new Constraints.Builder() + .setRequiredNetworkType(NetworkType.CONNECTED) + .build(); + + PeriodicWorkRequest pullNotificationRequest = + new PeriodicWorkRequest.Builder(PullNotificationWorker.class, 1, TimeUnit.HOURS) + .setConstraints(constraints) + .build(); + + WorkManager.getInstance(this).enqueueUniquePeriodicWork(PullNotificationWorker.WORKER_TAG, + ExistingPeriodicWorkPolicy.KEEP, pullNotificationRequest); + } + bindView(); + }).execute(); + } } private void bindView() { @@ -338,7 +372,8 @@ public class MainActivity extends AppCompatActivity implements SortTypeBottomShe accountViewModel.getAccountsExceptCurrentAccountLiveData().observe(this, adapter::changeAccountsDataset); if(getIntent().hasExtra(EXTRA_POST_TYPE)) { - if(getIntent().getExtras().getString(EXTRA_POST_TYPE).equals("popular")) { + String type = getIntent().getStringExtra(EXTRA_POST_TYPE); + if(type != null && type.equals("popular")) { viewPager.setCurrentItem(1); } else { viewPager.setCurrentItem(2); @@ -610,6 +645,7 @@ public class MainActivity extends AppCompatActivity implements SortTypeBottomShe outState.putString(ACCOUNT_PROFILE_IMAGE_URL_STATE, mProfileImageUrl); outState.putString(ACCOUNT_BANNER_IMAGE_URL_STATE, mBannerImageUrl); outState.putInt(ACCOUNT_KARMA_STATE, mKarma); + outState.putString(NEW_ACCOUNT_NAME_STATE, mNewAccountName); } @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/NotificationUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/NotificationUtils.java index 56bfaf88..ce71a57e 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/NotificationUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/NotificationUtils.java @@ -11,10 +11,10 @@ class NotificationUtils { static final String CHANNEL_POST_MEDIA = "Post Media"; static final String CHANNEL_ID_NEW_COMMENTS = "new_comments"; static final String CHANNEL_NEW_COMMENTS = "New Comments"; - static final String GROUP_NEW_COMMENTS = "ml.docilealligator.infinityforreddit.NEW_COMMENTS"; - static final int SUMMARY_ID_NEW_COMMENTS = 0; + static final int SUMMARY_BASE_ID_UNREAD_MESSAGE = 0; + static final int NOTIFICATION_BASE_ID_UNREAD_MESSAGE = 1; - static final int BASE_ID_UNREAD_MESSAGE = 1; + private static final String GROUP_USER_BASE = "ml.docilealligator.infinityforreddit."; static NotificationCompat.Builder buildNotification(NotificationManagerCompat notificationManager, Context context, String title, String content, @@ -57,4 +57,16 @@ class NotificationUtils { static NotificationManagerCompat getNotificationManager(Context context) { return NotificationManagerCompat.from(context); } + + static String getAccountGroupName(String accountName) { + return GROUP_USER_BASE + accountName; + } + + static int getSummaryIdUnreadMessage(int accountIndex) { + return SUMMARY_BASE_ID_UNREAD_MESSAGE + accountIndex * 1000; + } + + static int getNotificationIdUnreadMessage(int accountIndex, int messageIndex) { + return NOTIFICATION_BASE_ID_UNREAD_MESSAGE + accountIndex * 1000 + messageIndex; + } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PullNotificationWorker.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PullNotificationWorker.java index 5bf7e6a3..13bf43b5 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PullNotificationWorker.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PullNotificationWorker.java @@ -12,8 +12,14 @@ import androidx.core.app.NotificationManagerCompat; import androidx.work.Worker; import androidx.work.WorkerParameters; +import org.json.JSONException; +import org.json.JSONObject; + import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import javax.inject.Inject; import javax.inject.Named; @@ -26,10 +32,11 @@ public class PullNotificationWorker extends Worker { static final String WORKER_TAG = "PNWT"; private Context context; + private RedditAPI api; @Inject - @Named("oauth") - Retrofit mOauthRetrofit; + @Named("oauth_without_authenticator") + Retrofit mOauthWithoutAuthenticatorRetrofit; @Inject RedditDataRoomDatabase redditDataRoomDatabase; @@ -38,6 +45,7 @@ public class PullNotificationWorker extends Worker { super(context, workerParams); this.context = context; ((Infinity) context.getApplicationContext()).getAppComponent().inject(this); + api = mOauthWithoutAuthenticatorRetrofit.create(RedditAPI.class); } @NonNull @@ -46,109 +54,127 @@ public class PullNotificationWorker extends Worker { Log.i("workmanager", "do"); try { Log.i("workmanager", "before response"); - Account currentAccount = redditDataRoomDatabase.accountDao().getCurrentAccount(); - Response<String> response = mOauthRetrofit.create(RedditAPI.class).getMessages( - RedditUtils.getOAuthHeader(currentAccount.getAccessToken()), - FetchMessages.WHERE_UNREAD, null).execute(); - Log.i("workmanager", "has response"); - if(response.isSuccessful()) { - String responseBody = response.body(); - ArrayList<Message> messages = FetchMessages.parseMessage(responseBody, context.getResources().getConfiguration().locale); - - if(messages != null && !messages.isEmpty()) { - NotificationManagerCompat notificationManager = NotificationUtils.getNotificationManager(context); - - NotificationCompat.Builder summaryBuilder = NotificationUtils.buildSummaryNotification(context, - notificationManager, currentAccount.getUsername(), messages.size() + " new comment replies", - NotificationUtils.CHANNEL_ID_NEW_COMMENTS, NotificationUtils.CHANNEL_NEW_COMMENTS, - NotificationUtils.GROUP_NEW_COMMENTS); - - NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(); - - int messageSize = messages.size() >= 5 ? 5 : messages.size(); - - for(int i = messageSize - 1; i >= 0; i--) { - Message message = messages.get(i); - - inboxStyle.addLine(message.getAuthor() + " " + message.getBody()); - - String kind = message.getKind(); - String title; - String summary; - if(kind.equals(Message.TYPE_COMMENT) || kind.equals(Message.TYPE_LINK)) { - title = message.getAuthor(); - summary = context.getString(R.string.notification_summary_comment); - } else { - title = message.getTitle(); - if(kind.equals(Message.TYPE_ACCOUNT)) { - summary = context.getString(R.string.notification_summary_account); + + String currentAccountName = redditDataRoomDatabase.accountDao().getCurrentAccount().getUsername(); + + List<Account> accounts = redditDataRoomDatabase.accountDao().getAllAccounts(); + for(int accountIndex = 0; accountIndex < accounts.size(); accountIndex++) { + Account account = accounts.get(accountIndex); + Log.i("workmanager", account.getUsername() + " " + account.getAccessToken()); + + Response<String> response = fetchMessages(account); + + if(response != null && response.isSuccessful()) { + Log.i("workmanager", "has response"); + String responseBody = response.body(); + ArrayList<Message> messages = FetchMessages.parseMessage(responseBody, context.getResources().getConfiguration().locale); + + if(messages != null && !messages.isEmpty()) { + NotificationManagerCompat notificationManager = NotificationUtils.getNotificationManager(context); + + NotificationCompat.Builder summaryBuilder = NotificationUtils.buildSummaryNotification(context, + notificationManager, account.getUsername(), + context.getString(R.string.notification_new_messages, messages.size()), + NotificationUtils.CHANNEL_ID_NEW_COMMENTS, NotificationUtils.CHANNEL_NEW_COMMENTS, + NotificationUtils.getAccountGroupName(account.getUsername())); + + NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(); + + int messageSize = messages.size() >= 5 ? 5 : messages.size(); + + for(int messageIndex = messageSize - 1; messageIndex >= 0; messageIndex--) { + Message message = messages.get(messageIndex); + + inboxStyle.addLine(message.getAuthor() + " " + message.getBody()); + + String kind = message.getKind(); + Log.i("workmanager", kind); + String title; + String summary; + if(kind.equals(Message.TYPE_COMMENT) || kind.equals(Message.TYPE_LINK)) { + title = message.getAuthor(); + summary = message.getSubject().substring(0, 1).toUpperCase() + message.getSubject().substring(1); + } else { + title = message.getTitle() == null || message.getTitle().equals("") ? message.getSubject() : message.getTitle(); + if(kind.equals(Message.TYPE_ACCOUNT)) { + summary = context.getString(R.string.notification_summary_account); + } else if(kind.equals(Message.TYPE_MESSAGE)) { + summary = context.getString(R.string.notification_summary_message); + } else if(kind.equals(Message.TYPE_SUBREDDIT)) { + summary = context.getString(R.string.notification_summary_subreddit); + } else { + summary = context.getString(R.string.notification_summary_award); + } + } + + NotificationCompat.Builder builder = NotificationUtils.buildNotification(notificationManager, + context, title, message.getBody(), summary, + NotificationUtils.CHANNEL_ID_NEW_COMMENTS, + NotificationUtils.CHANNEL_NEW_COMMENTS, + NotificationUtils.getAccountGroupName(account.getUsername())); + + if(kind.equals(Message.TYPE_COMMENT)) { + Intent intent = new Intent(context, LinkResolverActivity.class); + Uri uri = LinkResolverActivity.getRedditUriByPath(message.getContext()); + intent.setData(uri); + if(!account.getUsername().equals(currentAccountName)) { + intent.putExtra(LinkResolverActivity.EXTRA_SWITCH_ACCOUNT, true); + intent.putExtra(LinkResolverActivity.EXTRA_NEW_ACCOUNT_NAME, account.getUsername()); + } + PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); + builder.setContentIntent(pendingIntent); + } else if(kind.equals(Message.TYPE_ACCOUNT)) { + Intent intent = new Intent(context, ViewMessageActivity.class); + PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, 0, intent, 0); + builder.setContentIntent(summaryPendingIntent); + } else if(kind.equals(Message.TYPE_LINK)) { + Intent intent = new Intent(context, LinkResolverActivity.class); + Uri uri = LinkResolverActivity.getRedditUriByPath(message.getContext()); + intent.setData(uri); + if(!account.getUsername().equals(currentAccountName)) { + intent.putExtra(LinkResolverActivity.EXTRA_SWITCH_ACCOUNT, true); + intent.putExtra(LinkResolverActivity.EXTRA_NEW_ACCOUNT_NAME, account.getUsername()); + } + PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); + builder.setContentIntent(pendingIntent); } else if(kind.equals(Message.TYPE_MESSAGE)) { - summary = context.getString(R.string.notification_summary_message); + Intent intent = new Intent(context, ViewMessageActivity.class); + PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, 0, intent, 0); + builder.setContentIntent(summaryPendingIntent); } else if(kind.equals(Message.TYPE_SUBREDDIT)) { - summary = context.getString(R.string.notification_summary_subreddit); + Intent intent = new Intent(context, ViewMessageActivity.class); + PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, 0, intent, 0); + builder.setContentIntent(summaryPendingIntent); } else { - summary = context.getString(R.string.notification_summary_award); + Intent intent = new Intent(context, ViewMessageActivity.class); + PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, 0, intent, 0); + builder.setContentIntent(summaryPendingIntent); } + notificationManager.notify(NotificationUtils.getNotificationIdUnreadMessage(accountIndex, messageIndex), builder.build()); } - NotificationCompat.Builder builder = NotificationUtils.buildNotification(notificationManager, - context, title, message.getBody(), summary, - NotificationUtils.CHANNEL_ID_NEW_COMMENTS, - NotificationUtils.CHANNEL_NEW_COMMENTS, NotificationUtils.GROUP_NEW_COMMENTS); - - if(kind.equals(Message.TYPE_COMMENT)) { - Intent intent = new Intent(context, LinkResolverActivity.class); - Uri uri = LinkResolverActivity.getRedditUriByPath(message.getContext()); - intent.setData(uri); - PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); - builder.setContentIntent(pendingIntent); - } else if(kind.equals(Message.TYPE_ACCOUNT)) { - Intent intent = new Intent(context, ViewMessageActivity.class); - PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, 0, intent, 0); - builder.setContentIntent(summaryPendingIntent); - } else if(kind.equals(Message.TYPE_LINK)) { - Intent intent = new Intent(context, LinkResolverActivity.class); - Uri uri = LinkResolverActivity.getRedditUriByPath(message.getContext()); - intent.setData(uri); - PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); - builder.setContentIntent(pendingIntent); - } else if(kind.equals(Message.TYPE_MESSAGE)) { - Intent intent = new Intent(context, ViewMessageActivity.class); - PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, 0, intent, 0); - builder.setContentIntent(summaryPendingIntent); - } else if(kind.equals(Message.TYPE_SUBREDDIT)) { - Intent intent = new Intent(context, ViewMessageActivity.class); - PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, 0, intent, 0); - builder.setContentIntent(summaryPendingIntent); - } else { - Intent intent = new Intent(context, ViewMessageActivity.class); - PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, 0, intent, 0); - builder.setContentIntent(summaryPendingIntent); - } - notificationManager.notify(NotificationUtils.BASE_ID_UNREAD_MESSAGE + i, builder.build()); - } - - inboxStyle.setBigContentTitle(messages.size() + " New Messages") - .setSummaryText(currentAccount.getUsername()); + inboxStyle.setBigContentTitle(context.getString(R.string.notification_new_messages, messages.size())) + .setSummaryText(account.getUsername()); - summaryBuilder.setStyle(inboxStyle); + summaryBuilder.setStyle(inboxStyle); - Intent summaryIntent = new Intent(context, ViewMessageActivity.class); - PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, 0, summaryIntent, 0); - summaryBuilder.setContentIntent(summaryPendingIntent); + Intent summaryIntent = new Intent(context, ViewMessageActivity.class); + PendingIntent summaryPendingIntent = PendingIntent.getActivity(context, 0, summaryIntent, 0); + summaryBuilder.setContentIntent(summaryPendingIntent); - notificationManager.notify(NotificationUtils.SUMMARY_ID_NEW_COMMENTS, summaryBuilder.build()); + notificationManager.notify(NotificationUtils.getSummaryIdUnreadMessage(accountIndex), summaryBuilder.build()); - Log.i("workmanager", "message size " + messages.size()); + Log.i("workmanager", "message size " + messages.size()); + } else { + Log.i("workmanager", "retry1"); + return Result.retry(); + } } else { - Log.i("workmanager", "retry1"); + Log.i("workmanager", "retry2 " + response.code()); return Result.retry(); } - } else { - Log.i("workmanager", "retry2 " + response.code()); - return Result.retry(); } - } catch (IOException e) { + } catch (IOException | JSONException e) { e.printStackTrace(); Log.i("workmanager", "retry3"); return Result.retry(); @@ -157,4 +183,35 @@ public class PullNotificationWorker extends Worker { Log.i("workmanager", "success"); return Result.success(); } + + private Response<String> fetchMessages(Account account) throws IOException, JSONException { + Response<String> response = api.getMessages( + RedditUtils.getOAuthHeader(account.getAccessToken()), + FetchMessages.WHERE_INBOX, null).execute(); + if(response.isSuccessful()) { + return response; + } else { + if(response.code() == 401) { + String refreshToken = account.getRefreshToken(); + + Map<String, String> params = new HashMap<>(); + params.put(RedditUtils.GRANT_TYPE_KEY, RedditUtils.GRANT_TYPE_REFRESH_TOKEN); + params.put(RedditUtils.REFRESH_TOKEN_KEY, refreshToken); + + Response accessTokenResponse = api.getAccessToken(RedditUtils.getHttpBasicAuthHeader(), params).execute(); + if(accessTokenResponse.isSuccessful() && accessTokenResponse.body() != null) { + JSONObject jsonObject = new JSONObject((String) accessTokenResponse.body()); + String newAccessToken = jsonObject.getString(RedditUtils.ACCESS_TOKEN_KEY); + account.setAccessToken(newAccessToken); + redditDataRoomDatabase.accountDao().changeAccessToken(account.getUsername(), newAccessToken); + + return fetchMessages(account); + } else { + return null; + } + } else { + return null; + } + } + } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java index 9e7bdb9b..c48f2697 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java @@ -60,6 +60,8 @@ public class ViewPostDetailActivity extends AppCompatActivity implements FlairBo static final String EXTRA_POST_LIST_POSITION = "EPLI"; static final String EXTRA_POST_ID = "EPI"; static final String EXTRA_SINGLE_COMMENT_ID = "ESCI"; + static final String EXTRA_NOTIFICATION_FULLNAME = "ENI"; + static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; private static final int EDIT_POST_REQUEST_CODE = 2; static final int EDIT_COMMENT_REQUEST_CODE = 3; @@ -96,6 +98,8 @@ public class ViewPostDetailActivity extends AppCompatActivity implements FlairBo boolean loadMoreChildrenSuccess = true; @State boolean hasMoreChildren; + @State + String mNewAccountName; private boolean showToast = false; @@ -190,8 +194,11 @@ public class ViewPostDetailActivity extends AppCompatActivity implements FlairBo mRecyclerView.setLayoutManager(mLinearLayoutManager); mSingleCommentId = getIntent().hasExtra(EXTRA_SINGLE_COMMENT_ID) ? getIntent().getExtras().getString(EXTRA_SINGLE_COMMENT_ID) : null; - if(savedInstanceState == null && mSingleCommentId != null) { - isSingleCommentThreadMode = true; + if(savedInstanceState == null) { + if(mSingleCommentId != null) { + isSingleCommentThreadMode = true; + } + mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); } orientation = getResources().getConfiguration().orientation; @@ -208,16 +215,32 @@ public class ViewPostDetailActivity extends AppCompatActivity implements FlairBo } private void getCurrentAccountAndBindView() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if(account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - } + if(mNewAccountName != null) { + new SwitchAccountAsyncTask(mRedditDataRoomDatabase, mNewAccountName, () -> { + mNewAccountName = null; + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if(account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } - bindView(); - }).execute(); + bindView(); + }).execute(); + }).execute(); + } else { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if(account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + + bindView(); + }).execute(); + } } private void bindView() { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java index 39053d1a..6cba00f7 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewSubredditDetailActivity.java @@ -46,7 +46,9 @@ import retrofit2.Retrofit; public class ViewSubredditDetailActivity extends AppCompatActivity implements SortTypeBottomSheetFragment.SortTypeSelectionCallback, PostTypeBottomSheetFragment.PostTypeSelectionCallback { - public static final String EXTRA_SUBREDDIT_NAME_KEY = "ESN"; + static final String EXTRA_SUBREDDIT_NAME_KEY = "ESN"; + static final String EXTRA_NOTIFICATION_FULLNAME = "ENF"; + static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; private static final String FETCH_SUBREDDIT_INFO_STATE = "FSIS"; private static final String FRAGMENT_OUT_STATE_KEY = "FOSK"; @@ -54,6 +56,7 @@ public class ViewSubredditDetailActivity extends AppCompatActivity implements So private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; private static final String ACCESS_TOKEN_STATE = "ATS"; private static final String ACCOUNT_NAME_STATE = "ANS"; + private static final String NEW_ACCOUNT_NAME_STATE = "NANS"; @BindView(R.id.coordinator_layout_view_subreddit_detail_activity) CoordinatorLayout coordinatorLayout; @BindView(R.id.appbar_layout_view_subreddit_detail) AppBarLayout appBarLayout; @@ -76,6 +79,7 @@ public class ViewSubredditDetailActivity extends AppCompatActivity implements So private boolean subscriptionReady = false; private boolean isInLazyMode = false; private boolean showToast = false; + private String mNewAccountName; private RequestManager glide; private Fragment mFragment; @@ -149,6 +153,7 @@ public class ViewSubredditDetailActivity extends AppCompatActivity implements So subredditName = getIntent().getExtras().getString(EXTRA_SUBREDDIT_NAME_KEY); if(savedInstanceState == null) { + mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); getCurrentAccountAndBindView(); } else { mFetchSubredditInfoSuccess = savedInstanceState.getBoolean(FETCH_SUBREDDIT_INFO_STATE); @@ -156,6 +161,7 @@ public class ViewSubredditDetailActivity extends AppCompatActivity implements So mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); + mNewAccountName = savedInstanceState.getString(NEW_ACCOUNT_NAME_STATE); if(!mNullAccessToken && mAccessToken == null) { getCurrentAccountAndBindView(); @@ -257,15 +263,30 @@ public class ViewSubredditDetailActivity extends AppCompatActivity implements So } private void getCurrentAccountAndBindView() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if(account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - } - bindView(true); - }).execute(); + if(mNewAccountName != null) { + new SwitchAccountAsyncTask(mRedditDataRoomDatabase, mNewAccountName, () -> { + mNewAccountName = null; + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if(account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + bindView(true); + }).execute(); + }).execute(); + } else { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if(account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + bindView(true); + }).execute(); + } } private void fetchSubredditData() { @@ -430,6 +451,7 @@ public class ViewSubredditDetailActivity extends AppCompatActivity implements So outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); outState.putString(ACCESS_TOKEN_STATE, mAccessToken); outState.putString(ACCOUNT_NAME_STATE, mAccountName); + outState.putString(NEW_ACCOUNT_NAME_STATE, mNewAccountName); getSupportFragmentManager().putFragment(outState, FRAGMENT_OUT_STATE_KEY, mFragment); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewUserDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewUserDetailActivity.java index e9c54118..8875ea63 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewUserDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewUserDetailActivity.java @@ -50,13 +50,16 @@ import retrofit2.Retrofit; public class ViewUserDetailActivity extends AppCompatActivity implements UserThingSortTypeBottomSheetFragment.UserThingSortTypeSelectionCallback { - public static final String EXTRA_USER_NAME_KEY = "EUNK"; + static final String EXTRA_USER_NAME_KEY = "EUNK"; + static final String EXTRA_NOTIFICATION_FULLNAME = "ENF"; + static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; private static final String FETCH_USER_INFO_STATE = "FSIS"; private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; private static final String ACCESS_TOKEN_STATE = "ATS"; private static final String ACCOUNT_NAME_STATE = "ANS"; private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; + private static final String NEW_ACCOUNT_NAME_STATE = "NANS"; @BindView(R.id.coordinator_layout_view_user_detail_activity) CoordinatorLayout coordinatorLayout; @BindView(R.id.view_pager_view_user_detail_activity) ViewPager viewPager; @@ -93,6 +96,7 @@ public class ViewUserDetailActivity extends AppCompatActivity implements UserThi private int collapsedTabBackgroundColor; private int collapsedTabIndicatorColor; private boolean showToast = false; + private String mNewAccountName; @Inject @Named("no_oauth") @@ -114,9 +118,10 @@ public class ViewUserDetailActivity extends AppCompatActivity implements UserThi ((Infinity) getApplication()).getAppComponent().inject(this); - username = getIntent().getExtras().getString(EXTRA_USER_NAME_KEY); + username = getIntent().getStringExtra(EXTRA_USER_NAME_KEY); if (savedInstanceState == null) { + mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); getCurrentAccountAndInitializeViewPager(); } else { mFetchUserInfoSuccess = savedInstanceState.getBoolean(FETCH_USER_INFO_STATE); @@ -124,6 +129,7 @@ public class ViewUserDetailActivity extends AppCompatActivity implements UserThi mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); + mNewAccountName = savedInstanceState.getString(NEW_ACCOUNT_NAME_STATE); if (!mNullAccessToken && mAccessToken == null) { getCurrentAccountAndInitializeViewPager(); @@ -337,15 +343,30 @@ public class ViewUserDetailActivity extends AppCompatActivity implements UserThi } private void getCurrentAccountAndInitializeViewPager() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - } - initializeViewPager(); - }).execute(); + if(mNewAccountName != null) { + new SwitchAccountAsyncTask(mRedditDataRoomDatabase, mNewAccountName, () -> { + mNewAccountName = null; + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + initializeViewPager(); + }).execute(); + }).execute(); + } else { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + initializeViewPager(); + }).execute(); + } } private void initializeViewPager() { @@ -484,6 +505,7 @@ public class ViewUserDetailActivity extends AppCompatActivity implements UserThi outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); outState.putString(ACCESS_TOKEN_STATE, mAccessToken); outState.putString(ACCOUNT_NAME_STATE, mAccountName); + outState.putString(NEW_ACCOUNT_NAME_STATE, mNewAccountName); } private void showMessage(int resId, boolean retry) { |