Profile edits for display name and bio are working. Avatar and header image picking are in but not uploaded.

This commit is contained in:
Vavassor 2017-04-17 02:49:56 -04:00
parent e15f1cfcab
commit 18e40855ad
5 changed files with 132 additions and 9 deletions

View file

@ -1,15 +1,26 @@
package com.keylesspalace.tusky; package com.keylesspalace.tusky;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView;
import com.keylesspalace.tusky.entity.Account; import com.keylesspalace.tusky.entity.Account;
import com.keylesspalace.tusky.entity.Profile;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
@ -19,14 +30,18 @@ import retrofit2.Response;
public class EditProfileActivity extends BaseActivity { public class EditProfileActivity extends BaseActivity {
private static final String TAG = "EditProfileActivity"; private static final String TAG = "EditProfileActivity";
private static final int MEDIA_PICK_RESULT = 1;
private static final int PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 1;
@BindView(R.id.edit_profile_display_name) EditText displayNameEditText; @BindView(R.id.edit_profile_display_name) EditText displayNameEditText;
@BindView(R.id.edit_profile_note) EditText noteEditText; @BindView(R.id.edit_profile_note) EditText noteEditText;
@BindView(R.id.edit_profile_avatar) Button avatarButton; @BindView(R.id.edit_profile_avatar) Button avatarButton;
@BindView(R.id.edit_profile_header) Button headerButton; @BindView(R.id.edit_profile_header) Button headerButton;
@BindView(R.id.edit_profile_error) TextView errorText;
private String priorDisplayName; private String priorDisplayName;
private String priorNote; private String priorNote;
private boolean isAlreadySaving;
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
@ -46,11 +61,26 @@ public class EditProfileActivity extends BaseActivity {
if (savedInstanceState != null) { if (savedInstanceState != null) {
priorDisplayName = savedInstanceState.getString("priorDisplayName"); priorDisplayName = savedInstanceState.getString("priorDisplayName");
priorNote = savedInstanceState.getString("priorNote"); priorNote = savedInstanceState.getString("priorNote");
isAlreadySaving = savedInstanceState.getBoolean("isAlreadySaving");
} else { } else {
priorDisplayName = null; priorDisplayName = null;
priorNote = null; priorNote = null;
isAlreadySaving = false;
} }
avatarButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onMediaPick();
}
});
headerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onMediaPick();
}
});
mastodonAPI.accountVerifyCredentials().enqueue(new Callback<Account>() { mastodonAPI.accountVerifyCredentials().enqueue(new Callback<Account>() {
@Override @Override
public void onResponse(Call<Account> call, Response<Account> response) { public void onResponse(Call<Account> call, Response<Account> response) {
@ -62,7 +92,7 @@ public class EditProfileActivity extends BaseActivity {
priorDisplayName = me.getDisplayName(); priorDisplayName = me.getDisplayName();
priorNote = me.note.toString(); priorNote = me.note.toString();
displayNameEditText.setText(priorDisplayName); displayNameEditText.setText(priorDisplayName);
noteEditText.setText(HtmlUtils.fromHtml(priorNote)); noteEditText.setText(priorNote);
} }
@Override @Override
@ -76,6 +106,7 @@ public class EditProfileActivity extends BaseActivity {
protected void onSaveInstanceState(Bundle outState) { protected void onSaveInstanceState(Bundle outState) {
outState.putString("priorDisplayName", priorDisplayName); outState.putString("priorDisplayName", priorDisplayName);
outState.putString("priorNote", priorNote); outState.putString("priorNote", priorNote);
outState.putBoolean("isAlreadySaving", isAlreadySaving);
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
} }
@ -83,6 +114,41 @@ public class EditProfileActivity extends BaseActivity {
Log.e(TAG, "The account failed to load."); Log.e(TAG, "The account failed to load.");
} }
private void onMediaPick() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN &&
ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[] { Manifest.permission.READ_EXTERNAL_STORAGE },
PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
} else {
initiateMediaPicking();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[],
@NonNull int[] grantResults) {
switch (requestCode) {
case PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
initiateMediaPicking();
} else {
errorText.setText(R.string.error_media_upload_permission);
}
break;
}
}
}
private void initiateMediaPicking() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
startActivityForResult(intent, MEDIA_PICK_RESULT);
}
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.edit_profile_toolbar, menu); getMenuInflater().inflate(R.menu.edit_profile_toolbar, menu);
@ -105,6 +171,9 @@ public class EditProfileActivity extends BaseActivity {
} }
private void save() { private void save() {
if (isAlreadySaving) {
return;
}
String newDisplayName = displayNameEditText.getText().toString(); String newDisplayName = displayNameEditText.getText().toString();
if (newDisplayName.isEmpty()) { if (newDisplayName.isEmpty()) {
displayNameEditText.setError(getString(R.string.error_empty)); displayNameEditText.setError(getString(R.string.error_empty));
@ -115,7 +184,7 @@ public class EditProfileActivity extends BaseActivity {
newDisplayName = null; newDisplayName = null;
} }
String newNote = HtmlUtils.toHtml(noteEditText.getText()); String newNote = noteEditText.getText().toString();
if (newNote.isEmpty()) { if (newNote.isEmpty()) {
noteEditText.setError(getString(R.string.error_empty)); noteEditText.setError(getString(R.string.error_empty));
return; return;
@ -125,6 +194,41 @@ public class EditProfileActivity extends BaseActivity {
newNote = null; newNote = null;
} }
mastodonAPI.accountUpdateCredentials(newDisplayName, newNote, null, null); isAlreadySaving = true;
Profile profile = new Profile();
profile.displayName = newDisplayName;
profile.note = newNote;
profile.avatar = null;
profile.header = null;
mastodonAPI.accountUpdateCredentials(profile).enqueue(new Callback<Account>() {
@Override
public void onResponse(Call<Account> call, Response<Account> response) {
if (!response.isSuccessful()) {
onSaveFailure();
return;
}
finish();
}
@Override
public void onFailure(Call<Account> call, Throwable t) {
onSaveFailure();
}
});
}
private void onSaveFailure() {
isAlreadySaving = false;
errorText.setText(getString(R.string.error_media_upload_sending));
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == MEDIA_PICK_RESULT && resultCode == RESULT_OK && data != null) {
Uri uri = data.getData();
Log.d(TAG, "picked: " + uri.toString());
}
} }
} }

View file

@ -20,6 +20,7 @@ import com.keylesspalace.tusky.entity.Account;
import com.keylesspalace.tusky.entity.AppCredentials; import com.keylesspalace.tusky.entity.AppCredentials;
import com.keylesspalace.tusky.entity.Media; import com.keylesspalace.tusky.entity.Media;
import com.keylesspalace.tusky.entity.Notification; import com.keylesspalace.tusky.entity.Notification;
import com.keylesspalace.tusky.entity.Profile;
import com.keylesspalace.tusky.entity.Relationship; import com.keylesspalace.tusky.entity.Relationship;
import com.keylesspalace.tusky.entity.Status; import com.keylesspalace.tusky.entity.Status;
import com.keylesspalace.tusky.entity.StatusContext; import com.keylesspalace.tusky.entity.StatusContext;
@ -29,6 +30,7 @@ import java.util.List;
import okhttp3.MultipartBody; import okhttp3.MultipartBody;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.DELETE; import retrofit2.http.DELETE;
import retrofit2.http.Field; import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded; import retrofit2.http.FormUrlEncoded;
@ -115,11 +117,7 @@ public interface MastodonAPI {
@GET("api/v1/accounts/verify_credentials") @GET("api/v1/accounts/verify_credentials")
Call<Account> accountVerifyCredentials(); Call<Account> accountVerifyCredentials();
@PATCH("api/v1/accounts/update_credentials") @PATCH("api/v1/accounts/update_credentials")
Call<Account> accountUpdateCredentials( Call<Account> accountUpdateCredentials(@Body Profile profile);
@Field("display_name") String displayName,
@Field("note") String note,
@Field("avatar") String avatar,
@Field("header") String header);
@GET("api/v1/accounts/search") @GET("api/v1/accounts/search")
Call<List<Account>> searchAccounts( Call<List<Account>> searchAccounts(
@Query("q") String q, @Query("q") String q,

View file

@ -0,0 +1,17 @@
package com.keylesspalace.tusky.entity;
import com.google.gson.annotations.SerializedName;
public class Profile {
@SerializedName("display_name")
public String displayName;
@SerializedName("note")
public String note;
@SerializedName("avatar")
public String avatar;
@SerializedName("header")
public String header;
}

View file

@ -19,6 +19,11 @@
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:elevation="4dp" /> android:elevation="4dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/edit_profile_error" />
<EditText <EditText
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View file

@ -16,7 +16,6 @@
<string name="error_media_upload_image_or_video">Images and videos cannot both be attached to the same status.</string> <string name="error_media_upload_image_or_video">Images and videos cannot both be attached to the same status.</string>
<string name="error_media_upload_sending">The upload failed.</string> <string name="error_media_upload_sending">The upload failed.</string>
<string name="error_report_too_few_statuses">At least one status must be reported.</string> <string name="error_report_too_few_statuses">At least one status must be reported.</string>
<string name="error_empty">This cannot be empty.</string>
<string name="title_home">Home</string> <string name="title_home">Home</string>
<string name="title_notifications">Notifications</string> <string name="title_notifications">Notifications</string>