Allow login with email.

Skip the call to api/v3/user, which only works with username, and instead retrieves the user information from the api/v3/site call, that was already being performed.
This commit is contained in:
tinsukE 2024-01-03 15:15:07 +01:00
parent 02bed2eb3b
commit e7b61e363b
7 changed files with 145 additions and 197 deletions

View File

@ -1,99 +0,0 @@
package eu.toldi.infinityforlemmy;
import android.os.AsyncTask;
import androidx.annotation.NonNull;
import org.json.JSONException;
import org.json.JSONObject;
import eu.toldi.infinityforlemmy.apis.LemmyAPI;
import eu.toldi.infinityforlemmy.utils.LemmyUtils;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Retrofit;
public class FetchMyInfo {
public static void fetchAccountInfo(final Retrofit retrofit, RedditDataRoomDatabase redditDataRoomDatabase,
String username,String accessToken, final FetchMyInfoListener fetchMyInfoListener) {
LemmyAPI api = retrofit.create(LemmyAPI.class);
Call<String> userInfo = api.userInfo(username,accessToken);
userInfo.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) {
if (response.isSuccessful()) {
new ParseAndSaveAccountInfoAsyncTask(response.body(), redditDataRoomDatabase, fetchMyInfoListener).execute();
} else {
fetchMyInfoListener.onFetchMyInfoFailed(false);
}
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
fetchMyInfoListener.onFetchMyInfoFailed(false);
}
});
}
public interface FetchMyInfoListener {
void onFetchMyInfoSuccess(String name, String display_name,String profileImageUrl, String bannerImageUrl);
void onFetchMyInfoFailed(boolean parseFailed);
}
private static class ParseAndSaveAccountInfoAsyncTask extends AsyncTask<Void, Void, Void> {
private JSONObject jsonResponse;
private RedditDataRoomDatabase redditDataRoomDatabase;
private FetchMyInfoListener fetchMyInfoListener;
private boolean parseFailed;
private String name;
private String profileImageUrl;
private String bannerImageUrl;
private String display_name;
ParseAndSaveAccountInfoAsyncTask(String response, RedditDataRoomDatabase redditDataRoomDatabase,
FetchMyInfoListener fetchMyInfoListener) {
try {
jsonResponse = new JSONObject(response);
this.redditDataRoomDatabase = redditDataRoomDatabase;
this.fetchMyInfoListener = fetchMyInfoListener;
parseFailed = false;
} catch (JSONException e) {
fetchMyInfoListener.onFetchMyInfoFailed(true);
}
}
@Override
protected Void doInBackground(Void... voids) {
try {
JSONObject person = jsonResponse.getJSONObject("person_view").getJSONObject("person");
name = LemmyUtils.actorID2FullName(person.getString("actor_id"));
if (!person.isNull("avatar")) {
profileImageUrl = person.getString("avatar");
}
if (!person.isNull("banner")) {
bannerImageUrl = person.getString("banner");
}
display_name = (person.has("display_name")) ? person.getString("display_name") : person.getString("name");
redditDataRoomDatabase.accountDao().updateAccountInfo(name, profileImageUrl, bannerImageUrl);
} catch (JSONException e) {
parseFailed = true;
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
if (!parseFailed) {
fetchMyInfoListener.onFetchMyInfoSuccess(name,display_name, profileImageUrl, bannerImageUrl);
} else {
fetchMyInfoListener.onFetchMyInfoFailed(true);
}
}
}
}

View File

@ -42,6 +42,7 @@ import eu.toldi.infinityforlemmy.site.FetchSiteInfo;
import eu.toldi.infinityforlemmy.site.SiteInfo; import eu.toldi.infinityforlemmy.site.SiteInfo;
import eu.toldi.infinityforlemmy.site.SiteStatistics; import eu.toldi.infinityforlemmy.site.SiteStatistics;
import eu.toldi.infinityforlemmy.user.BasicUserInfo; import eu.toldi.infinityforlemmy.user.BasicUserInfo;
import eu.toldi.infinityforlemmy.user.MyUserInfo;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon; import io.noties.markwon.Markwon;
@ -170,7 +171,7 @@ public class InstanceInfoActivity extends BaseActivity {
private void fetchInstanceInfo() { private void fetchInstanceInfo() {
FetchSiteInfo.fetchSiteInfo(mRetorifitHolder.getRetrofit(), null, new FetchSiteInfo.FetchSiteInfoListener() { FetchSiteInfo.fetchSiteInfo(mRetorifitHolder.getRetrofit(), null, new FetchSiteInfo.FetchSiteInfoListener() {
@Override @Override
public void onFetchSiteInfoSuccess(SiteInfo siteInfo) { public void onFetchSiteInfoSuccess(SiteInfo siteInfo, MyUserInfo myUserInfo) {
mLoadingConstraintLayout.setVisibility(View.GONE); mLoadingConstraintLayout.setVisibility(View.GONE);
toolbar.setTitle(siteInfo.getName()); toolbar.setTitle(siteInfo.getName());
if (siteInfo.getSidebar() != null) { if (siteInfo.getSidebar() != null) {
@ -197,7 +198,7 @@ public class InstanceInfoActivity extends BaseActivity {
} }
@Override @Override
public void onFetchSiteInfoFailed() { public void onFetchSiteInfoFailed(boolean parseFailed) {
} }
}); });

View File

@ -39,7 +39,6 @@ import javax.inject.Named;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import eu.toldi.infinityforlemmy.FetchMyInfo;
import eu.toldi.infinityforlemmy.Infinity; import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.R; import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; import eu.toldi.infinityforlemmy.RedditDataRoomDatabase;
@ -55,6 +54,7 @@ import eu.toldi.infinityforlemmy.lemmyverse.LemmyInstance;
import eu.toldi.infinityforlemmy.lemmyverse.LemmyVerseFetchInstances; import eu.toldi.infinityforlemmy.lemmyverse.LemmyVerseFetchInstances;
import eu.toldi.infinityforlemmy.site.FetchSiteInfo; import eu.toldi.infinityforlemmy.site.FetchSiteInfo;
import eu.toldi.infinityforlemmy.site.SiteInfo; import eu.toldi.infinityforlemmy.site.SiteInfo;
import eu.toldi.infinityforlemmy.user.MyUserInfo;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
import eu.toldi.infinityforlemmy.utils.Utils; import eu.toldi.infinityforlemmy.utils.Utils;
import retrofit2.Call; import retrofit2.Call;
@ -205,62 +205,52 @@ public class LoginActivity extends BaseActivity {
String accessToken = responseJSON.getString("jwt"); String accessToken = responseJSON.getString("jwt");
mRetrofit.setAccessToken(null); mRetrofit.setAccessToken(null);
FetchMyInfo.fetchAccountInfo(mRetrofit.getRetrofit(), mRedditDataRoomDatabase, username, FetchSiteInfo.fetchSiteInfo(mRetrofit.getRetrofit(), accessToken, new FetchSiteInfo.FetchSiteInfoListener() {
accessToken, new FetchMyInfo.FetchMyInfoListener() { @Override
@Override public void onFetchSiteInfoSuccess(SiteInfo siteInfo, MyUserInfo myUserInfo) {
public void onFetchMyInfoSuccess(String name, String display_name, String profileImageUrl, String bannerImageUrl) { if (myUserInfo == null) {
FetchSiteInfo.fetchSiteInfo(mRetrofit.getRetrofit(), accessToken, new FetchSiteInfo.FetchSiteInfoListener() { finish();
@Override Toast.makeText(LoginActivity.this, R.string.parse_user_info_error, Toast.LENGTH_SHORT).show();
public void onFetchSiteInfoSuccess(SiteInfo siteInfo) { }
boolean canDownvote = siteInfo.isEnable_downvotes();
ParseAndInsertNewAccount.parseAndInsertNewAccount(mExecutor, new Handler(), name, display_name, accessToken, profileImageUrl, bannerImageUrl, authCode, finalInstance, canDownvote, mRedditDataRoomDatabase.accountDao(),
() -> {
Intent resultIntent = new Intent();
setResult(Activity.RESULT_OK, resultIntent);
finish();
});
mCurrentAccountSharedPreferences.edit().putBoolean(SharedPreferencesUtils.CAN_DOWNVOTE, canDownvote).apply();
String[] version = siteInfo.getVersion().split("\\.");
if (version.length > 0) {
Log.d("SwitchAccount", "Lemmy Version: " + version[0] + "." + version[1]);
int majorVersion = Integer.parseInt(version[0]);
int minorVersion = Integer.parseInt(version[1]);
if (majorVersion > 0 || (majorVersion == 0 && minorVersion >= 19)) {
mRetrofit.setAccessToken(accessToken);
mCurrentAccountSharedPreferences.edit().putBoolean(SharedPreferencesUtils.BEARER_TOKEN_AUTH, true).apply();
}
}
}
@Override boolean canDownvote = siteInfo.isEnable_downvotes();
public void onFetchSiteInfoFailed() { ParseAndInsertNewAccount.parseAndInsertNewAccount(mExecutor, new Handler(), myUserInfo.getName(), myUserInfo.getDisplayName(), accessToken, myUserInfo.getProfileImageUrl(), myUserInfo.getBannerImageUrl(), authCode, finalInstance, canDownvote, mRedditDataRoomDatabase.accountDao(),
ParseAndInsertNewAccount.parseAndInsertNewAccount(mExecutor, new Handler(), name,display_name, accessToken, profileImageUrl, bannerImageUrl, authCode, finalInstance,true, mRedditDataRoomDatabase.accountDao(), () -> {
() -> { Intent resultIntent = new Intent();
Intent resultIntent = new Intent(); setResult(Activity.RESULT_OK, resultIntent);
setResult(Activity.RESULT_OK, resultIntent); finish();
finish();
});
mCurrentAccountSharedPreferences.edit().putBoolean(SharedPreferencesUtils.CAN_DOWNVOTE, true).apply();
}
}); });
mCurrentAccountSharedPreferences.edit().putString(SharedPreferencesUtils.ACCESS_TOKEN, accessToken) mCurrentAccountSharedPreferences.edit()
.putString(SharedPreferencesUtils.ACCOUNT_NAME, display_name) .putString(SharedPreferencesUtils.ACCESS_TOKEN, accessToken)
.putString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, name) .putString(SharedPreferencesUtils.ACCOUNT_NAME, myUserInfo.getDisplayName())
.putString(SharedPreferencesUtils.ACCOUNT_INSTANCE,finalInstance) .putString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, myUserInfo.getName())
.putString(SharedPreferencesUtils.ACCOUNT_IMAGE_URL, profileImageUrl).apply(); .putString(SharedPreferencesUtils.ACCOUNT_INSTANCE,finalInstance)
.putString(SharedPreferencesUtils.ACCOUNT_IMAGE_URL, myUserInfo.getProfileImageUrl())
.putBoolean(SharedPreferencesUtils.CAN_DOWNVOTE, canDownvote).apply();
String[] version = siteInfo.getVersion().split("\\.");
if (version.length > 0) {
Log.d("SwitchAccount", "Lemmy Version: " + version[0] + "." + version[1]);
int majorVersion = Integer.parseInt(version[0]);
int minorVersion = Integer.parseInt(version[1]);
if (majorVersion > 0 || (majorVersion == 0 && minorVersion >= 19)) {
mRetrofit.setAccessToken(accessToken);
mCurrentAccountSharedPreferences.edit().putBoolean(SharedPreferencesUtils.BEARER_TOKEN_AUTH, true).apply();
} }
}
}
@Override @Override
public void onFetchMyInfoFailed(boolean parseFailed) { public void onFetchSiteInfoFailed(boolean parseFailed) {
if (parseFailed) { if (parseFailed) {
Toast.makeText(LoginActivity.this, R.string.parse_user_info_error, Toast.LENGTH_SHORT).show(); finish();
} else { Toast.makeText(LoginActivity.this, R.string.parse_user_info_error, Toast.LENGTH_SHORT).show();
Toast.makeText(LoginActivity.this, R.string.cannot_fetch_user_info, Toast.LENGTH_SHORT).show(); } else {
} progressBar.setVisibility(ProgressBar.GONE);
loginButton.setEnabled(true);
finish(); Toast.makeText(LoginActivity.this, R.string.cannot_fetch_user_info, Toast.LENGTH_SHORT).show();
} }
}); }
});
} catch (JSONException e) { } catch (JSONException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }

View File

@ -11,6 +11,7 @@ import eu.toldi.infinityforlemmy.RetrofitHolder;
import eu.toldi.infinityforlemmy.account.Account; import eu.toldi.infinityforlemmy.account.Account;
import eu.toldi.infinityforlemmy.site.FetchSiteInfo; import eu.toldi.infinityforlemmy.site.FetchSiteInfo;
import eu.toldi.infinityforlemmy.site.SiteInfo; import eu.toldi.infinityforlemmy.site.SiteInfo;
import eu.toldi.infinityforlemmy.user.MyUserInfo;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
public class SwitchAccount { public class SwitchAccount {
@ -33,7 +34,7 @@ public class SwitchAccount {
retrofitHolder.setAccessToken(null); retrofitHolder.setAccessToken(null);
FetchSiteInfo.fetchSiteInfo(retrofitHolder.getRetrofit(), account.getAccessToken(), new FetchSiteInfo.FetchSiteInfoListener() { FetchSiteInfo.fetchSiteInfo(retrofitHolder.getRetrofit(), account.getAccessToken(), new FetchSiteInfo.FetchSiteInfoListener() {
@Override @Override
public void onFetchSiteInfoSuccess(SiteInfo siteInfo) { public void onFetchSiteInfoSuccess(SiteInfo siteInfo, MyUserInfo myUserInfo) {
boolean canDownvote = siteInfo.isEnable_downvotes(); boolean canDownvote = siteInfo.isEnable_downvotes();
currentAccountSharedPreferences.edit().putBoolean(SharedPreferencesUtils.CAN_DOWNVOTE, canDownvote).apply(); currentAccountSharedPreferences.edit().putBoolean(SharedPreferencesUtils.CAN_DOWNVOTE, canDownvote).apply();
String[] version = siteInfo.getVersion().split("\\."); String[] version = siteInfo.getVersion().split("\\.");
@ -49,7 +50,7 @@ public class SwitchAccount {
} }
@Override @Override
public void onFetchSiteInfoFailed() { public void onFetchSiteInfoFailed(boolean parseFailed) {
Log.e("SwitchAccount", "Failed to fetch site info"); Log.e("SwitchAccount", "Failed to fetch site info");
currentAccountSharedPreferences.edit().putBoolean(SharedPreferencesUtils.CAN_DOWNVOTE, true).apply(); currentAccountSharedPreferences.edit().putBoolean(SharedPreferencesUtils.CAN_DOWNVOTE, true).apply();
} }

View File

@ -1,6 +1,9 @@
package eu.toldi.infinityforlemmy.site; package eu.toldi.infinityforlemmy.site;
import org.json.JSONException;
import eu.toldi.infinityforlemmy.apis.LemmyAPI; import eu.toldi.infinityforlemmy.apis.LemmyAPI;
import eu.toldi.infinityforlemmy.user.MyUserInfo;
import retrofit2.Retrofit; import retrofit2.Retrofit;
public class FetchSiteInfo { public class FetchSiteInfo {
@ -11,24 +14,29 @@ public class FetchSiteInfo {
@Override @Override
public void onResponse(retrofit2.Call<String> call, retrofit2.Response<String> response) { public void onResponse(retrofit2.Call<String> call, retrofit2.Response<String> response) {
if (response.isSuccessful()) { if (response.isSuccessful()) {
String siteInfoJson = response.body(); try {
SiteInfo siteInfo = SiteInfo.parseSiteInfo(siteInfoJson); String siteInfoJson = response.body();
fetchSiteInfoListener.onFetchSiteInfoSuccess(siteInfo); SiteInfo siteInfo = SiteInfo.parseSiteInfo(siteInfoJson);
MyUserInfo myUserInfo = MyUserInfo.parseFromSiteInfo(siteInfoJson);
fetchSiteInfoListener.onFetchSiteInfoSuccess(siteInfo, myUserInfo);
} catch (JSONException e) {
fetchSiteInfoListener.onFetchSiteInfoFailed(true);
}
} else { } else {
fetchSiteInfoListener.onFetchSiteInfoFailed(); fetchSiteInfoListener.onFetchSiteInfoFailed(false);
} }
} }
@Override @Override
public void onFailure(retrofit2.Call<String> call, Throwable t) { public void onFailure(retrofit2.Call<String> call, Throwable t) {
fetchSiteInfoListener.onFetchSiteInfoFailed(); fetchSiteInfoListener.onFetchSiteInfoFailed(false);
} }
} }
); );
} }
public interface FetchSiteInfoListener { public interface FetchSiteInfoListener {
void onFetchSiteInfoSuccess(SiteInfo siteInfo); void onFetchSiteInfoSuccess(SiteInfo siteInfo, MyUserInfo myUserInfo);
void onFetchSiteInfoFailed(); void onFetchSiteInfoFailed(boolean parseFailed);
} }
} }

View File

@ -79,45 +79,40 @@ public class SiteInfo {
return version; return version;
} }
public static SiteInfo parseSiteInfo(String siteInfoJson) { public static SiteInfo parseSiteInfo(String siteInfoJson) throws JSONException {
try { JSONObject siteInfo = new JSONObject(siteInfoJson);
JSONObject siteInfo = new JSONObject(siteInfoJson); JSONObject siteView = siteInfo.getJSONObject("site_view");
JSONObject siteView = siteInfo.getJSONObject("site_view"); JSONObject site = siteView.getJSONObject("site");
JSONObject site = siteView.getJSONObject("site"); JSONObject localSite = siteView.getJSONObject("local_site");
JSONObject localSite = siteView.getJSONObject("local_site");
int id = site.getInt("id"); int id = site.getInt("id");
String name = site.getString("name"); String name = site.getString("name");
String sidebar = null; String sidebar = null;
if (site.has("sidebar")) if (site.has("sidebar"))
sidebar = site.getString("sidebar"); sidebar = site.getString("sidebar");
String version = siteInfo.getString("version"); String version = siteInfo.getString("version");
String description = null; String description = null;
if (site.has("description")) if (site.has("description"))
description = site.getString("description"); description = site.getString("description");
boolean enable_downvotes = localSite.getBoolean("enable_downvotes"); boolean enable_downvotes = localSite.getBoolean("enable_downvotes");
boolean enable_nsfw = localSite.getBoolean("enable_nsfw"); boolean enable_nsfw = localSite.getBoolean("enable_nsfw");
boolean community_creation_admin_only = localSite.getBoolean("community_creation_admin_only"); boolean community_creation_admin_only = localSite.getBoolean("community_creation_admin_only");
JSONObject counts = siteView.getJSONObject("counts"); JSONObject counts = siteView.getJSONObject("counts");
List<BasicUserInfo> admins = new ArrayList<>(); List<BasicUserInfo> admins = new ArrayList<>();
if (siteInfo.has("admins")) { if (siteInfo.has("admins")) {
JSONArray adminsJson = siteInfo.getJSONArray("admins"); JSONArray adminsJson = siteInfo.getJSONArray("admins");
for (int i = 0; i < adminsJson.length(); i++) { for (int i = 0; i < adminsJson.length(); i++) {
JSONObject adminJson = adminsJson.getJSONObject(i).getJSONObject("person"); JSONObject adminJson = adminsJson.getJSONObject(i).getJSONObject("person");
admins.add(new BasicUserInfo(adminJson.getInt("id"), adminJson.getString("name"), admins.add(new BasicUserInfo(adminJson.getInt("id"), adminJson.getString("name"),
LemmyUtils.actorID2FullName(adminJson.getString("actor_id")), adminJson.optString("avatar ", ""), LemmyUtils.actorID2FullName(adminJson.getString("actor_id")), adminJson.optString("avatar ", ""),
adminJson.optString("display_name", adminJson.getString("name"))) adminJson.optString("display_name", adminJson.getString("name")))
); );
}
} }
return new SiteInfo(id, name, version, sidebar, description, enable_downvotes, enable_nsfw, community_creation_admin_only, admins, SiteStatistics.parseSiteStatistics(counts));
} catch (JSONException e) {
e.printStackTrace();
return null;
} }
return new SiteInfo(id, name, version, sidebar, description, enable_downvotes, enable_nsfw, community_creation_admin_only, admins, SiteStatistics.parseSiteStatistics(counts));
} }
} }

View File

@ -0,0 +1,52 @@
package eu.toldi.infinityforlemmy.user;
import org.json.JSONException;
import org.json.JSONObject;
public class MyUserInfo {
private final String name;
private final String displayName;
private final String profileImageUrl;
private final String bannerImageUrl;
private MyUserInfo(String name, String displayName, String profileImageUrl, String bannerImageUrl) {
this.name = name;
this.displayName = displayName;
this.profileImageUrl = profileImageUrl;
this.bannerImageUrl = bannerImageUrl;
}
public String getName() {
return name;
}
public String getDisplayName() {
return displayName;
}
public String getProfileImageUrl() {
return profileImageUrl;
}
public String getBannerImageUrl() {
return bannerImageUrl;
}
public static MyUserInfo parseFromSiteInfo(String siteInfoJson) throws JSONException {
JSONObject siteInfo = new JSONObject(siteInfoJson);
JSONObject myUser = siteInfo.optJSONObject("my_user");
if (myUser == null) {
return null;
}
JSONObject localUserView = myUser.getJSONObject("local_user_view");
JSONObject person = localUserView.getJSONObject("person");
String name = person.getString("name");
String displayName = person.optString("display_name");
String avatar = person.optString("avatar");
String banner = person.optString("banner");
return new MyUserInfo(name, displayName, avatar, banner);
}
}