mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-11-17 20:27:29 +00:00
Merge branch 'master' into add-sentry
This commit is contained in:
commit
fba0a751b1
@ -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;
|
} else if (result == null) return;
|
||||||
nextCursor = result.getNextCursor();
|
nextCursor = result.getNextCursor();
|
||||||
hasNextPage = result.hasNextPage();
|
hasNextPage = result.hasNextPage();
|
||||||
feedModels.addAll(result.getFeedModels());
|
|
||||||
|
final List<Media> mediaResults = result.getFeedModels();
|
||||||
|
feedModels.addAll(mediaResults);
|
||||||
|
|
||||||
if (fetchListener != null) {
|
if (fetchListener != null) {
|
||||||
// if (feedModels.size() < 15 && hasNextPage) {
|
// if (feedModels.size() < 15 && hasNextPage) {
|
||||||
// feedService.fetch(csrfToken, nextCursor, this);
|
// feedService.fetch(csrfToken, nextCursor, this);
|
||||||
|
@ -133,7 +133,7 @@ public final class PostFetcher extends AsyncTask<Void, Void, Media> {
|
|||||||
// feedModelBuilder.setSliderItems(postModels);
|
// feedModelBuilder.setSliderItems(postModels);
|
||||||
// }
|
// }
|
||||||
// return feedModelBuilder.build();
|
// return feedModelBuilder.build();
|
||||||
return ResponseBodyUtils.parseGraphQLItem(media);
|
return ResponseBodyUtils.parseGraphQLItem(media, null);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// if (logCollector != null) {
|
// 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);
|
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
|
@Override
|
||||||
|
@ -32,11 +32,15 @@ import awais.instagrabber.customviews.helpers.RecyclerLazyLoaderAtEdge;
|
|||||||
import awais.instagrabber.interfaces.FetchListener;
|
import awais.instagrabber.interfaces.FetchListener;
|
||||||
import awais.instagrabber.models.PostsLayoutPreferences;
|
import awais.instagrabber.models.PostsLayoutPreferences;
|
||||||
import awais.instagrabber.repositories.responses.Media;
|
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.ResponseBodyUtils;
|
||||||
import awais.instagrabber.utils.Utils;
|
import awais.instagrabber.utils.Utils;
|
||||||
import awais.instagrabber.viewmodels.MediaViewModel;
|
import awais.instagrabber.viewmodels.MediaViewModel;
|
||||||
import awais.instagrabber.workers.DownloadWorker;
|
import awais.instagrabber.workers.DownloadWorker;
|
||||||
|
|
||||||
|
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||||
|
|
||||||
public class PostsRecyclerView extends RecyclerView {
|
public class PostsRecyclerView extends RecyclerView {
|
||||||
private static final String TAG = "PostsRecyclerView";
|
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> models = mediaViewModel.getList().getValue();
|
||||||
final List<Media> modelsCopy = models == null ? new ArrayList<>() : new ArrayList<>(models);
|
final List<Media> modelsCopy = models == null ? new ArrayList<>() : new ArrayList<>(models);
|
||||||
|
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);
|
modelsCopy.addAll(result);
|
||||||
|
}
|
||||||
mediaViewModel.getList().postValue(modelsCopy);
|
mediaViewModel.getList().postValue(modelsCopy);
|
||||||
dispatchFetchStatus();
|
dispatchFetchStatus();
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package awais.instagrabber.customviews.emoji;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@ -12,10 +11,12 @@ public class Emoji {
|
|||||||
private final List<Emoji> variants;
|
private final List<Emoji> variants;
|
||||||
private GoogleCompatEmojiDrawable drawable;
|
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.unicode = unicode;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.variants = new LinkedList<>();
|
this.variants = variants;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUnicode() {
|
public String getUnicode() {
|
||||||
@ -35,7 +36,7 @@ public class Emoji {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public GoogleCompatEmojiDrawable getDrawable() {
|
public GoogleCompatEmojiDrawable getDrawable() {
|
||||||
if (drawable == null) {
|
if (drawable == null && unicode != null) {
|
||||||
drawable = new GoogleCompatEmojiDrawable(unicode);
|
drawable = new GoogleCompatEmojiDrawable(unicode);
|
||||||
}
|
}
|
||||||
return drawable;
|
return drawable;
|
||||||
@ -60,6 +61,7 @@ public class Emoji {
|
|||||||
return "Emoji{" +
|
return "Emoji{" +
|
||||||
"unicode='" + unicode + '\'' +
|
"unicode='" + unicode + '\'' +
|
||||||
", name='" + name + '\'' +
|
", name='" + name + '\'' +
|
||||||
|
", variants=" + variants +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package awais.instagrabber.customviews.emoji;
|
package awais.instagrabber.customviews.emoji;
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes;
|
import androidx.annotation.DrawableRes;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@ -10,12 +10,13 @@ import awais.instagrabber.R;
|
|||||||
|
|
||||||
public class EmojiCategory {
|
public class EmojiCategory {
|
||||||
private final EmojiCategoryType type;
|
private final EmojiCategoryType type;
|
||||||
private final Map<String, Emoji> emojis = new LinkedHashMap<>();
|
private final Map<String, Emoji> emojis;
|
||||||
@DrawableRes
|
@DrawableRes
|
||||||
private int drawableRes;
|
private int drawableRes;
|
||||||
|
|
||||||
public EmojiCategory(final EmojiCategoryType type) {
|
public EmojiCategory(final EmojiCategoryType type, final Map<String, Emoji> emojis) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
this.emojis = emojis;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EmojiCategoryType getType() {
|
public EmojiCategoryType getType() {
|
||||||
@ -73,4 +74,13 @@ public class EmojiCategory {
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(type);
|
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;
|
if (getArguments() == null) return;
|
||||||
final HashTagFragmentArgs fragmentArgs = HashTagFragmentArgs.fromBundle(getArguments());
|
final HashTagFragmentArgs fragmentArgs = HashTagFragmentArgs.fromBundle(getArguments());
|
||||||
hashtag = fragmentArgs.getHashtag();
|
hashtag = fragmentArgs.getHashtag();
|
||||||
|
if (hashtag.charAt(0) == '#') hashtag = hashtag.substring(1);
|
||||||
fetchHashtagModel();
|
fetchHashtagModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -925,7 +925,7 @@ public class PostViewV2Fragment extends SharedElementTransitionDialogFragment im
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setupLocation(final Location location) {
|
private void setupLocation(final Location location) {
|
||||||
if (location == null) {
|
if (location == null || !detailsVisible) {
|
||||||
binding.location.setVisibility(View.GONE);
|
binding.location.setVisibility(View.GONE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import android.content.Context;
|
|||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
@ -57,7 +56,6 @@ import awais.instagrabber.activities.MainActivity;
|
|||||||
import awais.instagrabber.adapters.FeedAdapterV2;
|
import awais.instagrabber.adapters.FeedAdapterV2;
|
||||||
import awais.instagrabber.adapters.HighlightsAdapter;
|
import awais.instagrabber.adapters.HighlightsAdapter;
|
||||||
import awais.instagrabber.asyncs.CreateThreadAction;
|
import awais.instagrabber.asyncs.CreateThreadAction;
|
||||||
import awais.instagrabber.asyncs.ProfileFetcher;
|
|
||||||
import awais.instagrabber.asyncs.ProfilePostFetchService;
|
import awais.instagrabber.asyncs.ProfilePostFetchService;
|
||||||
import awais.instagrabber.customviews.PrimaryActionModeCallback;
|
import awais.instagrabber.customviews.PrimaryActionModeCallback;
|
||||||
import awais.instagrabber.customviews.PrimaryActionModeCallback.CallbacksHelper;
|
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.PostsLayoutPreferencesDialogFragment;
|
||||||
import awais.instagrabber.dialogs.ProfilePicDialogFragment;
|
import awais.instagrabber.dialogs.ProfilePicDialogFragment;
|
||||||
import awais.instagrabber.fragments.PostViewV2Fragment;
|
import awais.instagrabber.fragments.PostViewV2Fragment;
|
||||||
import awais.instagrabber.interfaces.FetchListener;
|
|
||||||
import awais.instagrabber.managers.DirectMessagesManager;
|
import awais.instagrabber.managers.DirectMessagesManager;
|
||||||
import awais.instagrabber.managers.InboxManager;
|
import awais.instagrabber.managers.InboxManager;
|
||||||
import awais.instagrabber.models.HighlightModel;
|
import awais.instagrabber.models.HighlightModel;
|
||||||
@ -93,11 +90,14 @@ import awais.instagrabber.utils.CookieUtils;
|
|||||||
import awais.instagrabber.utils.DownloadUtils;
|
import awais.instagrabber.utils.DownloadUtils;
|
||||||
import awais.instagrabber.utils.TextUtils;
|
import awais.instagrabber.utils.TextUtils;
|
||||||
import awais.instagrabber.utils.Utils;
|
import awais.instagrabber.utils.Utils;
|
||||||
|
import awais.instagrabber.viewmodels.AppStateViewModel;
|
||||||
import awais.instagrabber.viewmodels.HighlightsViewModel;
|
import awais.instagrabber.viewmodels.HighlightsViewModel;
|
||||||
import awais.instagrabber.webservices.FriendshipService;
|
import awais.instagrabber.webservices.FriendshipService;
|
||||||
|
import awais.instagrabber.webservices.GraphQLService;
|
||||||
import awais.instagrabber.webservices.MediaService;
|
import awais.instagrabber.webservices.MediaService;
|
||||||
import awais.instagrabber.webservices.ServiceCallback;
|
import awais.instagrabber.webservices.ServiceCallback;
|
||||||
import awais.instagrabber.webservices.StoriesService;
|
import awais.instagrabber.webservices.StoriesService;
|
||||||
|
import awais.instagrabber.webservices.UserService;
|
||||||
|
|
||||||
import static androidx.core.content.PermissionChecker.checkSelfPermission;
|
import static androidx.core.content.PermissionChecker.checkSelfPermission;
|
||||||
import static awais.instagrabber.fragments.HashTagFragment.ARG_HASHTAG;
|
import static awais.instagrabber.fragments.HashTagFragment.ARG_HASHTAG;
|
||||||
@ -120,6 +120,8 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
private FriendshipService friendshipService;
|
private FriendshipService friendshipService;
|
||||||
private StoriesService storiesService;
|
private StoriesService storiesService;
|
||||||
private MediaService mediaService;
|
private MediaService mediaService;
|
||||||
|
private UserService userService;
|
||||||
|
private GraphQLService graphQLService;
|
||||||
private boolean shouldRefresh = true;
|
private boolean shouldRefresh = true;
|
||||||
private boolean hasStories = false;
|
private boolean hasStories = false;
|
||||||
private HighlightsAdapter highlightsAdapter;
|
private HighlightsAdapter highlightsAdapter;
|
||||||
@ -304,6 +306,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
private LayoutProfileDetailsBinding profileDetailsBinding;
|
private LayoutProfileDetailsBinding profileDetailsBinding;
|
||||||
private AccountRepository accountRepository;
|
private AccountRepository accountRepository;
|
||||||
private FavoriteRepository favoriteRepository;
|
private FavoriteRepository favoriteRepository;
|
||||||
|
private AppStateViewModel appStateViewModel;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
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;
|
friendshipService = isLoggedIn ? FriendshipService.getInstance(deviceUuid, csrfToken, myId) : null;
|
||||||
storiesService = isLoggedIn ? StoriesService.getInstance(null, 0L, null) : null;
|
storiesService = isLoggedIn ? StoriesService.getInstance(null, 0L, null) : null;
|
||||||
mediaService = isLoggedIn ? MediaService.getInstance(null, null, 0) : 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()));
|
accountRepository = AccountRepository.getInstance(AccountDataSource.getInstance(getContext()));
|
||||||
favoriteRepository = FavoriteRepository.getInstance(FavoriteDataSource.getInstance(getContext()));
|
favoriteRepository = FavoriteRepository.getInstance(FavoriteDataSource.getInstance(getContext()));
|
||||||
|
appStateViewModel = new ViewModelProvider(fragmentActivity).get(AppStateViewModel.class);
|
||||||
setHasOptionsMenu(true);
|
setHasOptionsMenu(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -601,14 +607,51 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
if (usernameTemp.startsWith("@")) {
|
if (usernameTemp.startsWith("@")) {
|
||||||
usernameTemp = usernameTemp.substring(1);
|
usernameTemp = usernameTemp.substring(1);
|
||||||
}
|
}
|
||||||
new ProfileFetcher(TextUtils.isEmpty(username) ? null : usernameTemp, myId, isLoggedIn, new FetchListener<User>() {
|
if (TextUtils.isEmpty(usernameTemp)) {
|
||||||
@Override
|
profileModel = appStateViewModel.getCurrentUser();
|
||||||
public void onResult(final User user) {
|
username = profileModel.getUsername();
|
||||||
if (getContext() == null) return;
|
|
||||||
if (TextUtils.isEmpty(username)) {
|
|
||||||
username = user.getUsername();
|
|
||||||
setUsernameDelayed();
|
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) {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
profileModel = user;
|
||||||
setProfileDetails();
|
setProfileDetails();
|
||||||
}
|
}
|
||||||
@ -618,14 +661,12 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
Log.e(TAG, "Error fetching profile", t);
|
Log.e(TAG, "Error fetching profile", t);
|
||||||
final Context context = getContext();
|
final Context context = getContext();
|
||||||
try {
|
try {
|
||||||
if (t == null) Toast.makeText(context,
|
if (t == null) Toast.makeText(context, R.string.error_loading_profile, Toast.LENGTH_LONG).show();
|
||||||
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();
|
else Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
|
||||||
} catch (final Throwable ignored) {}
|
} catch (final Throwable ignored) {}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setProfileDetails() {
|
private void setProfileDetails() {
|
||||||
|
@ -8,10 +8,9 @@ import androidx.preference.PreferenceScreen;
|
|||||||
import androidx.preference.SwitchPreferenceCompat;
|
import androidx.preference.SwitchPreferenceCompat;
|
||||||
|
|
||||||
import awais.instagrabber.R;
|
import awais.instagrabber.R;
|
||||||
|
import awais.instagrabber.dialogs.KeywordsFilterDialog;
|
||||||
import awais.instagrabber.utils.Constants;
|
import awais.instagrabber.utils.Constants;
|
||||||
|
|
||||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
|
||||||
|
|
||||||
public class PostPreferencesFragment extends BasePreferencesFragment {
|
public class PostPreferencesFragment extends BasePreferencesFragment {
|
||||||
@Override
|
@Override
|
||||||
void setupPreferenceScreen(final PreferenceScreen screen) {
|
void setupPreferenceScreen(final PreferenceScreen screen) {
|
||||||
@ -20,6 +19,8 @@ public class PostPreferencesFragment extends BasePreferencesFragment {
|
|||||||
// generalCategory.addPreference(getAutoPlayVideosPreference(context));
|
// generalCategory.addPreference(getAutoPlayVideosPreference(context));
|
||||||
screen.addPreference(getAlwaysMuteVideosPreference(context));
|
screen.addPreference(getAlwaysMuteVideosPreference(context));
|
||||||
screen.addPreference(getShowCaptionPreference(context));
|
screen.addPreference(getShowCaptionPreference(context));
|
||||||
|
screen.addPreference(getToggleKeywordFilterPreference(context));
|
||||||
|
screen.addPreference(getEditKeywordFilterPreference(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Preference getAutoPlayVideosPreference(@NonNull final Context context) {
|
private Preference getAutoPlayVideosPreference(@NonNull final Context context) {
|
||||||
@ -46,4 +47,24 @@ public class PostPreferencesFragment extends BasePreferencesFragment {
|
|||||||
preference.setIconSpaceReserved(false);
|
preference.setIconSpaceReserved(false);
|
||||||
return preference;
|
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_THEME = "app_theme_v19";
|
||||||
public static final String APP_LANGUAGE = "app_language_v19";
|
public static final String APP_LANGUAGE = "app_language_v19";
|
||||||
public static final String STORY_SORT = "story_sort";
|
public static final String STORY_SORT = "story_sort";
|
||||||
|
// set string prefs
|
||||||
|
public static final String KEYWORD_FILTERS = "keyword_filters";
|
||||||
// int prefs, do not export
|
// int prefs, do not export
|
||||||
public static final String PREV_INSTALL_VERSION = "prevVersion";
|
public static final String PREV_INSTALL_VERSION = "prevVersion";
|
||||||
public static final String BROWSER_UA_CODE = "browser_ua_code";
|
public static final String BROWSER_UA_CODE = "browser_ua_code";
|
||||||
public static final String APP_UA_CODE = "app_ua_code";
|
public static final String APP_UA_CODE = "app_ua_code";
|
||||||
// boolean prefs
|
// boolean prefs
|
||||||
public static final String DOWNLOAD_USER_FOLDER = "download_user_folder";
|
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";
|
// deprecated: public static final String BOTTOM_TOOLBAR = "bottom_toolbar";
|
||||||
public static final String FOLDER_SAVE_TO = "saved_to";
|
public static final String FOLDER_SAVE_TO = "saved_to";
|
||||||
public static final String AUTOPLAY_VIDEOS = "autoplay_videos";
|
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();
|
// 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) {
|
if (itemJson == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -728,41 +729,28 @@ public final class ResponseBodyUtils {
|
|||||||
width = dimensions.optInt("width");
|
width = dimensions.optInt("width");
|
||||||
}
|
}
|
||||||
String thumbnailUrl = null;
|
String thumbnailUrl = null;
|
||||||
try {
|
final JSONArray displayResources = feedItem.getJSONArray("display_resources");
|
||||||
thumbnailUrl = feedItem.getJSONArray("display_resources")
|
final List<MediaCandidate> candidates = new ArrayList<MediaCandidate>();
|
||||||
.getJSONObject(0)
|
for (int i = 0; i < displayResources.length(); i++) {
|
||||||
.getString("src");
|
final JSONObject displayResource = displayResources.getJSONObject(i);
|
||||||
} catch (JSONException ignored) {}
|
candidates.add(new MediaCandidate(
|
||||||
// final FeedModel.Builder feedModelBuilder = new FeedModel.Builder()
|
displayResource.getInt("config_width"),
|
||||||
// .setProfileModel(profileModel)
|
displayResource.getInt("config_height"),
|
||||||
// .setItemType(isVideo ? MediaItemType.MEDIA_TYPE_VIDEO
|
displayResource.getString("src")
|
||||||
// : MediaItemType.MEDIA_TYPE_IMAGE)
|
));
|
||||||
// .setViewCount(videoViews)
|
}
|
||||||
// .setPostId(feedItem.getString(Constants.EXTRAS_ID))
|
final ImageVersions2 imageVersions2 = new ImageVersions2(candidates);
|
||||||
// .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);
|
|
||||||
|
|
||||||
User user = null;
|
User user = backup;
|
||||||
long userId = -1;
|
long userId = -1;
|
||||||
if (feedItem.has("owner")) {
|
if (feedItem.has("owner") && user == null) {
|
||||||
final JSONObject owner = feedItem.getJSONObject("owner");
|
final JSONObject owner = feedItem.getJSONObject("owner");
|
||||||
final FriendshipStatus friendshipStatus = new FriendshipStatus(
|
final FriendshipStatus friendshipStatus = new FriendshipStatus(
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
owner.optBoolean("is_private"),
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
@ -774,7 +762,7 @@ public final class ResponseBodyUtils {
|
|||||||
userId,
|
userId,
|
||||||
owner.optString(Constants.EXTRAS_USERNAME),
|
owner.optString(Constants.EXTRAS_USERNAME),
|
||||||
owner.optString("full_name"),
|
owner.optString("full_name"),
|
||||||
owner.optBoolean("is_private"),
|
false,
|
||||||
owner.optString("profile_pic_url"),
|
owner.optString("profile_pic_url"),
|
||||||
null,
|
null,
|
||||||
friendshipStatus,
|
friendshipStatus,
|
||||||
@ -783,13 +771,6 @@ public final class ResponseBodyUtils {
|
|||||||
null, null, null, null);
|
null, null, null, null);
|
||||||
}
|
}
|
||||||
final String id = feedItem.getString(Constants.EXTRAS_ID);
|
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;
|
VideoVersion videoVersion = null;
|
||||||
if (isVideo) {
|
if (isVideo) {
|
||||||
videoVersion = new VideoVersion(
|
videoVersion = new VideoVersion(
|
||||||
@ -821,7 +802,7 @@ public final class ResponseBodyUtils {
|
|||||||
for (int i = 0; i < children.length(); i++) {
|
for (int i = 0; i < children.length(); i++) {
|
||||||
final JSONObject child = children.optJSONObject(i);
|
final JSONObject child = children.optJSONObject(i);
|
||||||
if (child == null) continue;
|
if (child == null) continue;
|
||||||
final Media media = parseGraphQLItem(child);
|
final Media media = parseGraphQLItem(child, null);
|
||||||
media.setIsSidecarChild(true);
|
media.setIsSidecarChild(true);
|
||||||
childItems.add(media);
|
childItems.add(media);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,9 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.StringDef;
|
import androidx.annotation.StringDef;
|
||||||
import androidx.appcompat.app.AppCompatDelegate;
|
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;
|
||||||
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_NUMBER;
|
||||||
import static awais.instagrabber.fragments.settings.PreferenceKeys.PREF_ENABLE_DM_AUTO_REFRESH_FREQ_UNIT;
|
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_DARK_THEME;
|
||||||
import static awais.instagrabber.utils.Constants.PREF_EMOJI_VARIANTS;
|
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.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_LIGHT_THEME;
|
||||||
import static awais.instagrabber.utils.Constants.PREF_LIKED_POSTS_LAYOUT;
|
import static awais.instagrabber.utils.Constants.PREF_LIKED_POSTS_LAYOUT;
|
||||||
import static awais.instagrabber.utils.Constants.PREF_LOCATION_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.SKIPPED_VERSION;
|
||||||
import static awais.instagrabber.utils.Constants.STORY_SORT;
|
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.SWAP_DATE_TIME_FORMAT_ENABLED;
|
||||||
|
import static awais.instagrabber.utils.Constants.TOGGLE_KEYWORD_FILTER;
|
||||||
|
|
||||||
public final class SettingsHelper {
|
public final class SettingsHelper {
|
||||||
private final SharedPreferences sharedPreferences;
|
private final SharedPreferences sharedPreferences;
|
||||||
@ -69,6 +74,12 @@ public final class SettingsHelper {
|
|||||||
return stringDefault;
|
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) {
|
public int getInteger(@IntegerSettings final String key) {
|
||||||
final int integerDefault = getIntegerDefault(key);
|
final int integerDefault = getIntegerDefault(key);
|
||||||
if (sharedPreferences != null) return sharedPreferences.getInt(key, integerDefault);
|
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();
|
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) {
|
public void putInteger(@IntegerSettings final String key, final int val) {
|
||||||
if (sharedPreferences != null) sharedPreferences.edit().putInt(key, val).apply();
|
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,
|
@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,
|
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,
|
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 {}
|
public @interface BooleanSettings {}
|
||||||
|
|
||||||
@StringDef({PREV_INSTALL_VERSION, BROWSER_UA_CODE, APP_UA_CODE, PREF_ENABLE_DM_AUTO_REFRESH_FREQ_NUMBER})
|
@StringDef({PREV_INSTALL_VERSION, BROWSER_UA_CODE, APP_UA_CODE, PREF_ENABLE_DM_AUTO_REFRESH_FREQ_NUMBER})
|
||||||
public @interface IntegerSettings {}
|
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 android.util.Log;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.gson.FieldNamingPolicy;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -52,7 +53,12 @@ public final class EmojiParser {
|
|||||||
}
|
}
|
||||||
try (final InputStream in = classLoader.getResourceAsStream(file)) {
|
try (final InputStream in = classLoader.getResourceAsStream(file)) {
|
||||||
final String json = NetworkUtils.readFromInputStream(in);
|
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();
|
final Type type = new TypeToken<Map<EmojiCategoryType, EmojiCategory>>() {}.getType();
|
||||||
categoryMap = gson.fromJson(json, type);
|
categoryMap = gson.fromJson(json, type);
|
||||||
// Log.d(TAG, "EmojiParser: " + categoryMap);
|
// Log.d(TAG, "EmojiParser: " + categoryMap);
|
||||||
@ -68,7 +74,7 @@ public final class EmojiParser {
|
|||||||
.build()
|
.build()
|
||||||
.stream())
|
.stream())
|
||||||
.collect(Collectors.toMap(Emoji::getUnicode, Function.identity()));
|
.collect(Collectors.toMap(Emoji::getUnicode, Function.identity()));
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "EmojiParser: ", e);
|
Log.e(TAG, "EmojiParser: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,18 @@
|
|||||||
package awais.instagrabber.viewmodels;
|
package awais.instagrabber.viewmodels;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.os.AsyncTask;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.lifecycle.AndroidViewModel;
|
import androidx.lifecycle.AndroidViewModel;
|
||||||
|
|
||||||
import awais.instagrabber.asyncs.ProfileFetcher;
|
|
||||||
import awais.instagrabber.db.datasources.AccountDataSource;
|
import awais.instagrabber.db.datasources.AccountDataSource;
|
||||||
import awais.instagrabber.db.entities.Account;
|
|
||||||
import awais.instagrabber.db.repositories.AccountRepository;
|
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.repositories.responses.User;
|
||||||
import awais.instagrabber.utils.Constants;
|
import awais.instagrabber.utils.Constants;
|
||||||
import awais.instagrabber.utils.CookieUtils;
|
import awais.instagrabber.utils.CookieUtils;
|
||||||
import awais.instagrabber.utils.TextUtils;
|
import awais.instagrabber.utils.TextUtils;
|
||||||
|
import awais.instagrabber.webservices.ServiceCallback;
|
||||||
|
import awais.instagrabber.webservices.UserService;
|
||||||
|
|
||||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||||
|
|
||||||
@ -27,6 +24,7 @@ public class AppStateViewModel extends AndroidViewModel {
|
|||||||
|
|
||||||
private User currentUser;
|
private User currentUser;
|
||||||
private AccountRepository accountRepository;
|
private AccountRepository accountRepository;
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
public AppStateViewModel(@NonNull final Application application) {
|
public AppStateViewModel(@NonNull final Application application) {
|
||||||
super(application);
|
super(application);
|
||||||
@ -34,6 +32,7 @@ public class AppStateViewModel extends AndroidViewModel {
|
|||||||
cookie = settingsHelper.getString(Constants.COOKIE);
|
cookie = settingsHelper.getString(Constants.COOKIE);
|
||||||
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
|
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
|
||||||
if (!isLoggedIn) return;
|
if (!isLoggedIn) return;
|
||||||
|
userService = UserService.getInstance();
|
||||||
accountRepository = AccountRepository.getInstance(AccountDataSource.getInstance(application));
|
accountRepository = AccountRepository.getInstance(AccountDataSource.getInstance(application));
|
||||||
fetchProfileDetails();
|
fetchProfileDetails();
|
||||||
}
|
}
|
||||||
@ -44,6 +43,14 @@ public class AppStateViewModel extends AndroidViewModel {
|
|||||||
|
|
||||||
private void fetchProfileDetails() {
|
private void fetchProfileDetails() {
|
||||||
final long uid = CookieUtils.getUserIdFromCookie(cookie);
|
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 variables,
|
||||||
final String arg1,
|
final String arg1,
|
||||||
final String arg2,
|
final String arg2,
|
||||||
|
final User backup,
|
||||||
final ServiceCallback<PostsFetchResponse> callback) {
|
final ServiceCallback<PostsFetchResponse> callback) {
|
||||||
final Map<String, String> queryMap = new HashMap<>();
|
final Map<String, String> queryMap = new HashMap<>();
|
||||||
queryMap.put("query_hash", queryHash);
|
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) {
|
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||||
try {
|
try {
|
||||||
// Log.d(TAG, "onResponse: body: " + response.body());
|
// 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) {
|
if (callback != null) {
|
||||||
callback.onSuccess(postsFetchResponse);
|
callback.onSuccess(postsFetchResponse);
|
||||||
}
|
}
|
||||||
@ -96,6 +97,7 @@ public class GraphQLService extends BaseService {
|
|||||||
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
||||||
Constants.EXTRAS_LOCATION,
|
Constants.EXTRAS_LOCATION,
|
||||||
"edge_location_to_media",
|
"edge_location_to_media",
|
||||||
|
null,
|
||||||
callback);
|
callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,12 +110,14 @@ public class GraphQLService extends BaseService {
|
|||||||
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
||||||
Constants.EXTRAS_HASHTAG,
|
Constants.EXTRAS_HASHTAG,
|
||||||
"edge_hashtag_to_media",
|
"edge_hashtag_to_media",
|
||||||
|
null,
|
||||||
callback);
|
callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fetchProfilePosts(final long profileId,
|
public void fetchProfilePosts(final long profileId,
|
||||||
final int postsPerPage,
|
final int postsPerPage,
|
||||||
final String maxId,
|
final String maxId,
|
||||||
|
final User backup,
|
||||||
final ServiceCallback<PostsFetchResponse> callback) {
|
final ServiceCallback<PostsFetchResponse> callback) {
|
||||||
fetch("18a7b935ab438c4514b1f742d8fa07a7",
|
fetch("18a7b935ab438c4514b1f742d8fa07a7",
|
||||||
"{\"id\":\"" + profileId + "\"," +
|
"{\"id\":\"" + profileId + "\"," +
|
||||||
@ -121,6 +125,7 @@ public class GraphQLService extends BaseService {
|
|||||||
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
||||||
Constants.EXTRAS_USER,
|
Constants.EXTRAS_USER,
|
||||||
"edge_owner_to_timeline_media",
|
"edge_owner_to_timeline_media",
|
||||||
|
backup,
|
||||||
callback);
|
callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,21 +139,28 @@ public class GraphQLService extends BaseService {
|
|||||||
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
||||||
Constants.EXTRAS_USER,
|
Constants.EXTRAS_USER,
|
||||||
"edge_user_to_photos_of_you",
|
"edge_user_to_photos_of_you",
|
||||||
|
null,
|
||||||
callback);
|
callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@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 {
|
throws JSONException {
|
||||||
if (TextUtils.isEmpty(response.body())) {
|
if (TextUtils.isEmpty(response.body())) {
|
||||||
Log.e(TAG, "parseResponse: feed response body is empty with status code: " + response.code());
|
Log.e(TAG, "parseResponse: feed response body is empty with status code: " + response.code());
|
||||||
return new PostsFetchResponse(Collections.emptyList(), false, null);
|
return new PostsFetchResponse(Collections.emptyList(), false, null);
|
||||||
}
|
}
|
||||||
return parseResponseBody(response.body(), arg1, arg2);
|
return parseResponseBody(response.body(), arg1, arg2, backup);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@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 {
|
throws JSONException {
|
||||||
final List<Media> items = new ArrayList<>();
|
final List<Media> items = new ArrayList<>();
|
||||||
final JSONObject timelineFeed = new JSONObject(body)
|
final JSONObject timelineFeed = new JSONObject(body)
|
||||||
@ -174,7 +186,7 @@ public class GraphQLService extends BaseService {
|
|||||||
if (itemJson == null) {
|
if (itemJson == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final Media media = ResponseBodyUtils.parseGraphQLItem(itemJson);
|
final Media media = ResponseBodyUtils.parseGraphQLItem(itemJson, backup);
|
||||||
if (media != null) {
|
if (media != null) {
|
||||||
items.add(media);
|
items.add(media);
|
||||||
}
|
}
|
||||||
|
@ -121,9 +121,15 @@ public class NewsService extends BaseService {
|
|||||||
callback.onSuccess(null);
|
callback.onSuccess(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final List<AymlUser> aymlUsers = new ArrayList<>();
|
final List<AymlUser> aymlUsers = new ArrayList<AymlUser>();
|
||||||
aymlUsers.addAll(body.getNewSuggestedUsers().getSuggestions());
|
final List<AymlUser> newSuggestions = body.getNewSuggestedUsers().getSuggestions();
|
||||||
aymlUsers.addAll(body.getSuggestedUsers().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()
|
final List<Notification> newsItems = aymlUsers.stream()
|
||||||
.map(i -> {
|
.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_null_response">Response is null!</string>
|
||||||
<string name="generic_not_ok_response">Response status is not ok!</string>
|
<string name="generic_not_ok_response">Response status is not ok!</string>
|
||||||
<string name="generic_failed_request">Request failed!</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="marked_as_seen">Marked as seen</string>
|
||||||
<string name="delete_unsuccessful">Delete unsuccessful</string>
|
<string name="delete_unsuccessful">Delete unsuccessful</string>
|
||||||
<string name="crash_report_subject">Barinsta Crash Report</string>
|
<string name="crash_report_subject">Barinsta Crash Report</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user