From 456e7ff1c51caa8eed2a4afe80ff12bdecbbce71 Mon Sep 17 00:00:00 2001 From: Mariotaku Lee Date: Thu, 18 Jun 2015 22:15:29 +0800 Subject: [PATCH] fixed update profile banner --- .../api/twitter/api/UsersResources.java | 4 +- .../com/github/ooxi/jdatauri/DataUri.java | 434 ------------------ .../support/UserProfileEditorFragment.java | 44 +- .../layout/fragment_user_profile_editor.xml | 1 - 4 files changed, 21 insertions(+), 462 deletions(-) delete mode 100644 twidere/src/main/java/com/github/ooxi/jdatauri/DataUri.java diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/api/UsersResources.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/api/UsersResources.java index 2ee83ff7f..4728ffd87 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/api/UsersResources.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/api/twitter/api/UsersResources.java @@ -133,14 +133,14 @@ public interface UsersResources { @POST("/account/update_profile_banner.json") @Body(BodyType.MULTIPART) - ResponseCode updateProfileBannerImage(@Part("image") FileTypedData data, @Part("width") int width, + ResponseCode updateProfileBannerImage(@Part("banner") FileTypedData data, @Part("width") int width, @Part("height") int height, @Part("offset_left") int offsetLeft, @Part("offset_top") int offsetTop) throws TwitterException; @POST("/account/update_profile_banner.json") @Body(BodyType.MULTIPART) - ResponseCode updateProfileBannerImage(@Part("image") FileTypedData data) throws TwitterException; + ResponseCode updateProfileBannerImage(@Part("banner") FileTypedData data) throws TwitterException; @POST("/account/update_profile_image.json") @Body(BodyType.MULTIPART) diff --git a/twidere/src/main/java/com/github/ooxi/jdatauri/DataUri.java b/twidere/src/main/java/com/github/ooxi/jdatauri/DataUri.java deleted file mode 100644 index c309b423c..000000000 --- a/twidere/src/main/java/com/github/ooxi/jdatauri/DataUri.java +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2015 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.github.ooxi.jdatauri; - -import android.util.Base64; - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.nio.charset.Charset; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -/** - * A data URI parser - * - * @see https://tools.ietf.org/html/rfc2397 - * @see http://shadow2531.com/opera/testcases/datauri/data_uri_rules.html - * @see https://en.wikipedia.org/wiki/Data_URI_scheme - * - * @author ooxi - */ -public class DataUri { - - private static final String CHARSET_OPTION_NAME = "charset"; - private static final String FILENAME_OPTION_NAME = "filename"; - private static final String CONTENT_DISPOSITION_OPTION_NAME = "content-disposition"; - - private final String mime; - private final Charset charset; - private final String filename; - private final String contentDisposition; - private final byte[] data; - - - - public DataUri(String mime, Charset charset, byte[] data) { - this(mime, charset, null, null, data); - } - - public DataUri(String mime, Charset charset, String filename, String contentDisposition, byte[] data) { - this.mime = mime; - this.charset = charset; - this.filename = filename; - this.contentDisposition = contentDisposition; - this.data = data; - - if (null == mime) { - throw new NullPointerException("`mime' must not be null"); - } - if (null == data) { - throw new NullPointerException("`data' must not be null"); - } - } - - - - public String getMime() { - return mime; - } - - /** - * @warning May be null - */ - public Charset getCharset() { - return charset; - } - - /** - * @warning May be null - */ - public String getFilename() { - return filename; - } - - /** - * @warning May be null - */ - public String getContentDisposition() { - return contentDisposition; - } - - public byte[] getData() { - return data; - } - - - - @Override - public int hashCode() { - int hash = 3; - hash = 23 * hash + (this.mime != null ? this.mime.hashCode() : 0); - hash = 23 * hash + (this.charset != null ? this.charset.hashCode() : 0); - hash = 23 * hash + (this.filename != null ? this.filename.hashCode() : 0); - hash = 23 * hash + (this.contentDisposition != null ? this.contentDisposition.hashCode() : 0); - hash = 23 * hash + Arrays.hashCode(this.data); - return hash; - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final DataUri other = (DataUri) obj; - if ((this.mime == null) ? (other.mime != null) : !this.mime.equals(other.mime)) { - return false; - } - if (this.charset != other.charset && (this.charset == null || !this.charset.equals(other.charset))) { - return false; - } - if ((this.filename == null) ? (other.filename != null) : !this.filename.equals(other.filename)) { - return false; - } - if ((this.contentDisposition == null) ? (other.contentDisposition != null) : !this.contentDisposition.equals(other.contentDisposition)) { - return false; - } - if (!Arrays.equals(this.data, other.data)) { - return false; - } - return true; - } - - - - /** - * Tries to parse a data URI described in RFC2397 - * - * @param uri A string representing the data URI - * @param charset Charset to use when decoding percent encoded options - * like filename - * - * @return Parsed data URI - * @throws IllegalArgumentException iff an error occured during parse - * process - */ - public static DataUri parse(String uri, Charset charset) { - - /* If URI does not start with a case-insensitive "data:": - * Throw a MALFORMED_URI exception. - */ - if (!uri.toLowerCase().startsWith("data:")) { - throw new IllegalArgumentException("URI must start with a case-insensitive `data:'"); - } - - /* If URI does not contain a ",": - * Throw a MALFORMED_URI exception. - */ - if (-1 == uri.indexOf(',')) { - throw new IllegalArgumentException("URI must contain a `,'"); - } - - /* Let supportedContentEncodings be an array of strings - * representing the supported content encodings. (["base64"] for - * example) - */ - Collection supportedContentEncodings = Arrays.asList( - "base64" - ); - - /* Let mimeType be a string with the value "text/plain". - */ - String mimeType = "text/plain"; - - /* Let contentEncoding be an empy string. - */ - String contentEncoding = ""; - - /* Let contentEncodingAlreadySet be a boolean with a value of - * false. - */ - boolean contentEncodingAlreadySet = false; - - /* Let supportedValues be a map of string:string pairs where the - * first string in each pair represents the name of the - * supported value and the second string in each pair represents - * an empty string or default string value. (Example: {"charset" - * : "", "filename" : "", "content-disposition" : ""}) - */ - final Map supportedValues = new HashMap() {{ - put(CHARSET_OPTION_NAME, ""); - put(FILENAME_OPTION_NAME, ""); - put(CONTENT_DISPOSITION_OPTION_NAME, ""); - }}; - - /* Let supportedValueSetBits be a map of string:bool pairs - * representing each of the names in supportedValues with each - * name set to false. - */ - final Map supportedValueSetBits = new HashMap() {{ - for (String key : supportedValues.keySet()) { - put(key, false); - } - }}; - - /* Let comma be the position of the first "," found in URI. - */ - int comma = uri.indexOf(','); - - /* Let temp be the substring of URI from, and including, - * position 5 to, and excluding, the comma position. (between - * "data:" and first ",") - */ - String temp = uri.substring("data:".length(), comma); - - /* Let headers be an array of strings returned by splitting temp - * by ";". - */ - String[] headers = temp.split(";"); - - /* For each string s in headers: - */ - for (int header = 0; header < headers.length; ++header) { - String s = headers[header]; - - /* Let s equal the lowercase version of s - */ - s = s.toLowerCase(); - - /* Let eq be the position result of searching for "=" in - * s. - */ - int eq = s.indexOf('='); - - /* Let name and value be empty strings. - */ - String name; - String value = ""; - - /* If eq is not a valid position in s: - */ - if (-1 == eq) { - - /* Let name equal the result of percent-decoding - * s. - */ - name = percentDecode(s, charset); - - /* Let name equal the result of trimming leading - * and trailing white-space from name. - */ - name = name.trim(); - - /* Else: - */ - } else { - - /* Let name equal the substring of s from - * position 0 to, but not including, position - * eq. - */ - name = s.substring(0, eq); - - /* Let name equal the result of percent-decoding - * name. - */ - name = percentDecode(name, charset); - - /* Let name equal the result of trimmnig leading - * and trailing white-space from name. - */ - name = name.trim(); - - /* Let value equal the substring of s from - * position eq + 1 to the end of s. - */ - value = s.substring(eq + 1); - - /* Let value equal the result of precent- - * decoding value. - */ - value = percentDecode(value, charset); - - /* Let value equal the result of trimming - * leading and trailing white-space from value. - */ - value = value.trim(); - } - - /* If s is the first element in headers and eq is not a - * valid position in s and the length of name is greater - * than 0: - */ - if ((0 == header) && (-1 == eq) && !name.isEmpty()) { - - /* Let mimeType equal name. - */ - mimeType = name; - - /* Else: - */ - } else { - - /* If eq is not a valid position in s: - */ - if (-1 == eq) { - - /* If name is found case-insensitively - * in supportedContentEncodings: - */ - final String nameCaseInsensitive = name.toLowerCase(); - - if (supportedContentEncodings.contains(nameCaseInsensitive)) { - - /* If contentEncodingAlreadySet - * is false: - */ - if (!contentEncodingAlreadySet) { - - /* Let contentEncoding - * equal name. - */ - contentEncoding = name; - - /* Let contentEncodingAlreadySet - * equal true. - */ - contentEncodingAlreadySet = true; - } - } - - /* Else: - */ - } else { - - /* If the length of value is greater - * than 0 and name is found case- - * insensitively in supportedValues: - */ - final String nameCaseInsensitive = name.toLowerCase(); - - if (!value.isEmpty() && supportedValues.containsKey(nameCaseInsensitive)) { - - /* If the corresponding value - * for name found (case- - * insensitivley) in - * supportedValueSetBits is - * false: - */ - boolean valueSet = supportedValueSetBits.get(nameCaseInsensitive); - - if (!valueSet) { - - /* Let the corresponding - * value for name found - * (case-insensitively) - * in supportedValues - * equal value. - */ - supportedValues.put(nameCaseInsensitive, value); - - /* Let the corresponding - * value for name found - * (case-insensitively) - * in supportedValueSetBits - * equal true. - */ - supportedValueSetBits.put(nameCaseInsensitive, true); - } - } - } - } - - } - - /* Let data be the substring of URI from position comma + 1 to - * the end of URI. - */ - String data = uri.substring(comma + 1); - - /* Let data be the result of percent-decoding data. - */ - data = percentDecode(data, charset); - - /* Let dataURIObject be an object consisting of the mimeType, - * contentEncoding, data and supportedValues objects. - */ - final String finalMimeType = mimeType; - final Charset finalCharset = supportedValues.get(CHARSET_OPTION_NAME).isEmpty() - ? null : Charset.forName(supportedValues.get(CHARSET_OPTION_NAME)); - final String finalFilename = supportedValues.get(FILENAME_OPTION_NAME).isEmpty() - ? null : supportedValues.get(FILENAME_OPTION_NAME); - final String finalContentDisposition = supportedValues.get(CONTENT_DISPOSITION_OPTION_NAME).isEmpty() - ? null : supportedValues.get(CONTENT_DISPOSITION_OPTION_NAME); - final byte[] finalData = "base64".equalsIgnoreCase(contentEncoding) - ? Base64.decode(data, Base64.DEFAULT) : data.getBytes(charset); - - DataUri dataURIObject = new DataUri( - finalMimeType, - finalCharset, - finalFilename, - finalContentDisposition, - finalData - ); - - /* return dataURIObject. - */ - return dataURIObject; - } - - - - /** - * @warning URLDecoder.decode does not do percentDecoding, but instead decodes - * application/x-www-form-urlencoded therefore the .replace hack - */ - private static String percentDecode(String s, Charset cs) { - try { - return URLDecoder.decode(s, cs.name()).replace(' ', '+'); - } catch (UnsupportedEncodingException e) { - throw new IllegalStateException("Charset `"+ cs.name() +"' not supported", e); - } - } -} \ No newline at end of file diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserProfileEditorFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserProfileEditorFragment.java index 1351512ec..d0394fefe 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserProfileEditorFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserProfileEditorFragment.java @@ -30,6 +30,7 @@ import android.support.annotation.Nullable; import android.support.v4.app.DialogFragment; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; +import android.support.v4.app.FragmentManager; import android.support.v4.app.LoaderManager; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.Loader; @@ -87,6 +88,7 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On private static final int REQUEST_PICK_BACKGROUND_COLOR = 4; private static final int RESULT_REMOVE_BANNER = 101; + private static final String UPDATE_PROFILE_DIALOG_FRAGMENT_TAG = "update_profile"; private MediaLoaderWrapper mLazyImageLoader; private AsyncTaskManager mAsyncTaskManager; @@ -203,6 +205,14 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On return super.onOptionsItemSelected(item); } + @Override + public void onResume() { + super.onResume(); + if (mTask != null && mTask.getStatus() == Status.PENDING) { + AsyncTaskUtils.executeTask(mTask); + } + } + @Override public void onActivityCreated(final Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); @@ -295,13 +305,11 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On } else { mTask = new UpdateProfileBannerImageTaskInternal(getActivity(), mAsyncTaskManager, mAccountId, data.getData(), true); } - AsyncTaskUtils.executeTask(mTask); break; } case REQUEST_UPLOAD_PROFILE_IMAGE: { if (mTask != null && mTask.getStatus() == Status.RUNNING) return; mTask = new UpdateProfileImageTaskInternal(getActivity(), mAsyncTaskManager, mAccountId, data.getData(), true); - AsyncTaskUtils.executeTask(mTask); break; } case REQUEST_PICK_LINK_COLOR: { @@ -322,20 +330,6 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On } - - boolean isProfileChanged() { - final ParcelableUser user = mUser; - if (user == null) return true; - if (!stringEquals(mEditName.getText(), user.name)) return true; - if (!stringEquals(mEditDescription.getText(), user.description_expanded)) return true; - if (!stringEquals(mEditLocation.getText(), user.location)) return true; - if (!stringEquals(mEditUrl.getText(), isEmpty(user.url_expanded) ? user.url : user.url_expanded)) - return true; - if (mLinkColor.getColor() != user.link_color) return true; - if (mBackgroundColor.getColor() != user.background_color) return true; - return false; - } - private void displayUser(final ParcelableUser user) { if (!mGetUserInfoCalled) return; mGetUserInfoCalled = false; @@ -373,15 +367,15 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On } private void setUpdateState(final boolean start) { - mEditName.setEnabled(!start); - mEditDescription.setEnabled(!start); - mEditLocation.setEnabled(!start); - mEditUrl.setEnabled(!start); - mProfileImageView.setEnabled(!start); - mProfileImageView.setOnClickListener(start ? null : this); - mProfileBannerView.setEnabled(!start); - mProfileBannerView.setOnClickListener(start ? null : this); - invalidateOptionsMenu(); + final FragmentManager fm = getChildFragmentManager(); + final Fragment f = fm.findFragmentByTag(UPDATE_PROFILE_DIALOG_FRAGMENT_TAG); + if (!start && f instanceof DialogFragment) { + ((DialogFragment) f).dismiss(); + } else if (start) { + SupportProgressDialogFragment df = new SupportProgressDialogFragment(); + df.show(fm, UPDATE_PROFILE_DIALOG_FRAGMENT_TAG); + df.setCancelable(false); + } } private static boolean stringEquals(final CharSequence str1, final CharSequence str2) { diff --git a/twidere/src/main/res/layout/fragment_user_profile_editor.xml b/twidere/src/main/res/layout/fragment_user_profile_editor.xml index 13a57ee71..d35c62f6a 100644 --- a/twidere/src/main/res/layout/fragment_user_profile_editor.xml +++ b/twidere/src/main/res/layout/fragment_user_profile_editor.xml @@ -105,7 +105,6 @@ android:layout_height="wrap_content" android:layout_marginLeft="@dimen/element_spacing_normal" android:layout_marginStart="@dimen/element_spacing_normal" - android:paddingTop="@dimen/element_spacing_normal" android:text="@string/profile_banner" android:textAllCaps="true" android:textAppearance="?android:textAppearanceSmall"