mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-11-22 06:37:30 +00:00
Add account switcher in MorePreferencesFragment
This commit is contained in:
parent
3e7097ff6d
commit
00762c85e6
@ -3,7 +3,6 @@ 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;
|
||||
@ -23,8 +22,6 @@ import awais.instagrabber.databinding.ActivityLoginBinding;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||
|
||||
public final class Login extends BaseLanguageActivity implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
|
||||
private final WebViewClient webViewClient = new WebViewClient() {
|
||||
@Override
|
||||
@ -36,15 +33,23 @@ public final class Login extends BaseLanguageActivity implements View.OnClickLis
|
||||
public void onPageFinished(final WebView view, final String url) {
|
||||
webViewUrl = url;
|
||||
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) {
|
||||
if (Utils.isEmpty(mainCookie) || !mainCookie.contains("; ds_user_id=")) {
|
||||
ready = true;
|
||||
return;
|
||||
}
|
||||
if (mainCookie.contains("; ds_user_id=") && ready) {
|
||||
returnCookieResult(mainCookie);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void returnCookieResult(final String mainCookie) {
|
||||
final Intent intent = new Intent();
|
||||
intent.putExtra("cookie", mainCookie);
|
||||
setResult(Constants.LOGIN_RESULT_CODE, intent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final WebChromeClient webChromeClient = new WebChromeClient();
|
||||
private String webViewUrl, defaultUserAgent;
|
||||
private boolean ready = false;
|
||||
@ -67,16 +72,15 @@ public final class Login extends BaseLanguageActivity implements View.OnClickLis
|
||||
public void onClick(final View v) {
|
||||
if (v == loginBinding.refresh) {
|
||||
loginBinding.webView.loadUrl("https://instagram.com/");
|
||||
} else if (v == loginBinding.cookies) {
|
||||
final String mainCookie = Utils.getCookie(webViewUrl);
|
||||
if (Utils.isEmpty(mainCookie) || !mainCookie.contains("; ds_user_id="))
|
||||
Toast.makeText(this, R.string.login_error_loading_cookies, Toast.LENGTH_SHORT).show();
|
||||
else {
|
||||
Utils.setupCookies(mainCookie);
|
||||
settingsHelper.putString(Constants.COOKIE, mainCookie);
|
||||
Toast.makeText(this, R.string.login_success_loading_cookies, Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
if (v == loginBinding.cookies) {
|
||||
final String mainCookie = Utils.getCookie(webViewUrl);
|
||||
if (Utils.isEmpty(mainCookie) || !mainCookie.contains("; ds_user_id=")) {
|
||||
Toast.makeText(this, R.string.login_error_loading_cookies, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
returnCookieResult(mainCookie);
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,7 +88,8 @@ public final class Login extends BaseLanguageActivity implements View.OnClickLis
|
||||
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
|
||||
final WebSettings webSettings = loginBinding.webView.getSettings();
|
||||
|
||||
final String newUserAgent = isChecked ? "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"
|
||||
final String newUserAgent = isChecked
|
||||
? "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"
|
||||
: defaultUserAgent;
|
||||
|
||||
webSettings.setUserAgentString(newUserAgent);
|
||||
|
@ -109,7 +109,6 @@ public class MainActivity extends BaseLanguageActivity {
|
||||
setContentView(binding.getRoot());
|
||||
final Toolbar toolbar = binding.toolbar;
|
||||
setSupportActionBar(toolbar);
|
||||
isLoggedIn = !Utils.isEmpty(cookie) && Utils.getUserIdFromCookie(cookie) != null;
|
||||
if (savedInstanceState == null) {
|
||||
setupBottomNavigationBar(true);
|
||||
}
|
||||
@ -315,6 +314,8 @@ public class MainActivity extends BaseLanguageActivity {
|
||||
|
||||
private void setupBottomNavigationBar(final boolean setDefaultFromSettings) {
|
||||
int main_nav_ids = R.array.main_nav_ids;
|
||||
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||
isLoggedIn = !Utils.isEmpty(cookie) && Utils.getUserIdFromCookie(cookie) != null;
|
||||
if (!isLoggedIn) {
|
||||
main_nav_ids = R.array.logged_out_main_nav_ids;
|
||||
binding.bottomNavView.getMenu().clear();
|
||||
@ -329,7 +330,7 @@ public class MainActivity extends BaseLanguageActivity {
|
||||
mainNavList.add(resourceId);
|
||||
}
|
||||
navIds.recycle();
|
||||
if (setDefaultFromSettings) {
|
||||
if (setDefaultFromSettings || !isLoggedIn) {
|
||||
final String defaultTabIdString = settingsHelper.getString(Constants.DEFAULT_TAB);
|
||||
try {
|
||||
final int defaultNavId = Utils.isEmpty(defaultTabIdString) || !isLoggedIn
|
||||
|
@ -0,0 +1,112 @@
|
||||
package awais.instagrabber.adapters;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import awais.instagrabber.R;
|
||||
import awais.instagrabber.databinding.PrefAccountSwitcherBinding;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.DataBox;
|
||||
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||
|
||||
public class AccountSwitcherListAdapter extends ArrayAdapter<DataBox.CookieModel> {
|
||||
private static final String TAG = "AccountSwitcherListAdap";
|
||||
|
||||
private final OnAccountClickListener clickListener;
|
||||
private final OnAccountLongClickListener longClickListener;
|
||||
|
||||
public AccountSwitcherListAdapter(@NonNull final Context context,
|
||||
final int resource,
|
||||
@NonNull final List<DataBox.CookieModel> allUsers,
|
||||
final OnAccountClickListener clickListener,
|
||||
final OnAccountLongClickListener longClickListener) {
|
||||
super(context, resource, allUsers);
|
||||
this.clickListener = clickListener;
|
||||
this.longClickListener = longClickListener;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public View getView(final int position, @Nullable final View convertView, @NonNull final ViewGroup parent) {
|
||||
final DataBox.CookieModel model = getItem(position);
|
||||
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||
if (convertView == null) {
|
||||
final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
|
||||
final PrefAccountSwitcherBinding binding = PrefAccountSwitcherBinding.inflate(layoutInflater, parent, false);
|
||||
final ViewHolder viewHolder = new ViewHolder(binding);
|
||||
viewHolder.itemView.setTag(viewHolder);
|
||||
if (model == null) return viewHolder.itemView;
|
||||
final boolean equals = model.getCookie().equals(cookie);
|
||||
viewHolder.bind(model, equals, clickListener, longClickListener);
|
||||
return viewHolder.itemView;
|
||||
}
|
||||
final ViewHolder viewHolder = (ViewHolder) convertView.getTag();
|
||||
if (model == null) return viewHolder.itemView;
|
||||
final boolean equals = model.getCookie().equals(cookie);
|
||||
viewHolder.bind(model, equals, clickListener, longClickListener);
|
||||
return viewHolder.itemView;
|
||||
}
|
||||
|
||||
public interface OnAccountClickListener {
|
||||
void onAccountClick(final DataBox.CookieModel model, final boolean isCurrent);
|
||||
}
|
||||
|
||||
public interface OnAccountLongClickListener {
|
||||
boolean onAccountLongClick(final DataBox.CookieModel model, final boolean isCurrent);
|
||||
}
|
||||
|
||||
private static class ViewHolder {
|
||||
private final View itemView;
|
||||
private final PrefAccountSwitcherBinding binding;
|
||||
|
||||
public ViewHolder(final PrefAccountSwitcherBinding binding) {
|
||||
this.itemView = binding.getRoot();
|
||||
this.binding = binding;
|
||||
binding.arrowDown.setImageResource(R.drawable.ic_check_24);
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
public void bind(final DataBox.CookieModel model,
|
||||
final boolean isCurrent,
|
||||
final OnAccountClickListener clickListener,
|
||||
final OnAccountLongClickListener longClickListener) {
|
||||
// Log.d(TAG, model.getFullName());
|
||||
itemView.setOnClickListener(v -> {
|
||||
if (clickListener == null) return;
|
||||
clickListener.onAccountClick(model, isCurrent);
|
||||
});
|
||||
itemView.setOnLongClickListener(v -> {
|
||||
if (longClickListener == null) return false;
|
||||
return longClickListener.onAccountLongClick(model, isCurrent);
|
||||
});
|
||||
binding.profilePic.setImageURI(model.getProfilePic());
|
||||
binding.username.setText("@" + model.getUsername());
|
||||
binding.fullName.setTypeface(null);
|
||||
final String fullName = model.getFullName();
|
||||
if (TextUtils.isEmpty(fullName)) {
|
||||
binding.fullName.setVisibility(View.GONE);
|
||||
} else {
|
||||
binding.fullName.setVisibility(View.VISIBLE);
|
||||
binding.fullName.setText(fullName);
|
||||
}
|
||||
if (!isCurrent) {
|
||||
binding.arrowDown.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
binding.fullName.setTypeface(binding.fullName.getTypeface(), Typeface.BOLD);
|
||||
binding.arrowDown.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
@ -147,12 +147,14 @@ public final class QuickAccessDialog extends BottomSheetDialogFragment implement
|
||||
if (cookieModel.isSelected())
|
||||
Toast.makeText(v.getContext(), R.string.quick_access_cannot_delete_curr, Toast.LENGTH_SHORT).show();
|
||||
else
|
||||
new AlertDialog.Builder(activity).setPositiveButton(R.string.yes, (d, which) -> {
|
||||
new AlertDialog.Builder(activity)
|
||||
.setMessage(getString(R.string.quick_access_confirm_delete, cookieModel.getUsername()))
|
||||
.setPositiveButton(R.string.yes, (d, which) -> {
|
||||
Utils.dataBox.delUserCookie(cookieModel);
|
||||
rvQuickAccess.findViewWithTag(cookieModel).setVisibility(View.GONE);
|
||||
})
|
||||
.setNegativeButton(R.string.no, null).setMessage(getString(R.string.quick_access_confirm_delete,
|
||||
cookieModel.getUsername())).show();
|
||||
.setNegativeButton(R.string.no, null)
|
||||
.show();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -60,6 +60,7 @@ 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.NestedCoordinatorLayout;
|
||||
import awais.instagrabber.customviews.helpers.RecyclerLazyLoader;
|
||||
import awais.instagrabber.databinding.FragmentProfileBinding;
|
||||
import awais.instagrabber.dialogs.ProfilePicDialogFragment;
|
||||
@ -107,6 +108,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
private MenuItem favMenuItem;
|
||||
private boolean isPullToRefresh;
|
||||
private HighlightsAdapter highlightsAdapter;
|
||||
private HighlightsViewModel highlightsViewModel;
|
||||
|
||||
private final Runnable usernameSettingRunnable = () -> {
|
||||
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
|
||||
@ -197,7 +199,6 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
action.setUsername("@" + text);
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
};
|
||||
private HighlightsViewModel highlightsViewModel;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
@ -283,8 +284,12 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
setUsernameDelayed();
|
||||
}
|
||||
if (Utils.isEmpty(username) && !isLoggedIn) {
|
||||
binding.infoContainer.setVisibility(View.GONE);
|
||||
binding.privatePage1.setImageResource(R.drawable.ic_outline_info_24);
|
||||
binding.privatePage2.setText(R.string.no_acc);
|
||||
final NestedCoordinatorLayout.LayoutParams layoutParams = (NestedCoordinatorLayout.LayoutParams) binding.privatePage.getLayoutParams();
|
||||
layoutParams.topMargin = 0;
|
||||
binding.privatePage.setLayoutParams(layoutParams);
|
||||
binding.privatePage.setVisibility(View.VISIBLE);
|
||||
return;
|
||||
}
|
||||
@ -302,10 +307,6 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
this.username = username;
|
||||
setUsernameDelayed();
|
||||
fetchProfileDetails();
|
||||
// adds cookies to database for quick access
|
||||
final DataBox.CookieModel cookieModel = Utils.dataBox.getCookie(uid);
|
||||
if (Utils.dataBox.getCookieCount() == 0 || cookieModel == null || Utils.isEmpty(cookieModel.getUsername()))
|
||||
Utils.dataBox.addUserCookie(new DataBox.CookieModel(uid, username, cookie));
|
||||
};
|
||||
boolean found = false;
|
||||
final DataBox.CookieModel cookieModel = Utils.dataBox.getCookie(uid);
|
||||
@ -334,7 +335,9 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
&& profileModel != null
|
||||
&& userIdFromCookie != null
|
||||
&& userIdFromCookie.equals(profileModel.getId());
|
||||
if (favMenuItem != null) {
|
||||
favMenuItem.setVisible(isSelf);
|
||||
}
|
||||
setProfileDetails();
|
||||
|
||||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
@ -651,18 +654,12 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
});
|
||||
});
|
||||
binding.btnSaved.setOnClickListener(v -> {
|
||||
// startActivity(new Intent(requireContext(), SavedViewerFragment.class)
|
||||
// .putExtra(Constants.EXTRAS_INDEX, "$" + profileModel.getId())
|
||||
// .putExtra(Constants.EXTRAS_USER, "@" + profileModel.getUsername()));
|
||||
final NavDirections action = ProfileFragmentDirections.actionProfileFragmentToSavedViewerFragment(profileModel.getUsername(),
|
||||
profileModel.getId(),
|
||||
PostItemType.SAVED);
|
||||
NavHostFragment.findNavController(this).navigate(action);
|
||||
});
|
||||
binding.btnLiked.setOnClickListener(v -> {
|
||||
// startActivity(new Intent(requireContext(), SavedViewerFragment.class)
|
||||
// .putExtra(Constants.EXTRAS_INDEX, "^" + profileModel.getId())
|
||||
// .putExtra(Constants.EXTRAS_USER, username));
|
||||
final NavDirections action = ProfileFragmentDirections.actionProfileFragmentToSavedViewerFragment(profileModel.getUsername(),
|
||||
profileModel.getId(),
|
||||
PostItemType.LIKED);
|
||||
|
@ -1,57 +1,94 @@
|
||||
package awais.instagrabber.fragments.settings;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.navigation.NavDirections;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import awais.instagrabber.BuildConfig;
|
||||
import awais.instagrabber.R;
|
||||
import awais.instagrabber.activities.Login;
|
||||
import awais.instagrabber.adapters.AccountSwitcherListAdapter;
|
||||
import awais.instagrabber.adapters.AccountSwitcherListAdapter.OnAccountClickListener;
|
||||
import awais.instagrabber.databinding.PrefAccountSwitcherBinding;
|
||||
import awais.instagrabber.repositories.responses.UserInfo;
|
||||
import awais.instagrabber.services.ProfileService;
|
||||
import awais.instagrabber.services.ServiceCallback;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.DataBox;
|
||||
import awais.instagrabber.utils.FlavorTown;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
|
||||
import static awais.instagrabber.adapters.AccountSwitcherListAdapter.OnAccountLongClickListener;
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||
|
||||
public class MorePreferencesFragment extends BasePreferencesFragment {
|
||||
private static final String TAG = "MorePreferencesFragment";
|
||||
|
||||
private final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||
private AlertDialog accountSwitchDialog;
|
||||
private DataBox.CookieModel tappedModel;
|
||||
private ArrayAdapter<DataBox.CookieModel> adapter;
|
||||
|
||||
@Override
|
||||
void setupPreferenceScreen(final PreferenceScreen screen) {
|
||||
screen.addPreference(new MoreHeaderPreference(requireContext()));
|
||||
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||
final boolean isLoggedIn = !Utils.isEmpty(cookie) && Utils.getUserIdFromCookie(cookie) != null;
|
||||
// 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;
|
||||
}));
|
||||
// To re-login, user can just add the same account back from account switcher dialog
|
||||
// accountCategory.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 -> {
|
||||
accountCategory.addPreference(getAccountSwitcherPreference(cookie));
|
||||
accountCategory.addPreference(getPreference(R.string.logout, "Remove all accounts", -1, preference -> {
|
||||
if (getContext() == null) return false;
|
||||
new AlertDialog.Builder(getContext())
|
||||
.setTitle(R.string.logout)
|
||||
.setMessage("This will remove all added accounts from the app!\n"
|
||||
+ "To remove just one account, long tap the account from the account switcher dialog.\n"
|
||||
+ "Do you want to continue?")
|
||||
.setPositiveButton(R.string.yes, (dialog, which) -> {
|
||||
Utils.setupCookies("LOGOUT");
|
||||
shouldRecreate();
|
||||
Toast.makeText(requireContext(), R.string.logout_success, Toast.LENGTH_SHORT).show();
|
||||
settingsHelper.putString(Constants.COOKIE, "");
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show();
|
||||
return true;
|
||||
}));
|
||||
} else {
|
||||
// Need to show something to trigger login activity
|
||||
accountCategory.addPreference(getPreference(R.string.add_account, R.drawable.ic_add, preference -> {
|
||||
startActivityForResult(new Intent(getContext(), Login.class), Constants.LOGIN_RESULT_CODE);
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
@ -86,10 +123,129 @@ public class MorePreferencesFragment extends BasePreferencesFragment {
|
||||
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);
|
||||
// No use as the timing of show is unreliable
|
||||
// Toast.makeText(requireContext(), R.string.login_success_loading_cookies, Toast.LENGTH_SHORT).show();
|
||||
|
||||
// adds cookies to database for quick access
|
||||
final String uid = Utils.getUserIdFromCookie(cookie);
|
||||
final ProfileService profileService = ProfileService.getInstance();
|
||||
profileService.getUserInfo(uid, new ServiceCallback<UserInfo>() {
|
||||
@Override
|
||||
public void onSuccess(final UserInfo result) {
|
||||
// Log.d(TAG, "adding userInfo: " + result);
|
||||
if (result != null) {
|
||||
Utils.dataBox.addOrUpdateUser(uid, result.getUsername(), cookie, result.getFullName(), result.getProfilePicUrl());
|
||||
}
|
||||
final FragmentActivity activity = getActivity();
|
||||
if (activity == null) return;
|
||||
activity.recreate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable t) {
|
||||
Log.e(TAG, "Error fetching user info", t);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private AccountSwitcherPreference getAccountSwitcherPreference(final String cookie) {
|
||||
final List<DataBox.CookieModel> allUsers = Utils.dataBox.getAllCookies();
|
||||
if (getContext() != null && allUsers != null) {
|
||||
sortUserList(cookie, allUsers);
|
||||
final OnAccountClickListener clickListener = (model, isCurrent) -> {
|
||||
if (isCurrent) {
|
||||
if (accountSwitchDialog == null) return;
|
||||
accountSwitchDialog.dismiss();
|
||||
return;
|
||||
}
|
||||
tappedModel = model;
|
||||
shouldRecreate();
|
||||
if (accountSwitchDialog == null) return;
|
||||
accountSwitchDialog.dismiss();
|
||||
};
|
||||
final OnAccountLongClickListener longClickListener = (model, isCurrent) -> {
|
||||
if (isCurrent) {
|
||||
new AlertDialog.Builder(getContext())
|
||||
.setMessage(R.string.quick_access_cannot_delete_curr)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show();
|
||||
return true;
|
||||
}
|
||||
new AlertDialog.Builder(getContext())
|
||||
.setMessage(getString(R.string.quick_access_confirm_delete, model.getUsername()))
|
||||
.setPositiveButton(R.string.yes, (dialog, which) -> {
|
||||
Utils.dataBox.delUserCookie(model);
|
||||
adapter.clear();
|
||||
final List<DataBox.CookieModel> users = Utils.dataBox.getAllCookies();
|
||||
if (users == null) return;
|
||||
adapter.addAll(users);
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show();
|
||||
accountSwitchDialog.dismiss();
|
||||
return true;
|
||||
};
|
||||
adapter = new AccountSwitcherListAdapter(
|
||||
getContext(),
|
||||
R.layout.pref_account_switcher,
|
||||
allUsers,
|
||||
clickListener,
|
||||
longClickListener
|
||||
);
|
||||
accountSwitchDialog = new AlertDialog.Builder(getContext())
|
||||
.setTitle("Accounts")
|
||||
.setNeutralButton("Add account", (dialog1, which) -> startActivityForResult(
|
||||
new Intent(getContext(), Login.class),
|
||||
Constants.LOGIN_RESULT_CODE))
|
||||
.setAdapter(adapter, null)
|
||||
.create();
|
||||
accountSwitchDialog.setOnDismissListener(dialog -> {
|
||||
if (tappedModel == null) return;
|
||||
Utils.setupCookies(tappedModel.getCookie());
|
||||
settingsHelper.putString(Constants.COOKIE, tappedModel.getCookie());
|
||||
});
|
||||
}
|
||||
final AlertDialog finalDialog = accountSwitchDialog;
|
||||
return new AccountSwitcherPreference(requireContext(), cookie, v -> {
|
||||
if (finalDialog == null) return;
|
||||
finalDialog.show();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the user list by following logic:
|
||||
* <ol>
|
||||
* <li>Keep currently active account at top.
|
||||
* <li>Check if any user does not have a full name.
|
||||
* <li>If all have full names, sort by full names.
|
||||
* <li>Otherwise, sort by the usernames
|
||||
* </ol>
|
||||
*
|
||||
* @param cookie active cookie
|
||||
* @param allUsers list of users
|
||||
*/
|
||||
private void sortUserList(final String cookie, final List<DataBox.CookieModel> allUsers) {
|
||||
boolean sortByName = true;
|
||||
for (final DataBox.CookieModel user : allUsers) {
|
||||
if (Utils.isEmpty(user.getFullName())) {
|
||||
sortByName = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
final boolean finalSortByName = sortByName;
|
||||
Collections.sort(allUsers, (o1, o2) -> {
|
||||
// keep current account at top
|
||||
if (o1.getCookie().equals(cookie)) return -1;
|
||||
if (finalSortByName) {
|
||||
// sort by full name
|
||||
return o1.getFullName().compareTo(o2.getFullName());
|
||||
}
|
||||
// otherwise sort by username
|
||||
return o1.getUsername().compareTo(o2.getUsername());
|
||||
});
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@ -139,4 +295,33 @@ public class MorePreferencesFragment extends BasePreferencesFragment {
|
||||
setSelectable(false);
|
||||
}
|
||||
}
|
||||
|
||||
public static class AccountSwitcherPreference extends Preference {
|
||||
|
||||
private final String cookie;
|
||||
private final View.OnClickListener onClickListener;
|
||||
|
||||
public AccountSwitcherPreference(final Context context,
|
||||
final String cookie,
|
||||
final View.OnClickListener onClickListener) {
|
||||
super(context);
|
||||
this.cookie = cookie;
|
||||
this.onClickListener = onClickListener;
|
||||
setLayoutResource(R.layout.pref_account_switcher);
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Override
|
||||
public void onBindViewHolder(final PreferenceViewHolder holder) {
|
||||
final View root = holder.itemView;
|
||||
if (onClickListener != null) root.setOnClickListener(onClickListener);
|
||||
final PrefAccountSwitcherBinding binding = PrefAccountSwitcherBinding.bind(root);
|
||||
final String uid = Utils.getUserIdFromCookie(cookie);
|
||||
final DataBox.CookieModel user = Utils.dataBox.getCookie(uid);
|
||||
if (user == null) return;
|
||||
binding.fullName.setText(user.getFullName());
|
||||
binding.username.setText("@" + user.getUsername());
|
||||
binding.profilePic.setImageURI(user.getProfilePic());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,13 +37,6 @@ public class SettingsPreferencesFragment extends BasePreferencesFragment {
|
||||
private static AppCompatTextView customPathTextView;
|
||||
private boolean isLoggedIn;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
void setupPreferenceScreen(final PreferenceScreen screen) {
|
||||
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||
|
@ -0,0 +1,11 @@
|
||||
package awais.instagrabber.repositories;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.Path;
|
||||
|
||||
public interface ProfileRepository {
|
||||
|
||||
@GET("api/v1/users/{uid}/info/")
|
||||
Call<String> getUserInfo(@Path("uid") final String uid);
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package awais.instagrabber.repositories.responses;
|
||||
|
||||
public class UserInfo {
|
||||
private final String pk;
|
||||
private final String username;
|
||||
private final String fullName;
|
||||
private final String profilePicUrl;
|
||||
|
||||
public UserInfo(final String pk, final String username, final String fullName, final String profilePicUrl) {
|
||||
this.pk = pk;
|
||||
this.username = username;
|
||||
this.fullName = fullName;
|
||||
this.profilePicUrl = profilePicUrl;
|
||||
}
|
||||
|
||||
public String getPk() {
|
||||
return pk;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
public String getProfilePicUrl() {
|
||||
return profilePicUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UserInfo{" +
|
||||
"uid='" + pk + '\'' +
|
||||
", username='" + username + '\'' +
|
||||
", fullName='" + fullName + '\'' +
|
||||
", profilePicUrl='" + profilePicUrl + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -17,7 +17,8 @@ public class AddCookiesInterceptor implements Interceptor {
|
||||
final Request request = chain.request();
|
||||
final Request.Builder builder = request.newBuilder();
|
||||
final String cookie = Utils.settingsHelper.getString(Constants.COOKIE);
|
||||
builder.addHeader("Cookie", cookie);
|
||||
builder.addHeader("Cookie", cookie)
|
||||
.addHeader("User-Agent", Constants.I_USER_AGENT);
|
||||
final Request updatedRequest = builder.build();
|
||||
return chain.proceed(updatedRequest);
|
||||
}
|
||||
|
@ -1,4 +0,0 @@
|
||||
package awais.instagrabber.services;
|
||||
|
||||
public interface FeedService {
|
||||
}
|
@ -17,7 +17,7 @@ import retrofit2.Response;
|
||||
import retrofit2.Retrofit;
|
||||
|
||||
public class FriendshipService extends BaseService {
|
||||
private static final String TAG = "ProfileService";
|
||||
private static final String TAG = "FriendshipService";
|
||||
|
||||
private final FriendshipRepository repository;
|
||||
|
||||
|
@ -18,18 +18,22 @@ class LoggingInterceptor implements Interceptor {
|
||||
@NonNull
|
||||
@Override
|
||||
public Response intercept(Interceptor.Chain chain) throws IOException {
|
||||
Request request = chain.request();
|
||||
final Request request = chain.request();
|
||||
long t1 = System.nanoTime();
|
||||
Log.i(TAG, String.format("Sending request %s on %s%n%s",
|
||||
request.url(), chain.connection(), request.headers()));
|
||||
Response response = chain.proceed(request);
|
||||
final Response response = chain.proceed(request);
|
||||
long t2 = System.nanoTime();
|
||||
Log.i(TAG, String.format("Received response for %s in %.1fms%n%s", response.request().url(), (t2 - t1) / 1e6d, response.headers()));
|
||||
MediaType contentType = response.body().contentType();
|
||||
String content = response.body().string();
|
||||
Log.d("OkHttp", content);
|
||||
|
||||
ResponseBody wrappedBody = ResponseBody.create(contentType, content);
|
||||
final ResponseBody body = response.body();
|
||||
MediaType contentType = null;
|
||||
String content = "";
|
||||
if (body != null) {
|
||||
contentType = body.contentType();
|
||||
content = body.string();
|
||||
Log.d(TAG, content);
|
||||
}
|
||||
final ResponseBody wrappedBody = ResponseBody.create(contentType, content);
|
||||
return response.newBuilder()
|
||||
.body(wrappedBody)
|
||||
.build();
|
||||
|
@ -0,0 +1,69 @@
|
||||
package awais.instagrabber.services;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import awais.instagrabber.repositories.ProfileRepository;
|
||||
import awais.instagrabber.repositories.responses.UserInfo;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
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 getUserInfo(final String uid, final ServiceCallback<UserInfo> callback) {
|
||||
final Call<String> request = repository.getUserInfo(uid);
|
||||
request.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
final String body = response.body();
|
||||
if (body == null) return;
|
||||
try {
|
||||
final JSONObject jsonObject = new JSONObject(body);
|
||||
final JSONObject user = jsonObject.optJSONObject(Constants.EXTRAS_USER);
|
||||
if (user == null) return;
|
||||
// Log.d(TAG, "user: " + user.toString());
|
||||
final UserInfo userInfo = new UserInfo(
|
||||
uid,
|
||||
user.getString(Constants.EXTRAS_USERNAME),
|
||||
user.optString("full_name"),
|
||||
user.optString("profile_pic_url")
|
||||
);
|
||||
callback.onSuccess(userInfo);
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "Error parsing json", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
||||
callback.onFailure(t);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.util.ObjectsCompat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ -19,38 +20,60 @@ import awaisomereport.LogCollector;
|
||||
import static awais.instagrabber.utils.Utils.logCollector;
|
||||
|
||||
public final class DataBox extends SQLiteOpenHelper {
|
||||
private static final String TAG = "DataBox";
|
||||
|
||||
private static DataBox sInstance;
|
||||
private final static int VERSION = 1;
|
||||
|
||||
private final static int VERSION = 2;
|
||||
private final static String TABLE_COOKIES = "cookies";
|
||||
private final static String TABLE_FAVORITES = "favorites";
|
||||
private final static String KEY_DATE_ADDED = "date_added";
|
||||
private final static String KEY_QUERY_TEXT = "query_text";
|
||||
private final static String KEY_QUERY_DISPLAY = "query_display";
|
||||
|
||||
private final static String KEY_ID = "id";
|
||||
private final static String KEY_USERNAME = Constants.EXTRAS_USERNAME;
|
||||
private final static String KEY_COOKIE = "cookie";
|
||||
private final static String KEY_UID = "uid";
|
||||
private Context c;
|
||||
private final static String KEY_FULL_NAME = "full_name";
|
||||
private final static String KEY_PROFILE_PIC = "profile_pic";
|
||||
|
||||
private final Context c;
|
||||
|
||||
public static synchronized DataBox getInstance(final Context context) {
|
||||
if (sInstance == null) sInstance = new DataBox(context.getApplicationContext());
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
public DataBox(@Nullable final Context context) {
|
||||
private DataBox(@Nullable final Context context) {
|
||||
super(context, "cookiebox.db", null, VERSION);
|
||||
c = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@NonNull final SQLiteDatabase db) {
|
||||
db.execSQL("CREATE TABLE cookies (id INTEGER PRIMARY KEY, uid TEXT, username TEXT, cookie TEXT)");
|
||||
Log.i(TAG, "Creating tables...");
|
||||
db.execSQL("CREATE TABLE " + TABLE_COOKIES + " ("
|
||||
+ KEY_ID + " INTEGER PRIMARY KEY,"
|
||||
+ KEY_UID + " TEXT,"
|
||||
+ KEY_USERNAME + " TEXT,"
|
||||
+ KEY_COOKIE + " TEXT,"
|
||||
+ KEY_FULL_NAME + " TEXT,"
|
||||
+ KEY_PROFILE_PIC + " TEXT)");
|
||||
db.execSQL("CREATE TABLE favorites (id INTEGER PRIMARY KEY, query_text TEXT, date_added INTEGER, query_display TEXT)");
|
||||
Log.i(TAG, "Tables created!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) { }
|
||||
public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
|
||||
Log.i(TAG, String.format("Updating DB from v%d to v%d", oldVersion, newVersion));
|
||||
if (oldVersion == 1) {
|
||||
db.execSQL("ALTER TABLE " + TABLE_COOKIES + " ADD " + KEY_FULL_NAME + " TEXT");
|
||||
db.execSQL("ALTER TABLE " + TABLE_COOKIES + " ADD " + KEY_PROFILE_PIC + " TEXT");
|
||||
}
|
||||
Log.i(TAG, String.format("DB update from v%d to v%d completed!", oldVersion, newVersion));
|
||||
}
|
||||
|
||||
///////////////////////////////////////// YOUR FAVORITES! HERE /////////////////////////////////////////
|
||||
public final void addFavorite(@NonNull final FavoriteModel favoriteModel) {
|
||||
final String query = favoriteModel.getQuery();
|
||||
final String display = favoriteModel.getDisplayName();
|
||||
@ -96,7 +119,7 @@ public final class DataBox extends SQLiteOpenHelper {
|
||||
} catch (final Exception e) {
|
||||
if (logCollector != null)
|
||||
logCollector.appendException(e, LogCollector.LogFile.DATA_BOX_FAVORITES, "delFavorite");
|
||||
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
|
||||
if (BuildConfig.DEBUG) Log.e(TAG, "Error", e);
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
@ -120,7 +143,8 @@ public final class DataBox extends SQLiteOpenHelper {
|
||||
? cursor.getString(0)
|
||||
: "@" + cursor.getString(0), // query text
|
||||
cursor.getLong(1), // date added
|
||||
cursor.getString(2) == null ? (cursor.getString(0).charAt(0) == '@' || cursor.getString(0).charAt(0) == '#' || cursor.getString(0).contains("/"))
|
||||
cursor.getString(2) == null ? (cursor.getString(0).charAt(0) == '@' || cursor.getString(0).charAt(0) == '#' || cursor
|
||||
.getString(0).contains("/"))
|
||||
? cursor.getString(0)
|
||||
: "@" + cursor.getString(0) : cursor.getString(2) // display
|
||||
);
|
||||
@ -154,7 +178,7 @@ public final class DataBox extends SQLiteOpenHelper {
|
||||
if (logCollector != null)
|
||||
logCollector.appendException(e, LogCollector.LogFile.DATA_BOX_FAVORITES, "migrate");
|
||||
Toast.makeText(c, "DB migration failed, contact maintainer.", Toast.LENGTH_SHORT).show();
|
||||
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
|
||||
if (BuildConfig.DEBUG) Log.e(TAG, "", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,11 +186,9 @@ public final class DataBox extends SQLiteOpenHelper {
|
||||
}
|
||||
|
||||
public final String getFavorite(@NonNull final String query) {
|
||||
ArrayList<FavoriteModel> favorites = null;
|
||||
|
||||
try (final SQLiteDatabase db = getReadableDatabase();
|
||||
final Cursor cursor = db.rawQuery("SELECT query_text, date_added FROM favorites WHERE "
|
||||
+KEY_QUERY_TEXT+"='"+query+"' ORDER BY date_added DESC", null)) {
|
||||
+ KEY_QUERY_TEXT + "='" + query + "' ORDER BY date_added DESC", null)) {
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
return cursor.getString(0) + "/" + String.valueOf(cursor.getLong(1));
|
||||
}
|
||||
@ -174,34 +196,36 @@ public final class DataBox extends SQLiteOpenHelper {
|
||||
|
||||
return null;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////// YOUR COOKIES FOR COOKIE MONSTER ARE HERE /////////////////////////////////////
|
||||
public final void addUserCookie(@NonNull final CookieModel cookieModel) {
|
||||
final String cookieModelUid = cookieModel.getUid();
|
||||
if (!Utils.isEmpty(cookieModelUid)) {
|
||||
public final void addOrUpdateUser(final String uid,
|
||||
final String username,
|
||||
final String cookie,
|
||||
final String fullName,
|
||||
final String profilePicUrl) {
|
||||
if (Utils.isEmpty(uid)) return;
|
||||
try (final SQLiteDatabase db = getWritableDatabase()) {
|
||||
db.beginTransaction();
|
||||
try {
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(KEY_USERNAME, cookieModel.getUsername());
|
||||
values.put(KEY_COOKIE, cookieModel.getCookie());
|
||||
values.put(KEY_UID, cookieModelUid);
|
||||
values.put(KEY_USERNAME, username);
|
||||
values.put(KEY_COOKIE, cookie);
|
||||
values.put(KEY_UID, uid);
|
||||
values.put(KEY_FULL_NAME, fullName);
|
||||
values.put(KEY_PROFILE_PIC, profilePicUrl);
|
||||
|
||||
final int rows = db.update(TABLE_COOKIES, values, KEY_UID + "=?", new String[]{cookieModelUid});
|
||||
final int rows = db.update(TABLE_COOKIES, values, KEY_UID + "=?", new String[]{uid});
|
||||
|
||||
if (rows != 1)
|
||||
db.insertOrThrow(TABLE_COOKIES, null, values);
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} catch (final Exception e) {
|
||||
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
|
||||
if (BuildConfig.DEBUG) Log.e(TAG, "Error", e);
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final synchronized void delUserCookie(@NonNull final CookieModel cookieModel) {
|
||||
final String cookieModelUid = cookieModel.getUid();
|
||||
@ -222,6 +246,21 @@ public final class DataBox extends SQLiteOpenHelper {
|
||||
}
|
||||
}
|
||||
|
||||
public final synchronized void deleteAllUserCookies() {
|
||||
try (final SQLiteDatabase db = getWritableDatabase()) {
|
||||
db.beginTransaction();
|
||||
try {
|
||||
final int rowsDeleted = db.delete(TABLE_COOKIES, null, null);
|
||||
|
||||
if (rowsDeleted > 0) db.setTransactionSuccessful();
|
||||
} catch (final Exception e) {
|
||||
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final int getCookieCount() {
|
||||
int cookieCount = 0;
|
||||
try (final SQLiteDatabase db = getReadableDatabase();
|
||||
@ -235,12 +274,24 @@ public final class DataBox extends SQLiteOpenHelper {
|
||||
public final CookieModel getCookie(final String uid) {
|
||||
CookieModel cookie = null;
|
||||
try (final SQLiteDatabase db = getReadableDatabase();
|
||||
final Cursor cursor = db.rawQuery("SELECT uid, username, cookie FROM cookies WHERE uid = ?", new String[]{uid})) {
|
||||
final Cursor cursor = db.rawQuery(
|
||||
"SELECT "
|
||||
+ KEY_UID + ","
|
||||
+ KEY_USERNAME + ","
|
||||
+ KEY_COOKIE + ","
|
||||
+ KEY_FULL_NAME + ","
|
||||
+ KEY_PROFILE_PIC
|
||||
+ " FROM " + TABLE_COOKIES
|
||||
+ " WHERE " + KEY_UID + " = ?",
|
||||
new String[]{uid})
|
||||
) {
|
||||
if (cursor != null && cursor.moveToFirst())
|
||||
cookie = new CookieModel(
|
||||
cursor.getString(0), // uid
|
||||
cursor.getString(1), // username
|
||||
cursor.getString(2) // cookie
|
||||
cursor.getString(cursor.getColumnIndex(KEY_UID)),
|
||||
cursor.getString(cursor.getColumnIndex(KEY_USERNAME)),
|
||||
cursor.getString(cursor.getColumnIndex(KEY_COOKIE)),
|
||||
cursor.getString(cursor.getColumnIndex(KEY_FULL_NAME)),
|
||||
cursor.getString(cursor.getColumnIndex(KEY_PROFILE_PIC))
|
||||
);
|
||||
}
|
||||
return cookie;
|
||||
@ -251,14 +302,24 @@ public final class DataBox extends SQLiteOpenHelper {
|
||||
ArrayList<CookieModel> cookies = null;
|
||||
|
||||
try (final SQLiteDatabase db = getReadableDatabase();
|
||||
final Cursor cursor = db.rawQuery("SELECT uid, username, cookie FROM cookies", null)) {
|
||||
final Cursor cursor = db.rawQuery(
|
||||
"SELECT "
|
||||
+ KEY_UID + ","
|
||||
+ KEY_USERNAME + ","
|
||||
+ KEY_COOKIE + ","
|
||||
+ KEY_FULL_NAME + ","
|
||||
+ KEY_PROFILE_PIC
|
||||
+ " FROM " + TABLE_COOKIES, null)
|
||||
) {
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
cookies = new ArrayList<>();
|
||||
do {
|
||||
cookies.add(new CookieModel(
|
||||
cursor.getString(0), // uid
|
||||
cursor.getString(1), // username
|
||||
cursor.getString(2) // cookie
|
||||
cursor.getString(cursor.getColumnIndex(KEY_UID)),
|
||||
cursor.getString(cursor.getColumnIndex(KEY_USERNAME)),
|
||||
cursor.getString(cursor.getColumnIndex(KEY_COOKIE)),
|
||||
cursor.getString(cursor.getColumnIndex(KEY_FULL_NAME)),
|
||||
cursor.getString(cursor.getColumnIndex(KEY_PROFILE_PIC))
|
||||
));
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
@ -266,16 +327,25 @@ public final class DataBox extends SQLiteOpenHelper {
|
||||
|
||||
return cookies;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static class CookieModel {
|
||||
private final String uid, username, cookie;
|
||||
private final String uid;
|
||||
private final String username;
|
||||
private final String cookie;
|
||||
private final String fullName;
|
||||
private final String profilePic;
|
||||
private boolean selected;
|
||||
|
||||
public CookieModel(final String uid, final String username, final String cookie) {
|
||||
public CookieModel(final String uid,
|
||||
final String username,
|
||||
final String cookie,
|
||||
final String fullName,
|
||||
final String profilePic) {
|
||||
this.uid = uid;
|
||||
this.username = username;
|
||||
this.cookie = cookie;
|
||||
this.fullName = fullName;
|
||||
this.profilePic = profilePic;
|
||||
}
|
||||
|
||||
public String getUid() {
|
||||
@ -290,6 +360,14 @@ public final class DataBox extends SQLiteOpenHelper {
|
||||
return cookie;
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
public String getProfilePic() {
|
||||
return profilePic;
|
||||
}
|
||||
|
||||
public boolean isSelected() {
|
||||
return selected;
|
||||
}
|
||||
@ -298,6 +376,21 @@ public final class DataBox extends SQLiteOpenHelper {
|
||||
this.selected = selected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final CookieModel that = (CookieModel) o;
|
||||
return ObjectsCompat.equals(uid, that.uid) &&
|
||||
ObjectsCompat.equals(username, that.username) &&
|
||||
ObjectsCompat.equals(cookie, that.cookie);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ObjectsCompat.hash(uid, username, cookie);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
|
@ -97,14 +97,16 @@ public final class ExportImportUtils {
|
||||
final AppCompatEditText editText = new AppCompatEditText(context);
|
||||
editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(32)});
|
||||
editText.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||
new AlertDialog.Builder(context).setView(editText).setTitle(R.string.password).setPositiveButton(R.string.confirm, (dialog, which) -> {
|
||||
new AlertDialog.Builder(context).setView(editText).setTitle(R.string.password)
|
||||
.setPositiveButton(R.string.confirm, (dialog, which) -> {
|
||||
final CharSequence text = editText.getText();
|
||||
if (!Utils.isEmpty(text)) {
|
||||
try {
|
||||
final byte[] passwordBytes = text.toString().getBytes();
|
||||
final byte[] bytes = new byte[32];
|
||||
System.arraycopy(passwordBytes, 0, bytes, 0, Math.min(passwordBytes.length, 32));
|
||||
saveToSettings(new String(PasswordUtils.dec(builder.toString(), bytes)), flags, fetchListener);
|
||||
saveToSettings(new String(PasswordUtils.dec(builder.toString(), bytes)), flags,
|
||||
fetchListener);
|
||||
} catch (final Exception e) {
|
||||
if (fetchListener != null) fetchListener.onResult(false);
|
||||
if (logCollector != null)
|
||||
@ -156,8 +158,12 @@ public final class ExportImportUtils {
|
||||
final int cookiesLen = cookies.length();
|
||||
for (int i = 0; i < cookiesLen; ++i) {
|
||||
final JSONObject cookieObject = cookies.getJSONObject(i);
|
||||
Utils.dataBox.addUserCookie(new DataBox.CookieModel(cookieObject.getString("i"),
|
||||
cookieObject.getString("u"), cookieObject.getString("c")));
|
||||
// final DataBox.CookieModel cookieModel = new DataBox.CookieModel(cookieObject.getString("i"),
|
||||
// cookieObject.getString("u"),
|
||||
// cookieObject.getString("c"),
|
||||
// fullName,
|
||||
// profilePic);
|
||||
// Utils.dataBox.addOrUpdateUser(cookieModel.getUid(), cookieModel.getUserInfo(), cookieModel.getCookie());
|
||||
}
|
||||
}
|
||||
|
||||
@ -167,7 +173,8 @@ public final class ExportImportUtils {
|
||||
for (int i = 0; i < favsLen; ++i) {
|
||||
final JSONObject favsObject = favs.getJSONObject(i);
|
||||
Utils.dataBox.addFavorite(new DataBox.FavoriteModel(favsObject.getString("q"),
|
||||
favsObject.getLong("d"), favsObject.has("s") ? favsObject.getString("s") : favsObject.getString("q")));
|
||||
favsObject.getLong("d"),
|
||||
favsObject.has("s") ? favsObject.getString("s") : favsObject.getString("q")));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ import java.util.List;
|
||||
import awais.instagrabber.R;
|
||||
|
||||
public class NavigationExtensions {
|
||||
// private static final String TAG = "NavigationExtensions";
|
||||
|
||||
@NonNull
|
||||
public static LiveData<NavController> setupWithNavController(@NonNull final BottomNavigationView bottomNavigationView,
|
||||
@ -48,7 +49,6 @@ public class NavigationExtensions {
|
||||
detachNavHostFragment(fragmentManager, navHostFragment);
|
||||
}
|
||||
}
|
||||
|
||||
final String[] selectedItemTag = {graphIdToTagMap.get(bottomNavigationView.getSelectedItemId())};
|
||||
final String firstFragmentTag = graphIdToTagMap.get(firstFragmentGraphId);
|
||||
final boolean[] isOnFirstFragment = {selectedItemTag[0] != null && selectedItemTag[0].equals(firstFragmentTag)};
|
||||
@ -61,7 +61,8 @@ public class NavigationExtensions {
|
||||
fragmentManager.popBackStack(firstFragmentTag, FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
Fragment fragment = fragmentManager.findFragmentByTag(newlySelectedItemTag);
|
||||
if (fragment == null) {
|
||||
throw new RuntimeException("null cannot be cast to non-null NavHostFragment");
|
||||
return false;
|
||||
// throw new RuntimeException("null cannot be cast to non-null NavHostFragment");
|
||||
}
|
||||
final NavHostFragment selectedFragment = (NavHostFragment) fragment;
|
||||
if (!firstFragmentTag.equals(newlySelectedItemTag)) {
|
||||
@ -158,7 +159,8 @@ public class NavigationExtensions {
|
||||
final String newlySelectedItemTag = graphIdToTagMap.get(item.getItemId());
|
||||
final Fragment fragmentByTag = fragmentManager.findFragmentByTag(newlySelectedItemTag);
|
||||
if (fragmentByTag == null) {
|
||||
throw new NullPointerException("null cannot be cast to non-null type NavHostFragment");
|
||||
return;
|
||||
// throw new NullPointerException("null cannot be cast to non-null type NavHostFragment");
|
||||
}
|
||||
final NavHostFragment selectedFragment = (NavHostFragment) fragmentByTag;
|
||||
final NavController navController = selectedFragment.getNavController();
|
||||
|
@ -133,6 +133,7 @@ public final class Utils {
|
||||
}
|
||||
if (cookieRaw.equals("LOGOUT")) {
|
||||
cookieStore.removeAll();
|
||||
dataBox.deleteAllUserCookies();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
10
app/src/main/res/drawable/ic_arrow_drop_down_24.xml
Normal file
10
app/src/main/res/drawable/ic_arrow_drop_down_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="M7,10l5,5 5,-5z"/>
|
||||
</vector>
|
10
app/src/main/res/drawable/ic_check_24.xml
Normal file
10
app/src/main/res/drawable/ic_check_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="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
|
||||
</vector>
|
65
app/src/main/res/layout/pref_account_switcher.xml
Normal file
65
app/src/main/res/layout/pref_account_switcher.xml
Normal file
@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:padding="16dp">
|
||||
|
||||
<com.facebook.drawee.view.SimpleDraweeView
|
||||
android:id="@+id/profile_pic"
|
||||
android:layout_width="@dimen/image_size_40"
|
||||
android:layout_height="@dimen/image_size_40"
|
||||
android:scaleType="centerCrop"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:roundAsCircle="true" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/full_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@id/username"
|
||||
app:layout_constraintEnd_toStartOf="@id/arrow_down"
|
||||
app:layout_constraintStart_toEndOf="@id/profile_pic"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="full name" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/username"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingRight="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/arrow_down"
|
||||
app:layout_constraintStart_toEndOf="@id/profile_pic"
|
||||
app:layout_constraintTop_toBottomOf="@id/full_name"
|
||||
tools:text="\@username" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/arrow_down"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/full_name"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_arrow_drop_down_24"
|
||||
app:tint="?colorAccent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -109,7 +109,6 @@
|
||||
</string-array>
|
||||
<array name="logged_out_main_nav_ids">
|
||||
<item>@navigation/profile_nav_graph</item>
|
||||
<item>@navigation/discover_nav_graph</item>
|
||||
<item>@navigation/more_nav_graph</item>
|
||||
</array>
|
||||
</resources>
|
||||
|
@ -4,6 +4,7 @@
|
||||
<dimen name="private_page_margins">@dimen/profile_picture_size</dimen>
|
||||
|
||||
<dimen name="profile_picture_size">90dp</dimen>
|
||||
<dimen name="image_size_40">40dp</dimen>
|
||||
<dimen name="feed_profile_size">48dp</dimen>
|
||||
<dimen name="slider_item_size">80dp</dimen>
|
||||
<dimen name="highlight_size">70dp</dimen>
|
||||
|
@ -89,7 +89,7 @@
|
||||
<string name="story_mentions">Mentions</string>
|
||||
<string name="priv_acc">This Account is Private</string>
|
||||
<string name="priv_acc_confirm">You won\'t be able to access posts after unfollowing! Are you sure?</string>
|
||||
<string name="no_acc">You can log in via Settings on the bottom-right corner. Or, you can view public accounts without login!</string>
|
||||
<string name="no_acc">You can log in via More -> Account on the bottom-right corner or you can view public accounts without login!</string>
|
||||
<string name="no_acc_logged_in">You can swipe left/right for explore/feed, or search something below!</string>
|
||||
<string name="empty_acc">This Account has No Posts</string>
|
||||
<string name="empty_list">No Such Posts!</string>
|
||||
@ -258,4 +258,5 @@
|
||||
<string name="pref_category_theme">Theme</string>
|
||||
<string name="pref_category_downloads">Downloads</string>
|
||||
<string name="pref_category_locale">Locale</string>
|
||||
<string name="add_account">Add account</string>
|
||||
</resources>
|
Loading…
Reference in New Issue
Block a user