mirror of
				https://github.com/KokaKiwi/BarInsta
				synced 2025-10-31 03:25:34 +00:00 
			
		
		
		
	Merge branch 'master' into master
This commit is contained in:
		
						commit
						700711f5f3
					
				| @ -111,7 +111,6 @@ dependencies { | ||||
|     implementation 'com.squareup.retrofit2:converter-gson:2.9.0' | ||||
| 
 | ||||
|     implementation 'org.apache.commons:commons-imaging:1.0-alpha2' | ||||
|     implementation 'com.ibm.icu:icu4j:68.1' | ||||
|     implementation 'com.github.ammargitham:uCrop:2.3-native-beta-2' | ||||
|     implementation 'com.github.ammargitham:android-gpuimage:2.1.1-beta4' | ||||
| 
 | ||||
|  | ||||
| @ -22,7 +22,7 @@ | ||||
|         android:label="@string/app_name" | ||||
|         android:requestLegacyExternalStorage="true" | ||||
|         android:supportsRtl="true" | ||||
|         android:theme="@style/AppTheme.Light.White" | ||||
|         android:theme="@style/AppTheme.Launcher" | ||||
|         tools:ignore="UnusedAttribute"> | ||||
|         <activity | ||||
|             android:name=".activities.MainActivity" | ||||
|  | ||||
| @ -72,7 +72,6 @@ import awais.instagrabber.interfaces.FetchListener; | ||||
| import awais.instagrabber.models.IntentModel; | ||||
| import awais.instagrabber.models.SuggestionModel; | ||||
| import awais.instagrabber.models.enums.SuggestionType; | ||||
| import awais.instagrabber.repositories.responses.directmessages.DirectThread; | ||||
| import awais.instagrabber.services.ActivityCheckerService; | ||||
| import awais.instagrabber.services.DMSyncAlarmReceiver; | ||||
| import awais.instagrabber.utils.AppExecutors; | ||||
| @ -251,7 +250,17 @@ public class MainActivity extends BaseLanguageActivity implements FragmentManage | ||||
| 
 | ||||
|     @Override | ||||
|     public void onBackPressed() { | ||||
|         if (isTaskRoot() && isBackStackEmpty) { | ||||
|         int currentNavControllerBackStack = 2; | ||||
|         if (currentNavControllerLiveData != null) { | ||||
|             final NavController navController = currentNavControllerLiveData.getValue(); | ||||
|             if (navController != null) { | ||||
|                 @SuppressLint("RestrictedApi") final Deque<NavBackStackEntry> backStack = navController.getBackStack(); | ||||
|                 if (backStack != null) { | ||||
|                     currentNavControllerBackStack = backStack.size(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         if (isTaskRoot() && isBackStackEmpty && currentNavControllerBackStack == 2) { | ||||
|             finishAfterTransition(); | ||||
|             return; | ||||
|         } | ||||
| @ -577,10 +586,10 @@ public class MainActivity extends BaseLanguageActivity implements FragmentManage | ||||
|     private void showThread(@NonNull final Intent intent) { | ||||
|         final String threadId = intent.getStringExtra(Constants.DM_THREAD_ACTION_EXTRA_THREAD_ID); | ||||
|         final String threadTitle = intent.getStringExtra(Constants.DM_THREAD_ACTION_EXTRA_THREAD_TITLE); | ||||
|         navigateToThread(threadId, threadTitle, null); | ||||
|         navigateToThread(threadId, threadTitle); | ||||
|     } | ||||
| 
 | ||||
|     public void navigateToThread(final String threadId, final String threadTitle, final DirectThread backup) { | ||||
|     public void navigateToThread(final String threadId, final String threadTitle) { | ||||
|         if (threadId == null || threadTitle == null) return; | ||||
|         currentNavControllerLiveData.observe(this, new Observer<NavController>() { | ||||
|             @Override | ||||
| @ -594,7 +603,7 @@ public class MainActivity extends BaseLanguageActivity implements FragmentManage | ||||
|                         // need handler.post() to wait for the fragment manager to be ready to navigate | ||||
|                         new Handler().post(() -> { | ||||
|                             final DirectMessageInboxFragmentDirections.ActionInboxToThread action = DirectMessageInboxFragmentDirections | ||||
|                                     .actionInboxToThread(threadId, threadTitle, backup); | ||||
|                                     .actionInboxToThread(threadId, threadTitle); | ||||
|                             navController.navigate(action); | ||||
|                         }); | ||||
|                         return; | ||||
| @ -607,7 +616,7 @@ public class MainActivity extends BaseLanguageActivity implements FragmentManage | ||||
|                                                          @Nullable final Bundle arguments) { | ||||
|                             if (destination.getId() == R.id.directMessagesInboxFragment) { | ||||
|                                 final DirectMessageInboxFragmentDirections.ActionInboxToThread action = DirectMessageInboxFragmentDirections | ||||
|                                         .actionInboxToThread(threadId, threadTitle, backup); | ||||
|                                         .actionInboxToThread(threadId, threadTitle); | ||||
|                                 controller.navigate(action); | ||||
|                                 controller.removeOnDestinationChangedListener(this); | ||||
|                             } | ||||
|  | ||||
| @ -12,4 +12,7 @@ public class SliderCallbackAdapter implements SliderItemsAdapter.SliderCallback | ||||
| 
 | ||||
|     @Override | ||||
|     public void onPlayerPause(final int position) {} | ||||
| 
 | ||||
|     @Override | ||||
|     public void onPlayerRelease(final int position) {} | ||||
| } | ||||
|  | ||||
| @ -148,5 +148,7 @@ public final class SliderItemsAdapter extends ListAdapter<Media, SliderItemViewH | ||||
|         void onPlayerPlay(int position); | ||||
| 
 | ||||
|         void onPlayerPause(int position); | ||||
| 
 | ||||
|         void onPlayerRelease(int position); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -114,6 +114,13 @@ public class SliderVideoViewHolder extends SliderItemViewHolder { | ||||
|                     sliderCallback.onPlayerPause(position); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public void onRelease() { | ||||
|                 if (sliderCallback != null) { | ||||
|                     sliderCallback.onPlayerRelease(position); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|         final float aspectRatio = (float) media.getOriginalWidth() / media.getOriginalHeight(); | ||||
|         String videoUrl = null; | ||||
|  | ||||
| @ -15,4 +15,7 @@ public class VideoPlayerCallbackAdapter implements VideoPlayerViewHelper.VideoPl | ||||
| 
 | ||||
|     @Override | ||||
|     public void onPause() {} | ||||
| 
 | ||||
|     @Override | ||||
|     public void onRelease() {} | ||||
| } | ||||
|  | ||||
| @ -359,6 +359,9 @@ public class VideoPlayerViewHelper implements Player.EventListener { | ||||
|     // } | ||||
| 
 | ||||
|     public void releasePlayer() { | ||||
|         if (videoPlayerCallback != null) { | ||||
|             videoPlayerCallback.onRelease(); | ||||
|         } | ||||
|         if (player != null) { | ||||
|             player.release(); | ||||
|             player = null; | ||||
| @ -453,5 +456,7 @@ public class VideoPlayerViewHelper implements Player.EventListener { | ||||
|         void onPlay(); | ||||
| 
 | ||||
|         void onPause(); | ||||
| 
 | ||||
|         void onRelease(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -16,6 +16,18 @@ public class EmojiCategory { | ||||
| 
 | ||||
|     public EmojiCategory(final EmojiCategoryType type) { | ||||
|         this.type = type; | ||||
|     } | ||||
| 
 | ||||
|     public EmojiCategoryType getType() { | ||||
|         return type; | ||||
|     } | ||||
| 
 | ||||
|     public Map<String, Emoji> getEmojis() { | ||||
|         return emojis; | ||||
|     } | ||||
| 
 | ||||
|     public int getDrawableRes() { | ||||
|         if (drawableRes == 0) { | ||||
|             switch (type) { | ||||
|                 case SMILEYS_AND_EMOTION: | ||||
|                     drawableRes = R.drawable.ic_round_emoji_emotions_24; | ||||
| @ -46,16 +58,6 @@ public class EmojiCategory { | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|     public EmojiCategoryType getType() { | ||||
|         return type; | ||||
|     } | ||||
| 
 | ||||
|     public Map<String, Emoji> getEmojis() { | ||||
|         return emojis; | ||||
|     } | ||||
| 
 | ||||
|     public int getDrawableRes() { | ||||
|         return drawableRes; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -48,6 +48,7 @@ import androidx.core.content.PermissionChecker; | ||||
| import androidx.core.view.ViewCompat; | ||||
| import androidx.core.widget.NestedScrollView; | ||||
| import androidx.fragment.app.DialogFragment; | ||||
| import androidx.fragment.app.FragmentActivity; | ||||
| import androidx.lifecycle.LiveData; | ||||
| import androidx.lifecycle.MutableLiveData; | ||||
| import androidx.lifecycle.Observer; | ||||
| @ -1062,15 +1063,28 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im | ||||
| 
 | ||||
|             @Override | ||||
|             public void onPlayerPlay(final int position) { | ||||
|                 final FragmentActivity activity = getActivity(); | ||||
|                 if (activity == null) return; | ||||
|                 Utils.enabledKeepScreenOn(activity); | ||||
|                 if (!detailsVisible || hasBeenToggled) return; | ||||
|                 showPlayerControls(); | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public void onPlayerPause(final int position) { | ||||
|                 final FragmentActivity activity = getActivity(); | ||||
|                 if (activity == null) return; | ||||
|                 Utils.disableKeepScreenOn(activity); | ||||
|                 if (detailsVisible || hasBeenToggled) return; | ||||
|                 toggleDetails(); | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public void onPlayerRelease(final int position) { | ||||
|                 final FragmentActivity activity = getActivity(); | ||||
|                 if (activity == null) return; | ||||
|                 Utils.disableKeepScreenOn(activity); | ||||
|             } | ||||
|         }); | ||||
|         binding.sliderParent.setAdapter(sliderItemsAdapter); | ||||
|         if (sliderPosition >= 0 && sliderPosition < media.getCarouselMedia().size()) { | ||||
| @ -1206,7 +1220,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im | ||||
| 
 | ||||
|             @Override | ||||
|             public void onPlayerViewLoaded() { | ||||
|                 binding.playerControls.getRoot().setVisibility(View.VISIBLE); | ||||
|                 // binding.playerControls.getRoot().setVisibility(View.VISIBLE); | ||||
|                 final ViewGroup.LayoutParams layoutParams = binding.videoPost.playerView.getLayoutParams(); | ||||
|                 final int requiredWidth = Utils.displayMetrics.widthPixels; | ||||
|                 final int resultingHeight = NumberUtils | ||||
| @ -1218,10 +1232,27 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im | ||||
| 
 | ||||
|             @Override | ||||
|             public void onPlay() { | ||||
|                 final FragmentActivity activity = getActivity(); | ||||
|                 if (activity == null) return; | ||||
|                 Utils.enabledKeepScreenOn(activity); | ||||
|                 if (detailsVisible) { | ||||
|                     new Handler().postDelayed(() -> toggleDetails(), DETAILS_HIDE_DELAY_MILLIS); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public void onPause() { | ||||
|                 final FragmentActivity activity = getActivity(); | ||||
|                 if (activity == null) return; | ||||
|                 Utils.disableKeepScreenOn(activity); | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public void onRelease() { | ||||
|                 final FragmentActivity activity = getActivity(); | ||||
|                 if (activity == null) return; | ||||
|                 Utils.disableKeepScreenOn(activity); | ||||
|             } | ||||
|         }; | ||||
|         final float aspectRatio = (float) media.getOriginalWidth() / media.getOriginalHeight(); | ||||
|         String videoUrl = null; | ||||
|  | ||||
| @ -257,7 +257,7 @@ public class DirectMessageInboxFragment extends Fragment implements SwipeRefresh | ||||
|             navigating = true; | ||||
|             if (isAdded()) { | ||||
|                 final DirectMessageInboxFragmentDirections.ActionInboxToThread directions = DirectMessageInboxFragmentDirections | ||||
|                         .actionInboxToThread(thread.getThreadId(), thread.getThreadTitle(), thread); | ||||
|                         .actionInboxToThread(thread.getThreadId(), thread.getThreadTitle()); | ||||
|                 NavHostFragment.findNavController(this).navigate(directions); | ||||
|             } | ||||
|             navigating = false; | ||||
|  | ||||
| @ -81,7 +81,6 @@ public class DirectMessageSettingsFragment extends Fragment implements ConfirmDi | ||||
|         final AppStateViewModel appStateViewModel = new ViewModelProvider(fragmentActivity).get(AppStateViewModel.class); | ||||
|         viewModel = new ViewModelProvider(this, new DirectSettingsViewModelFactory(fragmentActivity.getApplication(), | ||||
|                                                                                    args.getThreadId(), | ||||
|                                                                                    args.getBackup(), | ||||
|                                                                                    args.getPending(), | ||||
|                                                                                    appStateViewModel.getCurrentUser())) | ||||
|                 .get(DirectSettingsViewModel.class); | ||||
| @ -348,15 +347,15 @@ public class DirectMessageSettingsFragment extends Fragment implements ConfirmDi | ||||
|         usersAdapter = new DirectUsersAdapter( | ||||
|                 inviter != null ? inviter.getPk() : -1, | ||||
|                 (position, user, selected) -> { | ||||
|                     if (!TextUtils.isEmpty(user.getFbId())) { | ||||
|                     if (TextUtils.isEmpty(user.getUsername()) && !TextUtils.isEmpty(user.getFbId())) { | ||||
|                         Utils.openURL(context, "https://facebook.com/" + user.getFbId()); | ||||
|                         return; | ||||
|                     } | ||||
|                     else { | ||||
|                     if (TextUtils.isEmpty(user.getUsername())) return; | ||||
|                     final ProfileNavGraphDirections.ActionGlobalProfileFragment directions = ProfileNavGraphDirections | ||||
|                             .actionGlobalProfileFragment() | ||||
|                             .setUsername("@" + user.getUsername()); | ||||
|                     NavHostFragment.findNavController(this).navigate(directions); | ||||
|                     } | ||||
|                 }, | ||||
|                 (position, user) -> { | ||||
|                     final ArrayList<Option<String>> options = viewModel.createUserOptions(user); | ||||
|  | ||||
| @ -100,6 +100,7 @@ import awais.instagrabber.repositories.responses.directmessages.DirectThread; | ||||
| import awais.instagrabber.repositories.responses.directmessages.RankedRecipient; | ||||
| import awais.instagrabber.utils.AppExecutors; | ||||
| import awais.instagrabber.utils.Constants; | ||||
| import awais.instagrabber.utils.DMUtils; | ||||
| import awais.instagrabber.utils.DownloadUtils; | ||||
| import awais.instagrabber.utils.PermissionUtils; | ||||
| import awais.instagrabber.utils.ResponseBodyUtils; | ||||
| @ -317,6 +318,7 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact | ||||
|         backStackSavedStateResultLiveData.postValue(null); | ||||
|     }; | ||||
|     private final MutableLiveData<Integer> inputLength = new MutableLiveData<>(0); | ||||
|     private MenuItem markAsSeenMenuItem; | ||||
| 
 | ||||
|     @Override | ||||
|     public void onCreate(@Nullable final Bundle savedInstanceState) { | ||||
| @ -329,7 +331,6 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact | ||||
|         final DirectMessageThreadFragmentArgs fragmentArgs = DirectMessageThreadFragmentArgs.fromBundle(arguments); | ||||
|         viewModel = new ViewModelProvider(this, new DirectThreadViewModelFactory(fragmentActivity.getApplication(), | ||||
|                                                                                  fragmentArgs.getThreadId(), | ||||
|                                                                                  fragmentArgs.getBackup(), | ||||
|                                                                                  fragmentArgs.getPending(), | ||||
|                                                                                  appStateViewModel.getCurrentUser())) | ||||
|                 .get(DirectThreadViewModel.class); | ||||
| @ -368,9 +369,13 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact | ||||
|     @Override | ||||
|     public void onCreateOptionsMenu(@NonNull final Menu menu, @NonNull final MenuInflater inflater) { | ||||
|         inflater.inflate(R.menu.dm_thread_menu, menu); | ||||
|         final MenuItem markAsSeenMenuItem = menu.findItem(R.id.mark_as_seen); | ||||
|         markAsSeenMenuItem = menu.findItem(R.id.mark_as_seen); | ||||
|         if (markAsSeenMenuItem != null) { | ||||
|             if (autoMarkAsSeen) { | ||||
|                 markAsSeenMenuItem.setVisible(false); | ||||
|             } else { | ||||
|                 markAsSeenMenuItem.setEnabled(false); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -379,15 +384,14 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact | ||||
|         final int itemId = item.getItemId(); | ||||
|         if (itemId == R.id.info) { | ||||
|             final DirectMessageThreadFragmentDirections.ActionThreadToSettings directions = DirectMessageThreadFragmentDirections | ||||
|                     .actionThreadToSettings(viewModel.getThreadId(), null, null); | ||||
|                     .actionThreadToSettings(viewModel.getThreadId(), null); | ||||
|             final Boolean pending = viewModel.isPending().getValue(); | ||||
|             directions.setPending(pending == null ? false : pending); | ||||
|             NavHostFragment.findNavController(this).navigate(directions); | ||||
|             return true; | ||||
|         } | ||||
|         if (itemId == R.id.mark_as_seen) { | ||||
|             // new ThreadAction().execute("seen", lastMessage); | ||||
|             item.setVisible(false); | ||||
|             handleMarkAsSeen(item); | ||||
|             return true; | ||||
|         } | ||||
|         if (itemId == R.id.refresh && viewModel != null) { | ||||
| @ -397,6 +401,40 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact | ||||
|         return super.onOptionsItemSelected(item); | ||||
|     } | ||||
| 
 | ||||
|     private void handleMarkAsSeen(@NonNull final MenuItem item) { | ||||
|         final LiveData<Resource<Object>> resourceLiveData = viewModel.markAsSeen(); | ||||
|         resourceLiveData.observe(getViewLifecycleOwner(), new Observer<Resource<Object>>() { | ||||
|             @Override | ||||
|             public void onChanged(final Resource<Object> resource) { | ||||
|                 try { | ||||
|                     if (resource == null) return; | ||||
|                     final Context context = getContext(); | ||||
|                     if (context == null) return; | ||||
|                     switch (resource.status) { | ||||
|                         case SUCCESS: | ||||
|                             Toast.makeText(context, R.string.marked_as_seen, Toast.LENGTH_SHORT).show(); | ||||
|                         case LOADING: | ||||
|                             item.setEnabled(false); | ||||
|                             break; | ||||
|                         case ERROR: | ||||
|                             item.setEnabled(true); | ||||
|                             if (resource.message != null) { | ||||
|                                 Snackbar.make(context, binding.getRoot(), resource.message, Snackbar.LENGTH_LONG).show(); | ||||
|                                 return; | ||||
|                             } | ||||
|                             if (resource.resId != 0) { | ||||
|                                 Snackbar.make(binding.getRoot(), resource.resId, Snackbar.LENGTH_LONG).show(); | ||||
|                                 return; | ||||
|                             } | ||||
|                             break; | ||||
|                     } | ||||
|                 } finally { | ||||
|                     resourceLiveData.removeObserver(this); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { | ||||
|         super.onActivityResult(requestCode, resultCode, data); | ||||
| @ -464,6 +502,12 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact | ||||
|         cleanup(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onDestroy() { | ||||
|         viewModel.deleteThreadIfRequired(); | ||||
|         super.onDestroy(); | ||||
|     } | ||||
| 
 | ||||
|     @SuppressLint("UnsafeExperimentalUsageError") | ||||
|     private void cleanup() { | ||||
|         if (prevTitleRunnable != null) { | ||||
| @ -903,9 +947,15 @@ public class DirectMessageThreadFragment extends Fragment implements DirectReact | ||||
|     } | ||||
| 
 | ||||
|     private void submitItemsToAdapter(final List<DirectItem> items) { | ||||
|         binding.chats.post(() -> { | ||||
|             if (autoMarkAsSeen) { | ||||
|             binding.chats.post(() -> viewModel.markAsSeen()); | ||||
|                 viewModel.markAsSeen(); | ||||
|                 return; | ||||
|             } | ||||
|             final DirectThread thread = threadLiveData.getValue(); | ||||
|             if (thread == null) return; | ||||
|             markAsSeenMenuItem.setEnabled(!DMUtils.isRead(thread)); | ||||
|         }); | ||||
|         if (itemsAdapter == null) return; | ||||
|         itemsAdapter.submitList(items, () -> { | ||||
|             itemOrHeaders = itemsAdapter.getList(); | ||||
|  | ||||
| @ -163,7 +163,7 @@ public class DirectPendingInboxFragment extends Fragment implements SwipeRefresh | ||||
|             navigating = true; | ||||
|             if (isAdded()) { | ||||
|                 final DirectPendingInboxFragmentDirections.ActionPendingInboxToThread directions = DirectPendingInboxFragmentDirections | ||||
|                         .actionPendingInboxToThread(thread.getThreadId(), thread.getThreadTitle(), thread); | ||||
|                         .actionPendingInboxToThread(thread.getThreadId(), thread.getThreadTitle()); | ||||
|                 directions.setPending(true); | ||||
|                 NavHostFragment.findNavController(this).navigate(directions); | ||||
|             } | ||||
|  | ||||
| @ -74,6 +74,8 @@ import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment; | ||||
| import awais.instagrabber.dialogs.ProfilePicDialogFragment; | ||||
| import awais.instagrabber.fragments.PostViewV2Fragment; | ||||
| import awais.instagrabber.interfaces.FetchListener; | ||||
| import awais.instagrabber.managers.DirectMessagesManager; | ||||
| import awais.instagrabber.managers.InboxManager; | ||||
| import awais.instagrabber.models.HighlightModel; | ||||
| import awais.instagrabber.models.PostsLayoutPreferences; | ||||
| import awais.instagrabber.models.StoryModel; | ||||
| @ -590,8 +592,11 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe | ||||
| 
 | ||||
|     private void fetchProfileDetails() { | ||||
|         accountIsUpdated = false; | ||||
|         new ProfileFetcher(TextUtils.isEmpty(username) ? null : username.trim().substring(1), | ||||
|                 myId, isLoggedIn, new FetchListener<User>() { | ||||
|         String usernameTemp = username.trim(); | ||||
|         if (usernameTemp.startsWith("@")) { | ||||
|             usernameTemp = usernameTemp.substring(1); | ||||
|         } | ||||
|         new ProfileFetcher(TextUtils.isEmpty(username) ? null : usernameTemp, myId, isLoggedIn, new FetchListener<User>() { | ||||
|             @Override | ||||
|             public void onResult(final User user) { | ||||
|                 if (getContext() == null) return; | ||||
| @ -612,7 +617,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe | ||||
|                                                   isLoggedIn ? R.string.error_loading_profile_loggedin : R.string.error_loading_profile, | ||||
|                                                   Toast.LENGTH_LONG).show(); | ||||
|                     else Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show(); | ||||
|                 } catch (final Throwable e) {} | ||||
|                 } catch (final Throwable ignored) {} | ||||
|             } | ||||
| 
 | ||||
|         }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | ||||
| @ -1073,7 +1078,12 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe | ||||
|                     profileDetailsBinding.btnDM.setEnabled(true); | ||||
|                     return; | ||||
|                 } | ||||
|                 fragmentActivity.navigateToThread(thread.getThreadId(), profileModel.getUsername(), thread); | ||||
|                 final InboxManager inboxManager = DirectMessagesManager.getInstance().getInboxManager(); | ||||
|                 if (!inboxManager.containsThread(thread.getThreadId())) { | ||||
|                     thread.setTemp(true); | ||||
|                     inboxManager.addThread(thread, 0); | ||||
|                 } | ||||
|                 fragmentActivity.navigateToThread(thread.getThreadId(), profileModel.getUsername()); | ||||
|                 profileDetailsBinding.btnDM.setEnabled(true); | ||||
|             }).execute(); | ||||
|          }); | ||||
|  | ||||
| @ -74,9 +74,8 @@ public final class DirectMessagesManager { | ||||
| 
 | ||||
|     public ThreadManager getThreadManager(@NonNull final String threadId, | ||||
|                                           final boolean pending, | ||||
|                                           final DirectThread backup, | ||||
|                                           @NonNull final User currentUser, | ||||
|                                           @NonNull final ContentResolver contentResolver) { | ||||
|         return ThreadManager.getInstance(threadId, pending, backup, currentUser, contentResolver); | ||||
|         return ThreadManager.getInstance(threadId, pending, currentUser, contentResolver); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -18,6 +18,7 @@ import java.util.Collections; | ||||
| import java.util.Comparator; | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| import java.util.Objects; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| import java.util.stream.Collectors; | ||||
| 
 | ||||
| @ -357,4 +358,15 @@ public final class InboxManager { | ||||
|     public void setPendingRequestsTotal(final int total) { | ||||
|         pendingRequestsTotal.postValue(total); | ||||
|     } | ||||
| 
 | ||||
|     public boolean containsThread(final String threadId) { | ||||
|         if (threadId == null) return false; | ||||
|         synchronized (this.inbox) { | ||||
|             final DirectInbox currentDirectInbox = getCurrentDirectInbox(); | ||||
|             if (currentDirectInbox == null) return false; | ||||
|             final List<DirectThread> threads = currentDirectInbox.getThreads(); | ||||
|             if (threads == null) return false; | ||||
|             return threads.stream().anyMatch(thread -> Objects.equals(thread.getThreadId(), threadId)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -123,7 +123,6 @@ public final class ThreadManager { | ||||
| 
 | ||||
|     public static ThreadManager getInstance(@NonNull final String threadId, | ||||
|                                             final boolean pending, | ||||
|                                             final DirectThread backup, | ||||
|                                             @NonNull final User currentUser, | ||||
|                                             @NonNull final ContentResolver contentResolver) { | ||||
|         ThreadManager instance = INSTANCE_MAP.get(threadId); | ||||
| @ -131,7 +130,7 @@ public final class ThreadManager { | ||||
|             synchronized (LOCK) { | ||||
|                 instance = INSTANCE_MAP.get(threadId); | ||||
|                 if (instance == null) { | ||||
|                     instance = new ThreadManager(threadId, pending, backup, currentUser, contentResolver); | ||||
|                     instance = new ThreadManager(threadId, pending, currentUser, contentResolver); | ||||
|                     INSTANCE_MAP.put(threadId, instance); | ||||
|                 } | ||||
|             } | ||||
| @ -145,7 +144,6 @@ public final class ThreadManager { | ||||
| 
 | ||||
|     private ThreadManager(@NonNull final String threadId, | ||||
|                           final boolean pending, | ||||
|                           final DirectThread backup, | ||||
|                           @NonNull final User currentUser, | ||||
|                           @NonNull final ContentResolver contentResolver) { | ||||
|         final DirectMessagesManager messagesManager = DirectMessagesManager.getInstance(); | ||||
| @ -164,17 +162,17 @@ public final class ThreadManager { | ||||
|         service = DirectMessagesService.getInstance(csrfToken, viewerId, deviceUuid); | ||||
|         mediaService = MediaService.getInstance(deviceUuid, csrfToken, viewerId); | ||||
|         friendshipService = FriendshipService.getInstance(deviceUuid, csrfToken, viewerId); | ||||
|         setupTransformations(backup); | ||||
|         setupTransformations(); | ||||
|         // fetchChats(); | ||||
|     } | ||||
| 
 | ||||
|     public void moveFromPending() { | ||||
|         final DirectMessagesManager messagesManager = DirectMessagesManager.getInstance(); | ||||
|         this.inboxManager = messagesManager.getInboxManager(); | ||||
|         setupTransformations(null); | ||||
|         setupTransformations(); | ||||
|     } | ||||
| 
 | ||||
|     private void setupTransformations(final DirectThread backup) { | ||||
|     private void setupTransformations() { | ||||
|         // Transformations | ||||
|         thread = distinctUntilChanged(map(inboxManager.getInbox(), inboxResource -> { | ||||
|             if (inboxResource == null) { | ||||
| @ -188,7 +186,7 @@ public final class ThreadManager { | ||||
|             final DirectThread thread = threads.stream() | ||||
|                                                .filter(t -> t.getThreadId().equals(threadId)) | ||||
|                                                .findFirst() | ||||
|                                                .orElse(backup); | ||||
|                                                .orElse(null); | ||||
|             if (thread != null) { | ||||
|                 cursor = thread.getOldestCursor(); | ||||
|                 hasOlder = thread.hasOlder(); | ||||
| @ -1799,18 +1797,23 @@ public final class ThreadManager { | ||||
|         return inviter; | ||||
|     } | ||||
| 
 | ||||
|     public void markAsSeen(@NonNull final DirectItem directItem) { | ||||
|     public LiveData<Resource<Object>> markAsSeen(@NonNull final DirectItem directItem) { | ||||
|         final MutableLiveData<Resource<Object>> data = new MutableLiveData<>(); | ||||
|         data.postValue(Resource.loading(null)); | ||||
|         final Call<DirectItemSeenResponse> request = service.markAsSeen(threadId, directItem); | ||||
|         request.enqueue(new Callback<DirectItemSeenResponse>() { | ||||
|             @Override | ||||
|             public void onResponse(@NonNull final Call<DirectItemSeenResponse> call, | ||||
|                                    @NonNull final Response<DirectItemSeenResponse> response) { | ||||
|                 if (!response.isSuccessful()) { | ||||
|                     handleErrorBody(call, response, null); | ||||
|                     handleErrorBody(call, response, data); | ||||
|                     return; | ||||
|                 } | ||||
|                 final DirectItemSeenResponse seenResponse = response.body(); | ||||
|                 if (seenResponse == null) return; | ||||
|                 if (seenResponse == null) { | ||||
|                     data.postValue(Resource.error(R.string.generic_null_response, null)); | ||||
|                     return; | ||||
|                 } | ||||
|                 inboxManager.fetchUnseenCount(); | ||||
|                 final DirectItemSeenResponsePayload payload = seenResponse.getPayload(); | ||||
|                 if (payload == null) return; | ||||
| @ -1822,14 +1825,17 @@ public final class ThreadManager { | ||||
|                 lastSeenAt.put(currentUser.getPk(), new DirectThreadLastSeenAt(timestamp, directItem.getItemId())); | ||||
|                 thread.setLastSeenAt(lastSeenAt); | ||||
|                 setThread(thread, true); | ||||
|                 data.postValue(Resource.success(new Object())); | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public void onFailure(@NonNull final Call<DirectItemSeenResponse> call, | ||||
|                                   @NonNull final Throwable t) { | ||||
|                 Log.e(TAG, "onFailure: ", t); | ||||
|                 data.postValue(Resource.error(t.getMessage(), null)); | ||||
|             } | ||||
|         }); | ||||
|         return data; | ||||
|     } | ||||
| 
 | ||||
|     private interface OnSuccessAction { | ||||
|  | ||||
| @ -45,6 +45,7 @@ public class DirectThread implements Serializable, Cloneable { | ||||
|     private boolean approvalRequiredForNewMembers; | ||||
|     private int inputMode; | ||||
|     private final List<ThreadContext> threadContextItems; | ||||
|     private boolean isTemp; | ||||
| 
 | ||||
|     public DirectThread(final String threadId, | ||||
|                         final String threadV2Id, | ||||
| @ -292,6 +293,14 @@ public class DirectThread implements Serializable, Cloneable { | ||||
|         return threadContextItems; | ||||
|     } | ||||
| 
 | ||||
|     public boolean isTemp() { | ||||
|         return isTemp; | ||||
|     } | ||||
| 
 | ||||
|     public void setTemp(final boolean isTemp) { | ||||
|         this.isTemp = isTemp; | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     public DirectItem getFirstDirectItem() { | ||||
|         DirectItem firstItem = null; | ||||
|  | ||||
| @ -359,4 +359,16 @@ public final class Utils { | ||||
|         } | ||||
|         return drawable; | ||||
|     } | ||||
| 
 | ||||
|     public static void enabledKeepScreenOn(@NonNull final Activity activity) { | ||||
|         final Window window = activity.getWindow(); | ||||
|         if (window == null) return; | ||||
|         window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); | ||||
|     } | ||||
| 
 | ||||
|     public static void disableKeepScreenOn(@NonNull final Activity activity) { | ||||
|         final Window window = activity.getWindow(); | ||||
|         if (window == null) return; | ||||
|         window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -2,27 +2,25 @@ package awais.instagrabber.utils.emoji; | ||||
| 
 | ||||
| import android.util.Log; | ||||
| 
 | ||||
| import com.google.common.base.CharMatcher; | ||||
| import com.google.common.base.Splitter; | ||||
| import com.google.common.collect.ImmutableList; | ||||
| import com.ibm.icu.impl.Utility; | ||||
| import com.ibm.icu.lang.CharSequences; | ||||
| import com.ibm.icu.text.UnicodeSet; | ||||
| import com.google.gson.Gson; | ||||
| import com.google.gson.reflect.TypeToken; | ||||
| 
 | ||||
| import java.io.BufferedReader; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.io.InputStreamReader; | ||||
| import java.lang.reflect.Type; | ||||
| import java.util.Collection; | ||||
| import java.util.HashMap; | ||||
| import java.util.Iterator; | ||||
| import java.util.LinkedHashMap; | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.function.Function; | ||||
| import java.util.stream.Collectors; | ||||
| import java.util.stream.Stream; | ||||
| 
 | ||||
| import awais.instagrabber.customviews.emoji.Emoji; | ||||
| import awais.instagrabber.customviews.emoji.EmojiCategory; | ||||
| import awais.instagrabber.customviews.emoji.EmojiCategoryType; | ||||
| import awais.instagrabber.utils.NetworkUtils; | ||||
| 
 | ||||
| public final class EmojiParser { | ||||
|     private static final String TAG = EmojiParser.class.getSimpleName(); | ||||
| @ -30,51 +28,8 @@ public final class EmojiParser { | ||||
| 
 | ||||
|     private static EmojiParser instance; | ||||
| 
 | ||||
|     // private static final String COMBINING_ENCLOSING_KEYCAP = "\u20E3"; | ||||
|     // private static final String ZWJ = "\u200D"; | ||||
|     // private static final UnicodeSet REGIONAL_INDICATORS = new UnicodeSet(0x1F1E6, 0x1F1FF).freeze(); | ||||
|     // private static final UnicodeSet TAGS = new UnicodeSet(0xE0000, 0xE007F).freeze(); | ||||
|     // private static final UnicodeSet FAMILY = new UnicodeSet("[\u200D 👦-👩 💋 ❤]").freeze(); | ||||
|     // private static final UnicodeSet GENDER = new UnicodeSet().add(0x2640).add(0x2642).freeze(); | ||||
|     // private static final UnicodeSet SPECIALS = new UnicodeSet("[" | ||||
|     //         + "{🐈⬛}{🐻❄}{👨🍼}{👩🍼}{🧑🍼}{🧑🎄}{🧑🤝🧑}{🏳🌈} {👁🗨} {🏴☠} {🐕🦺} {👨🦯} {👨🦼} {👨🦽} {👩🦯} {👩🦼} {👩🦽}" | ||||
|     //         + "{🏳⚧}{🧑⚕}{🧑⚖}{🧑✈}{🧑🌾}{🧑🍳}{🧑🎓}{🧑🎤}{🧑🎨}{🧑🏫}{🧑🏭}{🧑💻}{🧑💼}{🧑🔧}{🧑🔬}{🧑🚀}{🧑🚒}{🧑🦯}{🧑🦼}{🧑🦽}" | ||||
|     //         + "{❤🔥}, {❤🩹}, {😮💨}, {😵💫}" // #E13.1 | ||||
|     //         + "]").freeze(); | ||||
|     // May have to add from above, if there is a failure in testAnnotationPaths. Failure will be like: | ||||
|     // got java.util.TreeSet<[//ldml/annotations/annotation[@cp="🏳⚧"][@type="tts"], //ldml/annotations/annotation[@cp="🧑⚕"][@type="tts"], ... | ||||
|     // just extract the items in "...", and change into {...} for adding above. | ||||
|     // Example: //ldml/annotations/annotation[@cp="🧑⚕"] ==> {🧑⚕} | ||||
|     // private static final UnicodeSet MAN_WOMAN = new UnicodeSet("[👨 👩]").freeze(); | ||||
|     // private static final UnicodeSet OBJECT = new UnicodeSet("[👩 🎓 🌾 🍳 🏫 🏭 🎨 🚒 ✈ 🚀 🎤 💻 🔬 💼 🔧 ⚖ ⚕]").freeze(); | ||||
|     // private static final String TYPE_TTS = "[@type=\"tts\"]"; | ||||
|     private static final String EMOJI_VARIANT = "\uFE0F"; | ||||
|     private static final UnicodeSet SKIN_TONE_MODIFIERS = new UnicodeSet("[🏻-🏿]").freeze(); | ||||
|     private static final String SKIN_TONE_PATTERN = SKIN_TONE_MODIFIERS.toPattern(true); | ||||
|     private static final Map<EmojiCategoryType, EmojiCategory> CATEGORY_MAP = new LinkedHashMap<>(); | ||||
|     private static final Map<String, Emoji> ALL_EMOJIS = new HashMap<>(); | ||||
| 
 | ||||
|     // private final UnicodeMap<String> emojiToMajorCategory = new UnicodeMap<>(); | ||||
|     // private final UnicodeMap<String> emojiToMinorCategory = new UnicodeMap<>(); | ||||
|     // private final UnicodeMap<String> toName = new UnicodeMap<>(); | ||||
|     // /** | ||||
|     //  * A mapping from a majorCategory to a unique ordering number, based on the first time it is encountered. | ||||
|     //  */ | ||||
|     // private final Map<String, Long> majorToOrder = new HashMap<>(); | ||||
|     // private final List<String> majorToOrder = new LinkedList<String>(); | ||||
|     // /** | ||||
|     //  * A mapping from a minorCategory to a unique ordering number, based on the first time it is encountered. | ||||
|     //  */ | ||||
|     // private final Map<String, Long> minorToOrder = new HashMap<>(); | ||||
|     // private final Map<String, Long> emojiToOrder = new LinkedHashMap<>(); | ||||
|     // private final UnicodeSet nonConstructed = new UnicodeSet(); | ||||
|     // private final UnicodeSet allRgi = new UnicodeSet(); | ||||
|     // private final UnicodeSet allRgiNoES = new UnicodeSet(); | ||||
|     // private final UnicodeMap<String> EXTRA_SYMBOL_MINOR_CATEGORIES = new UnicodeMap<>(); | ||||
|     // private final Map<String, Long> EXTRA_SYMBOL_ORDER; | ||||
|     // private final boolean DEBUG = false; | ||||
|     // private Set<String> NAME_PATHS = null; | ||||
|     // private Set<String> KEYWORD_PATHS = null; | ||||
|     private Map<String, Emoji> allEmojis = Collections.emptyMap(); | ||||
|     private Map<EmojiCategoryType, EmojiCategory> categoryMap = Collections.emptyMap(); | ||||
|     private ImmutableList<EmojiCategory> categories; | ||||
| 
 | ||||
|     public static EmojiParser getInstance() { | ||||
| @ -89,267 +44,56 @@ public final class EmojiParser { | ||||
|     } | ||||
| 
 | ||||
|     private EmojiParser() { | ||||
|         // Log.d(TAG, "Emoji: " + new Date()); | ||||
|         // String[][] data = { | ||||
|         //         {"arrow", "→ ↓ ↑ ← ↔ ↕ ⇆ ⇅"}, | ||||
|         //         {"alphanum", "© ® ℗ ™ µ"}, | ||||
|         //         {"geometric", "▼ ▶ ▲ ◀ ● ○ ◯ ◊"}, | ||||
|         //         {"math", "× ÷ √ ∞ ∆ ∇ ⁻ ¹ ² ³ ≡ ∈ ⊂ ∩ ∪ ° + ± − = ≈ ≠ > < ≤ ≥ ¬ | ~"}, | ||||
|         //         {"punctuation", "§ † ‡ \\u0020  , 、 ، ; : ؛ ! ¡ ? ¿ ؟ ¶ ※ / \\ & # % ‰ ′ ″ ‴ @ * ♪ ♭ ♯ ` ´ ^ ¨ ‐ ― _ - – — • · . … 。 ‧ ・ ‘ ’ ‚ ' “ ” „ » « ( ) [ ] { } 〔 〕 〈 〉 《 》 「 」 『 』 〖 〗 【 】"}, | ||||
|         //         {"currency", "€ £ ¥ ₹ ₽ $ ¢ ฿ ₪ ₺ ₫ ₱ ₩ ₡ ₦ ₮ ৳ ₴ ₸ ₲ ₵ ៛ ₭ ֏ ₥ ₾ ₼ ₿ ؋"}, | ||||
|         //         {"other-symbol", "‾‽‸⁂↚↛↮↙↜↝↞↟↠↡↢↣↤↥↦↧↨↫↬↭↯↰↱↲↳↴↵↶↷↸↹↺↻↼↽↾↿⇀⇁⇂⇃⇄⇇⇈⇉⇊⇋⇌⇐⇍⇑⇒⇏⇓⇔⇎⇖⇗⇘⇙⇚⇛⇜⇝⇞⇟⇠⇡⇢⇣⇤⇥⇦⇧⇨⇩⇪⇵∀∂∃∅∉∋∎∏∑≮≯∓∕⁄∗∘∙∝∟∠∣∥∧∫∬∮∴∵∶∷∼∽∾≃≅≌≒≖≣≦≧≪≫≬≳≺≻⊁⊃⊆⊇⊕⊖⊗⊘⊙⊚⊛⊞⊟⊥⊮⊰⊱⋭⊶⊹⊿⋁⋂⋃⋅⋆⋈⋒⋘⋙⋮⋯⋰⋱■□▢▣▤▥▦▧▨▩▬▭▮▰△▴▵▷▸▹►▻▽▾▿◁◂◃◄◅◆◇◈◉◌◍◎◐◑◒◓◔◕◖◗◘◙◜◝◞◟◠◡◢◣◤◥◦◳◷◻◽◿⨧⨯⨼⩣⩽⪍⪚⪺₢₣₤₰₳₶₷₨﷼"}, | ||||
|         // }; | ||||
|         // get the maximum suborder for each subcategory | ||||
|         // Map<String, Long> subcategoryToMaxSuborder = new HashMap<>(); | ||||
|         // for (String[] row : data) { | ||||
|         // final String subcategory = row[0]; | ||||
|         // for (Entry<String, String> entry : emojiToMinorCategory.entrySet()) { | ||||
|         //     if (entry.getValue().equals(subcategory)) { | ||||
|         //         String emoji = entry.getKey(); | ||||
|         //         Long order = emojiToOrder.get(emoji); | ||||
|         //         Long currentMax = subcategoryToMaxSuborder.get(subcategory); | ||||
|         //         if (order == null) continue; | ||||
|         //         if (currentMax == null || currentMax < order) { | ||||
|         //             subcategoryToMaxSuborder.put(subcategory, order); | ||||
|         //         } | ||||
|         //     } | ||||
|         // } | ||||
|         // } | ||||
|         // if (DEBUG) System.out.println(subcategoryToMaxSuborder); | ||||
|         // Map<String, Long> _EXTRA_SYMBOL_ORDER = new LinkedHashMap<>(); | ||||
|         // for (String[] row : data) { | ||||
|         //     final String subcategory = row[0]; | ||||
|         //     final String characters = row[1]; | ||||
|         // | ||||
|         //     List<String> items = new ArrayList<>(); | ||||
|         //     for (int cp : With.codePointArray(characters)) { | ||||
|         //         if (cp != ' ') { | ||||
|         //             items.add(With.fromCodePoint(cp)); | ||||
|         //         } | ||||
|         //     } | ||||
|         //     final UnicodeSet uset = new UnicodeSet().addAll(items); | ||||
|         //     if (uset.containsSome(EXTRA_SYMBOL_MINOR_CATEGORIES.keySet())) { | ||||
|         //         throw new IllegalArgumentException("Duplicate values in " + EXTRA_SYMBOL_MINOR_CATEGORIES); | ||||
|         //     } | ||||
|         //     EXTRA_SYMBOL_MINOR_CATEGORIES.putAll(uset, subcategory); | ||||
|         //     final Long countObject = subcategoryToMaxSuborder.get(subcategory); | ||||
|         //     if (countObject == null) continue; | ||||
|         //     long count = countObject; | ||||
|         //     for (String s : items) { | ||||
|         //         ++count; | ||||
|         //         _EXTRA_SYMBOL_ORDER.put(s, count); | ||||
|         //     } | ||||
|         //     subcategoryToMaxSuborder.put(subcategory, count); | ||||
|         // } | ||||
|         // if (DEBUG) System.out.println(_EXTRA_SYMBOL_ORDER); | ||||
|         // EXTRA_SYMBOL_MINOR_CATEGORIES.freeze(); | ||||
|         // EXTRA_SYMBOL_ORDER = ImmutableMap.copyOf(_EXTRA_SYMBOL_ORDER); | ||||
| 
 | ||||
|         /* | ||||
|             # group: Smileys & People | ||||
|             # subgroup: face-positive | ||||
|             1F600 ; fully-qualified     # 😀 grinning face | ||||
|          */ | ||||
|         final Splitter semi = Splitter.on(CharMatcher.anyOf(";#")).trimResults(); | ||||
|         String majorCategory; | ||||
| 
 | ||||
|         final String file = "res/raw/emoji_test.txt"; | ||||
|         final String file = "res/raw/emojis.json"; | ||||
|         final ClassLoader classLoader = getClass().getClassLoader(); | ||||
|         if (classLoader == null) { | ||||
|             Log.e(TAG, "Emoji: classLoader is null"); | ||||
|             return; | ||||
|         } | ||||
|         try (final InputStream in = classLoader.getResourceAsStream(file); | ||||
|              final BufferedReader reader = new BufferedReader(new InputStreamReader(in))) { | ||||
|             String line; | ||||
|             EmojiCategoryType categoryType = null; | ||||
|             while ((line = reader.readLine()) != null) { | ||||
|                 if (line.startsWith("#")) { | ||||
|                     line = line.substring(1).trim(); | ||||
|                     if (line.startsWith("group:")) { | ||||
|                         majorCategory = line.substring("group:".length()).trim(); | ||||
|                         if (!majorCategory.equals("Component")) { // Skip Component | ||||
|                             if (majorCategory.equals("Smileys & Emotion") || majorCategory.equals("People & Body")) { | ||||
|                                 // Put 'People & Body' in 'Smileys & Emotion' category | ||||
|                                 categoryType = EmojiCategoryType.SMILEYS_AND_EMOTION; | ||||
|                             } else { | ||||
|                                 categoryType = EmojiCategoryType.valueOfName(majorCategory); | ||||
|                             } | ||||
|                             final boolean contains = CATEGORY_MAP.containsKey(categoryType); | ||||
|                             if (!contains) { | ||||
|                                 CATEGORY_MAP.put(categoryType, new EmojiCategory(categoryType)); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     continue; | ||||
|                 } | ||||
|                 if (categoryType == null) continue; | ||||
|                 line = line.trim(); | ||||
|                 if (line.isEmpty()) { | ||||
|                     continue; | ||||
|                 } | ||||
|                 final Iterator<String> it = semi.split(line).iterator(); | ||||
|                 String emojiHex = it.next(); | ||||
|                 String original = Utility.fromHex(emojiHex, 4, " "); | ||||
|                 String status = it.next(); | ||||
|                 if (!status.startsWith("fully-qualified")) { // only use fully qualified | ||||
|                     continue; | ||||
|                 } | ||||
|                 final EmojiCategory emojiCategory = CATEGORY_MAP.get(categoryType); | ||||
|                 final Map<String, Emoji> emojis = emojiCategory == null ? new LinkedHashMap<>() : emojiCategory.getEmojis(); | ||||
|                 String comment = it.next(); | ||||
|                 // The comment is now of the form:  # 😁 E0.6 beaming face with smiling eyes | ||||
|                 int spacePos = comment.indexOf(' '); | ||||
|                 spacePos = comment.indexOf(' ', spacePos + 1); // get second space | ||||
|                 final String name = comment.substring(spacePos + 1).trim(); | ||||
|                 final Emoji emoji = new Emoji(original, name); | ||||
|                 ALL_EMOJIS.put(original, emoji); | ||||
|                 String minimal = original.replace(EMOJI_VARIANT, ""); | ||||
|                 //noinspection deprecation | ||||
|                 boolean singleton = CharSequences.getSingleCodePoint(minimal) != Integer.MAX_VALUE; | ||||
|                 if (!singleton && SKIN_TONE_MODIFIERS.containsSome(minimal)) { | ||||
|                     // skin tone variant | ||||
|                     final String parent = minimal.replaceAll(SKIN_TONE_PATTERN, ""); | ||||
|                     final Emoji parentEmoji = emojis.get(parent); | ||||
|                     if (parentEmoji != null) { | ||||
|                         parentEmoji.addVariant(emoji); | ||||
|                     } | ||||
|                     continue; | ||||
|                 } | ||||
|                 emojis.put(original, emoji); | ||||
|                 // skip constructed values | ||||
|                 // if (minimal.contains(COMBINING_ENCLOSING_KEYCAP) | ||||
|                 //         || REGIONAL_INDICATORS.containsSome(minimal) | ||||
|                 //         || TAGS.containsSome(minimal) | ||||
|                 //         || !singleton && MODIFIERS.containsSome(minimal) | ||||
|                 //         || !singleton && FAMILY.containsAll(minimal)) { | ||||
|                 //     // do nothing | ||||
|                 // } else if (minimal.contains(ZWJ)) { // only do certain ZWJ sequences | ||||
|                 //     if (SPECIALS.contains(minimal) | ||||
|                 //             || GENDER.containsSome(minimal) | ||||
|                 //             || MAN_WOMAN.contains(minimal.codePointAt(0)) && OBJECT.contains(minimal.codePointBefore(minimal.length()))) { | ||||
|                 //         // nonConstructed.add(minimal); | ||||
|                 //     } | ||||
|                 // } else if (!minimal.contains("🔟")) { | ||||
|                 //     // nonConstructed.add(minimal); | ||||
|                 // } | ||||
|             } | ||||
|             //        for (Entry<Pair<Integer,Integer>, String> entry : majorPlusMinorToEmoji.entries()) { | ||||
|             //            String minimal = entry.getValue(); | ||||
|             //            emojiToOrder.put(minimal, emojiToOrder.size()); | ||||
|             //        } | ||||
|         try (final InputStream in = classLoader.getResourceAsStream(file)) { | ||||
|             final String json = NetworkUtils.readFromInputStream(in); | ||||
|             final Gson gson = new Gson(); | ||||
|             final Type type = new TypeToken<Map<EmojiCategoryType, EmojiCategory>>() {}.getType(); | ||||
|             categoryMap = gson.fromJson(json, type); | ||||
|             // Log.d(TAG, "EmojiParser: " + categoryMap); | ||||
|             allEmojis = categoryMap.values() | ||||
|                                    .stream() | ||||
|                                    .flatMap((Function<EmojiCategory, Stream<Emoji>>) emojiCategory -> { | ||||
|                                        final Map<String, Emoji> emojis = emojiCategory.getEmojis(); | ||||
|                                        return emojis.values().stream(); | ||||
|                                    }) | ||||
|                                    .flatMap(emoji -> ImmutableList.<Emoji>builder() | ||||
|                                            .add(emoji) | ||||
|                                            .addAll(emoji.getVariants()) | ||||
|                                            .build() | ||||
|                                            .stream()) | ||||
|                                    .collect(Collectors.toMap(Emoji::getUnicode, Function.identity())); | ||||
|         } catch (IOException e) { | ||||
|             Log.e(TAG, "Emoji: ", e); | ||||
|             Log.e(TAG, "EmojiParser: ", e); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // private static <K, V> void putUnique(Map<K, V> map, K key, V value) { | ||||
|     //     V oldValue = map.put(key, value); | ||||
|     //     if (oldValue != null) { | ||||
|     //         throw new ICUException("Attempt to change value of " + map | ||||
|     //                                        + " for " + key | ||||
|     //                                        + " from " + oldValue | ||||
|     //                                        + " to " + value | ||||
|     //         ); | ||||
|     //     } | ||||
|     // } | ||||
| 
 | ||||
|     public Map<EmojiCategoryType, EmojiCategory> getCategoryMap() { | ||||
|         return CATEGORY_MAP; | ||||
|         return categoryMap; | ||||
|     } | ||||
| 
 | ||||
|     public List<EmojiCategory> getEmojiCategories() { | ||||
|         if (categories == null) { | ||||
|             final Collection<EmojiCategory> categoryCollection = CATEGORY_MAP.values(); | ||||
|             final Collection<EmojiCategory> categoryCollection = categoryMap.values(); | ||||
|             categories = ImmutableList.copyOf(categoryCollection); | ||||
|         } | ||||
|         return categories; | ||||
|     } | ||||
| 
 | ||||
|     public Map<String, Emoji> getAllEmojis() { | ||||
|         return ALL_EMOJIS; | ||||
|         return allEmojis; | ||||
|     } | ||||
| 
 | ||||
|     public Emoji getEmoji(final String emoji) { | ||||
|         if (emoji == null) { | ||||
|             return null; | ||||
|         } | ||||
|         return ALL_EMOJIS.get(emoji); | ||||
|     } | ||||
| 
 | ||||
|     // public String getMinorCategory(String emoji) { | ||||
|     //     String minorCat = emojiToMinorCategory.get(emoji); | ||||
|     //     if (minorCat == null) { | ||||
|     //         minorCat = EXTRA_SYMBOL_MINOR_CATEGORIES.get(emoji); | ||||
|     //         if (minorCat == null) { | ||||
|     //             throw new InternalCldrException("No minor category (aka subgroup) found for " + emoji | ||||
|     //                                                     + ". Update emoji-test.txt to latest, and setValue PathHeader.. functionMap.put(\"minor\", ..."); | ||||
|     //         } | ||||
|     //     } | ||||
|     //     return minorCat; | ||||
|     // } | ||||
| 
 | ||||
|     // public long getEmojiToOrder(String emoji) { | ||||
|     //     Long result = emojiToOrder.get(emoji); | ||||
|     //     if (result == null) { | ||||
|     //         result = EXTRA_SYMBOL_ORDER.get(emoji); | ||||
|     //         if (result == null) { | ||||
|     //             throw new InternalCldrException("No Order found for " + emoji | ||||
|     //                                                     + ". Update emoji-test.txt to latest, and setValue PathHeader.. functionMap.put(\"minor\", ..."); | ||||
|     //         } | ||||
|     //     } | ||||
|     //     return result; | ||||
|     // } | ||||
| 
 | ||||
|     // public long getEmojiMinorOrder(String minor) { | ||||
|     //     Long result = minorToOrder.get(minor); | ||||
|     //     if (result == null) { | ||||
|     //         throw new InternalCldrException("No minor category (aka subgroup) found for " + minor | ||||
|     //                                                 + ". Update emoji-test.txt to latest, and setValue PathHeader.. functionMap.put(\"minor\", ..."); | ||||
|     //     } | ||||
|     //     return result; | ||||
|     // } | ||||
| 
 | ||||
|     // public String getMajorCategory(String emoji) { | ||||
|     //     String majorCat = emojiToMajorCategory.get(emoji); | ||||
|     //     if (majorCat == null) { | ||||
|     //         if (EXTRA_SYMBOL_MINOR_CATEGORIES.containsKey(emoji)) { | ||||
|     //             majorCat = "Symbols"; | ||||
|     //         } else { | ||||
|     //             throw new InternalCldrException("No minor category (aka subgroup) found for " + emoji | ||||
|     //                                                     + ". Update emoji-test.txt to latest, and setValue PathHeader.. functionMap.put(\"major\", ..."); | ||||
|     //         } | ||||
|     //     } | ||||
|     //     return majorCat; | ||||
|     // } | ||||
| 
 | ||||
|     // public Set<String> getMinorCategoriesWithExtras() { | ||||
|     //     Set<String> result = new LinkedHashSet<>(emojiToMinorCategory.values()); | ||||
|     //     result.addAll(EXTRA_SYMBOL_MINOR_CATEGORIES.getAvailableValues()); | ||||
|     //     return ImmutableSet.copyOf(result); | ||||
|     // } | ||||
| 
 | ||||
|     // public UnicodeSet getEmojiInMinorCategoriesWithExtras(String minorCategory) { | ||||
|     //     return new UnicodeSet(emojiToMinorCategory.getSet(minorCategory)) | ||||
|     //             .addAll(EXTRA_SYMBOL_MINOR_CATEGORIES.getSet(minorCategory)) | ||||
|     //             .freeze(); | ||||
|     // } | ||||
| 
 | ||||
|     // public synchronized Set<String> getNamePaths() { | ||||
|     //     return NAME_PATHS != null ? NAME_PATHS : (NAME_PATHS = buildPaths(TYPE_TTS)); | ||||
|     // } | ||||
| 
 | ||||
|     // public synchronized Set<String> getKeywordPaths() { | ||||
|     //     return KEYWORD_PATHS != null ? KEYWORD_PATHS : (KEYWORD_PATHS = buildPaths("")); | ||||
|     // } | ||||
| 
 | ||||
|     // private ImmutableSet<String> buildPaths(String suffix) { | ||||
|     //     ImmutableSet.Builder<String> builder = ImmutableSet.builder(); | ||||
|     //     for (String s : getNonConstructed()) { | ||||
|     //         String base = "//ldml/annotations/annotation[@cp=\"" + s + "\"]" + suffix; | ||||
|     //         builder.add(base); | ||||
|     //     } | ||||
|     //     return builder.build(); | ||||
|     // } | ||||
|         return allEmojis.get(emoji); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,50 +0,0 @@ | ||||
| package awais.instagrabber.utils.emoji; | ||||
| 
 | ||||
| // © 2016 and later: Unicode, Inc. and others. | ||||
| // License & terms of use: http://www.unicode.org/copyright.html#License | ||||
| /* | ||||
|  ******************************************************************************* | ||||
|  * Copyright (C) 2009-2012, International Business Machines Corporation and         * | ||||
|  * others. All Rights Reserved.                                                * | ||||
|  ******************************************************************************* | ||||
|  */ | ||||
| 
 | ||||
| import java.util.Map; | ||||
| 
 | ||||
| /** | ||||
|  * @author markdavis | ||||
|  */ | ||||
| public class ImmutableEntry<K, V> implements Map.Entry<K, V> { | ||||
|     final K k; | ||||
|     final V v; | ||||
| 
 | ||||
|     ImmutableEntry(K key, V value) { | ||||
|         k = key; | ||||
|         v = value; | ||||
|     } | ||||
| 
 | ||||
|     public K getKey() {return k;} | ||||
| 
 | ||||
|     public V getValue() {return v;} | ||||
| 
 | ||||
|     public V setValue(V value) { | ||||
|         throw new UnsupportedOperationException(); | ||||
|     } | ||||
| 
 | ||||
|     public boolean equals(Object o) { | ||||
|         try { | ||||
|             Map.Entry e = (Map.Entry) o; | ||||
|             return UnicodeMap.areEqual(e.getKey(), k) && UnicodeMap.areEqual(e.getValue(), v); | ||||
|         } catch (ClassCastException e) { | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public int hashCode() { | ||||
|         return ((k == null ? 0 : k.hashCode()) ^ (v == null ? 0 : v.hashCode())); | ||||
|     } | ||||
| 
 | ||||
|     public String toString() { | ||||
|         return k + "=" + v; | ||||
|     } | ||||
| } | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -45,7 +45,6 @@ public class DirectSettingsViewModel extends AndroidViewModel { | ||||
| 
 | ||||
|     public DirectSettingsViewModel(final Application application, | ||||
|                                    @NonNull final String threadId, | ||||
|                                    final DirectThread backup, | ||||
|                                    final boolean pending, | ||||
|                                    @NonNull final User currentUser) { | ||||
|         super(application); | ||||
| @ -59,7 +58,7 @@ public class DirectSettingsViewModel extends AndroidViewModel { | ||||
|         final ContentResolver contentResolver = application.getContentResolver(); | ||||
|         resources = getApplication().getResources(); | ||||
|         final DirectMessagesManager messagesManager = DirectMessagesManager.getInstance(); | ||||
|         threadManager = messagesManager.getThreadManager(threadId, pending, backup, currentUser, contentResolver); | ||||
|         threadManager = messagesManager.getThreadManager(threadId, pending, currentUser, contentResolver); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|  | ||||
| @ -23,6 +23,7 @@ import java.util.stream.Collectors; | ||||
| 
 | ||||
| import awais.instagrabber.customviews.emoji.Emoji; | ||||
| import awais.instagrabber.managers.DirectMessagesManager; | ||||
| import awais.instagrabber.managers.InboxManager; | ||||
| import awais.instagrabber.managers.ThreadManager; | ||||
| import awais.instagrabber.models.Resource; | ||||
| import awais.instagrabber.repositories.responses.User; | ||||
| @ -57,7 +58,6 @@ public class DirectThreadViewModel extends AndroidViewModel { | ||||
| 
 | ||||
|     public DirectThreadViewModel(@NonNull final Application application, | ||||
|                                  @NonNull final String threadId, | ||||
|                                  final DirectThread backup, | ||||
|                                  final boolean pending, | ||||
|                                  @NonNull final User currentUser) { | ||||
|         super(application); | ||||
| @ -74,7 +74,7 @@ public class DirectThreadViewModel extends AndroidViewModel { | ||||
|         contentResolver = application.getContentResolver(); | ||||
|         recordingsDir = DirectoryUtils.getOutputMediaDirectory(application, "Recordings"); | ||||
|         final DirectMessagesManager messagesManager = DirectMessagesManager.getInstance(); | ||||
|         threadManager = messagesManager.getThreadManager(threadId, pending, backup, currentUser, contentResolver); | ||||
|         threadManager = messagesManager.getThreadManager(threadId, pending, currentUser, contentResolver); | ||||
|         threadManager.fetchPendingRequests(); | ||||
|     } | ||||
| 
 | ||||
| @ -278,16 +278,24 @@ public class DirectThreadViewModel extends AndroidViewModel { | ||||
|         return threadManager.declineRequest(); | ||||
|     } | ||||
| 
 | ||||
|     public void markAsSeen() { | ||||
|         if (currentUser == null) return; | ||||
|     public LiveData<Resource<Object>> markAsSeen() { | ||||
|         if (currentUser == null) { | ||||
|             return getSuccessEventResObjectLiveData(); | ||||
|         } | ||||
|         final DirectThread thread = getThread().getValue(); | ||||
|         if (thread == null) return; | ||||
|         if (thread == null) { | ||||
|             return getSuccessEventResObjectLiveData(); | ||||
|         } | ||||
|         final List<DirectItem> items = thread.getItems(); | ||||
|         if (items == null || items.isEmpty()) return; | ||||
|         if (items == null || items.isEmpty()) { | ||||
|             return getSuccessEventResObjectLiveData(); | ||||
|         } | ||||
|         final Optional<DirectItem> itemOptional = items.stream() | ||||
|                                                        .filter(item -> item.getUserId() != currentUser.getPk()) | ||||
|                                                        .findFirst(); | ||||
|         if (!itemOptional.isPresent()) return; | ||||
|         if (!itemOptional.isPresent()) { | ||||
|             return getSuccessEventResObjectLiveData(); | ||||
|         } | ||||
|         final DirectItem directItem = itemOptional.get(); | ||||
|         final Map<Long, DirectThreadLastSeenAt> lastSeenAt = thread.getLastSeenAt(); | ||||
|         if (lastSeenAt != null) { | ||||
| @ -296,10 +304,29 @@ public class DirectThreadViewModel extends AndroidViewModel { | ||||
|                 if (seenAt != null | ||||
|                         && (Objects.equals(seenAt.getItemId(), directItem.getItemId()) | ||||
|                         || Long.parseLong(seenAt.getTimestamp()) >= directItem.getTimestamp())) { | ||||
|                     return; | ||||
|                     return getSuccessEventResObjectLiveData(); | ||||
|                 } | ||||
|             } catch (Exception ignored) {} | ||||
|         } | ||||
|         threadManager.markAsSeen(directItem); | ||||
|             } catch (Exception ignored) { | ||||
|                 return getSuccessEventResObjectLiveData(); | ||||
|             } | ||||
|         } | ||||
|         return threadManager.markAsSeen(directItem); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     private MutableLiveData<Resource<Object>> getSuccessEventResObjectLiveData() { | ||||
|         final MutableLiveData<Resource<Object>> data = new MutableLiveData<>(); | ||||
|         data.postValue(Resource.success(new Object())); | ||||
|         return data; | ||||
|     } | ||||
| 
 | ||||
|     public void deleteThreadIfRequired() { | ||||
|         final DirectThread thread = getThread().getValue(); | ||||
|         if (thread == null) return; | ||||
|         if (thread.isTemp() && (thread.getItems() == null || thread.getItems().isEmpty())) { | ||||
|             final InboxManager inboxManager = DirectMessagesManager.getInstance().getInboxManager(); | ||||
|             inboxManager.removeThread(threadId); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -7,25 +7,21 @@ import androidx.lifecycle.ViewModel; | ||||
| import androidx.lifecycle.ViewModelProvider; | ||||
| 
 | ||||
| import awais.instagrabber.repositories.responses.User; | ||||
| import awais.instagrabber.repositories.responses.directmessages.DirectThread; | ||||
| import awais.instagrabber.viewmodels.DirectSettingsViewModel; | ||||
| 
 | ||||
| public class DirectSettingsViewModelFactory implements ViewModelProvider.Factory { | ||||
| 
 | ||||
|     private final Application application; | ||||
|     private final String threadId; | ||||
|     private final DirectThread backup; | ||||
|     private final boolean pending; | ||||
|     private final User currentUser; | ||||
| 
 | ||||
|     public DirectSettingsViewModelFactory(@NonNull final Application application, | ||||
|                                           @NonNull final String threadId, | ||||
|                                           @NonNull final DirectThread backup, | ||||
|                                           final boolean pending, | ||||
|                                           @NonNull final User currentUser) { | ||||
|         this.application = application; | ||||
|         this.threadId = threadId; | ||||
|         this.backup = backup; | ||||
|         this.pending = pending; | ||||
|         this.currentUser = currentUser; | ||||
|     } | ||||
| @ -34,6 +30,6 @@ public class DirectSettingsViewModelFactory implements ViewModelProvider.Factory | ||||
|     @Override | ||||
|     public <T extends ViewModel> T create(@NonNull final Class<T> modelClass) { | ||||
|         //noinspection unchecked | ||||
|         return (T) new DirectSettingsViewModel(application, threadId, backup, pending, currentUser); | ||||
|         return (T) new DirectSettingsViewModel(application, threadId, pending, currentUser); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -7,25 +7,21 @@ import androidx.lifecycle.ViewModel; | ||||
| import androidx.lifecycle.ViewModelProvider; | ||||
| 
 | ||||
| import awais.instagrabber.repositories.responses.User; | ||||
| import awais.instagrabber.repositories.responses.directmessages.DirectThread; | ||||
| import awais.instagrabber.viewmodels.DirectThreadViewModel; | ||||
| 
 | ||||
| public class DirectThreadViewModelFactory implements ViewModelProvider.Factory { | ||||
| 
 | ||||
|     private final Application application; | ||||
|     private final String threadId; | ||||
|     private final DirectThread backup; | ||||
|     private final boolean pending; | ||||
|     private final User currentUser; | ||||
| 
 | ||||
|     public DirectThreadViewModelFactory(@NonNull final Application application, | ||||
|                                         @NonNull final String threadId, | ||||
|                                         final DirectThread backup, | ||||
|                                         final boolean pending, | ||||
|                                         @NonNull final User currentUser) { | ||||
|         this.application = application; | ||||
|         this.threadId = threadId; | ||||
|         this.backup = backup; | ||||
|         this.pending = pending; | ||||
|         this.currentUser = currentUser; | ||||
|     } | ||||
| @ -34,6 +30,6 @@ public class DirectThreadViewModelFactory implements ViewModelProvider.Factory { | ||||
|     @Override | ||||
|     public <T extends ViewModel> T create(@NonNull final Class<T> modelClass) { | ||||
|         //noinspection unchecked | ||||
|         return (T) new DirectThreadViewModel(application, threadId, backup, pending, currentUser); | ||||
|         return (T) new DirectThreadViewModel(application, threadId, pending, currentUser); | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								app/src/main/res/drawable/barinsta_logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								app/src/main/res/drawable/barinsta_logo.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 48 KiB | 
							
								
								
									
										10
									
								
								app/src/main/res/drawable/launch_screen.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/src/main/res/drawable/launch_screen.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <layer-list xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:opacity="opaque"> | ||||
|     <item android:drawable="@color/grey_900" /> | ||||
|     <item> | ||||
|         <bitmap | ||||
|             android:gravity="center" | ||||
|             android:src="@drawable/barinsta_logo" /> | ||||
|     </item> | ||||
| </layer-list> | ||||
| @ -257,7 +257,7 @@ | ||||
|         android:layout_width="0dp" | ||||
|         android:layout_height="250dp" | ||||
|         android:translationY="250dp" | ||||
|         android:visibility="gone" | ||||
|         android:visibility="visible" | ||||
|         app:layout_constraintBottom_toBottomOf="parent" | ||||
|         app:layout_constraintEnd_toEndOf="parent" | ||||
|         app:layout_constraintStart_toStartOf="parent" | ||||
|  | ||||
| @ -8,7 +8,7 @@ | ||||
|         app:showAsAction="ifRoom" /> | ||||
|     <item | ||||
|         android:id="@+id/mark_as_seen" | ||||
|         android:icon="@drawable/ic_outline_views_24" | ||||
|         android:icon="@drawable/ic_check_all_24" | ||||
|         android:title="@string/mark_as_seen" | ||||
|         app:showAsAction="ifRoom" /> | ||||
|     <item | ||||
|  | ||||
| @ -122,10 +122,6 @@ | ||||
|             android:name="pending" | ||||
|             android:defaultValue="false" | ||||
|             app:argType="boolean" /> | ||||
|         <argument | ||||
|             android:name="backup" | ||||
|             app:nullable="true" | ||||
|             app:argType="awais.instagrabber.repositories.responses.directmessages.DirectThread" /> | ||||
|         <action | ||||
|             android:id="@+id/action_thread_to_settings" | ||||
|             app:destination="@id/directMessagesSettingsFragment" /> | ||||
| @ -156,11 +152,6 @@ | ||||
|             android:defaultValue="false" | ||||
|             app:argType="boolean" /> | ||||
| 
 | ||||
|         <argument | ||||
|             android:name="backup" | ||||
|             app:nullable="true" | ||||
|             app:argType="awais.instagrabber.repositories.responses.directmessages.DirectThread" /> | ||||
| 
 | ||||
|         <action | ||||
|             android:id="@+id/action_settings_to_inbox" | ||||
|             app:destination="@id/directMessagesInboxFragment" | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1
									
								
								app/src/main/res/raw/emojis.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								app/src/main/res/raw/emojis.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -471,4 +471,5 @@ | ||||
|     <string name="edit_keyword_filter">Edit keyword filters</string> | ||||
|     <string name="added_keywords">Added keyword: {0} to filter list</string> | ||||
|     <string name="removed_keywords">Removed keyword: {0} from filter list</string> | ||||
|     <string name="marked_as_seen">Marked as seen</string> | ||||
| </resources> | ||||
|  | ||||
| @ -140,4 +140,8 @@ | ||||
|         <item name="dmOutgoingBgColor">@color/deep_purple_400</item> | ||||
|         <item name="dmDateHeaderBgColor">@color/deep_purple_600</item> | ||||
|     </style> | ||||
| 
 | ||||
|     <style name="AppTheme.Launcher" parent="AppTheme.Dark"> | ||||
|         <item name="android:windowBackground">@drawable/launch_screen</item> | ||||
|     </style> | ||||
| </resources> | ||||
| @ -5,7 +5,7 @@ buildscript { | ||||
|     } | ||||
| 
 | ||||
|     dependencies { | ||||
|         classpath 'com.android.tools.build:gradle:4.1.2' | ||||
|         classpath 'com.android.tools.build:gradle:4.1.3' | ||||
|         def nav_version = "2.3.4" | ||||
|         classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" | ||||
|     } | ||||
|  | ||||
							
								
								
									
										6
									
								
								renovate.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								renovate.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| { | ||||
|   "extends": [ | ||||
|     "config:base" | ||||
|   ], | ||||
|   "prConcurrentLimit": 5 | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user