mirror of
https://github.com/KokaKiwi/BarInsta
synced 2026-03-05 20:11:36 +00:00
Preferences! Check description
1. Added preferences screens. 2. Some DM changes. 3. Init profile actions using services
This commit is contained in:
parent
3f6c74d671
commit
40e810e88c
63 changed files with 1484 additions and 478 deletions
|
|
@ -1372,12 +1372,15 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
|
|||
public void onClick(final View v) {
|
||||
final String userIdFromCookie = Utils.getUserIdFromCookie(MainHelper.this.cookie);
|
||||
final boolean isSelf = (isLoggedIn && mainActivity.profileModel != null) && userIdFromCookie != null && userIdFromCookie.equals(mainActivity.profileModel.getId());
|
||||
if (!isLoggedIn && Utils.dataBox.getFavorite(mainActivity.userQuery) != null && v == mainActivity.mainBinding.profileView.btnFollow) {
|
||||
if (!isLoggedIn
|
||||
&& Utils.dataBox.getFavorite(mainActivity.userQuery) != null
|
||||
&& v == mainActivity.mainBinding.profileView.btnFollow) {
|
||||
Utils.dataBox.delFavorite(new DataBox.FavoriteModel(mainActivity.userQuery,
|
||||
Long.parseLong(Utils.dataBox.getFavorite(mainActivity.userQuery).split("/")[1]),
|
||||
mainActivity.locationModel != null ? mainActivity.locationModel.getName() : mainActivity.userQuery.replaceAll("^@", "")));
|
||||
onRefresh();
|
||||
} else if (!isLoggedIn && (v == mainActivity.mainBinding.profileView.btnFollow || v == mainActivity.mainBinding.profileView.btnFollowTag)) {
|
||||
} else if (!isLoggedIn
|
||||
&& (v == mainActivity.mainBinding.profileView.btnFollow || v == mainActivity.mainBinding.profileView.btnFollowTag)) {
|
||||
Utils.dataBox.addFavorite(new DataBox.FavoriteModel(mainActivity.userQuery, System.currentTimeMillis(),
|
||||
mainActivity.locationModel != null ? mainActivity.locationModel.getName() : mainActivity.userQuery.replaceAll("^@", "")));
|
||||
onRefresh();
|
||||
|
|
@ -1389,7 +1392,7 @@ public final class MainHelper implements SwipeRefreshLayout.OnRefreshListener {
|
|||
new ProfileAction().execute("block");
|
||||
} else if (v == mainActivity.mainBinding.profileView.btnFollowTag) {
|
||||
new ProfileAction().execute("followtag");
|
||||
} else if (v == mainActivity.mainBinding.profileView.btnTagged || (v == mainActivity.mainBinding.profileView.btnRestrict && !isLoggedIn)) {
|
||||
} else if (v == mainActivity.mainBinding.profileView.btnTagged || v == mainActivity.mainBinding.profileView.btnRestrict) {
|
||||
mainActivity.startActivity(new Intent(mainActivity, SavedViewer.class)
|
||||
.putExtra(Constants.EXTRAS_INDEX, "%" + mainActivity.profileModel.getId())
|
||||
.putExtra(Constants.EXTRAS_USER, "@" + mainActivity.profileModel.getUsername())
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public abstract class BaseLanguageActivity extends AppCompatActivity {
|
|||
|
||||
@Override
|
||||
protected void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
Utils.changeTheme(this);
|
||||
Utils.changeTheme(getApplicationContext());
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
package awais.instagrabber.activities;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
|
@ -36,9 +38,9 @@ public final class Login extends BaseLanguageActivity implements View.OnClickLis
|
|||
final String mainCookie = Utils.getCookie(url);
|
||||
if (Utils.isEmpty(mainCookie) || !mainCookie.contains("; ds_user_id=")) ready = true;
|
||||
else if (mainCookie.contains("; ds_user_id=") && ready) {
|
||||
Utils.setupCookies(mainCookie);
|
||||
settingsHelper.putString(Constants.COOKIE, mainCookie);
|
||||
Toast.makeText(getApplicationContext(), R.string.login_success_loading_cookies, Toast.LENGTH_SHORT).show();
|
||||
final Intent intent = new Intent();
|
||||
intent.putExtra("cookie", mainCookie);
|
||||
setResult(Constants.LOGIN_RESULT_CODE, intent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
|
@ -95,7 +97,6 @@ public final class Login extends BaseLanguageActivity implements View.OnClickLis
|
|||
}
|
||||
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
@SuppressWarnings("deprecation")
|
||||
private void initWebView() {
|
||||
if (loginBinding != null) {
|
||||
loginBinding.webView.setWebChromeClient(webChromeClient);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,19 @@ import static awais.instagrabber.utils.Utils.settingsHelper;
|
|||
public class MainActivity extends BaseLanguageActivity {
|
||||
private static final String TAG = "MainActivity";
|
||||
|
||||
private static final List<Integer> SHOW_BOTTOM_VIEW_DESTINATIONS = Arrays.asList(
|
||||
R.id.directMessagesInboxFragment,
|
||||
R.id.feedFragment,
|
||||
R.id.profileFragment,
|
||||
R.id.discoverFragment,
|
||||
R.id.morePreferencesFragment);
|
||||
private static final List<Integer> KEEP_SCROLL_BEHAVIOUR_DESTINATIONS = Arrays.asList(
|
||||
R.id.directMessagesInboxFragment,
|
||||
R.id.feedFragment,
|
||||
R.id.profileFragment,
|
||||
R.id.discoverFragment,
|
||||
R.id.morePreferencesFragment,
|
||||
R.id.settingsPreferencesFragment);
|
||||
private ActivityMainBinding binding;
|
||||
private LiveData<NavController> currentNavControllerLiveData;
|
||||
|
||||
|
|
@ -69,17 +82,16 @@ public class MainActivity extends BaseLanguageActivity {
|
|||
R.navigation.direct_messages_nav_graph,
|
||||
R.navigation.feed_nav_graph,
|
||||
R.navigation.profile_nav_graph,
|
||||
R.navigation.discover_nav_graph
|
||||
R.navigation.discover_nav_graph,
|
||||
R.navigation.more_nav_graph
|
||||
));
|
||||
|
||||
binding.bottomNavView.setSelectedItemId(R.id.feed_nav_graph);
|
||||
final LiveData<NavController> navControllerLiveData = setupWithNavController(
|
||||
binding.bottomNavView,
|
||||
navList,
|
||||
getSupportFragmentManager(),
|
||||
R.id.main_nav_host,
|
||||
getIntent(),
|
||||
1);
|
||||
0);
|
||||
navControllerLiveData.observe(this, this::setupNavigation);
|
||||
currentNavControllerLiveData = navControllerLiveData;
|
||||
}
|
||||
|
|
@ -89,19 +101,12 @@ public class MainActivity extends BaseLanguageActivity {
|
|||
navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
|
||||
binding.appBarLayout.setExpanded(true, true);
|
||||
final int destinationId = destination.getId();
|
||||
final List<Integer> showBottomView = Arrays.asList(
|
||||
R.id.directMessagesInboxFragment,
|
||||
R.id.feedFragment,
|
||||
R.id.profileFragment,
|
||||
R.id.discoverFragment);
|
||||
|
||||
if (showBottomView.contains(destinationId)) {
|
||||
binding.bottomNavView.setVisibility(SHOW_BOTTOM_VIEW_DESTINATIONS.contains(destinationId) ? View.VISIBLE : View.GONE);
|
||||
if (KEEP_SCROLL_BEHAVIOUR_DESTINATIONS.contains(destinationId)) {
|
||||
setScrollingBehaviour();
|
||||
binding.bottomNavView.setVisibility(View.VISIBLE);
|
||||
return;
|
||||
} else {
|
||||
removeScrollingBehaviour();
|
||||
}
|
||||
removeScrollingBehaviour();
|
||||
binding.bottomNavView.setVisibility(View.GONE);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ import awais.instagrabber.asyncs.SuggestionsFetcher;
|
|||
import awais.instagrabber.asyncs.UsernameFetcher;
|
||||
import awais.instagrabber.asyncs.i.iStoryStatusFetcher;
|
||||
import awais.instagrabber.customviews.MouseDrawer;
|
||||
import awais.instagrabber.databinding.ActivityMainBinding;
|
||||
import awais.instagrabber.databinding.ActivityMainbackupBinding;
|
||||
import awais.instagrabber.dialogs.AboutDialog;
|
||||
import awais.instagrabber.dialogs.QuickAccessDialog;
|
||||
|
|
@ -95,8 +94,7 @@ public final class MainActivityBackup extends BaseLanguageActivity {
|
|||
// .putExtra(Constants.EXTRAS_HIGHLIGHT, highlightModel.getTitle())
|
||||
// .putExtra(Constants.EXTRAS_STORIES, result)
|
||||
// );
|
||||
}
|
||||
else
|
||||
} else
|
||||
Toast.makeText(MainActivityBackup.this, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show();
|
||||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
|
@ -105,7 +103,8 @@ public final class MainActivityBackup extends BaseLanguageActivity {
|
|||
|
||||
private SuggestionsAdapter suggestionAdapter;
|
||||
private MenuItem searchAction;
|
||||
public @NonNull ActivityMainbackupBinding mainBinding;
|
||||
public @NonNull
|
||||
ActivityMainbackupBinding mainBinding;
|
||||
public SearchView searchView;
|
||||
public MenuItem downloadAction, settingsAction, dmsAction, notifAction;
|
||||
public StoryModel[] storyModels;
|
||||
|
|
@ -253,7 +252,7 @@ public final class MainActivityBackup extends BaseLanguageActivity {
|
|||
final boolean isQueryNull = userQuery == null;
|
||||
if (isQueryNull) {
|
||||
allItems.clear();
|
||||
mainBinding.profileView.privatePage1.setImageResource(R.drawable.ic_info);
|
||||
mainBinding.profileView.privatePage1.setImageResource(R.drawable.ic_outline_info_24);
|
||||
mainBinding.profileView.privatePage2.setTextSize(20);
|
||||
mainBinding.profileView.privatePage2.setText(isLoggedIn ? R.string.no_acc_logged_in : R.string.no_acc);
|
||||
mainBinding.profileView.privatePage.setVisibility(View.VISIBLE);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import androidx.recyclerview.widget.DiffUtil;
|
|||
import androidx.recyclerview.widget.ListAdapter;
|
||||
|
||||
import awais.instagrabber.adapters.viewholder.DirectMessageInboxItemViewHolder;
|
||||
import awais.instagrabber.databinding.LayoutIncludeSimpleItemBinding;
|
||||
import awais.instagrabber.databinding.LayoutDmInboxItemBinding;
|
||||
import awais.instagrabber.models.direct_messages.InboxThreadModel;
|
||||
|
||||
public final class DirectMessageInboxAdapter extends ListAdapter<InboxThreadModel, DirectMessageInboxItemViewHolder> {
|
||||
|
|
@ -35,7 +35,7 @@ public final class DirectMessageInboxAdapter extends ListAdapter<InboxThreadMode
|
|||
@Override
|
||||
public DirectMessageInboxItemViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int type) {
|
||||
final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
|
||||
final LayoutIncludeSimpleItemBinding binding = LayoutIncludeSimpleItemBinding.inflate(layoutInflater, parent, false);
|
||||
final LayoutDmInboxItemBinding binding = LayoutDmInboxItemBinding.inflate(layoutInflater, parent, false);
|
||||
return new DirectMessageInboxItemViewHolder(binding);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,18 +2,16 @@ package awais.instagrabber.adapters.viewholder;
|
|||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.text.HtmlCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.RequestManager;
|
||||
import com.facebook.drawee.view.SimpleDraweeView;
|
||||
|
||||
import awais.instagrabber.R;
|
||||
import awais.instagrabber.databinding.LayoutIncludeSimpleItemBinding;
|
||||
import awais.instagrabber.databinding.LayoutDmInboxItemBinding;
|
||||
import awais.instagrabber.models.ProfileModel;
|
||||
import awais.instagrabber.models.direct_messages.DirectItemModel;
|
||||
import awais.instagrabber.models.direct_messages.InboxThreadModel;
|
||||
|
|
@ -21,19 +19,18 @@ import awais.instagrabber.models.enums.DirectItemType;
|
|||
|
||||
public final class DirectMessageInboxItemViewHolder extends RecyclerView.ViewHolder {
|
||||
private final LinearLayout multipleProfilePicsContainer;
|
||||
private final ImageView[] multipleProfilePics;
|
||||
private final LayoutIncludeSimpleItemBinding binding;
|
||||
private final SimpleDraweeView[] multipleProfilePics;
|
||||
private final LayoutDmInboxItemBinding binding;
|
||||
|
||||
public DirectMessageInboxItemViewHolder(@NonNull final LayoutIncludeSimpleItemBinding binding) {
|
||||
public DirectMessageInboxItemViewHolder(@NonNull final LayoutDmInboxItemBinding binding) {
|
||||
super(binding.getRoot());
|
||||
this.binding = binding;
|
||||
binding.tvLikes.setVisibility(View.GONE);
|
||||
multipleProfilePicsContainer = binding.container;
|
||||
multipleProfilePicsContainer = binding.multiPicContainer;
|
||||
final LinearLayout containerChild = (LinearLayout) multipleProfilePicsContainer.getChildAt(1);
|
||||
multipleProfilePics = new ImageView[]{
|
||||
(ImageView) multipleProfilePicsContainer.getChildAt(0),
|
||||
(ImageView) containerChild.getChildAt(0),
|
||||
(ImageView) containerChild.getChildAt(1)
|
||||
multipleProfilePics = new SimpleDraweeView[]{
|
||||
(SimpleDraweeView) multipleProfilePicsContainer.getChildAt(0),
|
||||
(SimpleDraweeView) containerChild.getChildAt(0),
|
||||
(SimpleDraweeView) containerChild.getChildAt(1)
|
||||
};
|
||||
binding.tvDate.setSelected(true);
|
||||
binding.tvUsername.setSelected(true);
|
||||
|
|
@ -45,17 +42,17 @@ public final class DirectMessageInboxItemViewHolder extends RecyclerView.ViewHol
|
|||
return;
|
||||
}
|
||||
itemView.setTag(model);
|
||||
final RequestManager glideRequestManager = Glide.with(itemView);
|
||||
final ProfileModel[] users = model.getUsers();
|
||||
if (users.length > 1) {
|
||||
binding.ivProfilePic.setVisibility(View.GONE);
|
||||
multipleProfilePicsContainer.setVisibility(View.VISIBLE);
|
||||
for (int i = 0; i < Math.min(3, users.length); ++i)
|
||||
glideRequestManager.load(users[i].getSdProfilePic()).into(multipleProfilePics[i]);
|
||||
for (int i = 0; i < Math.min(3, users.length); ++i) {
|
||||
multipleProfilePics[i].setImageURI(users[i].getSdProfilePic());
|
||||
}
|
||||
} else {
|
||||
binding.ivProfilePic.setVisibility(View.VISIBLE);
|
||||
multipleProfilePicsContainer.setVisibility(View.GONE);
|
||||
glideRequestManager.load(users.length == 1 ? users[0].getSdProfilePic() : null).into(binding.ivProfilePic);
|
||||
binding.ivProfilePic.setImageURI(users.length == 1 ? users[0].getSdProfilePic() : null);
|
||||
}
|
||||
binding.tvUsername.setText(model.getThreadTitle());
|
||||
final DirectItemModel lastItemModel = itemModels[itemModels.length - 1];
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import awaisomereport.LogCollector;
|
|||
import static awais.instagrabber.utils.Utils.logCollector;
|
||||
|
||||
public final class FeedFetcher extends AsyncTask<Void, Void, FeedModel[]> {
|
||||
private static final String TAG = "FeedFetcher";
|
||||
|
||||
private static final int maxItemsToLoad = 25; // max is 50, but that's too many posts, setting more than 30 is gay
|
||||
private final String endCursor;
|
||||
private final FetchListener<FeedModel[]> fetchListener;
|
||||
|
|
@ -61,8 +63,10 @@ public final class FeedFetcher extends AsyncTask<Void, Void, FeedModel[]> {
|
|||
final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
|
||||
|
||||
if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
||||
final JSONObject timelineFeed = new JSONObject(Utils.readFromConnection(urlConnection)).getJSONObject("data")
|
||||
.getJSONObject(Constants.EXTRAS_USER).getJSONObject("edge_web_feed_timeline");
|
||||
final String json = Utils.readFromConnection(urlConnection);
|
||||
Log.d(TAG, json);
|
||||
final JSONObject timelineFeed = new JSONObject(json).getJSONObject("data")
|
||||
.getJSONObject(Constants.EXTRAS_USER).getJSONObject("edge_web_feed_timeline");
|
||||
|
||||
final String endCursor;
|
||||
final boolean hasNextPage;
|
||||
|
|
@ -83,7 +87,8 @@ public final class FeedFetcher extends AsyncTask<Void, Void, FeedModel[]> {
|
|||
for (int i = 0; i < feedLen; ++i) {
|
||||
final JSONObject feedItem = feedItems.getJSONObject(i).getJSONObject("node");
|
||||
final String mediaType = feedItem.optString("__typename");
|
||||
if (mediaType.isEmpty() || "GraphSuggestedUserFeedUnit".equals(mediaType)) continue;
|
||||
if (mediaType.isEmpty() || "GraphSuggestedUserFeedUnit".equals(mediaType))
|
||||
continue;
|
||||
|
||||
final boolean isVideo = feedItem.optBoolean("is_video");
|
||||
final long videoViews = feedItem.optLong("video_view_count", 0);
|
||||
|
|
@ -93,7 +98,8 @@ public final class FeedFetcher extends AsyncTask<Void, Void, FeedModel[]> {
|
|||
final String resourceUrl;
|
||||
|
||||
if (isVideo) resourceUrl = feedItem.getString("video_url");
|
||||
else resourceUrl = feedItem.has("display_resources") ? Utils.getHighQualityImage(feedItem) : displayUrl;
|
||||
else
|
||||
resourceUrl = feedItem.has("display_resources") ? Utils.getHighQualityImage(feedItem) : displayUrl;
|
||||
|
||||
ProfileModel profileModel = null;
|
||||
if (feedItem.has("owner")) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@ import androidx.annotation.Nullable;
|
|||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
|
|
@ -23,6 +26,8 @@ import static awais.instagrabber.utils.Utils.logCollector;
|
|||
import static awaisomereport.LogCollector.LogFile;
|
||||
|
||||
public final class InboxFetcher extends AsyncTask<Void, Void, InboxModel> {
|
||||
private static final String TAG = "InboxFetcher";
|
||||
|
||||
private final String endCursor;
|
||||
private final FetchListener<InboxModel> fetchListener;
|
||||
|
||||
|
|
@ -43,46 +48,59 @@ public final class InboxFetcher extends AsyncTask<Void, Void, InboxModel> {
|
|||
conn.setRequestProperty("Accept-Language", LocaleUtils.getCurrentLocale().getLanguage() + ",en-US;q=0.8");
|
||||
conn.setUseCaches(false);
|
||||
|
||||
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
||||
JSONObject data = new JSONObject(Utils.readFromConnection(conn));
|
||||
// try (FileWriter fileWriter = new FileWriter(new File("/sdcard/test.json"))) {
|
||||
// fileWriter.write(data.toString(2));
|
||||
// }
|
||||
|
||||
final long seqId = data.optLong("seq_id");
|
||||
final int pendingRequestsCount = data.optInt("pending_requests_total");
|
||||
final boolean hasPendingTopRequests = data.optBoolean("has_pending_top_requests");
|
||||
|
||||
data = data.getJSONObject("inbox");
|
||||
|
||||
final boolean blendedInboxEnabled = data.optBoolean("blended_inbox_enabled");
|
||||
final boolean hasOlder = data.optBoolean("has_older");
|
||||
final int unseenCount = data.optInt("unseen_count");
|
||||
final long unseenCountTimestamp = data.optLong("unseen_count_ts");
|
||||
final String oldestCursor = data.optString("oldest_cursor");
|
||||
|
||||
InboxThreadModel[] inboxThreadModels = null;
|
||||
|
||||
final JSONArray threadsArray = data.optJSONArray("threads");
|
||||
if (threadsArray != null) {
|
||||
final int threadsLen = threadsArray.length();
|
||||
inboxThreadModels = new InboxThreadModel[threadsLen];
|
||||
|
||||
for (int i = 0; i < threadsLen; ++i)
|
||||
inboxThreadModels[i] = Utils.createInboxThreadModel(threadsArray.getJSONObject(i), false);
|
||||
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
|
||||
final InputStream responseInputStream = conn.getErrorStream();
|
||||
final BufferedReader r = new BufferedReader(new InputStreamReader(responseInputStream));
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
for (String line = r.readLine(); line != null; line = r.readLine()) {
|
||||
if (builder.length() != 0) {
|
||||
builder.append("\n");
|
||||
}
|
||||
builder.append(line);
|
||||
}
|
||||
|
||||
result = new InboxModel(hasOlder, hasPendingTopRequests,
|
||||
blendedInboxEnabled, unseenCount, pendingRequestsCount,
|
||||
seqId, unseenCountTimestamp, oldestCursor, inboxThreadModels);
|
||||
Log.e(TAG, "Error response: " + conn.getResponseCode() + ", " + builder.toString());
|
||||
r.close();
|
||||
conn.disconnect();
|
||||
return null;
|
||||
}
|
||||
JSONObject data = new JSONObject(Utils.readFromConnection(conn));
|
||||
// try (FileWriter fileWriter = new FileWriter(new File("/sdcard/test.json"))) {
|
||||
// fileWriter.write(data.toString(2));
|
||||
// }
|
||||
|
||||
final long seqId = data.optLong("seq_id");
|
||||
final int pendingRequestsCount = data.optInt("pending_requests_total");
|
||||
final boolean hasPendingTopRequests = data.optBoolean("has_pending_top_requests");
|
||||
|
||||
data = data.getJSONObject("inbox");
|
||||
|
||||
final boolean blendedInboxEnabled = data.optBoolean("blended_inbox_enabled");
|
||||
final boolean hasOlder = data.optBoolean("has_older");
|
||||
final int unseenCount = data.optInt("unseen_count");
|
||||
final long unseenCountTimestamp = data.optLong("unseen_count_ts");
|
||||
final String oldestCursor = data.optString("oldest_cursor");
|
||||
|
||||
InboxThreadModel[] inboxThreadModels = null;
|
||||
|
||||
final JSONArray threadsArray = data.optJSONArray("threads");
|
||||
if (threadsArray != null) {
|
||||
final int threadsLen = threadsArray.length();
|
||||
inboxThreadModels = new InboxThreadModel[threadsLen];
|
||||
|
||||
for (int i = 0; i < threadsLen; ++i)
|
||||
inboxThreadModels[i] = Utils.createInboxThreadModel(threadsArray.getJSONObject(i), false);
|
||||
}
|
||||
|
||||
result = new InboxModel(hasOlder, hasPendingTopRequests,
|
||||
blendedInboxEnabled, unseenCount, pendingRequestsCount,
|
||||
seqId, unseenCountTimestamp, oldestCursor, inboxThreadModels);
|
||||
|
||||
conn.disconnect();
|
||||
} catch (final Exception e) {
|
||||
result = null;
|
||||
if (logCollector != null)
|
||||
logCollector.appendException(e, LogFile.ASYNC_DMS, "doInBackground");
|
||||
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
|
||||
if (BuildConfig.DEBUG) Log.e(TAG, "", e);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ import androidx.fragment.app.FragmentManager;
|
|||
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import awais.instagrabber.BuildConfig;
|
||||
import awais.instagrabber.R;
|
||||
import awais.instagrabber.activities.Login;
|
||||
|
|
@ -50,6 +52,7 @@ import static awais.instagrabber.utils.Constants.MUTED_VIDEOS;
|
|||
import static awais.instagrabber.utils.Constants.STORIESIG;
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||
|
||||
@Deprecated
|
||||
public final class SettingsDialog extends BottomSheetDialogFragment implements View.OnClickListener, AdapterView.OnItemSelectedListener,
|
||||
CompoundButton.OnCheckedChangeListener {
|
||||
private Activity activity;
|
||||
|
|
@ -65,7 +68,8 @@ public final class SettingsDialog extends BottomSheetDialogFragment implements V
|
|||
public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) {
|
||||
if (requestCode != 6200) return;
|
||||
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) showDirectoryChooser();
|
||||
else Toast.makeText(activity, R.string.direct_download_perms_ask, Toast.LENGTH_SHORT).show();
|
||||
else
|
||||
Toast.makeText(activity, R.string.direct_download_perms_ask, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
private void showDirectoryChooser() {
|
||||
|
|
@ -73,10 +77,10 @@ public final class SettingsDialog extends BottomSheetDialogFragment implements V
|
|||
if (fragmentManager == null) fragmentManager = getChildFragmentManager();
|
||||
|
||||
new DirectoryChooser().setInitialDirectory(settingsHelper.getString(FOLDER_PATH))
|
||||
.setInteractionListener(path -> {
|
||||
settingsHelper.putString(FOLDER_PATH, path);
|
||||
somethingChanged = true;
|
||||
}).show(fragmentManager, null);
|
||||
.setInteractionListener(path -> {
|
||||
settingsHelper.putString(FOLDER_PATH, path);
|
||||
somethingChanged = true;
|
||||
}).show(fragmentManager, null);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
|
@ -115,12 +119,12 @@ public final class SettingsDialog extends BottomSheetDialogFragment implements V
|
|||
if (Utils.isEmpty(settingsHelper.getString(Constants.COOKIE))) btnLogout.setEnabled(false);
|
||||
|
||||
spAppTheme = contentView.findViewById(R.id.spAppTheme);
|
||||
currentTheme = settingsHelper.getInteger(APP_THEME);
|
||||
currentTheme = Integer.parseInt(settingsHelper.getString(APP_THEME));
|
||||
spAppTheme.setSelection(currentTheme);
|
||||
spAppTheme.setOnItemSelectedListener(this);
|
||||
|
||||
spLanguage = contentView.findViewById(R.id.spLanguage);
|
||||
currentLanguage = settingsHelper.getInteger(APP_LANGUAGE);
|
||||
currentLanguage = Integer.parseInt(settingsHelper.getString(APP_LANGUAGE));
|
||||
spLanguage.setSelection(currentLanguage);
|
||||
spLanguage.setOnItemSelectedListener(this);
|
||||
|
||||
|
|
@ -178,13 +182,13 @@ public final class SettingsDialog extends BottomSheetDialogFragment implements V
|
|||
public void onItemSelected(final AdapterView<?> spinner, final View view, final int position, final long id) {
|
||||
if (spinner == spAppTheme) {
|
||||
if (position != currentTheme) {
|
||||
settingsHelper.putInteger(APP_THEME, position);
|
||||
settingsHelper.putString(APP_THEME, String.valueOf(position));
|
||||
somethingChanged = true;
|
||||
}
|
||||
} else if (spinner == spLanguage) {
|
||||
selectedLanguage = position;
|
||||
if (position != currentLanguage) {
|
||||
settingsHelper.putInteger(APP_LANGUAGE, position);
|
||||
settingsHelper.putString(APP_LANGUAGE, String.valueOf(position));
|
||||
somethingChanged = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -205,7 +209,28 @@ public final class SettingsDialog extends BottomSheetDialogFragment implements V
|
|||
requestPermissions(Utils.PERMS, 6007);
|
||||
else Utils.showImportExportDialog(activity);
|
||||
} else if (v == btnTimeSettings) {
|
||||
new TimeSettingsDialog().show(fragmentManager, null);
|
||||
new TimeSettingsDialog(settingsHelper.getBoolean(Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED),
|
||||
settingsHelper.getString(Constants.CUSTOM_DATE_TIME_FORMAT),
|
||||
settingsHelper.getString(Constants.DATE_TIME_SELECTION),
|
||||
(isCustomFormat,
|
||||
formatSelection,
|
||||
spTimeFormatSelectedItemPosition,
|
||||
spSeparatorSelectedItemPosition,
|
||||
spDateFormatSelectedItemPosition,
|
||||
selectedFormat, currentFormat) -> {
|
||||
if (isCustomFormat) {
|
||||
settingsHelper.putString(Constants.CUSTOM_DATE_TIME_FORMAT, formatSelection);
|
||||
} else {
|
||||
final String formatSelectionUpdated = spTimeFormatSelectedItemPosition + ";"
|
||||
+ spSeparatorSelectedItemPosition + ';'
|
||||
+ spDateFormatSelectedItemPosition; // time;separator;date
|
||||
settingsHelper.putString(Constants.DATE_TIME_FORMAT, selectedFormat);
|
||||
settingsHelper.putString(Constants.DATE_TIME_SELECTION, formatSelectionUpdated);
|
||||
}
|
||||
settingsHelper.putBoolean(Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED, isCustomFormat);
|
||||
Utils.datetimeParser = (SimpleDateFormat) currentFormat.clone();
|
||||
}
|
||||
).show(fragmentManager, null);
|
||||
} else if (v == btnReport) {
|
||||
CrashReporter.get(activity.getApplication()).zipLogs().startCrashEmailIntent(activity, true);
|
||||
} else if (v == btnSaveTo) {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ import android.text.Editable;
|
|||
import android.text.TextWatcher;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.CompoundButton;
|
||||
|
||||
|
|
@ -19,38 +22,42 @@ import java.util.Date;
|
|||
import java.util.GregorianCalendar;
|
||||
|
||||
import awais.instagrabber.databinding.DialogTimeSettingsBinding;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.LocaleUtils;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||
|
||||
public final class TimeSettingsDialog extends DialogFragment implements AdapterView.OnItemSelectedListener, CompoundButton.OnCheckedChangeListener,
|
||||
View.OnClickListener, TextWatcher {
|
||||
private DialogTimeSettingsBinding timeSettingsBinding;
|
||||
private final Date magicDate;
|
||||
private SimpleDateFormat currentFormat;
|
||||
private String selectedFormat;
|
||||
private boolean customDateTimeFormatEnabled;
|
||||
private String customDateTimeFormat;
|
||||
private String dateTimeSelection;
|
||||
private final OnConfirmListener onConfirmListener;
|
||||
|
||||
public TimeSettingsDialog() {
|
||||
super();
|
||||
public TimeSettingsDialog(final boolean customDateTimeFormatEnabled,
|
||||
final String customDateTimeFormat,
|
||||
final String dateTimeSelection,
|
||||
final OnConfirmListener onConfirmListener) {
|
||||
this.customDateTimeFormatEnabled = customDateTimeFormatEnabled;
|
||||
this.customDateTimeFormat = customDateTimeFormat;
|
||||
this.dateTimeSelection = dateTimeSelection;
|
||||
this.onConfirmListener = onConfirmListener;
|
||||
final Calendar instance = GregorianCalendar.getInstance();
|
||||
instance.set(2020, 5, 22, 8, 17, 13);
|
||||
magicDate = instance.getTime();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) {
|
||||
final Dialog dialog = super.onCreateDialog(savedInstanceState);
|
||||
timeSettingsBinding = DialogTimeSettingsBinding.inflate(LayoutInflater.from(getContext()));
|
||||
public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) {
|
||||
timeSettingsBinding = DialogTimeSettingsBinding.inflate(inflater, container, false);
|
||||
|
||||
timeSettingsBinding.cbCustomFormat.setOnCheckedChangeListener(this);
|
||||
timeSettingsBinding.cbCustomFormat.setChecked(customDateTimeFormatEnabled);
|
||||
timeSettingsBinding.etCustomFormat.setText(customDateTimeFormat);
|
||||
|
||||
timeSettingsBinding.cbCustomFormat.setChecked(settingsHelper.getBoolean(Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED));
|
||||
timeSettingsBinding.etCustomFormat.setText(settingsHelper.getString(Constants.CUSTOM_DATE_TIME_FORMAT));
|
||||
|
||||
final String[] dateTimeFormat = settingsHelper.getString(Constants.DATE_TIME_SELECTION).split(";"); // output = time;separator;date
|
||||
final String[] dateTimeFormat = dateTimeSelection.split(";"); // output = time;separator;date
|
||||
timeSettingsBinding.spTimeFormat.setSelection(Integer.parseInt(dateTimeFormat[0]));
|
||||
timeSettingsBinding.spSeparator.setSelection(Integer.parseInt(dateTimeFormat[1]));
|
||||
timeSettingsBinding.spDateFormat.setSelection(Integer.parseInt(dateTimeFormat[2]));
|
||||
|
|
@ -67,8 +74,7 @@ public final class TimeSettingsDialog extends DialogFragment implements AdapterV
|
|||
timeSettingsBinding.btnConfirm.setOnClickListener(this);
|
||||
timeSettingsBinding.btnInfo.setOnClickListener(this);
|
||||
|
||||
dialog.setContentView(timeSettingsBinding.getRoot());
|
||||
return dialog;
|
||||
return timeSettingsBinding.getRoot();
|
||||
}
|
||||
|
||||
private void refreshTimeFormat() {
|
||||
|
|
@ -87,7 +93,8 @@ public final class TimeSettingsDialog extends DialogFragment implements AdapterV
|
|||
+ (isSwapTime ? dateStr : timeStr);
|
||||
|
||||
timeSettingsBinding.btnConfirm.setEnabled(true);
|
||||
timeSettingsBinding.timePreview.setText((currentFormat = new SimpleDateFormat(selectedFormat, LocaleUtils.getCurrentLocale())).format(magicDate));
|
||||
currentFormat = new SimpleDateFormat(selectedFormat, LocaleUtils.getCurrentLocale());
|
||||
timeSettingsBinding.timePreview.setText(currentFormat.format(magicDate));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -96,8 +103,8 @@ public final class TimeSettingsDialog extends DialogFragment implements AdapterV
|
|||
//noinspection ConstantConditions
|
||||
final String string = timeSettingsBinding.etCustomFormat.getText().toString();
|
||||
if (Utils.isEmpty(string)) throw new NullPointerException();
|
||||
|
||||
final String format = (currentFormat = new SimpleDateFormat(string, LocaleUtils.getCurrentLocale())).format(magicDate);
|
||||
currentFormat = new SimpleDateFormat(string, LocaleUtils.getCurrentLocale());
|
||||
final String format = currentFormat.format(magicDate);
|
||||
timeSettingsBinding.timePreview.setText(format);
|
||||
|
||||
timeSettingsBinding.btnConfirm.setEnabled(true);
|
||||
|
|
@ -115,6 +122,8 @@ public final class TimeSettingsDialog extends DialogFragment implements AdapterV
|
|||
@Override
|
||||
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
|
||||
if (buttonView == timeSettingsBinding.cbCustomFormat) {
|
||||
final View parent = (View) timeSettingsBinding.etCustomFormat.getParent();
|
||||
parent.setVisibility(isChecked ? View.VISIBLE : View.GONE);
|
||||
timeSettingsBinding.etCustomFormat.setEnabled(isChecked);
|
||||
timeSettingsBinding.btnInfo.setEnabled(isChecked);
|
||||
|
||||
|
|
@ -134,26 +143,16 @@ public final class TimeSettingsDialog extends DialogFragment implements AdapterV
|
|||
@Override
|
||||
public void onClick(final View v) {
|
||||
if (v == timeSettingsBinding.btnConfirm) {
|
||||
final String formatSelection;
|
||||
|
||||
final boolean isCustomFormat = timeSettingsBinding.cbCustomFormat.isChecked();
|
||||
|
||||
if (isCustomFormat) {
|
||||
//noinspection ConstantConditions
|
||||
formatSelection = timeSettingsBinding.etCustomFormat.getText().toString();
|
||||
settingsHelper.putString(Constants.CUSTOM_DATE_TIME_FORMAT, formatSelection);
|
||||
} else {
|
||||
formatSelection = timeSettingsBinding.spTimeFormat.getSelectedItemPosition() + ";"
|
||||
+ timeSettingsBinding.spSeparator.getSelectedItemPosition() + ';'
|
||||
+ timeSettingsBinding.spDateFormat.getSelectedItemPosition(); // time;separator;date
|
||||
|
||||
settingsHelper.putString(Constants.DATE_TIME_FORMAT, selectedFormat);
|
||||
settingsHelper.putString(Constants.DATE_TIME_SELECTION, formatSelection);
|
||||
final Editable etCustomFormatText = timeSettingsBinding.etCustomFormat.getText();
|
||||
if (onConfirmListener != null) {
|
||||
onConfirmListener.onConfirm(timeSettingsBinding.cbCustomFormat.isChecked(),
|
||||
etCustomFormatText == null ? null : etCustomFormatText.toString(),
|
||||
timeSettingsBinding.spTimeFormat.getSelectedItemPosition(),
|
||||
timeSettingsBinding.spSeparator.getSelectedItemPosition(),
|
||||
timeSettingsBinding.spDateFormat.getSelectedItemPosition(),
|
||||
selectedFormat,
|
||||
currentFormat);
|
||||
}
|
||||
|
||||
settingsHelper.putBoolean(Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED, isCustomFormat);
|
||||
|
||||
Utils.datetimeParser = (SimpleDateFormat) currentFormat.clone();
|
||||
dismiss();
|
||||
} else if (v == timeSettingsBinding.btnInfo) {
|
||||
timeSettingsBinding.customPanel.setVisibility(timeSettingsBinding.customPanel
|
||||
|
|
@ -162,6 +161,14 @@ public final class TimeSettingsDialog extends DialogFragment implements AdapterV
|
|||
}
|
||||
}
|
||||
|
||||
public interface OnConfirmListener {
|
||||
void onConfirm(boolean isCustomFormat,
|
||||
String formatSelection,
|
||||
int spTimeFormatSelectedItemPosition,
|
||||
int spSeparatorSelectedItemPosition,
|
||||
int spDateFormatSelectedItemPosition, final String selectedFormat, final SimpleDateFormat currentFormat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(final AdapterView<?> parent) { }
|
||||
|
||||
|
|
@ -170,4 +177,17 @@ public final class TimeSettingsDialog extends DialogFragment implements AdapterV
|
|||
|
||||
@Override
|
||||
public void afterTextChanged(final Editable s) { }
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
final Dialog dialog = getDialog();
|
||||
if (dialog == null) return;
|
||||
final Window window = dialog.getWindow();
|
||||
if (window == null) return;
|
||||
final WindowManager.LayoutParams params = window.getAttributes();
|
||||
params.width = ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
window.setAttributes(params);
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,8 @@ import android.os.Bundle;
|
|||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
|
|
@ -19,11 +21,11 @@ import android.widget.Toast;
|
|||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.AppCompatImageView;
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentContainerView;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
|
@ -49,7 +51,6 @@ import java.util.List;
|
|||
|
||||
import awais.instagrabber.R;
|
||||
import awais.instagrabber.activities.PostViewer;
|
||||
import awais.instagrabber.activities.ProfileViewer;
|
||||
import awais.instagrabber.adapters.DirectMessageItemsAdapter;
|
||||
import awais.instagrabber.asyncs.ImageUploader;
|
||||
import awais.instagrabber.asyncs.direct_messages.DirectMessageInboxThreadFetcher;
|
||||
|
|
@ -61,7 +62,6 @@ import awais.instagrabber.interfaces.MentionClickListener;
|
|||
import awais.instagrabber.models.ImageUploadOptions;
|
||||
import awais.instagrabber.models.PostModel;
|
||||
import awais.instagrabber.models.ProfileModel;
|
||||
import awais.instagrabber.models.StoryModel;
|
||||
import awais.instagrabber.models.direct_messages.DirectItemModel;
|
||||
import awais.instagrabber.models.direct_messages.InboxThreadModel;
|
||||
import awais.instagrabber.models.enums.DirectItemType;
|
||||
|
|
@ -74,7 +74,7 @@ public class DirectMessageThreadFragment extends Fragment {
|
|||
private static final String TAG = "DirectMessagesThreadFmt";
|
||||
private static final int PICK_IMAGE = 100;
|
||||
|
||||
private FragmentActivity fragmentActivity;
|
||||
private AppCompatActivity fragmentActivity;
|
||||
private String threadId, threadTitle;
|
||||
private String cursor;
|
||||
private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
|
||||
|
|
@ -83,7 +83,7 @@ public class DirectMessageThreadFragment extends Fragment {
|
|||
private DirectItemModelListViewModel listViewModel;
|
||||
private DirectItemModel directItemModel;
|
||||
private RecyclerView messageList;
|
||||
private AppCompatImageView dmInfo;
|
||||
// private AppCompatImageView dmInfo;
|
||||
private boolean hasSentSomething, hasDeletedSomething;
|
||||
private boolean hasOlder = true;
|
||||
|
||||
|
|
@ -157,7 +157,8 @@ public class DirectMessageThreadFragment extends Fragment {
|
|||
@Override
|
||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
fragmentActivity = requireActivity();
|
||||
fragmentActivity = (AppCompatActivity) requireActivity();
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -165,8 +166,8 @@ public class DirectMessageThreadFragment extends Fragment {
|
|||
final ViewGroup container,
|
||||
final Bundle savedInstanceState) {
|
||||
binding = FragmentDirectMessagesThreadBinding.inflate(inflater, container, false);
|
||||
CoordinatorLayout containerTwo = (CoordinatorLayout) container.getParent();
|
||||
dmInfo = containerTwo.findViewById(R.id.dmInfo);
|
||||
final FragmentContainerView containerTwo = (FragmentContainerView) container.getParent();
|
||||
// dmInfo = containerTwo.findViewById(R.id.dmInfo);
|
||||
final LinearLayout root = binding.getRoot();
|
||||
listViewModel = new ViewModelProvider(fragmentActivity).get(DirectItemModelListViewModel.class);
|
||||
if (getArguments() == null) {
|
||||
|
|
@ -177,6 +178,10 @@ public class DirectMessageThreadFragment extends Fragment {
|
|||
threadId = DirectMessageThreadFragmentArgs.fromBundle(getArguments()).getThreadId();
|
||||
}
|
||||
threadTitle = DirectMessageThreadFragmentArgs.fromBundle(getArguments()).getTitle();
|
||||
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setTitle(threadTitle);
|
||||
}
|
||||
binding.swipeRefreshLayout.setEnabled(false);
|
||||
messageList = binding.messageList;
|
||||
messageList.setHasFixedSize(true);
|
||||
|
|
@ -192,11 +197,11 @@ public class DirectMessageThreadFragment extends Fragment {
|
|||
}
|
||||
new DirectMessageInboxThreadFetcher(threadId, UserInboxDirection.OLDER, cursor, fetchListener).execute(); // serial because we don't want messages to be randomly ordered
|
||||
}));
|
||||
dmInfo.setOnClickListener(v -> {
|
||||
final NavDirections action =
|
||||
DirectMessageThreadFragmentDirections.actionDMThreadFragmentToDMSettingsFragment(threadId, threadTitle);
|
||||
NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(action);
|
||||
});
|
||||
// dmInfo.setOnClickListener(v -> {
|
||||
// final NavDirections action =
|
||||
// DirectMessageThreadFragmentDirections.actionDMThreadFragmentToDMSettingsFragment(threadId, threadTitle);
|
||||
// NavHostFragment.findNavController(DirectMessageThreadFragment.this).navigate(action);
|
||||
// });
|
||||
|
||||
final DialogInterface.OnClickListener onDialogListener = (dialogInterface, which) -> {
|
||||
if (which == 0) {
|
||||
|
|
@ -250,12 +255,11 @@ public class DirectMessageThreadFragment extends Fragment {
|
|||
default:
|
||||
Log.d("austin_debug", "unsupported type " + itemType);
|
||||
}
|
||||
}
|
||||
else if (which == 1) {
|
||||
} else if (which == 1) {
|
||||
sendText(null, directItemModel.getItemId(), directItemModel.isLiked());
|
||||
}
|
||||
else if (which == 2) {
|
||||
if (String.valueOf(directItemModel.getUserId()).equals(myId)) new Unsend().execute();
|
||||
} else if (which == 2) {
|
||||
if (String.valueOf(directItemModel.getUserId()).equals(myId))
|
||||
new Unsend().execute();
|
||||
else searchUsername(getUser(directItemModel.getUserId()).getUsername());
|
||||
}
|
||||
};
|
||||
|
|
@ -320,6 +324,12 @@ public class DirectMessageThreadFragment extends Fragment {
|
|||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareOptionsMenu(@NonNull final Menu menu) {
|
||||
final MenuItem item = menu.findItem(R.id.favourites);
|
||||
item.setVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
|
@ -423,7 +433,9 @@ public class DirectMessageThreadFragment extends Fragment {
|
|||
}
|
||||
|
||||
private void searchUsername(final String text) {
|
||||
startActivity(new Intent(requireContext(), ProfileViewer.class).putExtra(Constants.EXTRAS_USERNAME, text));
|
||||
// startActivity(new Intent(requireContext(), ProfileViewer.class).putExtra(Constants.EXTRAS_USERNAME, text));
|
||||
final NavDirections action = DirectMessageThreadFragmentDirections.actionDirectMessagesThreadFragmentToProfileFragment("@" + text);
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
}
|
||||
|
||||
public static class DirectItemModelListViewModel extends ViewModel {
|
||||
|
|
@ -434,8 +446,7 @@ public class DirectMessageThreadFragment extends Fragment {
|
|||
if (list == null) {
|
||||
list = new MutableLiveData<>();
|
||||
isEmpty = true;
|
||||
}
|
||||
else isEmpty = false;
|
||||
} else isEmpty = false;
|
||||
return list;
|
||||
}
|
||||
|
||||
|
|
@ -451,10 +462,10 @@ public class DirectMessageThreadFragment extends Fragment {
|
|||
|
||||
class Unsend extends AsyncTask<Void, Void, Void> {
|
||||
protected Void doInBackground(Void... lmao) {
|
||||
final String url = "https://i.instagram.com/api/v1/direct_v2/threads/"+threadId+"/items/"+directItemModel.getItemId()+"/delete/";
|
||||
final String url = "https://i.instagram.com/api/v1/direct_v2/threads/" + threadId + "/items/" + directItemModel.getItemId() + "/delete/";
|
||||
try {
|
||||
String urlParameters = "_csrftoken=" + cookie.split("csrftoken=")[1].split(";")[0]
|
||||
+"&_uuid=" + Utils.settingsHelper.getString(Constants.DEVICE_UUID);
|
||||
+ "&_uuid=" + Utils.settingsHelper.getString(Constants.DEVICE_UUID);
|
||||
final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
|
||||
urlConnection.setRequestMethod("POST");
|
||||
urlConnection.setUseCaches(false);
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ public class DiscoverFragment extends Fragment {
|
|||
private String discoverEndMaxId;
|
||||
private ActionMode actionMode;
|
||||
private DiscoverItemViewModel discoverItemViewModel;
|
||||
private boolean shouldRefresh = true;
|
||||
|
||||
private final FetchListener<DiscoverTopicModel> topicFetchListener = new FetchListener<DiscoverTopicModel>() {
|
||||
@Override
|
||||
|
|
@ -154,14 +155,20 @@ public class DiscoverFragment extends Fragment {
|
|||
final ViewGroup container,
|
||||
final Bundle savedInstanceState) {
|
||||
if (root != null) {
|
||||
shouldRefresh = false;
|
||||
return root;
|
||||
}
|
||||
binding = FragmentDiscoverBinding.inflate(inflater, container, false);
|
||||
root = binding.getRoot();
|
||||
setupExplore();
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
|
||||
if (!shouldRefresh) return;
|
||||
setupExplore();
|
||||
}
|
||||
|
||||
private void setupExplore() {
|
||||
discoverItemViewModel = new ViewModelProvider(fragmentActivity).get(DiscoverItemViewModel.class);
|
||||
final GridAutofitLayoutManager layoutManager = new GridAutofitLayoutManager(requireContext(), Utils.convertDpToPx(110));
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ public class FeedFragment extends Fragment {
|
|||
private String feedEndCursor = null;
|
||||
private FeedViewModel feedViewModel;
|
||||
private VideoAwareRecyclerScroller videoAwareRecyclerScroller;
|
||||
private boolean shouldRefresh = true;
|
||||
|
||||
private final FetchListener<FeedModel[]> feedFetchListener = new FetchListener<FeedModel[]>() {
|
||||
@Override
|
||||
|
|
@ -164,14 +165,21 @@ public class FeedFragment extends Fragment {
|
|||
final ViewGroup container,
|
||||
final Bundle savedInstanceState) {
|
||||
if (root != null) {
|
||||
shouldRefresh = false;
|
||||
return root;
|
||||
}
|
||||
binding = FragmentFeedBinding.inflate(inflater, container, false);
|
||||
root = binding.getRoot();
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
|
||||
if (!shouldRefresh) return;
|
||||
// setupActionBar();
|
||||
setupFeedStories();
|
||||
setupFeed();
|
||||
return root;
|
||||
shouldRefresh = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import android.os.Looper;
|
|||
import android.text.SpannableStringBuilder;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.text.style.StyleSpan;
|
||||
import android.util.Log;
|
||||
import android.view.ActionMode;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
|
|
@ -29,8 +30,10 @@ import androidx.core.view.ViewCompat;
|
|||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import awais.instagrabber.R;
|
||||
import awais.instagrabber.activities.FollowViewer;
|
||||
|
|
@ -47,17 +50,24 @@ import awais.instagrabber.customviews.PrimaryActionModeCallback;
|
|||
import awais.instagrabber.customviews.PrimaryActionModeCallback.CallbacksHelper;
|
||||
import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager;
|
||||
import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration;
|
||||
import awais.instagrabber.customviews.helpers.RecyclerLazyLoader;
|
||||
import awais.instagrabber.databinding.FragmentProfileBinding;
|
||||
import awais.instagrabber.fragments.main.viewmodels.ProfilePostsViewModel;
|
||||
import awais.instagrabber.interfaces.FetchListener;
|
||||
import awais.instagrabber.models.PostModel;
|
||||
import awais.instagrabber.models.ProfileModel;
|
||||
import awais.instagrabber.models.StoryModel;
|
||||
import awais.instagrabber.models.enums.DownloadMethod;
|
||||
import awais.instagrabber.models.enums.ItemGetType;
|
||||
import awais.instagrabber.services.ProfileService;
|
||||
import awais.instagrabber.repositories.responses.FriendshipRepositoryChangeResponseRootObject;
|
||||
import awais.instagrabber.services.FriendshipService;
|
||||
import awais.instagrabber.services.ServiceCallback;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.DataBox;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
import awaisomereport.LogCollector;
|
||||
|
||||
import static awais.instagrabber.utils.Utils.logCollector;
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||
|
||||
public class ProfileFragment extends Fragment {
|
||||
|
|
@ -74,8 +84,13 @@ public class ProfileFragment extends Fragment {
|
|||
private PostsAdapter postsAdapter;
|
||||
private ActionMode actionMode;
|
||||
private Handler usernameSettingHandler;
|
||||
private ProfileService profileService;
|
||||
|
||||
private FriendshipService friendshipService;
|
||||
private boolean shouldRefresh = true;
|
||||
private StoryModel[] storyModels;
|
||||
private boolean hasNextPage;
|
||||
private String endCursor;
|
||||
private AsyncTask<Void, Void, PostModel[]> currentlyExecuting;
|
||||
;
|
||||
private final Runnable usernameSettingRunnable = () -> {
|
||||
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
|
|
@ -118,11 +133,38 @@ public class ProfileFragment extends Fragment {
|
|||
}
|
||||
});
|
||||
|
||||
private final FetchListener<PostModel[]> postsFetchListener = new FetchListener<PostModel[]>() {
|
||||
@Override
|
||||
public void onResult(final PostModel[] result) {
|
||||
binding.swipeRefreshLayout.setRefreshing(false);
|
||||
if (result != null) {
|
||||
binding.mainPosts.post(() -> binding.mainPosts.setVisibility(View.VISIBLE));
|
||||
// final int oldSize = mainActivity.allItems.size();
|
||||
final List<PostModel> postModels = profilePostsViewModel.getList().getValue();
|
||||
final List<PostModel> finalList = postModels == null || postModels.isEmpty() ? new ArrayList<>() : new ArrayList<>(postModels);
|
||||
finalList.addAll(Arrays.asList(result));
|
||||
profilePostsViewModel.getList().postValue(finalList);
|
||||
PostModel model = null;
|
||||
if (result.length != 0) {
|
||||
model = result[result.length - 1];
|
||||
}
|
||||
if (model == null) return;
|
||||
endCursor = model.getEndCursor();
|
||||
hasNextPage = model.hasNextPage();
|
||||
model.setPageCursor(false, null);
|
||||
return;
|
||||
}
|
||||
binding.privatePage1.setImageResource(R.drawable.ic_cancel);
|
||||
binding.privatePage2.setText(R.string.empty_acc);
|
||||
binding.privatePage.setVisibility(View.VISIBLE);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
fragmentActivity = (MainActivity) requireActivity();
|
||||
profileService = ProfileService.getInstance();
|
||||
friendshipService = FriendshipService.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -130,6 +172,15 @@ public class ProfileFragment extends Fragment {
|
|||
final ViewGroup container,
|
||||
final Bundle savedInstanceState) {
|
||||
if (root != null) {
|
||||
if (getArguments() != null) {
|
||||
final ProfileFragmentArgs fragmentArgs = ProfileFragmentArgs.fromBundle(getArguments());
|
||||
if (!fragmentArgs.getUsername().equals(username)) {
|
||||
shouldRefresh = true;
|
||||
return root;
|
||||
}
|
||||
}
|
||||
setUsernameDelayed();
|
||||
shouldRefresh = false;
|
||||
return root;
|
||||
}
|
||||
binding = FragmentProfileBinding.inflate(inflater, container, false);
|
||||
|
|
@ -139,7 +190,9 @@ public class ProfileFragment extends Fragment {
|
|||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) {
|
||||
if (!shouldRefresh) return;
|
||||
init();
|
||||
shouldRefresh = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -162,12 +215,13 @@ public class ProfileFragment extends Fragment {
|
|||
setUsernameDelayed();
|
||||
}
|
||||
if (!isLoggedIn) {
|
||||
binding.privatePage1.setImageResource(R.drawable.ic_info);
|
||||
binding.privatePage1.setImageResource(R.drawable.ic_outline_info_24);
|
||||
binding.privatePage2.setText(R.string.no_acc);
|
||||
binding.privatePage.setVisibility(View.VISIBLE);
|
||||
return;
|
||||
}
|
||||
setupPosts();
|
||||
setupCommonListeners();
|
||||
fetchProfile();
|
||||
}
|
||||
|
||||
|
|
@ -205,18 +259,12 @@ public class ProfileFragment extends Fragment {
|
|||
private void fetchProfileDetails() {
|
||||
new ProfileFetcher(username.substring(1), profileModel -> {
|
||||
this.profileModel = profileModel;
|
||||
new PostsFetcher(profileModel.getId(),
|
||||
null,
|
||||
result -> profilePostsViewModel.getList().postValue(Arrays.asList(result)))
|
||||
.setUsername(profileModel.getUsername())
|
||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
setProfileDetails();
|
||||
|
||||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private void setProfileDetails() {
|
||||
setupCommonListeners();
|
||||
if (profileModel == null) {
|
||||
binding.swipeRefreshLayout.setRefreshing(false);
|
||||
Toast.makeText(requireContext(), R.string.error_loading_profile, Toast.LENGTH_SHORT).show();
|
||||
|
|
@ -225,12 +273,18 @@ public class ProfileFragment extends Fragment {
|
|||
binding.isVerified.setVisibility(profileModel.isVerified() ? View.VISIBLE : View.GONE);
|
||||
final String profileId = profileModel.getId();
|
||||
if (settingsHelper.getBoolean(Constants.STORIESIG)) {
|
||||
new iStoryStatusFetcher(profileId, profileModel.getUsername(), false, false,
|
||||
(!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)), false,
|
||||
new iStoryStatusFetcher(
|
||||
profileId,
|
||||
profileModel.getUsername(),
|
||||
false,
|
||||
false,
|
||||
(!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)),
|
||||
false,
|
||||
result -> {
|
||||
// mainActivity.storyModels = result;
|
||||
// if (result != null && result.length > 0)
|
||||
// binding.mainProfileImage.setStoriesBorder();
|
||||
storyModels = result;
|
||||
if (result != null && result.length > 0) {
|
||||
binding.mainProfileImage.setStoriesBorder();
|
||||
}
|
||||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
|
||||
new HighlightsFetcher(profileId, (!isLoggedIn && settingsHelper.getBoolean(Constants.STORIESIG)), result -> {
|
||||
|
|
@ -412,9 +466,7 @@ public class ProfileFragment extends Fragment {
|
|||
} else {
|
||||
binding.swipeRefreshLayout.setRefreshing(true);
|
||||
binding.mainPosts.setVisibility(View.VISIBLE);
|
||||
// currentlyExecuting = new PostsFetcher(profileId, postsFetchListener)
|
||||
// .setUsername(profileModel.getUsername())
|
||||
// .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
fetchPosts();
|
||||
}
|
||||
} else {
|
||||
binding.mainFollowers.setClickable(false);
|
||||
|
|
@ -451,14 +503,53 @@ public class ProfileFragment extends Fragment {
|
|||
new DataBox.FavoriteModel(username, System.currentTimeMillis(),
|
||||
username.replaceAll("^@", "")));
|
||||
}
|
||||
// onRefresh();
|
||||
fetchProfileDetails();
|
||||
return;
|
||||
}
|
||||
profileService.followProfile(username);
|
||||
if (profileModel.getFollowing() || profileModel.getRequested()) {
|
||||
friendshipService.unfollow(
|
||||
userIdFromCookie,
|
||||
profileModel.getId(),
|
||||
Utils.getCsrfTokenFromCookie(cookie),
|
||||
new ServiceCallback<FriendshipRepositoryChangeResponseRootObject>() {
|
||||
@Override
|
||||
public void onSuccess(final FriendshipRepositoryChangeResponseRootObject result) {
|
||||
Log.d(TAG, "Unfollow success: " + result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable t) {
|
||||
Log.e(TAG, "Error unfollowing", t);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
friendshipService.follow(
|
||||
userIdFromCookie,
|
||||
profileModel.getId(),
|
||||
Utils.getCsrfTokenFromCookie(cookie),
|
||||
new ServiceCallback<FriendshipRepositoryChangeResponseRootObject>() {
|
||||
@Override
|
||||
public void onSuccess(final FriendshipRepositoryChangeResponseRootObject result) {
|
||||
Log.d(TAG, "Follow success: " + result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable t) {
|
||||
Log.e(TAG, "Error following", t);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// binding.btnRestrict.setOnClickListener(profileActionListener);
|
||||
// binding.btnBlock.setOnClickListener(profileActionListener);
|
||||
binding.btnRestrict.setOnClickListener(v -> {
|
||||
if (!isLoggedIn) return;
|
||||
// restrict
|
||||
// new ProfileAction().execute("restrict");
|
||||
});
|
||||
binding.btnBlock.setOnClickListener(v -> {
|
||||
if (!isLoggedIn) return;
|
||||
// new MainHelper.ProfileAction().execute("block");
|
||||
});
|
||||
binding.btnSaved.setOnClickListener(v -> startActivity(new Intent(requireContext(), SavedViewer.class)
|
||||
.putExtra(Constants.EXTRAS_INDEX, "$" + profileModel.getId())
|
||||
.putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername())
|
||||
|
|
@ -516,8 +607,34 @@ public class ProfileFragment extends Fragment {
|
|||
onBackPressedDispatcher.addCallback(onBackPressedCallback);
|
||||
return true;
|
||||
});
|
||||
binding.mainPosts.setAdapter(postsAdapter);
|
||||
profilePostsViewModel.getList().observe(fragmentActivity, postsAdapter::submitList);
|
||||
binding.mainPosts.setAdapter(postsAdapter);
|
||||
final RecyclerLazyLoader lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> {
|
||||
if (!hasNextPage) return;
|
||||
binding.swipeRefreshLayout.setRefreshing(true);
|
||||
fetchPosts();
|
||||
endCursor = null;
|
||||
});
|
||||
binding.mainPosts.addOnScrollListener(lazyLoader);
|
||||
}
|
||||
|
||||
private void fetchPosts() {
|
||||
stopCurrentExecutor();
|
||||
currentlyExecuting = new PostsFetcher(profileModel.getId(), endCursor, postsFetchListener)
|
||||
.setUsername(profileModel.getUsername())
|
||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
public void stopCurrentExecutor() {
|
||||
if (currentlyExecuting != null) {
|
||||
try {
|
||||
currentlyExecuting.cancel(true);
|
||||
} catch (final Exception e) {
|
||||
if (logCollector != null)
|
||||
logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor");
|
||||
Log.e(TAG, "", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkAndResetAction() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
package awais.instagrabber.fragments.settings;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import awais.instagrabber.activities.MainActivity;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.LocaleUtils;
|
||||
|
||||
public abstract class BasePreferencesFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
private boolean shouldRecreate = false;
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) {
|
||||
final PreferenceManager preferenceManager = getPreferenceManager();
|
||||
preferenceManager.setSharedPreferencesName("settings");
|
||||
preferenceManager.getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
|
||||
final PreferenceScreen screen = preferenceManager.createPreferenceScreen(requireContext());
|
||||
setupPreferenceScreen(screen);
|
||||
setPreferenceScreen(screen);
|
||||
}
|
||||
|
||||
abstract void setupPreferenceScreen(PreferenceScreen screen);
|
||||
|
||||
protected void shouldRecreate() {
|
||||
this.shouldRecreate = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
|
||||
if (!shouldRecreate) return;
|
||||
final MainActivity activity = (MainActivity) getActivity();
|
||||
if (activity == null) return;
|
||||
if (key.equals(Constants.APP_LANGUAGE)) {
|
||||
LocaleUtils.setLocale(activity.getBaseContext());
|
||||
}
|
||||
shouldRecreate = false;
|
||||
activity.recreate();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
package awais.instagrabber.fragments.settings;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.navigation.NavDirections;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import awais.instagrabber.R;
|
||||
import awais.instagrabber.activities.Login;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||
|
||||
public class MorePreferencesFragment extends BasePreferencesFragment {
|
||||
private final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||
|
||||
@Override
|
||||
void setupPreferenceScreen(final PreferenceScreen screen) {
|
||||
screen.addPreference(new MoreHeaderPreference(requireContext()));
|
||||
|
||||
final PreferenceCategory accountCategory = new PreferenceCategory(requireContext());
|
||||
accountCategory.setTitle("Account");
|
||||
accountCategory.setIconSpaceReserved(false);
|
||||
screen.addPreference(accountCategory);
|
||||
final boolean isLoggedIn = !Utils.isEmpty(cookie) && Utils.getUserIdFromCookie(cookie) != null;
|
||||
screen.addPreference(getPreference(isLoggedIn ? R.string.relogin : R.string.login,
|
||||
isLoggedIn ? R.string.relogin_summary : -1,
|
||||
-1,
|
||||
preference -> {
|
||||
startActivityForResult(new Intent(requireContext(), Login.class), Constants.LOGIN_RESULT_CODE);
|
||||
return true;
|
||||
}));
|
||||
if (isLoggedIn) {
|
||||
screen.addPreference(getPreference(R.string.logout, -1, preference -> {
|
||||
Utils.setupCookies("LOGOUT");
|
||||
shouldRecreate();
|
||||
Toast.makeText(requireContext(), R.string.logout_success, Toast.LENGTH_SHORT).show();
|
||||
settingsHelper.putString(Constants.COOKIE, "");
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
|
||||
final PreferenceCategory defaultCategory = new PreferenceCategory(requireContext());
|
||||
screen.addPreference(defaultCategory);
|
||||
defaultCategory.addPreference(getPreference(R.string.action_notif, R.drawable.ic_not_liked, preference -> false));
|
||||
defaultCategory.addPreference(getPreference(R.string.action_settings, R.drawable.ic_outline_settings_24, preference -> {
|
||||
final NavDirections navDirections = MorePreferencesFragmentDirections.actionMorePreferencesFragmentToSettingsPreferencesFragment();
|
||||
NavHostFragment.findNavController(this).navigate(navDirections);
|
||||
return true;
|
||||
}));
|
||||
defaultCategory.addPreference(getPreference(R.string.action_about, R.drawable.ic_outline_info_24, preference -> false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(final int requestCode, final int resultCode, @Nullable final Intent data) {
|
||||
if (resultCode == Constants.LOGIN_RESULT_CODE) {
|
||||
if (data == null) return;
|
||||
final String cookie = data.getStringExtra("cookie");
|
||||
Utils.setupCookies(cookie);
|
||||
shouldRecreate();
|
||||
Toast.makeText(requireContext(), R.string.login_success_loading_cookies, Toast.LENGTH_SHORT).show();
|
||||
settingsHelper.putString(Constants.COOKIE, cookie);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Preference getPreference(final int title,
|
||||
final int icon,
|
||||
final Preference.OnPreferenceClickListener clickListener) {
|
||||
return getPreference(title, -1, icon, clickListener);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Preference getPreference(final int title,
|
||||
final int summary,
|
||||
final int icon,
|
||||
final Preference.OnPreferenceClickListener clickListener) {
|
||||
final Preference preference = new Preference(requireContext());
|
||||
if (icon <= 0) preference.setIconSpaceReserved(false);
|
||||
if (icon > 0) preference.setIcon(icon);
|
||||
preference.setTitle(title);
|
||||
if (summary > 0) {
|
||||
preference.setSummary(summary);
|
||||
}
|
||||
preference.setOnPreferenceClickListener(clickListener);
|
||||
return preference;
|
||||
}
|
||||
|
||||
public static class MoreHeaderPreference extends Preference {
|
||||
|
||||
public MoreHeaderPreference(final Context context) {
|
||||
super(context);
|
||||
setLayoutResource(R.layout.pref_more_header);
|
||||
setSelectable(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,285 @@
|
|||
package awais.instagrabber.fragments.settings;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.AppCompatButton;
|
||||
import androidx.appcompat.widget.AppCompatTextView;
|
||||
import androidx.preference.DropDownPreference;
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
import androidx.preference.SwitchPreferenceCompat;
|
||||
|
||||
import com.google.android.material.switchmaterial.SwitchMaterial;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import awais.instagrabber.R;
|
||||
import awais.instagrabber.dialogs.TimeSettingsDialog;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.DirectoryChooser;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
|
||||
import static awais.instagrabber.utils.Constants.FOLDER_PATH;
|
||||
import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO;
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||
|
||||
public class SettingsPreferencesFragment extends BasePreferencesFragment {
|
||||
private static final String TAG = "SettingsPrefsFrag";
|
||||
private static AppCompatTextView customPathTextView;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareOptionsMenu(@NonNull final Menu menu) {
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
final MenuItem item = menu.findItem(R.id.favourites);
|
||||
item.setVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
void setupPreferenceScreen(final PreferenceScreen screen) {
|
||||
screen.addPreference(getLanguagePreference());
|
||||
screen.addPreference(getThemePreference());
|
||||
screen.addPreference(getAmoledThemePreference());
|
||||
screen.addPreference(getDownloadUserFolderPreference());
|
||||
screen.addPreference(getSaveToCustomFolderPreference());
|
||||
screen.addPreference(getAutoPlayVideosPreference());
|
||||
screen.addPreference(getAlwaysMuteVideosPreference());
|
||||
screen.addPreference(getPostTimePreference());
|
||||
|
||||
final PreferenceCategory loggedInUsersPreferenceCategory = new PreferenceCategory(requireContext());
|
||||
loggedInUsersPreferenceCategory.setIconSpaceReserved(false);
|
||||
screen.addPreference(loggedInUsersPreferenceCategory);
|
||||
loggedInUsersPreferenceCategory.setTitle(R.string.login_settings);
|
||||
loggedInUsersPreferenceCategory.addPreference(getMarkStoriesSeenPreference());
|
||||
loggedInUsersPreferenceCategory.addPreference(getEnableActivityNotificationsPreference());
|
||||
|
||||
final PreferenceCategory anonUsersPreferenceCategory = new PreferenceCategory(requireContext());
|
||||
anonUsersPreferenceCategory.setIconSpaceReserved(false);
|
||||
screen.addPreference(anonUsersPreferenceCategory);
|
||||
anonUsersPreferenceCategory.setTitle(R.string.anonymous_settings);
|
||||
anonUsersPreferenceCategory.addPreference(getUseInstaDpPreference());
|
||||
anonUsersPreferenceCategory.addPreference(getUseStoriesIgPreference());
|
||||
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private DropDownPreference getLanguagePreference() {
|
||||
final DropDownPreference preference = new DropDownPreference(requireContext());
|
||||
preference.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance());
|
||||
final int length = getResources().getStringArray(R.array.languages).length;
|
||||
final String[] values = new String[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
values[i] = String.valueOf(i);
|
||||
}
|
||||
preference.setKey(Constants.APP_LANGUAGE);
|
||||
preference.setTitle(R.string.select_language);
|
||||
preference.setEntries(R.array.languages);
|
||||
preference.setIconSpaceReserved(false);
|
||||
preference.setEntryValues(values);
|
||||
preference.setOnPreferenceChangeListener((preference1, newValue) -> {
|
||||
shouldRecreate();
|
||||
return true;
|
||||
});
|
||||
return preference;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private DropDownPreference getThemePreference() {
|
||||
final DropDownPreference preference = new DropDownPreference(requireContext());
|
||||
preference.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance());
|
||||
final int length = getResources().getStringArray(R.array.theme_presets).length;
|
||||
final String[] values = new String[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
values[i] = String.valueOf(i);
|
||||
}
|
||||
preference.setKey(Constants.APP_THEME);
|
||||
preference.setTitle(R.string.theme_settings);
|
||||
preference.setEntries(R.array.theme_presets);
|
||||
preference.setIconSpaceReserved(false);
|
||||
preference.setEntryValues(values);
|
||||
preference.setOnPreferenceChangeListener((preference1, newValue) -> {
|
||||
shouldRecreate();
|
||||
return true;
|
||||
});
|
||||
return preference;
|
||||
}
|
||||
|
||||
private SwitchPreferenceCompat getAmoledThemePreference() {
|
||||
final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(requireContext());
|
||||
preference.setKey(Constants.AMOLED_THEME);
|
||||
preference.setTitle(R.string.use_amoled_dark_theme);
|
||||
preference.setIconSpaceReserved(false);
|
||||
preference.setOnPreferenceChangeListener((preference1, newValue) -> {
|
||||
final boolean isNight = Utils.isNight(requireContext(), settingsHelper.getThemeCode(true));
|
||||
if (isNight) shouldRecreate();
|
||||
return true;
|
||||
});
|
||||
return preference;
|
||||
}
|
||||
|
||||
private Preference getDownloadUserFolderPreference() {
|
||||
final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(requireContext());
|
||||
preference.setKey(Constants.DOWNLOAD_USER_FOLDER);
|
||||
preference.setTitle("Download to username folder");
|
||||
preference.setSummary(R.string.download_user_folder);
|
||||
preference.setIconSpaceReserved(false);
|
||||
return preference;
|
||||
}
|
||||
|
||||
private Preference getSaveToCustomFolderPreference() {
|
||||
return new SaveToCustomFolderPreference(requireContext(), (resultCallback) -> {
|
||||
new DirectoryChooser()
|
||||
.setInitialDirectory(settingsHelper.getString(FOLDER_PATH))
|
||||
.setInteractionListener(path -> {
|
||||
settingsHelper.putString(FOLDER_PATH, path);
|
||||
resultCallback.onResult(path);
|
||||
})
|
||||
.show(getParentFragmentManager(), null);
|
||||
});
|
||||
}
|
||||
|
||||
private Preference getAutoPlayVideosPreference() {
|
||||
final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(requireContext());
|
||||
preference.setKey(Constants.AUTOPLAY_VIDEOS);
|
||||
preference.setTitle(R.string.post_viewer_autoplay_video);
|
||||
preference.setIconSpaceReserved(false);
|
||||
return preference;
|
||||
}
|
||||
|
||||
private Preference getAlwaysMuteVideosPreference() {
|
||||
final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(requireContext());
|
||||
preference.setKey(Constants.MUTED_VIDEOS);
|
||||
preference.setTitle(R.string.post_viewer_muted_autoplay);
|
||||
preference.setIconSpaceReserved(false);
|
||||
return preference;
|
||||
}
|
||||
|
||||
private Preference getMarkStoriesSeenPreference() {
|
||||
final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(requireContext());
|
||||
preference.setKey(Constants.MARK_AS_SEEN);
|
||||
preference.setTitle(R.string.mark_as_seen_setting);
|
||||
preference.setSummary(R.string.mark_as_seen_setting_summary);
|
||||
preference.setIconSpaceReserved(false);
|
||||
return preference;
|
||||
}
|
||||
|
||||
private Preference getEnableActivityNotificationsPreference() {
|
||||
final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(requireContext());
|
||||
preference.setKey(Constants.CHECK_ACTIVITY);
|
||||
preference.setTitle(R.string.activity_setting);
|
||||
preference.setIconSpaceReserved(false);
|
||||
return preference;
|
||||
}
|
||||
|
||||
private Preference getUseInstaDpPreference() {
|
||||
final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(requireContext());
|
||||
preference.setKey(Constants.INSTADP);
|
||||
preference.setTitle(R.string.instadp_settings);
|
||||
preference.setIconSpaceReserved(false);
|
||||
return preference;
|
||||
}
|
||||
|
||||
private Preference getUseStoriesIgPreference() {
|
||||
final SwitchPreferenceCompat preference = new SwitchPreferenceCompat(requireContext());
|
||||
preference.setKey(Constants.STORIESIG);
|
||||
preference.setTitle(R.string.storiesig_settings);
|
||||
preference.setIconSpaceReserved(false);
|
||||
return preference;
|
||||
}
|
||||
|
||||
private Preference getPostTimePreference() {
|
||||
final Preference preference = new Preference(requireContext());
|
||||
preference.setTitle(R.string.time_settings);
|
||||
preference.setIconSpaceReserved(false);
|
||||
preference.setOnPreferenceClickListener(preference1 -> {
|
||||
new TimeSettingsDialog(settingsHelper.getBoolean(Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED),
|
||||
settingsHelper.getString(Constants.CUSTOM_DATE_TIME_FORMAT),
|
||||
settingsHelper.getString(Constants.DATE_TIME_SELECTION),
|
||||
(isCustomFormat,
|
||||
formatSelection,
|
||||
spTimeFormatSelectedItemPosition,
|
||||
spSeparatorSelectedItemPosition,
|
||||
spDateFormatSelectedItemPosition,
|
||||
selectedFormat, currentFormat) -> {
|
||||
if (isCustomFormat) {
|
||||
settingsHelper.putString(Constants.CUSTOM_DATE_TIME_FORMAT, formatSelection);
|
||||
} else {
|
||||
final String formatSelectionUpdated = spTimeFormatSelectedItemPosition + ";"
|
||||
+ spSeparatorSelectedItemPosition + ';'
|
||||
+ spDateFormatSelectedItemPosition; // time;separator;date
|
||||
settingsHelper.putString(Constants.DATE_TIME_FORMAT, selectedFormat);
|
||||
settingsHelper.putString(Constants.DATE_TIME_SELECTION, formatSelectionUpdated);
|
||||
}
|
||||
settingsHelper.putBoolean(Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED, isCustomFormat);
|
||||
Utils.datetimeParser = (SimpleDateFormat) currentFormat.clone();
|
||||
}
|
||||
).show(getParentFragmentManager(), null);
|
||||
return true;
|
||||
});
|
||||
return preference;
|
||||
}
|
||||
|
||||
public static class SaveToCustomFolderPreference extends Preference {
|
||||
|
||||
private final OnSelectFolderButtonClickListener onSelectFolderButtonClickListener;
|
||||
private String key;
|
||||
|
||||
public SaveToCustomFolderPreference(final Context context, final OnSelectFolderButtonClickListener onSelectFolderButtonClickListener) {
|
||||
super(context);
|
||||
this.onSelectFolderButtonClickListener = onSelectFolderButtonClickListener;
|
||||
key = Constants.FOLDER_SAVE_TO;
|
||||
setLayoutResource(R.layout.pref_custom_folder);
|
||||
setKey(key);
|
||||
setTitle(R.string.save_to_folder);
|
||||
setIconSpaceReserved(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(final PreferenceViewHolder holder) {
|
||||
super.onBindViewHolder(holder);
|
||||
final SwitchMaterial cbSaveTo = (SwitchMaterial) holder.findViewById(R.id.cbSaveTo);
|
||||
final View buttonContainer = holder.findViewById(R.id.button_container);
|
||||
customPathTextView = (AppCompatTextView) holder.findViewById(R.id.custom_path);
|
||||
cbSaveTo.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
settingsHelper.putBoolean(FOLDER_SAVE_TO, isChecked);
|
||||
buttonContainer.setVisibility(isChecked ? View.VISIBLE : View.GONE);
|
||||
final String customPath = settingsHelper.getString(FOLDER_PATH);
|
||||
customPathTextView.setText(customPath);
|
||||
});
|
||||
final boolean savedToEnabled = settingsHelper.getBoolean(key);
|
||||
holder.itemView.setOnClickListener(v -> cbSaveTo.toggle());
|
||||
cbSaveTo.setChecked(savedToEnabled);
|
||||
buttonContainer.setVisibility(savedToEnabled ? View.VISIBLE : View.GONE);
|
||||
final AppCompatButton btnSaveTo = (AppCompatButton) holder.findViewById(R.id.btnSaveTo);
|
||||
btnSaveTo.setOnClickListener(v -> {
|
||||
if (onSelectFolderButtonClickListener == null) return;
|
||||
onSelectFolderButtonClickListener.onClick(result -> {
|
||||
if (Utils.isEmpty(result)) return;
|
||||
customPathTextView.setText(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public interface ResultCallback {
|
||||
void onResult(String result);
|
||||
}
|
||||
|
||||
public interface OnSelectFolderButtonClickListener {
|
||||
void onClick(ResultCallback resultCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
package awais.instagrabber.fragments.settings.helpers;
|
||||
|
||||
public class AutoSummaryDropDownPreference {
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package awais.instagrabber.repositories;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import awais.instagrabber.repositories.responses.FriendshipRepositoryChangeResponseRootObject;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.FieldMap;
|
||||
import retrofit2.http.FormUrlEncoded;
|
||||
import retrofit2.http.POST;
|
||||
import retrofit2.http.Path;
|
||||
|
||||
public interface FriendshipRepository {
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/api/v1/friendships/{action}/{id}/")
|
||||
Call<FriendshipRepositoryChangeResponseRootObject> change(@Path("action") String action,
|
||||
@Path("id") String id,
|
||||
@FieldMap Map<String, String> form);
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
package awais.instagrabber.repositories;
|
||||
|
||||
public interface ProfileRepository {
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
package awais.instagrabber.repositories.responses;
|
||||
|
||||
public class FriendshipRepositoryChangeResponseFriendshipStatus {
|
||||
private boolean following;
|
||||
private boolean followedBy;
|
||||
private boolean blocking;
|
||||
private boolean muting;
|
||||
private boolean isPrivate;
|
||||
private boolean incomingRequest;
|
||||
private boolean outgoingRequest;
|
||||
private boolean isBestie;
|
||||
|
||||
public FriendshipRepositoryChangeResponseFriendshipStatus(final boolean following,
|
||||
final boolean followedBy,
|
||||
final boolean blocking,
|
||||
final boolean muting,
|
||||
final boolean isPrivate,
|
||||
final boolean incomingRequest,
|
||||
final boolean outgoingRequest,
|
||||
final boolean isBestie) {
|
||||
this.following = following;
|
||||
this.followedBy = followedBy;
|
||||
this.blocking = blocking;
|
||||
this.muting = muting;
|
||||
this.isPrivate = isPrivate;
|
||||
this.incomingRequest = incomingRequest;
|
||||
this.outgoingRequest = outgoingRequest;
|
||||
this.isBestie = isBestie;
|
||||
}
|
||||
|
||||
public boolean isFollowing() {
|
||||
return following;
|
||||
}
|
||||
|
||||
public boolean isFollowedBy() {
|
||||
return followedBy;
|
||||
}
|
||||
|
||||
public boolean isBlocking() {
|
||||
return blocking;
|
||||
}
|
||||
|
||||
public boolean isMuting() {
|
||||
return muting;
|
||||
}
|
||||
|
||||
public boolean isPrivate() {
|
||||
return isPrivate;
|
||||
}
|
||||
|
||||
public boolean isIncomingRequest() {
|
||||
return incomingRequest;
|
||||
}
|
||||
|
||||
public boolean isOutgoingRequest() {
|
||||
return outgoingRequest;
|
||||
}
|
||||
|
||||
public boolean isBestie() {
|
||||
return isBestie;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FriendshipRepositoryChangeResponseFriendshipStatus{" +
|
||||
"following=" + following +
|
||||
", followedBy=" + followedBy +
|
||||
", blocking=" + blocking +
|
||||
", muting=" + muting +
|
||||
", isPrivate=" + isPrivate +
|
||||
", incomingRequest=" + incomingRequest +
|
||||
", outgoingRequest=" + outgoingRequest +
|
||||
", isBestie=" + isBestie +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package awais.instagrabber.repositories.responses;
|
||||
|
||||
public class FriendshipRepositoryChangeResponseRootObject {
|
||||
private FriendshipRepositoryChangeResponseFriendshipStatus friendshipStatus;
|
||||
private String status;
|
||||
|
||||
public FriendshipRepositoryChangeResponseRootObject(final FriendshipRepositoryChangeResponseFriendshipStatus friendshipStatus, final String status) {
|
||||
this.friendshipStatus = friendshipStatus;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public FriendshipRepositoryChangeResponseFriendshipStatus getFriendshipStatus() {
|
||||
return friendshipStatus;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FriendshipRepositoryChangeResponseRootObject{" +
|
||||
"friendshipStatus=" + friendshipStatus +
|
||||
", status='" + status + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package awais.instagrabber.services;
|
|||
|
||||
import okhttp3.OkHttpClient;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
import retrofit2.converter.scalars.ScalarsConverterFactory;
|
||||
|
||||
public abstract class BaseService {
|
||||
|
|
@ -17,6 +18,7 @@ public abstract class BaseService {
|
|||
.build();
|
||||
builder = new Retrofit.Builder()
|
||||
.addConverterFactory(ScalarsConverterFactory.create())
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.client(client);
|
||||
}
|
||||
return builder;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
package awais.instagrabber.services;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import awais.instagrabber.repositories.FriendshipRepository;
|
||||
import awais.instagrabber.repositories.responses.FriendshipRepositoryChangeResponseRootObject;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
import retrofit2.Retrofit;
|
||||
|
||||
public class FriendshipService extends BaseService {
|
||||
private static final String TAG = "ProfileService";
|
||||
|
||||
private final FriendshipRepository repository;
|
||||
|
||||
private static FriendshipService instance;
|
||||
|
||||
private FriendshipService() {
|
||||
final Retrofit retrofit = getRetrofitBuilder()
|
||||
.baseUrl("https://i.instagram.com")
|
||||
.build();
|
||||
repository = retrofit.create(FriendshipRepository.class);
|
||||
}
|
||||
|
||||
public static FriendshipService getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new FriendshipService();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void follow(final String userId,
|
||||
final String targetUserId,
|
||||
final String crsfToken,
|
||||
final ServiceCallback<FriendshipRepositoryChangeResponseRootObject> callback) {
|
||||
change("create", userId, targetUserId, crsfToken, callback);
|
||||
}
|
||||
|
||||
public void unfollow(final String userId,
|
||||
final String targetUserId,
|
||||
final String crsfToken,
|
||||
final ServiceCallback<FriendshipRepositoryChangeResponseRootObject> callback) {
|
||||
change("destroy", userId, targetUserId, crsfToken, callback);
|
||||
}
|
||||
|
||||
private void change(final String action,
|
||||
final String userId,
|
||||
final String targetUserId,
|
||||
final String crsfToken,
|
||||
final ServiceCallback<FriendshipRepositoryChangeResponseRootObject> callback) {
|
||||
final Map<String, Object> form = new HashMap<>(5);
|
||||
form.put("_csrftoken", crsfToken);
|
||||
form.put("_uid", userId);
|
||||
form.put("_uuid", UUID.randomUUID().toString());
|
||||
form.put("user_id", targetUserId);
|
||||
final Map<String, String> signedForm = Utils.sign(form);
|
||||
final Call<FriendshipRepositoryChangeResponseRootObject> request = repository.change(action, targetUserId, signedForm);
|
||||
request.enqueue(new Callback<FriendshipRepositoryChangeResponseRootObject>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<FriendshipRepositoryChangeResponseRootObject> call,
|
||||
@NonNull final Response<FriendshipRepositoryChangeResponseRootObject> response) {
|
||||
if (callback != null) {
|
||||
callback.onSuccess(response.body());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull final Call<FriendshipRepositoryChangeResponseRootObject> call,
|
||||
@NonNull final Throwable t) {
|
||||
if (callback != null) {
|
||||
callback.onFailure(t);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
package awais.instagrabber.services;
|
||||
|
||||
import awais.instagrabber.repositories.ProfileRepository;
|
||||
import retrofit2.Retrofit;
|
||||
|
||||
public class ProfileService extends BaseService {
|
||||
private static final String TAG = "ProfileService";
|
||||
|
||||
private final ProfileRepository repository;
|
||||
|
||||
private static ProfileService instance;
|
||||
|
||||
private ProfileService() {
|
||||
final Retrofit retrofit = getRetrofitBuilder()
|
||||
.baseUrl("https://i.instagram.com")
|
||||
.build();
|
||||
repository = retrofit.create(ProfileRepository.class);
|
||||
}
|
||||
|
||||
public static ProfileService getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new ProfileService();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void followProfile(final String username) {
|
||||
// final String url = "https://www.instagram.com/web/" + (action.equals("followtag") && mainActivity.hashtagModel != null ? "tags/" + (mainActivity.hashtagModel.getFollowing() ? "unfollow/" : "follow/") + mainActivity.hashtagModel.getName() + "/" : (action.equals("restrict") && mainActivity.profileModel != null ? "restrict_action" : "friendships/" + mainActivity.profileModel.getId()) + "/" + (action.equals("follow") ?
|
||||
// mainActivity.profileModel.getFollowing() || mainActivity.profileModel.getRequested()
|
||||
// ? "unfollow/" : "follow/" :
|
||||
// action.equals("restrict") ?
|
||||
// mainActivity.profileModel.getRestricted() ? "unrestrict/" : "restrict/" :
|
||||
// mainActivity.profileModel.getBlocked() ? "unblock/" : "block/"));
|
||||
}
|
||||
}
|
||||
|
|
@ -64,4 +64,5 @@ public final class Constants {
|
|||
"\"gyroscope\", \"value\": \"gyroscope_enabled\" } ]";
|
||||
public static final String SIGNATURE_VERSION = "4";
|
||||
public static final String SIGNATURE_KEY = "9193488027538fd3450b83b7d05286d4ca9599a0f7eeed90d8c85925698a05dc";
|
||||
public static final int LOGIN_RESULT_CODE = 5000;
|
||||
}
|
||||
|
|
@ -217,8 +217,8 @@ public final class ExportImportUtils {
|
|||
if (settingsHelper != null) {
|
||||
try {
|
||||
final JSONObject json = new JSONObject();
|
||||
json.put(Constants.APP_THEME, settingsHelper.getInteger(Constants.APP_THEME));
|
||||
json.put(Constants.APP_LANGUAGE, settingsHelper.getInteger(Constants.APP_LANGUAGE));
|
||||
json.put(Constants.APP_THEME, settingsHelper.getString(Constants.APP_THEME));
|
||||
json.put(Constants.APP_LANGUAGE, settingsHelper.getString(Constants.APP_LANGUAGE));
|
||||
|
||||
String str = settingsHelper.getString(Constants.FOLDER_PATH);
|
||||
if (!Utils.isEmpty(str)) json.put(Constants.FOLDER_PATH, str);
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public final class LocaleUtils {
|
|||
if (Utils.settingsHelper == null)
|
||||
Utils.settingsHelper = new SettingsHelper(baseContext);
|
||||
|
||||
final int appLanguageIndex = Utils.settingsHelper.getInteger(Constants.APP_LANGUAGE);
|
||||
final int appLanguageIndex = Integer.parseInt(Utils.settingsHelper.getString(Constants.APP_LANGUAGE));
|
||||
|
||||
if (appLanguageIndex == 1) return "en";
|
||||
if (appLanguageIndex == 2) return "fr";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package awais.instagrabber.utils;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
|
|
@ -83,10 +84,18 @@ public final class SettingsHelper {
|
|||
int themeCode = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
|
||||
|
||||
if (!fromHelper && sharedPreferences != null) {
|
||||
themeCode = sharedPreferences.getInt(APP_THEME, themeCode);
|
||||
if (themeCode == 1) themeCode = AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY;
|
||||
else if (themeCode == 3) themeCode = AppCompatDelegate.MODE_NIGHT_NO;
|
||||
else if (themeCode == 0) themeCode = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
|
||||
themeCode = Integer.parseInt(sharedPreferences.getString(APP_THEME, String.valueOf(themeCode)));
|
||||
switch (themeCode) {
|
||||
case 1:
|
||||
themeCode = AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY;
|
||||
break;
|
||||
case 3:
|
||||
themeCode = AppCompatDelegate.MODE_NIGHT_NO;
|
||||
break;
|
||||
case 0:
|
||||
themeCode = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (themeCode == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM && Build.VERSION.SDK_INT < 29)
|
||||
|
|
@ -107,13 +116,13 @@ public final class SettingsHelper {
|
|||
if (sharedPreferences != null) sharedPreferences.edit().putBoolean(key, val).apply();
|
||||
}
|
||||
|
||||
@StringDef({COOKIE, FOLDER_PATH, DATE_TIME_FORMAT, DATE_TIME_SELECTION, CUSTOM_DATE_TIME_FORMAT, DEVICE_UUID})
|
||||
@StringDef({APP_LANGUAGE, APP_THEME, COOKIE, FOLDER_PATH, DATE_TIME_FORMAT, DATE_TIME_SELECTION, CUSTOM_DATE_TIME_FORMAT, DEVICE_UUID})
|
||||
public @interface StringSettings {}
|
||||
|
||||
@StringDef({DOWNLOAD_USER_FOLDER, BOTTOM_TOOLBAR, FOLDER_SAVE_TO, AUTOPLAY_VIDEOS, SHOW_QUICK_ACCESS_DIALOG, MUTED_VIDEOS,
|
||||
AUTOLOAD_POSTS, CUSTOM_DATE_TIME_FORMAT_ENABLED, MARK_AS_SEEN, INSTADP, STORIESIG, AMOLED_THEME, CHECK_ACTIVITY})
|
||||
public @interface BooleanSettings {}
|
||||
|
||||
@StringDef({APP_THEME, APP_LANGUAGE, PREV_INSTALL_VERSION})
|
||||
@StringDef({PREV_INSTALL_VERSION})
|
||||
public @interface IntegerSettings {}
|
||||
}
|
||||
|
|
@ -59,6 +59,7 @@ import java.net.URI;
|
|||
import java.net.URISyntaxException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
|
@ -820,24 +821,26 @@ public final class Utils {
|
|||
}
|
||||
AppCompatDelegate.setDefaultNightMode(themeCode);
|
||||
// use amoled theme only if enabled in settings
|
||||
if (isAmoledEnabled) {
|
||||
// check if setting is set to 'Dark'
|
||||
boolean isNight = themeCode == AppCompatDelegate.MODE_NIGHT_YES;
|
||||
// if not dark check if themeCode is MODE_NIGHT_FOLLOW_SYSTEM or MODE_NIGHT_AUTO_BATTERY
|
||||
if (!isNight && (themeCode == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM || themeCode == AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY)) {
|
||||
// check if resulting theme would be NIGHT
|
||||
final int uiMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
|
||||
isNight = uiMode == Configuration.UI_MODE_NIGHT_YES;
|
||||
}
|
||||
if (isNight) {
|
||||
// set amoled theme
|
||||
Log.d("InstaGrabber", "settings amoled theme");
|
||||
context.setTheme(R.style.Theme_Amoled);
|
||||
return;
|
||||
}
|
||||
if (isAmoledEnabled && isNight(context, themeCode)) {
|
||||
// set amoled theme
|
||||
Log.d(TAG, "settings amoled theme");
|
||||
context.setTheme(R.style.Theme_Amoled);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isNight(final Context context, final int themeCode) {
|
||||
// check if setting is set to 'Dark'
|
||||
boolean isNight = themeCode == AppCompatDelegate.MODE_NIGHT_YES;
|
||||
// if not dark check if themeCode is MODE_NIGHT_FOLLOW_SYSTEM or MODE_NIGHT_AUTO_BATTERY
|
||||
if (!isNight && (themeCode == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM || themeCode == AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY)) {
|
||||
// check if resulting theme would be NIGHT
|
||||
final int uiMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
|
||||
isNight = uiMode == Configuration.UI_MODE_NIGHT_YES;
|
||||
}
|
||||
return isNight;
|
||||
}
|
||||
|
||||
|
||||
public static void setTooltipText(final View view, @StringRes final int tooltipTextRes) {
|
||||
if (view != null && tooltipTextRes != 0 && tooltipTextRes != -1) {
|
||||
final Context context = view.getContext();
|
||||
|
|
@ -1208,6 +1211,20 @@ public final class Utils {
|
|||
dialog[0] = new AlertDialog.Builder(context).setView(importExportBinding.getRoot()).show();
|
||||
}
|
||||
|
||||
public static Map<String, String> sign(final Map<String, Object> form) {
|
||||
final String signed = sign(new JSONObject(form).toString());
|
||||
if (signed == null) {
|
||||
return null;
|
||||
}
|
||||
final String[] parts = signed.split("&");
|
||||
final Map<String, String> map = new HashMap<>();
|
||||
for (final String part : parts) {
|
||||
final String[] partSplit = part.split("=");
|
||||
map.put(partSplit[0], partSplit[1]);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public static String sign(final String message) {
|
||||
try {
|
||||
final Mac hasher = Mac.getInstance("HmacSHA256");
|
||||
|
|
@ -1440,4 +1457,11 @@ public final class Utils {
|
|||
public static int getResultingWidth(final int requiredHeight, final int height, final int width) {
|
||||
return requiredHeight * width / height;
|
||||
}
|
||||
|
||||
public static String getCsrfTokenFromCookie(final String cookie) {
|
||||
if (cookie == null) {
|
||||
return null;
|
||||
}
|
||||
return cookie.split("csrftoken=")[1].split(";")[0];
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue