Preferences! Check description
1. Added preferences screens. 2. Some DM changes. 3. Init profile actions using services
@ -39,6 +39,7 @@ android {
|
||||
dependencies {
|
||||
def appcompat_version = "1.2.0"
|
||||
def nav_version = "2.3.0"
|
||||
def preference_version = "1.1.1"
|
||||
|
||||
implementation "androidx.appcompat:appcompat:$appcompat_version"
|
||||
// For loading and tinting drawables on older versions of the platform
|
||||
@ -50,6 +51,8 @@ dependencies {
|
||||
implementation "androidx.navigation:navigation-fragment:$nav_version"
|
||||
implementation "androidx.navigation:navigation-ui:$nav_version"
|
||||
implementation "androidx.constraintlayout:constraintlayout:2.0.0"
|
||||
implementation "androidx.preference:preference:$preference_version"
|
||||
|
||||
|
||||
implementation 'org.jsoup:jsoup:1.13.1'
|
||||
implementation 'com.github.bumptech.glide:glide:4.11.0'
|
||||
@ -59,6 +62,7 @@ dependencies {
|
||||
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
|
||||
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
|
||||
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
|
||||
|
||||
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
|
||||
}
|
||||
|
@ -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();
|
||||
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,7 +63,9 @@ 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")
|
||||
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;
|
||||
@ -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,7 +48,21 @@ 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) {
|
||||
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);
|
||||
}
|
||||
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));
|
||||
@ -75,14 +94,13 @@ public final class InboxFetcher extends AsyncTask<Void, Void, InboxModel> {
|
||||
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() {
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,7 +821,14 @@ public final class Utils {
|
||||
}
|
||||
AppCompatDelegate.setDefaultNightMode(themeCode);
|
||||
// use amoled theme only if enabled in settings
|
||||
if (isAmoledEnabled) {
|
||||
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
|
||||
@ -829,15 +837,10 @@ public final class Utils {
|
||||
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;
|
||||
}
|
||||
}
|
||||
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];
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 451 B |
Before Width: | Height: | Size: 333 B |
Before Width: | Height: | Size: 435 B |
Before Width: | Height: | Size: 253 B |
Before Width: | Height: | Size: 239 B |
Before Width: | Height: | Size: 311 B |
Before Width: | Height: | Size: 597 B |
Before Width: | Height: | Size: 415 B |
Before Width: | Height: | Size: 560 B |
Before Width: | Height: | Size: 811 B |
Before Width: | Height: | Size: 570 B |
Before Width: | Height: | Size: 815 B |
@ -1,10 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:alpha="0.8"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M11,7h2v2h-2zM11,11h2v6h-2zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z"/>
|
10
app/src/main/res/drawable/ic_outline_settings_24.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98 0,-0.34 -0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.09,-0.16 -0.26,-0.25 -0.44,-0.25 -0.06,0 -0.12,0.01 -0.17,0.03l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.06,-0.02 -0.12,-0.03 -0.18,-0.03 -0.17,0 -0.34,0.09 -0.43,0.25l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98 0,0.33 0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.09,0.16 0.26,0.25 0.44,0.25 0.06,0 0.12,-0.01 0.17,-0.03l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.06,0.02 0.12,0.03 0.18,0.03 0.17,0 0.34,-0.09 0.43,-0.25l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM17.45,11.27c0.04,0.31 0.05,0.52 0.05,0.73 0,0.21 -0.02,0.43 -0.05,0.73l-0.14,1.13 0.89,0.7 1.08,0.84 -0.7,1.21 -1.27,-0.51 -1.04,-0.42 -0.9,0.68c-0.43,0.32 -0.84,0.56 -1.25,0.73l-1.06,0.43 -0.16,1.13 -0.2,1.35h-1.4l-0.19,-1.35 -0.16,-1.13 -1.06,-0.43c-0.43,-0.18 -0.83,-0.41 -1.23,-0.71l-0.91,-0.7 -1.06,0.43 -1.27,0.51 -0.7,-1.21 1.08,-0.84 0.89,-0.7 -0.14,-1.13c-0.03,-0.31 -0.05,-0.54 -0.05,-0.74s0.02,-0.43 0.05,-0.73l0.14,-1.13 -0.89,-0.7 -1.08,-0.84 0.7,-1.21 1.27,0.51 1.04,0.42 0.9,-0.68c0.43,-0.32 0.84,-0.56 1.25,-0.73l1.06,-0.43 0.16,-1.13 0.2,-1.35h1.39l0.19,1.35 0.16,1.13 1.06,0.43c0.43,0.18 0.83,0.41 1.23,0.71l0.91,0.7 1.06,-0.43 1.27,-0.51 0.7,1.21 -1.07,0.85 -0.89,0.7 0.14,1.13zM12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM12,14c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2z"/>
|
||||
</vector>
|
@ -63,7 +63,7 @@
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingRight="8dp"
|
||||
android:paddingBottom="4dp"
|
||||
app:srcCompat="@drawable/ic_info" />
|
||||
app:srcCompat="@drawable/ic_outline_info_24" />
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
@ -1,13 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="4dp"
|
||||
android:paddingLeft="4dp"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingEnd="4dp"
|
||||
android:paddingRight="4dp">
|
||||
android:padding="16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
@ -25,9 +22,8 @@
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/time_settings_title_custom" />
|
||||
|
||||
<CheckBox
|
||||
@ -40,7 +36,8 @@
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
android:id="@+id/etCustomFormat"
|
||||
@ -55,7 +52,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:src="@android:drawable/ic_menu_info_details" />
|
||||
app:srcCompat="@drawable/ic_outline_info_24" />
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
@ -73,63 +70,72 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0.84"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/time_settings_title_time_format" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatSpinner
|
||||
android:id="@+id/spTimeFormat"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_weight="1"
|
||||
android:entries="@array/time_presets" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0.7"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/time_settings_title_separator" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatSpinner
|
||||
android:id="@+id/spSeparator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_weight="1"
|
||||
android:entries="@array/separator_presets" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/time_settings_title_date_format" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatSpinner
|
||||
android:id="@+id/spDateFormat"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_weight="1"
|
||||
android:entries="@array/date_presets" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cbSwapTimeDate"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/time_settings_swap_time" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@ -137,25 +143,11 @@
|
||||
android:baselineAligned="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/time_settings_title_preview" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cbSwapTimeDate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="@string/time_settings_swap_time" />
|
||||
</LinearLayout>
|
||||
android:layout_gravity="bottom"
|
||||
android:text="@string/time_settings_title_preview" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/timePreview"
|
||||
|
@ -16,6 +16,6 @@
|
||||
android:id="@+id/inbox_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:listitem="@layout/layout_include_simple_item" />
|
||||
tools:listitem="@layout/layout_dm_inbox_item" />
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
</awais.instagrabber.customviews.helpers.NestedCoordinatorLayout>
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
<include
|
||||
android:id="@+id/container"
|
||||
layout="@layout/layout_include_simple_item" />
|
||||
layout="@layout/layout_dm_inbox_item" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvChildComments"
|
||||
|
@ -13,7 +13,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dip"
|
||||
android:layout_alignParentTop="true"
|
||||
android:background="?android:attr/dividerVertical" />
|
||||
android:background="@android:color/darker_gray" />
|
||||
|
||||
<View
|
||||
android:id="@+id/horizontalDivider"
|
||||
@ -23,9 +23,9 @@
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:background="?android:attr/dividerVertical" />
|
||||
android:background="@android:color/darker_gray" />
|
||||
|
||||
<Button
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
android:id="@+id/btnCancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
@ -38,7 +38,7 @@
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:text="@string/cancel" />
|
||||
|
||||
<Button
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
android:id="@+id/btnConfirm"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
@ -103,7 +103,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_below="@id/btnNavUp"
|
||||
android:background="#33B5E5" />
|
||||
android:background="@android:color/darker_gray" />
|
||||
</RelativeLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
|
121
app/src/main/res/layout/layout_dm_inbox_item.xml
Normal file
@ -0,0 +1,121 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="@dimen/simple_item_picture_size"
|
||||
android:layout_height="@dimen/simple_item_picture_size"
|
||||
android:gravity="center"
|
||||
android:padding="4dp">
|
||||
|
||||
<com.facebook.drawee.view.SimpleDraweeView
|
||||
android:id="@+id/ivProfilePic"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:roundAsCircle="true" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/multi_pic_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.facebook.drawee.view.SimpleDraweeView
|
||||
android:layout_width="@dimen/simple_item_picture_size_half"
|
||||
android:layout_height="match_parent"
|
||||
app:roundAsCircle="true" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="@dimen/simple_item_picture_size_half"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.facebook.drawee.view.SimpleDraweeView
|
||||
android:layout_width="@dimen/simple_item_picture_size_half"
|
||||
android:layout_height="@dimen/simple_item_picture_size_half"
|
||||
app:roundAsCircle="true" />
|
||||
|
||||
<com.facebook.drawee.view.SimpleDraweeView
|
||||
android:layout_width="@dimen/simple_item_picture_size_half"
|
||||
android:layout_height="@dimen/simple_item_picture_size_half"
|
||||
app:roundAsCircle="true" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:padding="8dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tvUsername"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:ellipsize="marquee"
|
||||
android:gravity="center_vertical"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toStartOf="@id/tvDate"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="username" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tvDate"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:ellipsize="marquee"
|
||||
android:gravity="center_vertical|end"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||
android:textStyle="italic"
|
||||
app:layout_constraintBottom_toTopOf="@id/comment_container"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/tvUsername"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="long date................................" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/comment_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvUsername">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/notTextType"
|
||||
android:layout_width="4dp"
|
||||
android:layout_height="4dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:layout_marginRight="4dp"
|
||||
android:visibility="gone"
|
||||
app:srcCompat="@android:drawable/ic_notification_overlay"
|
||||
app:tint="@color/feed_text_primary_color" />
|
||||
|
||||
<awais.instagrabber.customviews.RamboTextView
|
||||
android:id="@+id/tvComment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:autoLink="web|email"
|
||||
android:ellipsize="end"
|
||||
android:linksClickable="true"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||
tools:text="comment" />
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</LinearLayout>
|
@ -1,138 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="0dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingEnd="4dp"
|
||||
android:paddingRight="4dp">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="@dimen/simple_item_picture_size"
|
||||
android:layout_height="@dimen/simple_item_picture_size"
|
||||
android:gravity="center">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/ivProfilePic"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:layout_width="@dimen/simple_item_picture_size_half"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="@dimen/simple_item_picture_size_half"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:layout_width="@dimen/simple_item_picture_size_half"
|
||||
android:layout_height="@dimen/simple_item_picture_size_half" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:layout_width="@dimen/simple_item_picture_size_half"
|
||||
android:layout_height="@dimen/simple_item_picture_size_half" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tvUsername"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:layout_weight="1.0"
|
||||
android:ellipsize="marquee"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingEnd="4dp"
|
||||
android:paddingRight="4dp"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingRight="8dp"
|
||||
android:paddingBottom="16dp">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/notTextType"
|
||||
android:layout_width="4dp"
|
||||
android:layout_height="4dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:layout_marginRight="4dp"
|
||||
android:visibility="gone"
|
||||
app:srcCompat="@android:drawable/ic_notification_overlay"
|
||||
app:tint="@color/feed_text_primary_color" />
|
||||
|
||||
<awais.instagrabber.customviews.RamboTextView
|
||||
android:id="@+id/tvComment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:autoLink="web|email"
|
||||
android:ellipsize="end"
|
||||
android:linksClickable="true"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:weightSum="3">
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tvLikes"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="marquee"
|
||||
android:paddingStart="4dp"
|
||||
android:paddingLeft="4dp"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingRight="8dp"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
android:textSize="14sp" />
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tvDate"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:layout_gravity="start"
|
||||
android:ellipsize="marquee"
|
||||
android:paddingStart="4dp"
|
||||
android:paddingLeft="4dp"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingRight="8dp"
|
||||
android:singleLine="true"
|
||||
android:textStyle="italic"
|
||||
android:gravity="right"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
93
app/src/main/res/layout/pref_custom_folder.xml
Normal file
@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:animateLayoutChanges="true"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:orientation="vertical"
|
||||
android:paddingEnd="?android:attr/scrollbarSize"
|
||||
android:paddingRight="?android:attr/scrollbarSize">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="false"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="15dip"
|
||||
android:layout_marginLeft="15dip"
|
||||
android:layout_marginTop="6dip"
|
||||
android:layout_marginEnd="6dip"
|
||||
android:layout_marginRight="6dip"
|
||||
android:layout_marginBottom="6dip"
|
||||
android:layout_weight="1">
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
tools:text="Test" />
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@android:id/title"
|
||||
android:layout_alignStart="@android:id/title"
|
||||
android:layout_alignLeft="@android:id/title"
|
||||
android:maxLines="4"
|
||||
android:textAppearance="?android:attr/textAppearanceListItemSmall"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
tools:text="summary" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/cbSaveTo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/save_to_folder"
|
||||
android:paddingEnd="10dp"
|
||||
android:paddingRight="10dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/button_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="15dip"
|
||||
android:layout_marginLeft="15dip"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
android:id="@+id/btnSaveTo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/select_folder" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/custom_path"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceListItemSmall"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
tools:text="test path" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
14
app/src/main/res/layout/pref_more_header.xml
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="200dp"
|
||||
android:scaleType="fitCenter"
|
||||
app:srcCompat="@mipmap/ic_launcher" />
|
||||
|
||||
</LinearLayout>
|
@ -24,7 +24,7 @@
|
||||
<!-- android:title="@string/title_favorites"/>-->
|
||||
|
||||
<item
|
||||
android:id="@+id/moreFragment"
|
||||
android:id="@+id/more_nav_graph"
|
||||
android:icon="@drawable/ic_more_horiz_24"
|
||||
android:title="@string/more" />
|
||||
</menu>
|
@ -28,6 +28,9 @@
|
||||
<action
|
||||
android:id="@+id/action_dMThreadFragment_to_dMSettingsFragment"
|
||||
app:destination="@id/directMessagesSettingsFragment" />
|
||||
<action
|
||||
android:id="@+id/action_directMessagesThreadFragment_to_profileFragment"
|
||||
app:destination="@id/profileFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/directMessagesSettingsFragment"
|
||||
@ -41,4 +44,14 @@
|
||||
android:name="title"
|
||||
app:argType="string" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/profileFragment"
|
||||
android:name="awais.instagrabber.fragments.main.ProfileFragment"
|
||||
android:label="ProfileFragment"
|
||||
tools:layout="@layout/fragment_profile">
|
||||
<argument
|
||||
android:name="username"
|
||||
app:argType="string"
|
||||
app:nullable="false" />
|
||||
</fragment>
|
||||
</navigation>
|
19
app/src/main/res/navigation/more_nav_graph.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/more_nav_graph"
|
||||
app:startDestination="@id/morePreferencesFragment">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/morePreferencesFragment"
|
||||
android:name="awais.instagrabber.fragments.settings.MorePreferencesFragment"
|
||||
android:label="More">
|
||||
<action
|
||||
android:id="@+id/action_morePreferencesFragment_to_settingsPreferencesFragment"
|
||||
app:destination="@id/settingsPreferencesFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/settingsPreferencesFragment"
|
||||
android:name="awais.instagrabber.fragments.settings.SettingsPreferencesFragment"
|
||||
android:label="@string/action_settings" />
|
||||
</navigation>
|
@ -13,12 +13,31 @@
|
||||
<item>Turkish [Thanks to @faydin90 (Telegram)]</item>
|
||||
<item>Brazilian Portuguese [Thanks to @wagnim (GitHub)]</item>
|
||||
</string-array>
|
||||
<string-array name="languages_values">
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
<item>4</item>
|
||||
<item>5</item>
|
||||
<item>6</item>
|
||||
<item>7</item>
|
||||
<item>8</item>
|
||||
<item>9</item>
|
||||
<item>10</item>
|
||||
</string-array>
|
||||
<string-array name="theme_presets">
|
||||
<item>Auto / Follow System</item>
|
||||
<item>Auto / Follow Battery</item>
|
||||
<item>Dark</item>
|
||||
<item>Light</item>
|
||||
</string-array>
|
||||
<string-array name="theme_presets_values">
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
</string-array>
|
||||
<string-array name="separator_presets">
|
||||
<item>None</item>
|
||||
<item>\@</item>
|
||||
|
@ -12,8 +12,8 @@
|
||||
<dimen name="story_item_height">80dp</dimen>
|
||||
<dimen name="story_item_width">45dp</dimen>
|
||||
|
||||
<dimen name="simple_item_picture_size">@dimen/story_item_height</dimen>
|
||||
<dimen name="simple_item_picture_size_half">@dimen/story_item_width</dimen>
|
||||
<dimen name="simple_item_picture_size">80dp</dimen>
|
||||
<dimen name="simple_item_picture_size_half">40dp</dimen>
|
||||
|
||||
<dimen name="message_item_size">@dimen/simple_item_picture_size</dimen>
|
||||
<dimen name="message_item_profile_size">@dimen/feed_profile_size</dimen>
|
||||
|
@ -36,7 +36,8 @@
|
||||
<string name="bottom_toolbar">Show toolbar at bottom</string>
|
||||
<string name="download_user_folder">Download posts to username folder in Downloads</string>
|
||||
<string name="autoload_posts">Auto-load all posts from user</string>
|
||||
<string name="mark_as_seen_setting">Mark stories as seen after viewing\n(Story author will know you viewed it)</string>
|
||||
<string name="mark_as_seen_setting">Mark stories as seen after viewing</string>
|
||||
<string name="mark_as_seen_setting_summary">Story author will know you viewed it</string>
|
||||
<string name="activity_setting">Enable activity notifications</string>
|
||||
<string name="error_loading_profile">Error loading profile!\nTry logging in and search again.</string>
|
||||
<string name="error_creating_folders">Error creating Download folder(s).</string>
|
||||
@ -129,12 +130,12 @@
|
||||
<string name="refresh">Refresh</string>
|
||||
<string name="get_cookies">Get cookies</string>
|
||||
<string name="desktop_2fa">Desktop Mode</string>
|
||||
<string name="time_settings_title_custom">Custom Format</string>
|
||||
<string name="time_settings_title_custom">Use custom format</string>
|
||||
<string name="time_settings_title_separator">Separator</string>
|
||||
<string name="time_settings_title_time_format">Time Format</string>
|
||||
<string name="time_settings_title_date_format">Date Format</string>
|
||||
<string name="time_settings_title_preview">Preview</string>
|
||||
<string name="time_settings_swap_time">Swap Time and\nDate positions</string>
|
||||
<string name="time_settings_swap_time">Swap Time and Date positions</string>
|
||||
<string name="quick_access_info_dialog">Favorites panel is for adding your favorite hashtags and/or usernames.\n\nAnd the Quick Access panel is for quickly switching between accounts.\n\nNote 1: Make sure to Login into each account [Settings > Login] to add account to the list!\n\nNote 2: Log out of the current account and then log into the other account.</string>
|
||||
<string name="quick_access_cannot_delete_curr">Cannot delete currently in use account</string>
|
||||
<string name="quick_access_confirm_delete">Are you sure you want to delete %s?</string>
|
||||
@ -239,4 +240,7 @@
|
||||
<string name="more">More</string>
|
||||
<string name="title_dm">DM</string>
|
||||
<string name="number_selected">%d selected</string>
|
||||
<string name="relogin">Relogin</string>
|
||||
<string name="relogin_summary">Refresh your cookies if facing any issues</string>
|
||||
<string name="logout_success">Successfully logged out!</string>
|
||||
</resources>
|
||||
|