Onboarding & signup

This commit is contained in:
Grishka
2022-03-10 18:48:24 +03:00
parent 86892e4103
commit 03c0b183cb
80 changed files with 2024 additions and 261 deletions

View File

@@ -8,6 +8,7 @@ import android.util.Log;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonIOException;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
@@ -119,10 +120,19 @@ public class MastodonAPIController{
if(response.isSuccessful()){
T respObj;
try{
if(req.respTypeToken!=null)
respObj=gson.fromJson(reader, req.respTypeToken.getType());
else
respObj=gson.fromJson(reader, req.respClass);
if(BuildConfig.DEBUG){
JsonElement respJson=JsonParser.parseReader(reader);
Log.d(TAG, "["+(session==null ? "no-auth" : session.getID())+"] response body: "+respJson);
if(req.respTypeToken!=null)
respObj=gson.fromJson(respJson, req.respTypeToken.getType());
else
respObj=gson.fromJson(respJson, req.respClass);
}else{
if(req.respTypeToken!=null)
respObj=gson.fromJson(reader, req.respTypeToken.getType());
else
respObj=gson.fromJson(reader, req.respClass);
}
}catch(JsonIOException|JsonSyntaxException x){
if(BuildConfig.DEBUG)
Log.w(TAG, "["+(session==null ? "no-auth" : session.getID())+"] "+response+" error parsing or reading body", x);
@@ -146,6 +156,7 @@ public class MastodonAPIController{
}else{
try{
JsonObject error=JsonParser.parseReader(reader).getAsJsonObject();
Log.w(TAG, "["+(session==null ? "no-auth" : session.getID())+"] "+response+" received error: "+error);
req.onError(error.get("error").getAsString());
}catch(JsonIOException|JsonSyntaxException x){
req.onError(response.code()+" "+response.message());

View File

@@ -0,0 +1,24 @@
package org.joinmastodon.android.api.requests.accounts;
import org.joinmastodon.android.api.MastodonAPIRequest;
import org.joinmastodon.android.model.Token;
public class RegisterAccount extends MastodonAPIRequest<Token>{
public RegisterAccount(String username, String email, String password, String locale, String reason){
super(HttpMethod.POST, "/accounts", Token.class);
setRequestBody(new Body(username, email, password, locale, reason));
}
private static class Body{
public String username, email, password, locale, reason;
public boolean agreement=true;
public Body(String username, String email, String password, String locale, String reason){
this.username=username;
this.email=email;
this.password=password;
this.locale=locale;
this.reason=reason;
}
}
}

View File

@@ -0,0 +1,19 @@
package org.joinmastodon.android.api.requests.accounts;
import org.joinmastodon.android.api.MastodonAPIRequest;
public class ResendConfirmationEmail extends MastodonAPIRequest<Object>{
public ResendConfirmationEmail(String email){
super(HttpMethod.POST, "/emails/confirmations", Object.class);
// setRequestBody(new Body(email));
setRequestBody(new Object());
}
private static class Body{
public String email;
public Body(String email){
this.email=email;
}
}
}

View File

@@ -8,6 +8,7 @@ import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.AccountField;
import org.joinmastodon.android.ui.utils.UiUtils;
import java.io.File;
import java.util.List;
import okhttp3.MultipartBody;
@@ -16,6 +17,7 @@ import okhttp3.RequestBody;
public class UpdateAccountCredentials extends MastodonAPIRequest<Account>{
private String displayName, bio;
private Uri avatar, cover;
private File avatarFile, coverFile;
private List<AccountField> fields;
public UpdateAccountCredentials(String displayName, String bio, Uri avatar, Uri cover, List<AccountField> fields){
@@ -27,6 +29,15 @@ public class UpdateAccountCredentials extends MastodonAPIRequest<Account>{
this.fields=fields;
}
public UpdateAccountCredentials(String displayName, String bio, File avatar, File cover, List<AccountField> fields){
super(HttpMethod.PATCH, "/accounts/update_credentials", Account.class);
this.displayName=displayName;
this.bio=bio;
this.avatarFile=avatar;
this.coverFile=cover;
this.fields=fields;
}
@Override
public RequestBody getRequestBody(){
MultipartBody.Builder bldr=new MultipartBody.Builder()
@@ -36,9 +47,13 @@ public class UpdateAccountCredentials extends MastodonAPIRequest<Account>{
if(avatar!=null){
bldr.addFormDataPart("avatar", UiUtils.getFileName(avatar), new ContentUriRequestBody(avatar, null));
}else if(avatarFile!=null){
bldr.addFormDataPart("avatar", avatarFile.getName(), RequestBody.create(UiUtils.getFileMediaType(avatarFile), avatarFile));
}
if(cover!=null){
bldr.addFormDataPart("header", UiUtils.getFileName(cover), new ContentUriRequestBody(cover, null));
}else if(coverFile!=null){
bldr.addFormDataPart("header", coverFile.getName(), RequestBody.create(UiUtils.getFileMediaType(coverFile), coverFile));
}
if(fields.isEmpty()){
bldr.addFormDataPart("fields_attributes[0][name]", "").addFormDataPart("fields_attributes[0][value]", "");

View File

@@ -1,13 +1,15 @@
package org.joinmastodon.android.api.requests.oauth;
import com.google.gson.annotations.SerializedName;
import org.joinmastodon.android.api.MastodonAPIRequest;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.model.Token;
public class GetOauthToken extends MastodonAPIRequest<Token>{
public GetOauthToken(String clientID, String clientSecret, String code){
public GetOauthToken(String clientID, String clientSecret, String code, GrantType grantType){
super(HttpMethod.POST, "/oauth/token", Token.class);
setRequestBody(new Request(clientID, clientSecret, code));
setRequestBody(new Request(clientID, clientSecret, code, grantType));
}
@Override
@@ -16,17 +18,25 @@ public class GetOauthToken extends MastodonAPIRequest<Token>{
}
private static class Request{
public String grantType="authorization_code";
public GrantType grantType;
public String clientId;
public String clientSecret;
public String redirectUri=AccountSessionManager.REDIRECT_URI;
public String scope=AccountSessionManager.SCOPE;
public String code;
public Request(String clientId, String clientSecret, String code){
public Request(String clientId, String clientSecret, String code, GrantType grantType){
this.clientId=clientId;
this.clientSecret=clientSecret;
this.code=code;
this.grantType=grantType;
}
}
public enum GrantType{
@SerializedName("authorization_code")
AUTHORIZATION_CODE,
@SerializedName("client_credentials")
CLIENT_CREDENTIALS
}
}

View File

@@ -16,16 +16,18 @@ public class AccountSession{
public long infoLastUpdated;
public long instanceLastUpdated;
public Instance instance;
public boolean activated=true;
private transient MastodonAPIController apiController;
private transient StatusInteractionController statusInteractionController;
AccountSession(Token token, Account self, Application app, String domain, int tootCharLimit, Instance instance){
AccountSession(Token token, Account self, Application app, String domain, int tootCharLimit, Instance instance, boolean activated){
this.token=token;
this.self=self;
this.domain=domain;
this.app=app;
this.tootCharLimit=tootCharLimit;
this.instance=instance;
this.activated=activated;
instanceLastUpdated=infoLastUpdated=System.currentTimeMillis();
}

View File

@@ -1,5 +1,6 @@
package org.joinmastodon.android.api.session;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.SharedPreferences;
@@ -36,10 +37,12 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.browser.customtabs.CustomTabsIntent;
import me.grishka.appkit.api.Callback;
import me.grishka.appkit.api.ErrorResponse;
@@ -84,8 +87,8 @@ public class AccountSessionManager{
MastodonAPIController.runInBackground(()->readCustomEmojis(domains));
}
public void addAccount(Instance instance, Token token, Account self, Application app){
AccountSession session=new AccountSession(token, self, app, instance.uri, instance.maxTootChars, instance);
public void addAccount(Instance instance, Token token, Account self, Application app, boolean active){
AccountSession session=new AccountSession(token, self, app, instance.uri, instance.maxTootChars, instance, active);
sessions.put(session.getID(), session);
lastActiveAccountID=session.getID();
writeAccountsFile();
@@ -159,18 +162,13 @@ public class AccountSessionManager{
return unauthenticatedApiController;
}
public void authenticate(Context context, Instance instance){
public void authenticate(Activity activity, Instance instance){
authenticatingInstance=instance;
ProgressDialog progress=new ProgressDialog(context);
progress.setMessage(context.getString(R.string.preparing_auth));
progress.setCancelable(false);
progress.show();
new CreateOAuthApp()
.setCallback(new Callback<Application>(){
.setCallback(new Callback<>(){
@Override
public void onSuccess(Application result){
authenticatingApp=result;
progress.dismiss();
Uri uri=new Uri.Builder()
.scheme("https")
.authority(instance.uri)
@@ -184,15 +182,15 @@ public class AccountSessionManager{
new CustomTabsIntent.Builder()
.setShareState(CustomTabsIntent.SHARE_STATE_OFF)
.build()
.launchUrl(context, uri);
.launchUrl(activity, uri);
}
@Override
public void onError(ErrorResponse error){
error.showToast(context);
progress.dismiss();
error.showToast(activity);
}
})
.wrapProgress(activity, R.string.preparing_auth, false)
.execNoAuth(instance.uri);
}