mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-11-17 12:17:30 +00:00
Merge branch 'master' into add-sentry
This commit is contained in:
commit
fba0a751b1
@ -132,6 +132,6 @@ dependencies {
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.6'
|
||||
|
||||
githubImplementation 'io.sentry:sentry-android:4.3.0'
|
||||
|
||||
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter:5.7.1'
|
||||
}
|
||||
|
@ -0,0 +1,42 @@
|
||||
package awais.instagrabber.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import awais.instagrabber.R;
|
||||
import awais.instagrabber.adapters.viewholder.dialogs.KeywordsFilterDialogViewHolder;
|
||||
|
||||
public class KeywordsFilterAdapter extends RecyclerView.Adapter<KeywordsFilterDialogViewHolder> {
|
||||
|
||||
private final Context context;
|
||||
private final ArrayList<String> items;
|
||||
|
||||
public KeywordsFilterAdapter(Context context, ArrayList<String> items){
|
||||
this.context = context;
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public KeywordsFilterDialogViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
final View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_keyword, parent, false);
|
||||
return new KeywordsFilterDialogViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull KeywordsFilterDialogViewHolder holder, int position) {
|
||||
holder.bind(items, position, context, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return items.size();
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package awais.instagrabber.adapters.viewholder.dialogs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
import awais.instagrabber.R;
|
||||
import awais.instagrabber.adapters.KeywordsFilterAdapter;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.SettingsHelper;
|
||||
|
||||
public class KeywordsFilterDialogViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private final Button deleteButton;
|
||||
private final TextView item;
|
||||
|
||||
public KeywordsFilterDialogViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
deleteButton = itemView.findViewById(R.id.keyword_delete);
|
||||
item = itemView.findViewById(R.id.keyword_text);
|
||||
}
|
||||
|
||||
public void bind(ArrayList<String> items, int position, Context context, KeywordsFilterAdapter adapter){
|
||||
item.setText(items.get(position));
|
||||
deleteButton.setOnClickListener(view -> {
|
||||
final String s = items.get(position);
|
||||
SettingsHelper settingsHelper = new SettingsHelper(context);
|
||||
items.remove(position);
|
||||
settingsHelper.putStringSet(Constants.KEYWORD_FILTERS, new HashSet<>(items));
|
||||
adapter.notifyDataSetChanged();
|
||||
final String message = context.getString(R.string.removed_keywords, s);
|
||||
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}
|
||||
|
||||
public Button getDeleteButton(){
|
||||
return deleteButton;
|
||||
}
|
||||
|
||||
public TextView getTextView(){
|
||||
return item;
|
||||
}
|
||||
}
|
@ -40,7 +40,10 @@ public class FeedPostFetchService implements PostFetcher.PostFetchService {
|
||||
} else if (result == null) return;
|
||||
nextCursor = result.getNextCursor();
|
||||
hasNextPage = result.hasNextPage();
|
||||
feedModels.addAll(result.getFeedModels());
|
||||
|
||||
final List<Media> mediaResults = result.getFeedModels();
|
||||
feedModels.addAll(mediaResults);
|
||||
|
||||
if (fetchListener != null) {
|
||||
// if (feedModels.size() < 15 && hasNextPage) {
|
||||
// feedService.fetch(csrfToken, nextCursor, this);
|
||||
|
@ -133,7 +133,7 @@ public final class PostFetcher extends AsyncTask<Void, Void, Media> {
|
||||
// feedModelBuilder.setSliderItems(postModels);
|
||||
// }
|
||||
// return feedModelBuilder.build();
|
||||
return ResponseBodyUtils.parseGraphQLItem(media);
|
||||
return ResponseBodyUtils.parseGraphQLItem(media, null);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// if (logCollector != null) {
|
||||
|
@ -1,101 +0,0 @@
|
||||
package awais.instagrabber.asyncs;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import awais.instagrabber.interfaces.FetchListener;
|
||||
import awais.instagrabber.repositories.responses.FriendshipStatus;
|
||||
import awais.instagrabber.repositories.responses.User;
|
||||
import awais.instagrabber.webservices.GraphQLService;
|
||||
import awais.instagrabber.webservices.ServiceCallback;
|
||||
import awais.instagrabber.webservices.UserService;
|
||||
|
||||
public final class ProfileFetcher extends AsyncTask<Void, Void, Void> {
|
||||
private static final String TAG = ProfileFetcher.class.getSimpleName();
|
||||
private final UserService userService;
|
||||
private final GraphQLService graphQLService;
|
||||
|
||||
private final FetchListener<User> fetchListener;
|
||||
private final long myId;
|
||||
private final boolean isLoggedIn;
|
||||
private final String userName;
|
||||
|
||||
public ProfileFetcher(final String userName,
|
||||
final long myId,
|
||||
final boolean isLoggedIn,
|
||||
final FetchListener<User> fetchListener) {
|
||||
this.userName = userName;
|
||||
this.myId = myId;
|
||||
this.isLoggedIn = isLoggedIn;
|
||||
this.fetchListener = fetchListener;
|
||||
userService = isLoggedIn ? UserService.getInstance() : null;
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.getInstance();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected Void doInBackground(final Void... voids) {
|
||||
if (isLoggedIn && userName != null) {
|
||||
userService.getUsernameInfo(userName, new ServiceCallback<User>() {
|
||||
@Override
|
||||
public void onSuccess(final User user) {
|
||||
userService.getUserFriendship(user.getPk(), new ServiceCallback<FriendshipStatus>() {
|
||||
@Override
|
||||
public void onSuccess(final FriendshipStatus status) {
|
||||
user.setFriendshipStatus(status);
|
||||
fetchListener.onResult(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable t) {
|
||||
Log.e(TAG, "Error", t);
|
||||
fetchListener.onFailure(t);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable t) {
|
||||
Log.e(TAG, "Error", t);
|
||||
fetchListener.onFailure(t);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (isLoggedIn) {
|
||||
userService.getUserInfo(myId, new ServiceCallback<User>() {
|
||||
@Override
|
||||
public void onSuccess(final User user) {
|
||||
fetchListener.onResult(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable t) {
|
||||
Log.e(TAG, "Error", t);
|
||||
fetchListener.onFailure(t);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
graphQLService.fetchUser(userName, new ServiceCallback<User>() {
|
||||
@Override
|
||||
public void onSuccess(final User user) {
|
||||
fetchListener.onResult(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable t) {
|
||||
Log.e(TAG, "Error", t);
|
||||
fetchListener.onFailure(t);
|
||||
}
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
if (fetchListener != null) fetchListener.doBefore();
|
||||
}
|
||||
}
|
@ -49,7 +49,7 @@ public class ProfilePostFetchService implements PostFetcher.PostFetchService {
|
||||
}
|
||||
};
|
||||
if (isLoggedIn) profileService.fetchPosts(profileModel.getPk(), nextMaxId, cb);
|
||||
else graphQLService.fetchProfilePosts(profileModel.getPk(), 30, nextMaxId, cb);
|
||||
else graphQLService.fetchProfilePosts(profileModel.getPk(), 30, nextMaxId, profileModel, cb);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -32,11 +32,15 @@ import awais.instagrabber.customviews.helpers.RecyclerLazyLoaderAtEdge;
|
||||
import awais.instagrabber.interfaces.FetchListener;
|
||||
import awais.instagrabber.models.PostsLayoutPreferences;
|
||||
import awais.instagrabber.repositories.responses.Media;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.KeywordsFilterUtils;
|
||||
import awais.instagrabber.utils.ResponseBodyUtils;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
import awais.instagrabber.viewmodels.MediaViewModel;
|
||||
import awais.instagrabber.workers.DownloadWorker;
|
||||
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||
|
||||
public class PostsRecyclerView extends RecyclerView {
|
||||
private static final String TAG = "PostsRecyclerView";
|
||||
|
||||
@ -70,7 +74,13 @@ public class PostsRecyclerView extends RecyclerView {
|
||||
}
|
||||
final List<Media> models = mediaViewModel.getList().getValue();
|
||||
final List<Media> modelsCopy = models == null ? new ArrayList<>() : new ArrayList<>(models);
|
||||
modelsCopy.addAll(result);
|
||||
if (settingsHelper.getBoolean(Constants.TOGGLE_KEYWORD_FILTER)){
|
||||
final ArrayList<String> items = new ArrayList<>(settingsHelper.getStringSet(Constants.KEYWORD_FILTERS));
|
||||
modelsCopy.addAll(new KeywordsFilterUtils(items).filter(result));
|
||||
}
|
||||
else {
|
||||
modelsCopy.addAll(result);
|
||||
}
|
||||
mediaViewModel.getList().postValue(modelsCopy);
|
||||
dispatchFetchStatus();
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package awais.instagrabber.customviews.emoji;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@ -12,10 +11,12 @@ public class Emoji {
|
||||
private final List<Emoji> variants;
|
||||
private GoogleCompatEmojiDrawable drawable;
|
||||
|
||||
public Emoji(final String unicode, final String name) {
|
||||
public Emoji(final String unicode,
|
||||
final String name,
|
||||
final List<Emoji> variants) {
|
||||
this.unicode = unicode;
|
||||
this.name = name;
|
||||
this.variants = new LinkedList<>();
|
||||
this.variants = variants;
|
||||
}
|
||||
|
||||
public String getUnicode() {
|
||||
@ -35,7 +36,7 @@ public class Emoji {
|
||||
}
|
||||
|
||||
public GoogleCompatEmojiDrawable getDrawable() {
|
||||
if (drawable == null) {
|
||||
if (drawable == null && unicode != null) {
|
||||
drawable = new GoogleCompatEmojiDrawable(unicode);
|
||||
}
|
||||
return drawable;
|
||||
@ -60,6 +61,7 @@ public class Emoji {
|
||||
return "Emoji{" +
|
||||
"unicode='" + unicode + '\'' +
|
||||
", name='" + name + '\'' +
|
||||
", variants=" + variants +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package awais.instagrabber.customviews.emoji;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@ -10,12 +10,13 @@ import awais.instagrabber.R;
|
||||
|
||||
public class EmojiCategory {
|
||||
private final EmojiCategoryType type;
|
||||
private final Map<String, Emoji> emojis = new LinkedHashMap<>();
|
||||
private final Map<String, Emoji> emojis;
|
||||
@DrawableRes
|
||||
private int drawableRes;
|
||||
|
||||
public EmojiCategory(final EmojiCategoryType type) {
|
||||
public EmojiCategory(final EmojiCategoryType type, final Map<String, Emoji> emojis) {
|
||||
this.type = type;
|
||||
this.emojis = emojis;
|
||||
}
|
||||
|
||||
public EmojiCategoryType getType() {
|
||||
@ -73,4 +74,13 @@ public class EmojiCategory {
|
||||
public int hashCode() {
|
||||
return Objects.hash(type);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EmojiCategory{" +
|
||||
"type=" + type +
|
||||
", emojis=" + emojis +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,78 @@
|
||||
package awais.instagrabber.dialogs;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
import awais.instagrabber.R;
|
||||
import awais.instagrabber.adapters.KeywordsFilterAdapter;
|
||||
import awais.instagrabber.databinding.DialogKeywordsFilterBinding;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.SettingsHelper;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
|
||||
public final class KeywordsFilterDialog extends DialogFragment {
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
final Dialog dialog = getDialog();
|
||||
if (dialog == null) return;
|
||||
final Window window = dialog.getWindow();
|
||||
if (window == null) return;
|
||||
final int height = ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
final int width = (int) (Utils.displayMetrics.widthPixels * 0.8);
|
||||
window.setLayout(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
final DialogKeywordsFilterBinding dialogKeywordsFilterBinding = DialogKeywordsFilterBinding.inflate(inflater, container, false);
|
||||
init(dialogKeywordsFilterBinding, getContext());
|
||||
dialogKeywordsFilterBinding.btnOK.setOnClickListener(view -> this.dismiss());
|
||||
return dialogKeywordsFilterBinding.getRoot();
|
||||
}
|
||||
|
||||
private void init(DialogKeywordsFilterBinding dialogKeywordsFilterBinding, Context context){
|
||||
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
|
||||
final RecyclerView recyclerView = dialogKeywordsFilterBinding.recyclerKeyword;
|
||||
recyclerView.setLayoutManager(linearLayoutManager);
|
||||
|
||||
final SettingsHelper settingsHelper = new SettingsHelper(context);
|
||||
final ArrayList<String> items = new ArrayList<>(settingsHelper.getStringSet(Constants.KEYWORD_FILTERS));
|
||||
final KeywordsFilterAdapter adapter = new KeywordsFilterAdapter(context, items);
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
||||
final EditText editText = dialogKeywordsFilterBinding.editText;
|
||||
|
||||
dialogKeywordsFilterBinding.btnAdd.setOnClickListener(view ->{
|
||||
final String s = editText.getText().toString();
|
||||
if(s.isEmpty()) return;
|
||||
if(items.contains(s)) {
|
||||
editText.setText("");
|
||||
return;
|
||||
}
|
||||
items.add(s.toLowerCase());
|
||||
settingsHelper.putStringSet(Constants.KEYWORD_FILTERS, new HashSet<>(items));
|
||||
adapter.notifyItemInserted(items.size());
|
||||
final String message = context.getString(R.string.added_keywords, s);
|
||||
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
|
||||
editText.setText("");
|
||||
});
|
||||
}
|
||||
}
|
@ -378,6 +378,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
if (getArguments() == null) return;
|
||||
final HashTagFragmentArgs fragmentArgs = HashTagFragmentArgs.fromBundle(getArguments());
|
||||
hashtag = fragmentArgs.getHashtag();
|
||||
if (hashtag.charAt(0) == '#') hashtag = hashtag.substring(1);
|
||||
fetchHashtagModel();
|
||||
}
|
||||
|
||||
|
@ -925,7 +925,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
|
||||
}
|
||||
|
||||
private void setupLocation(final Location location) {
|
||||
if (location == null) {
|
||||
if (location == null || !detailsVisible) {
|
||||
binding.location.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
@ -57,7 +56,6 @@ import awais.instagrabber.activities.MainActivity;
|
||||
import awais.instagrabber.adapters.FeedAdapterV2;
|
||||
import awais.instagrabber.adapters.HighlightsAdapter;
|
||||
import awais.instagrabber.asyncs.CreateThreadAction;
|
||||
import awais.instagrabber.asyncs.ProfileFetcher;
|
||||
import awais.instagrabber.asyncs.ProfilePostFetchService;
|
||||
import awais.instagrabber.customviews.PrimaryActionModeCallback;
|
||||
import awais.instagrabber.customviews.PrimaryActionModeCallback.CallbacksHelper;
|
||||
@ -73,7 +71,6 @@ import awais.instagrabber.db.repositories.RepositoryCallback;
|
||||
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;
|
||||
@ -93,11 +90,14 @@ import awais.instagrabber.utils.CookieUtils;
|
||||
import awais.instagrabber.utils.DownloadUtils;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
import awais.instagrabber.viewmodels.AppStateViewModel;
|
||||
import awais.instagrabber.viewmodels.HighlightsViewModel;
|
||||
import awais.instagrabber.webservices.FriendshipService;
|
||||
import awais.instagrabber.webservices.GraphQLService;
|
||||
import awais.instagrabber.webservices.MediaService;
|
||||
import awais.instagrabber.webservices.ServiceCallback;
|
||||
import awais.instagrabber.webservices.StoriesService;
|
||||
import awais.instagrabber.webservices.UserService;
|
||||
|
||||
import static androidx.core.content.PermissionChecker.checkSelfPermission;
|
||||
import static awais.instagrabber.fragments.HashTagFragment.ARG_HASHTAG;
|
||||
@ -120,6 +120,8 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
private FriendshipService friendshipService;
|
||||
private StoriesService storiesService;
|
||||
private MediaService mediaService;
|
||||
private UserService userService;
|
||||
private GraphQLService graphQLService;
|
||||
private boolean shouldRefresh = true;
|
||||
private boolean hasStories = false;
|
||||
private HighlightsAdapter highlightsAdapter;
|
||||
@ -304,6 +306,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
private LayoutProfileDetailsBinding profileDetailsBinding;
|
||||
private AccountRepository accountRepository;
|
||||
private FavoriteRepository favoriteRepository;
|
||||
private AppStateViewModel appStateViewModel;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
@ -317,8 +320,11 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
friendshipService = isLoggedIn ? FriendshipService.getInstance(deviceUuid, csrfToken, myId) : null;
|
||||
storiesService = isLoggedIn ? StoriesService.getInstance(null, 0L, null) : null;
|
||||
mediaService = isLoggedIn ? MediaService.getInstance(null, null, 0) : null;
|
||||
userService = isLoggedIn ? UserService.getInstance() : null;
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.getInstance();
|
||||
accountRepository = AccountRepository.getInstance(AccountDataSource.getInstance(getContext()));
|
||||
favoriteRepository = FavoriteRepository.getInstance(FavoriteDataSource.getInstance(getContext()));
|
||||
appStateViewModel = new ViewModelProvider(fragmentActivity).get(AppStateViewModel.class);
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@ -601,31 +607,66 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
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;
|
||||
if (TextUtils.isEmpty(username)) {
|
||||
username = user.getUsername();
|
||||
setUsernameDelayed();
|
||||
if (TextUtils.isEmpty(usernameTemp)) {
|
||||
profileModel = appStateViewModel.getCurrentUser();
|
||||
username = profileModel.getUsername();
|
||||
setUsernameDelayed();
|
||||
setProfileDetails();
|
||||
}
|
||||
else if (isLoggedIn) {
|
||||
userService.getUsernameInfo(usernameTemp, new ServiceCallback<User>() {
|
||||
@Override
|
||||
public void onSuccess(final User user) {
|
||||
userService.getUserFriendship(user.getPk(), new ServiceCallback<FriendshipStatus>() {
|
||||
@Override
|
||||
public void onSuccess(final FriendshipStatus status) {
|
||||
user.setFriendshipStatus(status);
|
||||
profileModel = user;
|
||||
setProfileDetails();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable t) {
|
||||
Log.e(TAG, "Error fetching profile relationship", t);
|
||||
final Context context = getContext();
|
||||
try {
|
||||
if (t == null) Toast.makeText(context, R.string.error_loading_profile_loggedin, Toast.LENGTH_LONG).show();
|
||||
else Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} catch (final Throwable ignored) {}
|
||||
}
|
||||
});
|
||||
}
|
||||
profileModel = user;
|
||||
setProfileDetails();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable t) {
|
||||
Log.e(TAG, "Error fetching profile", t);
|
||||
final Context context = getContext();
|
||||
try {
|
||||
if (t == null) Toast.makeText(context,
|
||||
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 ignored) {}
|
||||
}
|
||||
@Override
|
||||
public void onFailure(final Throwable t) {
|
||||
Log.e(TAG, "Error fetching profile", t);
|
||||
final Context context = getContext();
|
||||
try {
|
||||
if (t == null) Toast.makeText(context, R.string.error_loading_profile_loggedin, Toast.LENGTH_LONG).show();
|
||||
else Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} catch (final Throwable ignored) {}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
graphQLService.fetchUser(usernameTemp, new ServiceCallback<User>() {
|
||||
@Override
|
||||
public void onSuccess(final User user) {
|
||||
profileModel = user;
|
||||
setProfileDetails();
|
||||
}
|
||||
|
||||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
@Override
|
||||
public void onFailure(final Throwable t) {
|
||||
Log.e(TAG, "Error fetching profile", t);
|
||||
final Context context = getContext();
|
||||
try {
|
||||
if (t == null) Toast.makeText(context, R.string.error_loading_profile, Toast.LENGTH_LONG).show();
|
||||
else Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} catch (final Throwable ignored) {}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void setProfileDetails() {
|
||||
|
@ -8,10 +8,9 @@ import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.SwitchPreferenceCompat;
|
||||
|
||||
import awais.instagrabber.R;
|
||||
import awais.instagrabber.dialogs.KeywordsFilterDialog;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||
|
||||
public class PostPreferencesFragment extends BasePreferencesFragment {
|
||||
@Override
|
||||
void setupPreferenceScreen(final PreferenceScreen screen) {
|
||||
@ -20,6 +19,8 @@ public class PostPreferencesFragment extends BasePreferencesFragment {
|
||||
// generalCategory.addPreference(getAutoPlayVideosPreference(context));
|
||||
screen.addPreference(getAlwaysMuteVideosPreference(context));
|
||||
screen.addPreference(getShowCaptionPreference(context));
|
||||
screen.addPreference(getToggleKeywordFilterPreference(context));
|
||||
screen.addPreference(getEditKeywordFilterPreference(context));
|
||||
}
|
||||
|
||||
private Preference getAutoPlayVideosPreference(@NonNull final Context context) {
|
||||
@ -46,4 +47,24 @@ public class PostPreferencesFragment extends BasePreferencesFragment {
|
||||
preference.setIconSpaceReserved(false);
|
||||
return preference;
|
||||
}
|
||||
|
||||
private Preference getToggleKeywordFilterPreference(@NonNull final Context context) {
|
||||
final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(context);
|
||||
preference.setKey(Constants.TOGGLE_KEYWORD_FILTER);
|
||||
preference.setDefaultValue(false);
|
||||
preference.setTitle(R.string.toggle_keyword_filter);
|
||||
preference.setIconSpaceReserved(false);
|
||||
return preference;
|
||||
}
|
||||
|
||||
private Preference getEditKeywordFilterPreference(@NonNull final Context context){
|
||||
final Preference preference = new Preference(context);
|
||||
preference.setTitle(R.string.edit_keyword_filter);
|
||||
preference.setIconSpaceReserved(false);
|
||||
preference.setOnPreferenceClickListener(view ->{
|
||||
new KeywordsFilterDialog().show(getParentFragmentManager(), null);
|
||||
return true;
|
||||
});
|
||||
return preference;
|
||||
}
|
||||
}
|
||||
|
@ -11,12 +11,15 @@ public final class Constants {
|
||||
public static final String APP_THEME = "app_theme_v19";
|
||||
public static final String APP_LANGUAGE = "app_language_v19";
|
||||
public static final String STORY_SORT = "story_sort";
|
||||
// set string prefs
|
||||
public static final String KEYWORD_FILTERS = "keyword_filters";
|
||||
// int prefs, do not export
|
||||
public static final String PREV_INSTALL_VERSION = "prevVersion";
|
||||
public static final String BROWSER_UA_CODE = "browser_ua_code";
|
||||
public static final String APP_UA_CODE = "app_ua_code";
|
||||
// boolean prefs
|
||||
public static final String DOWNLOAD_USER_FOLDER = "download_user_folder";
|
||||
public static final String TOGGLE_KEYWORD_FILTER = "toggle_keyword_filter";
|
||||
// deprecated: public static final String BOTTOM_TOOLBAR = "bottom_toolbar";
|
||||
public static final String FOLDER_SAVE_TO = "saved_to";
|
||||
public static final String AUTOPLAY_VIDEOS = "autoplay_videos";
|
||||
|
@ -0,0 +1,49 @@
|
||||
package awais.instagrabber.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import awais.instagrabber.repositories.responses.Caption;
|
||||
import awais.instagrabber.repositories.responses.Media;
|
||||
|
||||
public final class KeywordsFilterUtils {
|
||||
|
||||
private final ArrayList<String> keywords;
|
||||
|
||||
public KeywordsFilterUtils(final ArrayList<String> keywords){
|
||||
this.keywords = keywords;
|
||||
}
|
||||
|
||||
public boolean filter(final String caption){
|
||||
if(caption == null) return false;
|
||||
if(keywords.isEmpty()) return false;
|
||||
final String temp = caption.toLowerCase();
|
||||
for(final String s:keywords){
|
||||
if(temp.contains(s)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean filter(final Media media){
|
||||
if(media == null) return false;
|
||||
final Caption c = media.getCaption();
|
||||
if(c == null) return false;
|
||||
if(keywords.isEmpty()) return false;
|
||||
final String temp = c.getText().toLowerCase();
|
||||
for(final String s:keywords){
|
||||
if(temp.contains(s)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<Media> filter(final List<Media> media){
|
||||
if(keywords.isEmpty()) return media;
|
||||
if(media == null) return new ArrayList<>();
|
||||
|
||||
final List<Media> result= new ArrayList<>();
|
||||
for(final Media m:media){
|
||||
if(!filter(m)) result.add(m);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -675,7 +675,8 @@ public final class ResponseBodyUtils {
|
||||
// return feedModelBuilder.build();
|
||||
// }
|
||||
|
||||
public static Media parseGraphQLItem(final JSONObject itemJson) throws JSONException {
|
||||
// the "user" argument can be null, it's used because instagram redacts user details from responses
|
||||
public static Media parseGraphQLItem(final JSONObject itemJson, final User backup) throws JSONException {
|
||||
if (itemJson == null) {
|
||||
return null;
|
||||
}
|
||||
@ -728,41 +729,28 @@ public final class ResponseBodyUtils {
|
||||
width = dimensions.optInt("width");
|
||||
}
|
||||
String thumbnailUrl = null;
|
||||
try {
|
||||
thumbnailUrl = feedItem.getJSONArray("display_resources")
|
||||
.getJSONObject(0)
|
||||
.getString("src");
|
||||
} catch (JSONException ignored) {}
|
||||
// final FeedModel.Builder feedModelBuilder = new FeedModel.Builder()
|
||||
// .setProfileModel(profileModel)
|
||||
// .setItemType(isVideo ? MediaItemType.MEDIA_TYPE_VIDEO
|
||||
// : MediaItemType.MEDIA_TYPE_IMAGE)
|
||||
// .setViewCount(videoViews)
|
||||
// .setPostId(feedItem.getString(Constants.EXTRAS_ID))
|
||||
// .setDisplayUrl(resourceUrl)
|
||||
// .setThumbnailUrl(thumbnailUrl != null ? thumbnailUrl : displayUrl)
|
||||
// .setShortCode(feedItem.getString(Constants.EXTRAS_SHORTCODE))
|
||||
// .setPostCaption(captionText)
|
||||
// .setCommentsCount(commentsCount)
|
||||
// .setTimestamp(feedItem.optLong("taken_at_timestamp", -1))
|
||||
// .setLiked(feedItem.optBoolean("viewer_has_liked"))
|
||||
// .setBookmarked(feedItem.optBoolean("viewer_has_saved"))
|
||||
// .setLikesCount(likesCount)
|
||||
// .setLocationName(locationName)
|
||||
// .setLocationId(String.valueOf(locationId))
|
||||
// .setImageHeight(height)
|
||||
// .setImageWidth(width);
|
||||
final JSONArray displayResources = feedItem.getJSONArray("display_resources");
|
||||
final List<MediaCandidate> candidates = new ArrayList<MediaCandidate>();
|
||||
for (int i = 0; i < displayResources.length(); i++) {
|
||||
final JSONObject displayResource = displayResources.getJSONObject(i);
|
||||
candidates.add(new MediaCandidate(
|
||||
displayResource.getInt("config_width"),
|
||||
displayResource.getInt("config_height"),
|
||||
displayResource.getString("src")
|
||||
));
|
||||
}
|
||||
final ImageVersions2 imageVersions2 = new ImageVersions2(candidates);
|
||||
|
||||
User user = null;
|
||||
User user = backup;
|
||||
long userId = -1;
|
||||
if (feedItem.has("owner")) {
|
||||
if (feedItem.has("owner") && user == null) {
|
||||
final JSONObject owner = feedItem.getJSONObject("owner");
|
||||
final FriendshipStatus friendshipStatus = new FriendshipStatus(
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
owner.optBoolean("is_private"),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
@ -774,7 +762,7 @@ public final class ResponseBodyUtils {
|
||||
userId,
|
||||
owner.optString(Constants.EXTRAS_USERNAME),
|
||||
owner.optString("full_name"),
|
||||
owner.optBoolean("is_private"),
|
||||
false,
|
||||
owner.optString("profile_pic_url"),
|
||||
null,
|
||||
friendshipStatus,
|
||||
@ -783,13 +771,6 @@ public final class ResponseBodyUtils {
|
||||
null, null, null, null);
|
||||
}
|
||||
final String id = feedItem.getString(Constants.EXTRAS_ID);
|
||||
final ImageVersions2 imageVersions2 = new ImageVersions2(
|
||||
Collections.singletonList(new MediaCandidate(
|
||||
width,
|
||||
height,
|
||||
isVideo ? thumbnailUrl : resourceUrl
|
||||
))
|
||||
);
|
||||
VideoVersion videoVersion = null;
|
||||
if (isVideo) {
|
||||
videoVersion = new VideoVersion(
|
||||
@ -821,7 +802,7 @@ public final class ResponseBodyUtils {
|
||||
for (int i = 0; i < children.length(); i++) {
|
||||
final JSONObject child = children.optJSONObject(i);
|
||||
if (child == null) continue;
|
||||
final Media media = parseGraphQLItem(child);
|
||||
final Media media = parseGraphQLItem(child, null);
|
||||
media.setIsSidecarChild(true);
|
||||
childItems.add(media);
|
||||
}
|
||||
|
@ -8,6 +8,9 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.StringDef;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static awais.instagrabber.fragments.settings.PreferenceKeys.PREF_ENABLE_DM_AUTO_REFRESH;
|
||||
import static awais.instagrabber.fragments.settings.PreferenceKeys.PREF_ENABLE_DM_AUTO_REFRESH_FREQ_NUMBER;
|
||||
import static awais.instagrabber.fragments.settings.PreferenceKeys.PREF_ENABLE_DM_AUTO_REFRESH_FREQ_UNIT;
|
||||
@ -39,6 +42,7 @@ import static awais.instagrabber.utils.Constants.MUTED_VIDEOS;
|
||||
import static awais.instagrabber.utils.Constants.PREF_DARK_THEME;
|
||||
import static awais.instagrabber.utils.Constants.PREF_EMOJI_VARIANTS;
|
||||
import static awais.instagrabber.utils.Constants.PREF_HASHTAG_POSTS_LAYOUT;
|
||||
import static awais.instagrabber.utils.Constants.KEYWORD_FILTERS;
|
||||
import static awais.instagrabber.utils.Constants.PREF_LIGHT_THEME;
|
||||
import static awais.instagrabber.utils.Constants.PREF_LIKED_POSTS_LAYOUT;
|
||||
import static awais.instagrabber.utils.Constants.PREF_LOCATION_POSTS_LAYOUT;
|
||||
@ -54,6 +58,7 @@ import static awais.instagrabber.utils.Constants.SHOW_QUICK_ACCESS_DIALOG;
|
||||
import static awais.instagrabber.utils.Constants.SKIPPED_VERSION;
|
||||
import static awais.instagrabber.utils.Constants.STORY_SORT;
|
||||
import static awais.instagrabber.utils.Constants.SWAP_DATE_TIME_FORMAT_ENABLED;
|
||||
import static awais.instagrabber.utils.Constants.TOGGLE_KEYWORD_FILTER;
|
||||
|
||||
public final class SettingsHelper {
|
||||
private final SharedPreferences sharedPreferences;
|
||||
@ -69,6 +74,12 @@ public final class SettingsHelper {
|
||||
return stringDefault;
|
||||
}
|
||||
|
||||
public Set<String> getStringSet(@StringSetSettings final String key) {
|
||||
final Set<String> stringSetDefault = new HashSet<>();
|
||||
if (sharedPreferences != null) return sharedPreferences.getStringSet(key, stringSetDefault);
|
||||
return stringSetDefault;
|
||||
}
|
||||
|
||||
public int getInteger(@IntegerSettings final String key) {
|
||||
final int integerDefault = getIntegerDefault(key);
|
||||
if (sharedPreferences != null) return sharedPreferences.getInt(key, integerDefault);
|
||||
@ -123,6 +134,10 @@ public final class SettingsHelper {
|
||||
if (sharedPreferences != null) sharedPreferences.edit().putString(key, val).apply();
|
||||
}
|
||||
|
||||
public void putStringSet(@StringSetSettings final String key, final Set<String> val) {
|
||||
if (sharedPreferences != null) sharedPreferences.edit().putStringSet(key, val).apply();
|
||||
}
|
||||
|
||||
public void putInteger(@IntegerSettings final String key, final int val) {
|
||||
if (sharedPreferences != null) sharedPreferences.edit().putInt(key, val).apply();
|
||||
}
|
||||
@ -146,9 +161,12 @@ public final class SettingsHelper {
|
||||
@StringDef({DOWNLOAD_USER_FOLDER, FOLDER_SAVE_TO, AUTOPLAY_VIDEOS, SHOW_QUICK_ACCESS_DIALOG, MUTED_VIDEOS,
|
||||
SHOW_CAPTIONS, CUSTOM_DATE_TIME_FORMAT_ENABLED, MARK_AS_SEEN, DM_MARK_AS_SEEN, CHECK_ACTIVITY,
|
||||
CHECK_UPDATES, SWAP_DATE_TIME_FORMAT_ENABLED, PREF_ENABLE_DM_NOTIFICATIONS, PREF_ENABLE_DM_AUTO_REFRESH,
|
||||
FLAG_SECURE, PREF_ENABLE_SENTRY})
|
||||
FLAG_SECURE, TOGGLE_KEYWORD_FILTER, PREF_ENABLE_SENTRY})
|
||||
public @interface BooleanSettings {}
|
||||
|
||||
@StringDef({PREV_INSTALL_VERSION, BROWSER_UA_CODE, APP_UA_CODE, PREF_ENABLE_DM_AUTO_REFRESH_FREQ_NUMBER})
|
||||
public @interface IntegerSettings {}
|
||||
|
||||
@StringDef({KEYWORD_FILTERS})
|
||||
public @interface StringSetSettings {}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package awais.instagrabber.utils.emoji;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import awais.instagrabber.customviews.emoji.Emoji;
|
||||
import awais.instagrabber.customviews.emoji.EmojiCategory;
|
||||
import awais.instagrabber.customviews.emoji.EmojiCategoryType;
|
||||
|
||||
public class EmojiCategoryDeserializer implements JsonDeserializer<EmojiCategory> {
|
||||
private static final String TAG = EmojiCategoryDeserializer.class.getSimpleName();
|
||||
|
||||
@Override
|
||||
public EmojiCategory deserialize(final JsonElement json,
|
||||
final Type typeOfT,
|
||||
final JsonDeserializationContext context) throws JsonParseException {
|
||||
final JsonObject jsonObject = json.getAsJsonObject();
|
||||
final JsonElement typeElement = jsonObject.get("type");
|
||||
final JsonObject emojisObject = jsonObject.getAsJsonObject("emojis");
|
||||
if (typeElement == null || emojisObject == null) {
|
||||
throw new JsonParseException("Invalid json for EmojiCategory");
|
||||
}
|
||||
final String typeString = typeElement.getAsString();
|
||||
EmojiCategoryType type;
|
||||
try {
|
||||
type = EmojiCategoryType.valueOf(typeString);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(TAG, "deserialize: ", e);
|
||||
type = EmojiCategoryType.OTHERS;
|
||||
}
|
||||
final Map<String, Emoji> emojis = new LinkedHashMap<>();
|
||||
for (final Map.Entry<String, JsonElement> emojiObjectEntry : emojisObject.entrySet()) {
|
||||
final String unicode = emojiObjectEntry.getKey();
|
||||
final JsonElement value = emojiObjectEntry.getValue();
|
||||
if (unicode == null || value == null) {
|
||||
throw new JsonParseException("Invalid json for EmojiCategory");
|
||||
}
|
||||
final Emoji emoji = context.deserialize(value, Emoji.class);
|
||||
emojis.put(unicode, emoji);
|
||||
}
|
||||
return new EmojiCategory(type, emojis);
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package awais.instagrabber.utils.emoji;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import awais.instagrabber.customviews.emoji.Emoji;
|
||||
|
||||
public class EmojiDeserializer implements JsonDeserializer<Emoji> {
|
||||
@Override
|
||||
public Emoji deserialize(final JsonElement json,
|
||||
final Type typeOfT,
|
||||
final JsonDeserializationContext context) throws JsonParseException {
|
||||
final JsonObject jsonObject = json.getAsJsonObject();
|
||||
final JsonElement unicodeElement = jsonObject.get("unicode");
|
||||
final JsonElement nameElement = jsonObject.get("name");
|
||||
if (unicodeElement == null || nameElement == null) {
|
||||
throw new JsonParseException("Invalid json for Emoji class");
|
||||
}
|
||||
final JsonElement variantsElement = jsonObject.get("variants");
|
||||
final List<Emoji> variants = new LinkedList<>();
|
||||
if (variantsElement != null) {
|
||||
final JsonArray variantsArray = variantsElement.getAsJsonArray();
|
||||
for (final JsonElement variantElement : variantsArray) {
|
||||
final Emoji variant = context.deserialize(variantElement, Emoji.class);
|
||||
if (variant != null) {
|
||||
variants.add(variant);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Emoji(
|
||||
unicodeElement.getAsString(),
|
||||
nameElement.getAsString(),
|
||||
variants
|
||||
);
|
||||
}
|
||||
}
|
@ -3,10 +3,11 @@ package awais.instagrabber.utils.emoji;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.gson.FieldNamingPolicy;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collection;
|
||||
@ -52,7 +53,12 @@ public final class EmojiParser {
|
||||
}
|
||||
try (final InputStream in = classLoader.getResourceAsStream(file)) {
|
||||
final String json = NetworkUtils.readFromInputStream(in);
|
||||
final Gson gson = new Gson();
|
||||
final Gson gson = new GsonBuilder()
|
||||
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
|
||||
.registerTypeAdapter(EmojiCategory.class, new EmojiCategoryDeserializer())
|
||||
.registerTypeAdapter(Emoji.class, new EmojiDeserializer())
|
||||
.setLenient()
|
||||
.create();
|
||||
final Type type = new TypeToken<Map<EmojiCategoryType, EmojiCategory>>() {}.getType();
|
||||
categoryMap = gson.fromJson(json, type);
|
||||
// Log.d(TAG, "EmojiParser: " + categoryMap);
|
||||
@ -68,7 +74,7 @@ public final class EmojiParser {
|
||||
.build()
|
||||
.stream())
|
||||
.collect(Collectors.toMap(Emoji::getUnicode, Function.identity()));
|
||||
} catch (IOException e) {
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "EmojiParser: ", e);
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,18 @@
|
||||
package awais.instagrabber.viewmodels;
|
||||
|
||||
import android.app.Application;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
|
||||
import awais.instagrabber.asyncs.ProfileFetcher;
|
||||
import awais.instagrabber.db.datasources.AccountDataSource;
|
||||
import awais.instagrabber.db.entities.Account;
|
||||
import awais.instagrabber.db.repositories.AccountRepository;
|
||||
import awais.instagrabber.db.repositories.RepositoryCallback;
|
||||
import awais.instagrabber.interfaces.FetchListener;
|
||||
import awais.instagrabber.repositories.responses.User;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.CookieUtils;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
import awais.instagrabber.webservices.ServiceCallback;
|
||||
import awais.instagrabber.webservices.UserService;
|
||||
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||
|
||||
@ -27,6 +24,7 @@ public class AppStateViewModel extends AndroidViewModel {
|
||||
|
||||
private User currentUser;
|
||||
private AccountRepository accountRepository;
|
||||
private UserService userService;
|
||||
|
||||
public AppStateViewModel(@NonNull final Application application) {
|
||||
super(application);
|
||||
@ -34,6 +32,7 @@ public class AppStateViewModel extends AndroidViewModel {
|
||||
cookie = settingsHelper.getString(Constants.COOKIE);
|
||||
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
|
||||
if (!isLoggedIn) return;
|
||||
userService = UserService.getInstance();
|
||||
accountRepository = AccountRepository.getInstance(AccountDataSource.getInstance(application));
|
||||
fetchProfileDetails();
|
||||
}
|
||||
@ -44,6 +43,14 @@ public class AppStateViewModel extends AndroidViewModel {
|
||||
|
||||
private void fetchProfileDetails() {
|
||||
final long uid = CookieUtils.getUserIdFromCookie(cookie);
|
||||
new ProfileFetcher(null, uid, true, user -> this.currentUser = user).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
userService.getUserInfo(uid, new ServiceCallback<User>() {
|
||||
@Override
|
||||
public void onSuccess(final User user) {
|
||||
currentUser = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable t) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ public class GraphQLService extends BaseService {
|
||||
final String variables,
|
||||
final String arg1,
|
||||
final String arg2,
|
||||
final User backup,
|
||||
final ServiceCallback<PostsFetchResponse> callback) {
|
||||
final Map<String, String> queryMap = new HashMap<>();
|
||||
queryMap.put("query_hash", queryHash);
|
||||
@ -66,7 +67,7 @@ public class GraphQLService extends BaseService {
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
try {
|
||||
// Log.d(TAG, "onResponse: body: " + response.body());
|
||||
final PostsFetchResponse postsFetchResponse = parsePostResponse(response, arg1, arg2);
|
||||
final PostsFetchResponse postsFetchResponse = parsePostResponse(response, arg1, arg2, backup);
|
||||
if (callback != null) {
|
||||
callback.onSuccess(postsFetchResponse);
|
||||
}
|
||||
@ -96,6 +97,7 @@ public class GraphQLService extends BaseService {
|
||||
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
||||
Constants.EXTRAS_LOCATION,
|
||||
"edge_location_to_media",
|
||||
null,
|
||||
callback);
|
||||
}
|
||||
|
||||
@ -108,12 +110,14 @@ public class GraphQLService extends BaseService {
|
||||
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
||||
Constants.EXTRAS_HASHTAG,
|
||||
"edge_hashtag_to_media",
|
||||
null,
|
||||
callback);
|
||||
}
|
||||
|
||||
public void fetchProfilePosts(final long profileId,
|
||||
final int postsPerPage,
|
||||
final String maxId,
|
||||
final User backup,
|
||||
final ServiceCallback<PostsFetchResponse> callback) {
|
||||
fetch("18a7b935ab438c4514b1f742d8fa07a7",
|
||||
"{\"id\":\"" + profileId + "\"," +
|
||||
@ -121,6 +125,7 @@ public class GraphQLService extends BaseService {
|
||||
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
||||
Constants.EXTRAS_USER,
|
||||
"edge_owner_to_timeline_media",
|
||||
backup,
|
||||
callback);
|
||||
}
|
||||
|
||||
@ -134,21 +139,28 @@ public class GraphQLService extends BaseService {
|
||||
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
||||
Constants.EXTRAS_USER,
|
||||
"edge_user_to_photos_of_you",
|
||||
null,
|
||||
callback);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private PostsFetchResponse parsePostResponse(@NonNull final Response<String> response, @NonNull final String arg1, @NonNull final String arg2)
|
||||
private PostsFetchResponse parsePostResponse(@NonNull final Response<String> response,
|
||||
@NonNull final String arg1,
|
||||
@NonNull final String arg2,
|
||||
final User backup)
|
||||
throws JSONException {
|
||||
if (TextUtils.isEmpty(response.body())) {
|
||||
Log.e(TAG, "parseResponse: feed response body is empty with status code: " + response.code());
|
||||
return new PostsFetchResponse(Collections.emptyList(), false, null);
|
||||
}
|
||||
return parseResponseBody(response.body(), arg1, arg2);
|
||||
return parseResponseBody(response.body(), arg1, arg2, backup);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private PostsFetchResponse parseResponseBody(@NonNull final String body, @NonNull final String arg1, @NonNull final String arg2)
|
||||
private PostsFetchResponse parseResponseBody(@NonNull final String body,
|
||||
@NonNull final String arg1,
|
||||
@NonNull final String arg2,
|
||||
final User backup)
|
||||
throws JSONException {
|
||||
final List<Media> items = new ArrayList<>();
|
||||
final JSONObject timelineFeed = new JSONObject(body)
|
||||
@ -174,7 +186,7 @@ public class GraphQLService extends BaseService {
|
||||
if (itemJson == null) {
|
||||
continue;
|
||||
}
|
||||
final Media media = ResponseBodyUtils.parseGraphQLItem(itemJson);
|
||||
final Media media = ResponseBodyUtils.parseGraphQLItem(itemJson, backup);
|
||||
if (media != null) {
|
||||
items.add(media);
|
||||
}
|
||||
|
@ -121,9 +121,15 @@ public class NewsService extends BaseService {
|
||||
callback.onSuccess(null);
|
||||
return;
|
||||
}
|
||||
final List<AymlUser> aymlUsers = new ArrayList<>();
|
||||
aymlUsers.addAll(body.getNewSuggestedUsers().getSuggestions());
|
||||
aymlUsers.addAll(body.getSuggestedUsers().getSuggestions());
|
||||
final List<AymlUser> aymlUsers = new ArrayList<AymlUser>();
|
||||
final List<AymlUser> newSuggestions = body.getNewSuggestedUsers().getSuggestions();
|
||||
if (newSuggestions != null) {
|
||||
aymlUsers.addAll(newSuggestions);
|
||||
}
|
||||
final List<AymlUser> oldSuggestions = body.getSuggestedUsers().getSuggestions();
|
||||
if (oldSuggestions != null) {
|
||||
aymlUsers.addAll(oldSuggestions);
|
||||
}
|
||||
|
||||
final List<Notification> newsItems = aymlUsers.stream()
|
||||
.map(i -> {
|
||||
|
57
app/src/main/res/layout/dialog_keywords_filter.xml
Normal file
57
app/src/main/res/layout/dialog_keywords_filter.xml
Normal file
@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="16dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:animateLayoutChanges="true"
|
||||
android:paddingTop="16dp">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
android:id="@+id/edit_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/hint_keyword"
|
||||
android:singleLine="true"
|
||||
app:layout_constraintEnd_toStartOf="@id/btnAdd"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnAdd"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:background="@drawable/ic_add"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/edit_text"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="@id/edit_text" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerKeyword"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@id/btnAdd"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
tools:layout_editor_absoluteX="16dp"
|
||||
tools:listitem="@layout/item_keyword" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
android:id="@+id/btnOK"
|
||||
style="@style/Widget.AppCompat.Button.ButtonBar.AlertDialog"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:text="@string/ok"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/recyclerKeyword" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</ScrollView>
|
23
app/src/main/res/layout/item_keyword.xml
Normal file
23
app/src/main/res/layout/item_keyword.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingTop="8dp">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/keyword_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/keyword_delete"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:background="@drawable/ic_delete"
|
||||
android:scaleType="center" />
|
||||
|
||||
</LinearLayout>
|
@ -466,6 +466,11 @@
|
||||
<string name="generic_null_response">Response is null!</string>
|
||||
<string name="generic_not_ok_response">Response status is not ok!</string>
|
||||
<string name="generic_failed_request">Request failed!</string>
|
||||
<string name="hint_keyword">Keyword</string>
|
||||
<string name="toggle_keyword_filter">Enable keyword filter</string>
|
||||
<string name="edit_keyword_filter">Edit keyword filters</string>
|
||||
<string name="added_keywords">Added keyword: %s to filter list</string>
|
||||
<string name="removed_keywords">Removed keyword: %s from filter list</string>
|
||||
<string name="marked_as_seen">Marked as seen</string>
|
||||
<string name="delete_unsuccessful">Delete unsuccessful</string>
|
||||
<string name="crash_report_subject">Barinsta Crash Report</string>
|
||||
|
Loading…
Reference in New Issue
Block a user