diff options
Diffstat (limited to 'app/src/main')
7 files changed, 317 insertions, 43 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 17929a31..6c533f12 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -35,22 +35,41 @@ android:usesCleartextTraffic="true" tools:replace="android:label"> <activity + android:name=".activities.LoginChromeCustomTabActivity" + android:parentActivityName=".activities.MainActivity" + android:theme="@style/AppTheme.Slidable" + android:launchMode="singleTop" + android:exported="true"> + + <intent-filter> + <action android:name="android.intent.action.VIEW" /> + + <category android:name="android.intent.category.DEFAULT" /> + <category android:name="android.intent.category.BROWSABLE" /> + + <data + android:host="localhost" + android:scheme="infinity" /> + </intent-filter> + + </activity> + <activity android:name=".activities.CommentFilterUsageListingActivity" + android:exported="false" android:parentActivityName=".activities.SettingsActivity" - android:theme="@style/AppTheme.NoActionBar" - android:exported="false" /> + android:theme="@style/AppTheme.NoActionBar" /> <activity android:name=".activities.CustomizeCommentFilterActivity" + android:exported="false" android:label="@string/customize_comment_filter_activity_label" android:parentActivityName=".activities.SettingsActivity" - android:theme="@style/AppTheme.NoActionBar" - android:exported="false" /> + android:theme="@style/AppTheme.NoActionBar" /> <activity android:name=".activities.CommentFilterPreferenceActivity" + android:exported="false" android:label="@string/comment_filter_preference_activity_label" android:parentActivityName=".activities.SettingsActivity" - android:theme="@style/AppTheme.NoActionBar" - android:exported="false" /> + android:theme="@style/AppTheme.NoActionBar" /> <activity android:name=".activities.HistoryActivity" android:exported="false" @@ -123,11 +142,6 @@ android:parentActivityName=".activities.MainActivity" android:theme="@style/AppTheme.NoActionBar" /> <activity - android:name=".activities.GiveAwardActivity" - android:label="@string/give_award_activity_label" - android:parentActivityName=".activities.MainActivity" - android:theme="@style/AppTheme.Slidable" /> - <activity android:name=".activities.SelectUserFlairActivity" android:parentActivityName=".activities.MainActivity" android:theme="@style/AppTheme.Slidable" /> diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java index e7dbd276..eb1cb110 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java @@ -29,6 +29,7 @@ import ml.docilealligator.infinityforreddit.activities.InboxActivity; import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; import ml.docilealligator.infinityforreddit.activities.LockScreenActivity; import ml.docilealligator.infinityforreddit.activities.LoginActivity; +import ml.docilealligator.infinityforreddit.activities.LoginChromeCustomTabActivity; import ml.docilealligator.infinityforreddit.activities.MainActivity; import ml.docilealligator.infinityforreddit.activities.MultiredditSelectionActivity; import ml.docilealligator.infinityforreddit.activities.PostFilterPreferenceActivity; @@ -313,6 +314,8 @@ public interface AppComponent { void inject(CustomThemeListingFragment customThemeListingFragment); + void inject(LoginChromeCustomTabActivity loginChromeCustomTabActivity); + @Component.Factory interface Factory { AppComponent create(@BindsInstance Application application); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LoginActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LoginActivity.java index c617d811..549ab1c4 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LoginActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LoginActivity.java @@ -1,6 +1,5 @@ package ml.docilealligator.infinityforreddit.activities; -import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Bitmap; @@ -21,10 +20,10 @@ import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; -import androidx.core.app.ActivityCompat; import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import org.greenrobot.eventbus.EventBus; import org.json.JSONException; import org.json.JSONObject; @@ -45,6 +44,7 @@ import ml.docilealligator.infinityforreddit.asynctasks.ParseAndInsertNewAccount; import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.customviews.slidr.Slidr; import ml.docilealligator.infinityforreddit.databinding.ActivityLoginBinding; +import ml.docilealligator.infinityforreddit.events.NewUserLoggedInEvent; import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.Utils; @@ -114,18 +114,6 @@ public class LoginActivity extends BaseActivity { isAgreeToUserAgreement = savedInstanceState.getBoolean(IS_AGREE_TO_USER_AGGREMENT_STATE); } - binding.fabLoginActivity.setOnClickListener(view -> { - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.have_trouble_login_title) - .setMessage(R.string.have_trouble_login_message) - .setPositiveButton(R.string.yes, (dialogInterface, i) -> { - enableDom = !enableDom; - ActivityCompat.recreate(this); - }) - .setNegativeButton(R.string.no, null) - .show(); - }); - if (enableDom) { binding.twoFaInfOTextViewLoginActivity.setVisibility(View.GONE); } @@ -144,6 +132,22 @@ public class LoginActivity extends BaseActivity { String url = uriBuilder.toString(); + binding.fabLoginActivity.setOnClickListener(view -> { + /*new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.have_trouble_login_title) + .setMessage(R.string.have_trouble_login_message) + .setPositiveButton(R.string.yes, (dialogInterface, i) -> { + enableDom = !enableDom; + ActivityCompat.recreate(this); + }) + .setNegativeButton(R.string.no, null) + .show();*/ + + Intent intent = new Intent(this, LoginChromeCustomTabActivity.class); + startActivity(intent); + finish(); + }); + CookieManager.getInstance().removeAllCookies(aBoolean -> { }); @@ -190,8 +194,7 @@ public class LoginActivity extends BaseActivity { ParseAndInsertNewAccount.parseAndInsertNewAccount(mExecutor, new Handler(), name, accessToken, refreshToken, profileImageUrl, bannerImageUrl, karma, authCode, mRedditDataRoomDatabase.accountDao(), () -> { - Intent resultIntent = new Intent(); - setResult(Activity.RESULT_OK, resultIntent); + EventBus.getDefault().post(new NewUserLoggedInEvent()); finish(); }); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LoginChromeCustomTabActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LoginChromeCustomTabActivity.java new file mode 100644 index 00000000..84c06ea6 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LoginChromeCustomTabActivity.java @@ -0,0 +1,247 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.ActivityNotFoundException; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.widget.Toast; + +import androidx.activity.EdgeToEdge; +import androidx.annotation.NonNull; +import androidx.browser.customtabs.CustomTabColorSchemeParams; +import androidx.browser.customtabs.CustomTabsIntent; +import androidx.browser.customtabs.CustomTabsService; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; + +import org.greenrobot.eventbus.EventBus; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executor; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.FetchMyInfo; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.asynctasks.ParseAndInsertNewAccount; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.NewUserLoggedInEvent; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class LoginChromeCustomTabActivity extends BaseActivity { + + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("current_account") + SharedPreferences mCurrentAccountSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + @Inject + Executor mExecutor; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + super.onCreate(savedInstanceState); + EdgeToEdge.enable(this); + setContentView(R.layout.activity_login_chrome_custom_tab); + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { + Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); + return insets; + }); + + applyCustomTheme(); + + ArrayList<ResolveInfo> resolveInfos = getCustomTabsPackages(getPackageManager()); + if (!resolveInfos.isEmpty()) { + CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); + // add share action to menu list + builder.setShareState(CustomTabsIntent.SHARE_STATE_ON); + builder.setDefaultColorSchemeParams( + new CustomTabColorSchemeParams.Builder() + .setToolbarColor(mCustomThemeWrapper.getColorPrimary()) + .build()); + CustomTabsIntent customTabsIntent = builder.build(); + customTabsIntent.intent.setPackage(resolveInfos.get(0).activityInfo.packageName); + customTabsIntent.intent.putExtra("com.google.android.apps.chrome.EXTRA_OPEN_NEW_INCOGNITO_TAB", true); + + try { + Uri.Builder uriBuilder = Uri.parse(APIUtils.OAUTH_URL).buildUpon(); + uriBuilder.appendQueryParameter(APIUtils.CLIENT_ID_KEY, APIUtils.CLIENT_ID); + uriBuilder.appendQueryParameter(APIUtils.RESPONSE_TYPE_KEY, APIUtils.RESPONSE_TYPE); + uriBuilder.appendQueryParameter(APIUtils.STATE_KEY, APIUtils.STATE); + uriBuilder.appendQueryParameter(APIUtils.REDIRECT_URI_KEY, APIUtils.REDIRECT_URI); + uriBuilder.appendQueryParameter(APIUtils.DURATION_KEY, APIUtils.DURATION); + uriBuilder.appendQueryParameter(APIUtils.SCOPE_KEY, APIUtils.SCOPE); + + customTabsIntent.launchUrl(this, uriBuilder.build()); + } catch (ActivityNotFoundException e) { + // TODO catch this + } + } + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + + Uri uri = intent.getData(); + if (uri == null) { + return; + } + + String authCode = uri.getQueryParameter("code"); + if (authCode != null) { + String state = uri.getQueryParameter("state"); + if (APIUtils.STATE.equals(state)) { + Map<String, String> params = new HashMap<>(); + params.put(APIUtils.GRANT_TYPE_KEY, "authorization_code"); + params.put("code", authCode); + params.put(APIUtils.REDIRECT_URI_KEY, APIUtils.REDIRECT_URI); + + RedditAPI api = mRetrofit.create(RedditAPI.class); + Call<String> accessTokenCall = api.getAccessToken(APIUtils.getHttpBasicAuthHeader(), params); + accessTokenCall.enqueue(new Callback<>() { + @Override + public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) { + if (response.isSuccessful()) { + try { + String accountResponse = response.body(); + if (accountResponse == null) { + //Handle error + return; + } + + JSONObject responseJSON = new JSONObject(accountResponse); + String accessToken = responseJSON.getString(APIUtils.ACCESS_TOKEN_KEY); + String refreshToken = responseJSON.getString(APIUtils.REFRESH_TOKEN_KEY); + + FetchMyInfo.fetchAccountInfo(mOauthRetrofit, mRedditDataRoomDatabase, + accessToken, new FetchMyInfo.FetchMyInfoListener() { + @Override + public void onFetchMyInfoSuccess(String name, String profileImageUrl, String bannerImageUrl, int karma) { + mCurrentAccountSharedPreferences.edit().putString(SharedPreferencesUtils.ACCESS_TOKEN, accessToken) + .putString(SharedPreferencesUtils.ACCOUNT_NAME, name) + .putString(SharedPreferencesUtils.ACCOUNT_IMAGE_URL, profileImageUrl).apply(); + mCurrentAccountSharedPreferences.edit().remove(SharedPreferencesUtils.SUBSCRIBED_THINGS_SYNC_TIME).apply(); + ParseAndInsertNewAccount.parseAndInsertNewAccount(mExecutor, new Handler(), name, accessToken, refreshToken, profileImageUrl, bannerImageUrl, + karma, authCode, mRedditDataRoomDatabase.accountDao(), + () -> { + EventBus.getDefault().post(new NewUserLoggedInEvent()); + finish(); + }); + } + + @Override + public void onFetchMyInfoFailed(boolean parseFailed) { + if (parseFailed) { + Toast.makeText(LoginChromeCustomTabActivity.this, R.string.parse_user_info_error, Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(LoginChromeCustomTabActivity.this, R.string.cannot_fetch_user_info, Toast.LENGTH_SHORT).show(); + } + + finish(); + } + }); + } catch (JSONException e) { + e.printStackTrace(); + Toast.makeText(LoginChromeCustomTabActivity.this, R.string.parse_json_response_error, Toast.LENGTH_SHORT).show(); + finish(); + } + } else { + Toast.makeText(LoginChromeCustomTabActivity.this, R.string.retrieve_token_error, Toast.LENGTH_SHORT).show(); + finish(); + } + } + + @Override + public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) { + Toast.makeText(LoginChromeCustomTabActivity.this, R.string.retrieve_token_error, Toast.LENGTH_SHORT).show(); + t.printStackTrace(); + finish(); + } + }); + } else { + Toast.makeText(this, R.string.something_went_wrong, Toast.LENGTH_SHORT).show(); + finish(); + } + + } else if ("access_denied".equals(uri.getQueryParameter("error"))) { + Toast.makeText(this, R.string.access_denied, Toast.LENGTH_SHORT).show(); + finish(); + } + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + public SharedPreferences getCurrentAccountSharedPreferences() { + return mCurrentAccountSharedPreferences; + } + + @Override + public CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + + } + + private ArrayList<ResolveInfo> getCustomTabsPackages(PackageManager pm) { + // Get default VIEW intent handler. + Intent activityIntent = new Intent() + .setAction(Intent.ACTION_VIEW) + .addCategory(Intent.CATEGORY_BROWSABLE) + .setData(Uri.fromParts("http", "", null)); + + // Get all apps that can handle VIEW intents. + List<ResolveInfo> resolvedActivityList = pm.queryIntentActivities(activityIntent, 0); + ArrayList<ResolveInfo> packagesSupportingCustomTabs = new ArrayList<>(); + for (ResolveInfo info : resolvedActivityList) { + Intent serviceIntent = new Intent(); + serviceIntent.setAction(CustomTabsService.ACTION_CUSTOM_TABS_CONNECTION); + serviceIntent.setPackage(info.activityInfo.packageName); + // Check if this package also resolves the Custom Tabs service. + if (pm.resolveService(serviceIntent, 0) != null) { + packagesSupportingCustomTabs.add(info); + } + } + return packagesSupportingCustomTabs; + } +}
\ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java index aee81c32..b07f7a92 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java @@ -4,7 +4,6 @@ import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO; import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES; import android.Manifest; -import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; @@ -101,6 +100,7 @@ import ml.docilealligator.infinityforreddit.events.ChangeLockBottomAppBarEvent; import ml.docilealligator.infinityforreddit.events.ChangeNSFWEvent; import ml.docilealligator.infinityforreddit.events.ChangeRequireAuthToAccountSectionEvent; import ml.docilealligator.infinityforreddit.events.ChangeShowAvatarOnTheRightInTheNavigationDrawerEvent; +import ml.docilealligator.infinityforreddit.events.NewUserLoggedInEvent; import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.fragments.PostFragment; @@ -141,8 +141,6 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb private static final String NEW_ACCOUNT_NAME_STATE = "NANS"; private static final String INBOX_COUNT_STATE = "ICS"; - private static final int LOGIN_ACTIVITY_REQUEST_CODE = 0; - MultiRedditViewModel multiRedditViewModel; SubscribedSubredditViewModel subscribedSubredditViewModel; AccountViewModel accountViewModel; @@ -798,8 +796,7 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb } else if (stringId == R.string.settings) { intent = new Intent(MainActivity.this, SettingsActivity.class); } else if (stringId == R.string.add_account) { - Intent addAccountIntent = new Intent(MainActivity.this, LoginActivity.class); - startActivityForResult(addAccountIntent, LOGIN_ACTIVITY_REQUEST_CODE); + intent = new Intent(MainActivity.this, LoginActivity.class); } else if (stringId == R.string.anonymous_account) { SwitchToAnonymousMode.switchToAnonymousMode(mRedditDataRoomDatabase, mCurrentAccountSharedPreferences, mExecutor, new Handler(), false, () -> { @@ -1047,17 +1044,6 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb } @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == LOGIN_ACTIVITY_REQUEST_CODE && resultCode == Activity.RESULT_OK) { - Intent intent = new Intent(this, MainActivity.class); - startActivity(intent); - finish(); - } - - super.onActivityResult(requestCode, resultCode, data); - } - - @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main_activity, menu); applyMenuItemTheme(menu); @@ -1290,6 +1276,13 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb navigationWrapper.floatingActionButton.setVisibility(hideFab ? View.GONE : View.VISIBLE); } + @Subscribe + public void onNewUserLoggedInEvent(NewUserLoggedInEvent event) { + Intent intent = new Intent(this, MainActivity.class); + startActivity(intent); + finish(); + } + @Override public void onLongPress() { if (sectionsPagerAdapter != null) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/NewUserLoggedInEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/NewUserLoggedInEvent.java new file mode 100644 index 00000000..9e729270 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/NewUserLoggedInEvent.java @@ -0,0 +1,4 @@ +package ml.docilealligator.infinityforreddit.events; + +public class NewUserLoggedInEvent { +} diff --git a/app/src/main/res/layout/activity_login_chrome_custom_tab.xml b/app/src/main/res/layout/activity_login_chrome_custom_tab.xml new file mode 100644 index 00000000..534433ff --- /dev/null +++ b/app/src/main/res/layout/activity_login_chrome_custom_tab.xml @@ -0,0 +1,10 @@ +<?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:id="@+id/main" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".activities.LoginChromeCustomTabActivity"> + +</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file |