Provisional profile editor complete.

This commit is contained in:
Vavassor 2017-04-20 18:56:36 -04:00
parent 5941a2f5b3
commit b9f0c51e70
6 changed files with 170 additions and 97 deletions

View File

@ -96,8 +96,12 @@ public class BaseActivity extends AppCompatActivity {
overridePendingTransition(R.anim.slide_from_left, R.anim.slide_to_right); overridePendingTransition(R.anim.slide_from_left, R.anim.slide_to_right);
} }
protected SharedPreferences getPrivatePreferences() {
return getSharedPreferences(getString(R.string.preferences_file_key), Context.MODE_PRIVATE);
}
protected String getAccessToken() { protected String getAccessToken() {
SharedPreferences preferences = getSharedPreferences(getString(R.string.preferences_file_key), Context.MODE_PRIVATE); SharedPreferences preferences = getPrivatePreferences();
return preferences.getString("accessToken", null); return preferences.getString("accessToken", null);
} }
@ -107,7 +111,7 @@ public class BaseActivity extends AppCompatActivity {
} }
protected String getBaseUrl() { protected String getBaseUrl() {
SharedPreferences preferences = getSharedPreferences(getString(R.string.preferences_file_key), Context.MODE_PRIVATE); SharedPreferences preferences = getPrivatePreferences();
return "https://" + preferences.getString("domain", null); return "https://" + preferences.getString("domain", null);
} }
@ -157,8 +161,7 @@ public class BaseActivity extends AppCompatActivity {
} }
protected void redirectIfNotLoggedIn() { protected void redirectIfNotLoggedIn() {
SharedPreferences preferences = getSharedPreferences( SharedPreferences preferences = getPrivatePreferences();
getString(R.string.preferences_file_key), Context.MODE_PRIVATE);
String domain = preferences.getString("domain", null); String domain = preferences.getString("domain", null);
String accessToken = preferences.getString("accessToken", null); String accessToken = preferences.getString("accessToken", null);
if (domain == null || accessToken == null) { if (domain == null || accessToken == null) {

View File

@ -12,6 +12,7 @@ import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
@ -24,7 +25,6 @@ import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView;
import com.keylesspalace.tusky.entity.Account; import com.keylesspalace.tusky.entity.Account;
import com.keylesspalace.tusky.entity.Profile; import com.keylesspalace.tusky.entity.Profile;
@ -66,7 +66,7 @@ public class EditProfileActivity extends BaseActivity {
@BindView(R.id.edit_profile_header) Button headerButton; @BindView(R.id.edit_profile_header) Button headerButton;
@BindView(R.id.edit_profile_header_preview) ImageView headerPreview; @BindView(R.id.edit_profile_header_preview) ImageView headerPreview;
@BindView(R.id.edit_profile_header_progress) ProgressBar headerProgress; @BindView(R.id.edit_profile_header_progress) ProgressBar headerProgress;
@BindView(R.id.edit_profile_error) TextView errorText; @BindView(R.id.edit_profile_save_progress) ProgressBar saveProgress;
private String priorDisplayName; private String priorDisplayName;
private String priorNote; private String priorNote;
@ -131,7 +131,7 @@ public class EditProfileActivity extends BaseActivity {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
headerPreview.setImageBitmap(null); headerPreview.setImageBitmap(null);
avatarPreview.setVisibility(View.GONE); headerPreview.setVisibility(View.GONE);
headerBase64 = null; headerBase64 = null;
} }
}); });
@ -173,7 +173,11 @@ public class EditProfileActivity extends BaseActivity {
} }
private void onMediaPick(PickType pickType) { private void onMediaPick(PickType pickType) {
beginMediaPicking(pickType); if (currentlyPicking != PickType.NOTHING) {
// Ignore inputs if another pick operation is still occurring.
return;
}
currentlyPicking = pickType;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN &&
ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) { != PackageManager.PERMISSION_GRANTED) {
@ -195,7 +199,8 @@ public class EditProfileActivity extends BaseActivity {
initiateMediaPicking(); initiateMediaPicking();
} else { } else {
endMediaPicking(); endMediaPicking();
errorText.setText(R.string.error_media_upload_permission); Snackbar.make(avatarButton, R.string.error_media_upload_permission,
Snackbar.LENGTH_LONG).show();
} }
break; break;
} }
@ -205,18 +210,11 @@ public class EditProfileActivity extends BaseActivity {
private void initiateMediaPicking() { private void initiateMediaPicking() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE); intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*"); intent.setType("image/*");
switch (currentlyPicking) { switch (currentlyPicking) {
case AVATAR: { case AVATAR: { startActivityForResult(intent, AVATAR_PICK_RESULT); break; }
startActivityForResult(intent, AVATAR_PICK_RESULT); case HEADER: { startActivityForResult(intent, HEADER_PICK_RESULT); break; }
break;
}
case HEADER: {
startActivityForResult(intent, HEADER_PICK_RESULT);
break;
}
} }
} }
@Override @Override
@ -263,11 +261,16 @@ public class EditProfileActivity extends BaseActivity {
// If it's not any different, don't patch it. // If it's not any different, don't patch it.
newNote = null; newNote = null;
} }
if (newDisplayName == null && newNote == null && avatarBase64 == null
&& headerBase64 == null) {
// If nothing is changed, then there's nothing to save.
return;
}
saveProgress.setVisibility(View.VISIBLE);
isAlreadySaving = true; isAlreadySaving = true;
Log.d(TAG, "avatar " + avatarBase64);
Profile profile = new Profile(); Profile profile = new Profile();
profile.displayName = newDisplayName; profile.displayName = newDisplayName;
profile.note = newNote; profile.note = newNote;
@ -280,6 +283,9 @@ public class EditProfileActivity extends BaseActivity {
onSaveFailure(); onSaveFailure();
return; return;
} }
getPrivatePreferences().edit()
.putBoolean("refreshProfileHeader", true)
.apply();
finish(); finish();
} }
@ -292,21 +298,38 @@ public class EditProfileActivity extends BaseActivity {
private void onSaveFailure() { private void onSaveFailure() {
isAlreadySaving = false; isAlreadySaving = false;
errorText.setText(getString(R.string.error_media_upload_sending)); Snackbar.make(avatarButton, R.string.error_media_upload_sending, Snackbar.LENGTH_LONG)
.show();
saveProgress.setVisibility(View.GONE);
} }
private void beginMediaPicking(PickType pickType) { private void beginMediaPicking() {
currentlyPicking = pickType;
switch (currentlyPicking) { switch (currentlyPicking) {
case AVATAR: { avatarProgress.setVisibility(View.VISIBLE); break; } case AVATAR: {
case HEADER: { headerProgress.setVisibility(View.VISIBLE); break; } avatarProgress.setVisibility(View.VISIBLE);
avatarPreview.setVisibility(View.INVISIBLE);
break;
}
case HEADER: {
headerProgress.setVisibility(View.VISIBLE);
headerPreview.setVisibility(View.INVISIBLE);
break;
}
} }
} }
private void endMediaPicking() { private void endMediaPicking() {
switch (currentlyPicking) { switch (currentlyPicking) {
case AVATAR: { avatarProgress.setVisibility(View.GONE); break; } case AVATAR: {
case HEADER: { headerProgress.setVisibility(View.GONE); break; } avatarProgress.setVisibility(View.GONE);
avatarPreview.setVisibility(View.GONE);
break;
}
case HEADER: {
headerProgress.setVisibility(View.GONE);
headerPreview.setVisibility(View.GONE);
break;
}
} }
currentlyPicking = PickType.NOTHING; currentlyPicking = PickType.NOTHING;
} }
@ -321,6 +344,8 @@ public class EditProfileActivity extends BaseActivity {
.setInitialCropWindowPaddingRatio(0) .setInitialCropWindowPaddingRatio(0)
.setAspectRatio(AVATAR_WIDTH, AVATAR_HEIGHT) .setAspectRatio(AVATAR_WIDTH, AVATAR_HEIGHT)
.start(this); .start(this);
} else {
endMediaPicking();
} }
break; break;
} }
@ -330,6 +355,8 @@ public class EditProfileActivity extends BaseActivity {
.setInitialCropWindowPaddingRatio(0) .setInitialCropWindowPaddingRatio(0)
.setAspectRatio(HEADER_WIDTH, HEADER_HEIGHT) .setAspectRatio(HEADER_WIDTH, HEADER_HEIGHT)
.start(this); .start(this);
} else {
endMediaPicking();
} }
break; break;
} }
@ -346,6 +373,7 @@ public class EditProfileActivity extends BaseActivity {
} }
private void beginResize(Uri uri) { private void beginResize(Uri uri) {
beginMediaPicking();
int width, height; int width, height;
switch (currentlyPicking) { switch (currentlyPicking) {
default: { default: {
@ -366,7 +394,9 @@ public class EditProfileActivity extends BaseActivity {
@Override @Override
public void onSuccess(List<Bitmap> contentList) { public void onSuccess(List<Bitmap> contentList) {
Bitmap bitmap = contentList.get(0); Bitmap bitmap = contentList.get(0);
switch (currentlyPicking) { PickType pickType = currentlyPicking;
endMediaPicking();
switch (pickType) {
case AVATAR: { case AVATAR: {
avatarPreview.setImageBitmap(bitmap); avatarPreview.setImageBitmap(bitmap);
avatarPreview.setVisibility(View.VISIBLE); avatarPreview.setVisibility(View.VISIBLE);
@ -380,7 +410,6 @@ public class EditProfileActivity extends BaseActivity {
break; break;
} }
} }
endMediaPicking();
} }
@Override @Override
@ -391,7 +420,8 @@ public class EditProfileActivity extends BaseActivity {
} }
private void onResizeFailure() { private void onResizeFailure() {
errorText.setText(getString(R.string.error_media_upload_sending)); Snackbar.make(avatarButton, R.string.error_media_upload_sending, Snackbar.LENGTH_LONG)
.show();
endMediaPicking(); endMediaPicking();
} }

View File

@ -20,7 +20,6 @@ import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
@ -181,10 +180,10 @@ public class LoginActivity extends AppCompatActivity {
AppCredentials credentials = response.body(); AppCredentials credentials = response.body();
clientId = credentials.clientId; clientId = credentials.clientId;
clientSecret = credentials.clientSecret; clientSecret = credentials.clientSecret;
SharedPreferences.Editor editor = preferences.edit(); preferences.edit()
editor.putString(domain + "/client_id", clientId); .putString(domain + "/client_id", clientId)
editor.putString(domain + "/client_secret", clientSecret); .putString(domain + "/client_secret", clientSecret)
editor.apply(); .apply();
redirectUserToAuthorizeAndLogin(editText); redirectUserToAuthorizeAndLogin(editText);
} }
@ -248,11 +247,11 @@ public class LoginActivity extends AppCompatActivity {
protected void onStop() { protected void onStop() {
super.onStop(); super.onStop();
if (domain != null) { if (domain != null) {
SharedPreferences.Editor editor = preferences.edit(); preferences.edit()
editor.putString("domain", domain); .putString("domain", domain)
editor.putString("clientId", clientId); .putString("clientId", clientId)
editor.putString("clientSecret", clientSecret); .putString("clientSecret", clientSecret)
editor.apply(); .apply();
} }
} }
@ -327,10 +326,14 @@ public class LoginActivity extends AppCompatActivity {
} }
private void onLoginSuccess(String accessToken) { private void onLoginSuccess(String accessToken) {
SharedPreferences.Editor editor = preferences.edit(); boolean committed = preferences.edit()
editor.putString("domain", domain); .putString("domain", domain)
editor.putString("accessToken", accessToken); .putString("accessToken", accessToken)
editor.commit(); .commit();
if (!committed) {
editText.setError(getString(R.string.error_retrieving_oauth_token));
return;
}
Intent intent = new Intent(this, MainActivity.class); Intent intent = new Intent(this, MainActivity.class);
startActivity(intent); startActivity(intent);
finish(); finish();

View File

@ -16,7 +16,6 @@
package com.keylesspalace.tusky; package com.keylesspalace.tusky;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.Typeface; import android.graphics.Typeface;
@ -194,12 +193,24 @@ public class MainActivity extends BaseActivity {
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
SharedPreferences notificationPreferences = getApplicationContext().getSharedPreferences("Notifications", MODE_PRIVATE); SharedPreferences notificationPreferences = getApplicationContext()
SharedPreferences.Editor editor = notificationPreferences.edit(); .getSharedPreferences("Notifications", MODE_PRIVATE);
editor.putString("current", "[]"); notificationPreferences.edit()
editor.apply(); .putString("current", "[]")
.apply();
((NotificationManager) (getSystemService(NOTIFICATION_SERVICE))).cancel(MyFirebaseMessagingService.NOTIFY_ID); ((NotificationManager) (getSystemService(NOTIFICATION_SERVICE)))
.cancel(MyFirebaseMessagingService.NOTIFY_ID);
/* After editing a profile, the profile header in the navigation drawer needs to be
* refreshed */
SharedPreferences preferences = getPrivatePreferences();
if (preferences.getBoolean("refreshProfileHeader", false)) {
fetchUserInfo();
preferences.edit()
.putBoolean("refreshProfileHeader", false)
.apply();
}
} }
@Override @Override
@ -301,11 +312,10 @@ public class MainActivity extends BaseActivity {
private void logout() { private void logout() {
if (arePushNotificationsEnabled()) disablePushNotifications(); if (arePushNotificationsEnabled()) disablePushNotifications();
SharedPreferences preferences = getSharedPreferences(getString(R.string.preferences_file_key), Context.MODE_PRIVATE); getPrivatePreferences().edit()
SharedPreferences.Editor editor = preferences.edit(); .remove("domain")
editor.remove("domain"); .remove("accessToken")
editor.remove("accessToken"); .apply();
editor.apply();
Intent intent = new Intent(MainActivity.this, LoginActivity.class); Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent); startActivity(intent);
@ -375,9 +385,7 @@ public class MainActivity extends BaseActivity {
} }
@Override @Override
public void onSearchAction(String currentQuery) { public void onSearchAction(String currentQuery) {}
}
}); });
searchView.setOnBindSuggestionCallback(new SearchSuggestionsAdapter.OnBindSuggestionCallback() { searchView.setOnBindSuggestionCallback(new SearchSuggestionsAdapter.OnBindSuggestionCallback() {
@ -402,8 +410,7 @@ public class MainActivity extends BaseActivity {
} }
private void fetchUserInfo() { private void fetchUserInfo() {
SharedPreferences preferences = getSharedPreferences( SharedPreferences preferences = getPrivatePreferences();
getString(R.string.preferences_file_key), Context.MODE_PRIVATE);
final String domain = preferences.getString("domain", null); final String domain = preferences.getString("domain", null);
String id = preferences.getString("loggedInAccountId", null); String id = preferences.getString("loggedInAccountId", null);
String username = preferences.getString("loggedInAccountUsername", null); String username = preferences.getString("loggedInAccountUsername", null);
@ -421,6 +428,8 @@ public class MainActivity extends BaseActivity {
return; return;
} }
headerResult.clear();
Account me = response.body(); Account me = response.body();
ImageView background = headerResult.getHeaderBackgroundView(); ImageView background = headerResult.getHeaderBackgroundView();
int backgroundWidth = background.getWidth(); int backgroundWidth = background.getWidth();
@ -460,12 +469,10 @@ public class MainActivity extends BaseActivity {
private void onFetchUserInfoSuccess(String id, String username) { private void onFetchUserInfoSuccess(String id, String username) {
loggedInAccountId = id; loggedInAccountId = id;
loggedInAccountUsername = username; loggedInAccountUsername = username;
SharedPreferences preferences = getSharedPreferences( getPrivatePreferences().edit()
getString(R.string.preferences_file_key), Context.MODE_PRIVATE); .putString("loggedInAccountId", loggedInAccountId)
SharedPreferences.Editor editor = preferences.edit(); .putString("loggedInAccountUsername", loggedInAccountUsername)
editor.putString("loggedInAccountId", loggedInAccountId); .apply();
editor.putString("loggedInAccountUsername", loggedInAccountUsername);
editor.apply();
} }
private void onFetchUserInfoFailure(Exception exception) { private void onFetchUserInfoFailure(Exception exception) {

View File

@ -9,9 +9,11 @@ public class Profile {
@SerializedName("note") @SerializedName("note")
public String note; public String note;
/** Encoded in Base-64 */
@SerializedName("avatar") @SerializedName("avatar")
public String avatar; public String avatar;
/** Encoded in Base-64 */
@SerializedName("header") @SerializedName("header")
public String header; public String header;
} }

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -15,44 +14,54 @@
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
android:layout_marginBottom="8dp"
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"
android:id="@+id/edit_profile_display_name" android:id="@+id/edit_profile_display_name"
android:hint="@string/hint_display_name" android:hint="@string/hint_display_name"
android:maxLength="30" /> android:maxLength="30"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp" />
<EditText <EditText
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/edit_profile_note" android:id="@+id/edit_profile_note"
android:hint="@string/hint_note" android:hint="@string/hint_note"
android:maxLength="160" /> android:maxLength="160"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp" />
<TextView <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_avatar" android:orientation="horizontal"
android:labelFor="@+id/edit_profile_avatar" /> android:paddingLeft="16dp">
<Button <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@id/edit_profile_avatar" android:text="@string/label_avatar"
android:text="@string/action_photo_pick" /> android:labelFor="@+id/edit_profile_avatar"
android:layout_marginRight="8dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@id/edit_profile_avatar"
android:text="@string/action_photo_pick"
android:textColor="@color/text_color_primary_dark" />
</LinearLayout>
<RelativeLayout <RelativeLayout
android:layout_width="80dp" android:layout_width="wrap_content"
android:layout_height="80dp"> android:layout_height="wrap_content"
android:paddingLeft="16dp">
<ImageView <ImageView
android:layout_width="80dp" android:layout_width="80dp"
@ -71,21 +80,32 @@
</RelativeLayout> </RelativeLayout>
<TextView <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_header" android:orientation="horizontal"
android:labelFor="@+id/edit_profile_header" /> android:paddingLeft="16dp">
<Button <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@id/edit_profile_header" android:text="@string/label_header"
android:text="@string/action_photo_pick" /> android:labelFor="@+id/edit_profile_header"
android:layout_marginRight="8dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@id/edit_profile_header"
android:text="@string/action_photo_pick"
android:textColor="@color/text_color_primary_dark" />
</LinearLayout>
<RelativeLayout <RelativeLayout
android:layout_width="167.2dp" android:layout_width="wrap_content"
android:layout_height="80dp"> android:layout_height="wrap_content"
android:paddingLeft="16dp">
<ImageView <ImageView
android:layout_width="167.2dp" android:layout_width="167.2dp"
@ -106,4 +126,12 @@
</LinearLayout> </LinearLayout>
<ProgressBar
android:id="@+id/edit_profile_save_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="gone"
android:layout_gravity="center" />
</android.support.design.widget.CoordinatorLayout> </android.support.design.widget.CoordinatorLayout>