diff --git a/twidere.component.common/build.gradle b/twidere.component.common/build.gradle index 3da10ba6a..e3872e117 100644 --- a/twidere.component.common/build.gradle +++ b/twidere.component.common/build.gradle @@ -41,7 +41,7 @@ dependencies { apt 'com.github.mariotaku.ObjectCursor:processor:0.9.7' compile 'com.android.support:support-annotations:23.2.1' compile 'com.bluelinelabs:logansquare:1.3.7' - compile 'com.github.mariotaku.RestFu:library:0.9.25' + compile 'com.github.mariotaku.RestFu:library:0.9.26-SNAPSHOT' compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.2' compile 'com.github.mariotaku.ObjectCursor:core:0.9.7' compile fileTree(dir: 'libs', include: ['*.jar']) 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 90345960b..208570839 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 @@ -98,7 +98,6 @@ public interface UsersResources { ResponseList lookupUsersByScreenName(@Param(value = "screen_name", arrayDelimiter = ',') String[] screenNames) throws TwitterException; @POST("/account/remove_profile_banner.json") - @BodyType(BodyType.FORM) ResponseCode removeProfileBannerImage() throws TwitterException; @GET("/users/search.json") @@ -111,34 +110,27 @@ public interface UsersResources { User showUserByScreenName(@Query("screen_name") String screenName) throws TwitterException; @POST("/account/settings.json") - @BodyType(BodyType.FORM) AccountSettings updateAccountSettings(@Param SettingsUpdate settingsUpdate) throws TwitterException; @POST("/account/update_profile.json") - @BodyType(BodyType.FORM) User updateProfile(@Param ProfileUpdate profileUpdate) throws TwitterException; @POST("/account/update_profile_background_image.json") - @BodyType(BodyType.MULTIPART) User updateProfileBackgroundImage(@Param("image") FileBody data, @Param("tile") boolean tile) throws TwitterException; @POST("/account/update_profile_background_image.json") - @BodyType(BodyType.FORM) User updateProfileBackgroundImage(@Param("media_id") long mediaId, @Param("tile") boolean tile) throws TwitterException; @POST("/account/update_profile_banner.json") - @BodyType(BodyType.MULTIPART) ResponseCode updateProfileBannerImage(@Param("banner") FileBody data, @Param("width") int width, @Param("height") int height, @Param("offset_left") int offsetLeft, @Param("offset_top") int offsetTop) throws TwitterException; @POST("/account/update_profile_banner.json") - @BodyType(BodyType.MULTIPART) ResponseCode updateProfileBannerImage(@Param("banner") FileBody data) throws TwitterException; @POST("/account/update_profile_image.json") - @BodyType(BodyType.MULTIPART) User updateProfileImage(@Param("image") FileBody data) throws TwitterException; @GET("/account/verify_credentials.json") diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java index ac6bd3f2a..44a3cd8b8 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java @@ -68,7 +68,6 @@ public interface IntentConstants { String INTENT_ACTION_SEND_DIRECT_MESSAGE = INTENT_PACKAGE_PREFIX + "SEND_DIRECT_MESSAGE"; String INTENT_ACTION_DISCARD_DRAFT = INTENT_PACKAGE_PREFIX + "DISCARD_DRAFT"; String INTENT_ACTION_SEND_DRAFT = INTENT_PACKAGE_PREFIX + "SEND_DRAFT"; - String INTENT_ACTION_PICK_ACTIVITY = "org.mariotaku.twidere.PICK_ACTIVITY"; String INTENT_ACTION_PEBBLE_NOTIFICATION = "com.getpebble.action.SEND_NOTIFICATION"; diff --git a/twidere/build.gradle b/twidere/build.gradle index 156daf433..e8dddcdeb 100644 --- a/twidere/build.gradle +++ b/twidere/build.gradle @@ -139,8 +139,8 @@ dependencies { compile 'com.bluelinelabs:logansquare:1.3.7' compile 'com.soundcloud.android:android-crop:1.0.1@aar' compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.2' - compile 'com.github.mariotaku:PickNCrop:0.9.3' - compile 'com.github.mariotaku.RestFu:okhttp3:0.9.25' + compile 'com.github.mariotaku:PickNCrop:0.9.4-SNAPSHOT' + compile 'com.github.mariotaku.RestFu:okhttp3:0.9.26-SNAPSHOT' compile 'com.squareup.okhttp3:okhttp:3.2.0' compile 'com.lnikkila:extendedtouchview:0.1.0' compile 'com.google.dagger:dagger:2.1' @@ -150,7 +150,7 @@ dependencies { compile 'com.github.mariotaku.SQLiteQB:library:0.9.6' compile 'com.github.mariotaku.ObjectCursor:core:0.9.7' compile 'com.github.mariotaku:MultiValueSwitch:0.9.4' - compile 'com.github.mariotaku:AbstractTask:0.9' + compile 'com.github.mariotaku:AbstractTask:0.9.1' } task svgToDrawable(type: SvgDrawableTask) { diff --git a/twidere/src/main/AndroidManifest.xml b/twidere/src/main/AndroidManifest.xml index c921cd04f..226b70957 100644 --- a/twidere/src/main/AndroidManifest.xml +++ b/twidere/src/main/AndroidManifest.xml @@ -387,15 +387,6 @@ android:name=".activity.DataImportActivity" android:label="@string/import_settings" android:theme="@style/Theme.Twidere.NoDisplay"/> - - - - - - - >, OnItemClickListener { - - private ResolveInfoListAdapter mAdapter; - - private ListView mListView; - - @Override - public void onContentChanged() { - super.onContentChanged(); - mListView = (ListView) findViewById(android.R.id.list); - } - - @Override - public Loader> onCreateLoader(final int id, final Bundle args) { - final Intent intent = getIntent(); - final Intent extraIntent = intent.getParcelableExtra(EXTRA_INTENT); - - final String[] blacklist = intent.getStringArrayExtra(EXTRA_BLACKLIST); - return new IntentActivitiesLoader(this, extraIntent, blacklist, 0); - } - - @Override - public void onItemClick(final AdapterView parent, final View view, final int position, final long id) { - final Intent intent = getIntent(), data = new Intent(); - data.putExtra(EXTRA_DATA, mAdapter.getItem(position)); - data.putExtra(EXTRA_INTENT, intent.getParcelableExtra(EXTRA_INTENT)); - setResult(RESULT_OK, data); - finish(); - } - - @Override - public void onLoaderReset(final Loader> loader) { - mAdapter.clear(); - } - - @Override - public void onLoadFinished(final Loader> loader, final List data) { - mAdapter.clear(); - if (data != null) { - mAdapter.addAll(data); - } - } - - @Override - protected void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_activity_picker); - mAdapter = new ResolveInfoListAdapter(this); - mListView.setAdapter(mAdapter); - mListView.setOnItemClickListener(this); - getSupportLoaderManager().initLoader(0, null, this); - } - -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/ComposeActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/ComposeActivity.java index ce26e476a..ee9573edc 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/ComposeActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/ComposeActivity.java @@ -1914,7 +1914,8 @@ public class ComposeActivity extends BaseActivity implements OnMenuItemClickList } @Override - protected void beforeExecute(ParcelableLocation location) { + protected void beforeExecute() { + ParcelableLocation location = getParams(); final TextView textView = getCallback(); if (textView == null) return; diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/TwitterLinkHandlerActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/TwitterLinkHandlerActivity.java index 7cef3274e..bfbd7bae4 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/TwitterLinkHandlerActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/TwitterLinkHandlerActivity.java @@ -1,6 +1,7 @@ package org.mariotaku.twidere.activity; import android.app.Activity; +import android.content.ComponentName; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; @@ -15,8 +16,10 @@ import android.util.Pair; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.math.NumberUtils; import org.mariotaku.twidere.Constants; +import org.mariotaku.twidere.R; +import org.mariotaku.twidere.util.BugReporter; +import org.mariotaku.twidere.util.IntentUtils; import org.mariotaku.twidere.util.Utils; -import org.mariotaku.twidere.util.support.IntentSupport; import java.util.List; @@ -97,20 +100,20 @@ public class TwitterLinkHandlerActivity extends Activity implements Constants { startActivity(handled.first); } else { if (!handled.second) { -// BugReporter.error(new TwitterLinkException("Unable to handle twitter uri " + uri)); + BugReporter.logException(new TwitterLinkException("Unable to handle twitter uri " + uri)); } - final String packageName = mPreferences.getString(KEY_FALLBACK_TWITTER_LINK_HANDLER, null); final Intent fallbackIntent = new Intent(Intent.ACTION_VIEW, uri); - IntentSupport.setSelector(intent, new Intent(Intent.ACTION_VIEW).addCategory(IntentSupport.CATEGORY_APP_BROWSER)); - fallbackIntent.setPackage(packageName); - if (TextUtils.isEmpty(packageName) || packageManager.queryIntentActivities(fallbackIntent, 0).isEmpty()) { - final Intent pickIntent = new Intent(INTENT_ACTION_PICK_ACTIVITY); - pickIntent.putExtra(EXTRA_INTENT, new Intent(Intent.ACTION_VIEW, uri)); - pickIntent.putExtra(EXTRA_BLACKLIST, new String[]{getPackageName()}); - startActivityForResult(pickIntent, REQUEST_PICK_ACTIVITY); - return; - } else { + fallbackIntent.addCategory(Intent.CATEGORY_BROWSABLE); + fallbackIntent.setPackage(IntentUtils.getDefaultBrowserPackage(this)); + final ComponentName componentName = fallbackIntent.resolveActivity(packageManager); + if (componentName == null) { + final Intent targetIntent = new Intent(Intent.ACTION_VIEW, uri); + targetIntent.addCategory(Intent.CATEGORY_BROWSABLE); + startActivity(Intent.createChooser(targetIntent, getString(R.string.open_in_browser))); + } else if (!TextUtils.equals(getPackageName(), componentName.getPackageName())) { startActivity(fallbackIntent); + } else { + // TODO show error } } finish(); @@ -180,6 +183,7 @@ public class TwitterLinkHandlerActivity extends Activity implements Constants { return Pair.create(null, false); } + @NonNull private Pair handleUserSpecificPageIntent(Uri uri, List pathSegments, String screenName) { final int segsSize = pathSegments.size(); if (segsSize == 1) { diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/ResolveInfoListAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/ResolveInfoListAdapter.java deleted file mode 100644 index c46debe79..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/ResolveInfoListAdapter.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.mariotaku.twidere.adapter; - -import android.content.Context; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; - -import org.mariotaku.twidere.R; - -public class ResolveInfoListAdapter extends ArrayAdapter { - - private final PackageManager mPackageManager; - - public ResolveInfoListAdapter(final Context context) { - super(context, R.layout.list_item_two_line_small); - mPackageManager = context.getPackageManager(); - } - - @Override - public View getView(final int position, final View convertView, final ViewGroup parent) { - final View view = super.getView(position, convertView, parent); - final ResolveInfo info = getItem(position); - final ImageView icon = (ImageView) view.findViewById(android.R.id.icon); - final TextView text1 = (TextView) view.findViewById(android.R.id.text1); - final TextView text2 = (TextView) view.findViewById(android.R.id.text2); - icon.setImageDrawable(info.loadIcon(mPackageManager)); - text1.setText(info.loadLabel(mPackageManager)); - text2.setVisibility(View.GONE); - return view; - } - -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/app/TwidereApplication.java b/twidere/src/main/java/org/mariotaku/twidere/app/TwidereApplication.java index 11594c3f3..14a4b14ea 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/app/TwidereApplication.java +++ b/twidere/src/main/java/org/mariotaku/twidere/app/TwidereApplication.java @@ -48,6 +48,7 @@ import android.widget.TextView; import com.afollestad.appthemeengine.ATE; import com.afollestad.appthemeengine.Config; import com.pnikosis.materialishprogress.ProgressWheel; +import com.rengwuxian.materialedittext.MaterialEditText; import org.apache.commons.lang3.ArrayUtils; import org.mariotaku.twidere.BuildConfig; @@ -73,6 +74,7 @@ import org.mariotaku.twidere.util.theme.FloatingActionButtonViewProcessor; import org.mariotaku.twidere.util.theme.FontFamilyTagProcessor; import org.mariotaku.twidere.util.theme.IconActionButtonTagProcessor; import org.mariotaku.twidere.util.theme.ImageViewViewProcessor; +import org.mariotaku.twidere.util.theme.MaterialEditTextViewProcessor; import org.mariotaku.twidere.util.theme.OptimalLinkColorTagProcessor; import org.mariotaku.twidere.util.theme.ProfileImageViewViewProcessor; import org.mariotaku.twidere.util.theme.ProgressWheelViewProcessor; @@ -152,6 +154,7 @@ public class TwidereApplication extends Application implements Constants, ATE.registerViewProcessor(TimelineContentTextView.class, new TimelineContentTextViewViewProcessor()); ATE.registerViewProcessor(TextView.class, new TextViewViewProcessor()); ATE.registerViewProcessor(ImageView.class, new ImageViewViewProcessor()); + ATE.registerViewProcessor(MaterialEditText.class, new MaterialEditTextViewProcessor()); ATE.registerViewProcessor(ProgressWheel.class, new ProgressWheelViewProcessor()); ATE.registerViewProcessor(ProfileImageView.class, mProfileImageViewViewProcessor); ATE.registerTagProcessor(OptimalLinkColorTagProcessor.TAG, new OptimalLinkColorTagProcessor()); diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/UserProfileEditorFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/UserProfileEditorFragment.java index a6a726afa..83562e88d 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/UserProfileEditorFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/UserProfileEditorFragment.java @@ -22,8 +22,6 @@ package org.mariotaku.twidere.fragment; import android.content.Context; import android.content.Intent; import android.net.Uri; -import android.os.AsyncTask; -import android.os.AsyncTask.Status; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.DialogFragment; @@ -49,6 +47,7 @@ import android.widget.Toast; import com.rengwuxian.materialedittext.MaterialEditText; import com.twitter.Validator; +import org.mariotaku.abstask.library.AbstractTask; import org.mariotaku.abstask.library.TaskStarter; import org.mariotaku.twidere.R; import org.mariotaku.twidere.activity.ColorPickerDialogActivity; @@ -67,8 +66,8 @@ import org.mariotaku.twidere.model.UserKey; import org.mariotaku.twidere.model.util.ParcelableCredentialsUtils; import org.mariotaku.twidere.model.util.ParcelableUserUtils; import org.mariotaku.twidere.task.UpdateAccountInfoTask; +import org.mariotaku.twidere.task.UpdateProfileBackgroundImageTask; import org.mariotaku.twidere.task.UpdateProfileBannerImageTask; -import org.mariotaku.twidere.util.AsyncTaskUtils; import org.mariotaku.twidere.util.AsyncTwitterWrapper.UpdateProfileImageTask; import org.mariotaku.twidere.util.HtmlEscapeHelper; import org.mariotaku.twidere.util.KeyboardShortcutsHandler; @@ -90,15 +89,17 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On private static final int REQUEST_UPLOAD_PROFILE_IMAGE = 1; private static final int REQUEST_UPLOAD_PROFILE_BANNER_IMAGE = 2; - private static final int REQUEST_PICK_LINK_COLOR = 3; - private static final int REQUEST_PICK_BACKGROUND_COLOR = 4; + private static final int REQUEST_UPLOAD_PROFILE_BACKGROUND_IMAGE = 3; + private static final int REQUEST_PICK_LINK_COLOR = 11; + private static final int REQUEST_PICK_BACKGROUND_COLOR = 12; private static final int RESULT_REMOVE_BANNER = 101; private static final String UPDATE_PROFILE_DIALOG_FRAGMENT_TAG = "update_profile"; - private AsyncTask mTask; + private AbstractTask mTask; private ImageView mProfileImageView; private ImageView mProfileBannerView; + private ImageView mProfileBackgroundView; private MaterialEditText mEditName; private MaterialEditText mEditDescription; private MaterialEditText mEditLocation; @@ -106,6 +107,7 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On private View mProgressContainer, mEditProfileContent; private View mEditProfileImage; private View mEditProfileBanner; + private View mEditProfileBackground; private View mSetLinkColor, mSetBackgroundColor; private ForegroundColorView mLinkColor, mBackgroundColor; private UserKey mAccountId; @@ -129,7 +131,7 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On @Override public void onClick(final View view) { final ParcelableUser user = mUser; - if (user == null || (mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING)) + if (user == null || (mTask != null && !mTask.isFinished())) return; switch (view.getId()) { case R.id.profile_image: { @@ -150,6 +152,11 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On startActivityForResult(intent, REQUEST_UPLOAD_PROFILE_BANNER_IMAGE); break; } + case R.id.edit_profile_background: { + final Intent intent = ThemedImagePickerActivity.withThemed(getActivity()).build(); + startActivityForResult(intent, REQUEST_UPLOAD_PROFILE_BACKGROUND_IMAGE); + break; + } case R.id.set_link_color: { final Intent intent = new Intent(getActivity(), ColorPickerDialogActivity.class); intent.putExtra(EXTRA_COLOR, user.link_color); @@ -206,7 +213,7 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On final int backgroundColor = mBackgroundColor.getColor(); mTask = new UpdateProfileTaskInternal(this, mAccountId, mUser, name, url, location, description, linkColor, backgroundColor); - AsyncTaskUtils.executeTask(mTask); + TaskStarter.execute(mTask); return true; } } @@ -236,8 +243,12 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On mProfileImageView.setOnClickListener(this); mProfileBannerView.setOnClickListener(this); - mEditProfileBanner.setOnClickListener(this); + mProfileBackgroundView.setOnClickListener(this); + mEditProfileImage.setOnClickListener(this); + mEditProfileBanner.setOnClickListener(this); + mEditProfileBackground.setOnClickListener(this); + mSetLinkColor.setOnClickListener(this); mSetBackgroundColor.setOnClickListener(this); @@ -279,14 +290,16 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On super.onViewCreated(view, savedInstanceState); mProgressContainer = view.findViewById(R.id.progress_container); mEditProfileContent = view.findViewById(R.id.edit_profile_content); - mProfileBannerView = (ImageView) view.findViewById(R.id.profile_banner); mProfileImageView = (ImageView) view.findViewById(R.id.profile_image); + mProfileBannerView = (ImageView) view.findViewById(R.id.profile_banner); + mProfileBackgroundView = (ImageView) view.findViewById(R.id.profile_background); mEditName = (MaterialEditText) view.findViewById(R.id.name); mEditDescription = (MaterialEditText) view.findViewById(R.id.description); mEditLocation = (MaterialEditText) view.findViewById(R.id.location); mEditUrl = (MaterialEditText) view.findViewById(R.id.url); mEditProfileImage = view.findViewById(R.id.edit_profile_image); mEditProfileBanner = view.findViewById(R.id.edit_profile_banner); + mEditProfileBackground = view.findViewById(R.id.edit_profile_background); mLinkColor = (ForegroundColorView) view.findViewById(R.id.link_color); mBackgroundColor = (ForegroundColorView) view.findViewById(R.id.background_color); mSetLinkColor = view.findViewById(R.id.set_link_color); @@ -298,17 +311,26 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On if (resultCode == FragmentActivity.RESULT_CANCELED) return; switch (requestCode) { case REQUEST_UPLOAD_PROFILE_BANNER_IMAGE: { - if (mTask != null && mTask.getStatus() == Status.RUNNING) return; + if (mTask != null && !mTask.isFinished()) return; if (resultCode == RESULT_REMOVE_BANNER) { mTask = new RemoveProfileBannerTaskInternal(mAccountId); } else { - mTask = new UpdateProfileBannerImageTaskInternal(getActivity(), mAccountId, data.getData(), true); + mTask = new UpdateProfileBannerImageTaskInternal(getActivity(), mAccountId, + data.getData(), true); } break; } + case REQUEST_UPLOAD_PROFILE_BACKGROUND_IMAGE: { + //TODO upload profile background + if (mTask != null && !mTask.isFinished()) return; + mTask = new UpdateProfileBackgroundImageTaskInternal(getActivity(), mAccountId, + data.getData(), false, true); + break; + } case REQUEST_UPLOAD_PROFILE_IMAGE: { - if (mTask != null && mTask.getStatus() == Status.RUNNING) return; - mTask = new UpdateProfileImageTaskInternal(getActivity(), mAccountId, data.getData(), true); + if (mTask != null && !mTask.isFinished()) return; + mTask = new UpdateProfileImageTaskInternal(getActivity(), mAccountId, + data.getData(), true); break; } case REQUEST_PICK_LINK_COLOR: { @@ -341,10 +363,16 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On mEditLocation.setText(user.location); mEditUrl.setText(isEmpty(user.url_expanded) ? user.url : user.url_expanded); mMediaLoader.displayProfileImage(mProfileImageView, user); - final int def_width = getResources().getDisplayMetrics().widthPixels; - mMediaLoader.displayProfileBanner(mProfileBannerView, user.profile_banner_url, def_width); + final int defWidth = getResources().getDisplayMetrics().widthPixels; + mMediaLoader.displayProfileBanner(mProfileBannerView, user.profile_banner_url, defWidth); + mMediaLoader.displayImage(mProfileBackgroundView, user.profile_background_url); mLinkColor.setColor(user.link_color); mBackgroundColor.setColor(user.background_color); + if (USER_TYPE_FANFOU_COM.equals(user.key.getHost())) { + mEditProfileBanner.setVisibility(View.GONE); + } else { + mEditProfileBanner.setVisibility(View.VISIBLE); + } } else { mProgressContainer.setVisibility(View.GONE); mEditProfileContent.setVisibility(View.GONE); @@ -368,8 +396,8 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On @Override public void onResume() { super.onResume(); - if (mTask != null && mTask.getStatus() == Status.PENDING) { - AsyncTaskUtils.executeTask(mTask); + if (mTask != null && !mTask.isFinished()) { + TaskStarter.execute(mTask); } } @@ -415,7 +443,8 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On } - static class UpdateProfileTaskInternal extends AsyncTask> { + static class UpdateProfileTaskInternal extends AbstractTask, + UserProfileEditorFragment> { private static final String DIALOG_FRAGMENT_TAG = "updating_user_profile"; private final UserProfileEditorFragment mFragment; @@ -449,7 +478,7 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On } @Override - protected SingleResponse doInBackground(final Object... params) { + protected SingleResponse doLongOperation(final Object params) { final ParcelableCredentials credentials = ParcelableCredentialsUtils.getCredentials(mActivity, mAccountKey); if (credentials == null) return SingleResponse.getInstance(); final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mActivity, credentials, @@ -495,8 +524,8 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On } @Override - protected void onPostExecute(final SingleResponse result) { - super.onPostExecute(result); + protected void afterExecute(SingleResponse result) { + super.afterExecute(result); if (result.hasData()) { final ParcelableAccount account = result.getExtras().getParcelable(EXTRA_ACCOUNT); if (account != null) { @@ -518,7 +547,8 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On } @Override - protected void onPreExecute() { + protected void beforeExecute() { + super.beforeExecute(); mFragment.executeAfterFragmentResumed(new Action() { @Override public void execute(IBaseFragment fragment) { @@ -526,12 +556,11 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On df.setCancelable(false); } }); - super.onPreExecute(); } } - class RemoveProfileBannerTaskInternal extends AsyncTask> { + class RemoveProfileBannerTaskInternal extends AbstractTask, UserProfileEditorFragment> { private final UserKey mAccountKey; @@ -540,13 +569,13 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On } @Override - protected SingleResponse doInBackground(final Object... params) { + protected SingleResponse doLongOperation(final Object params) { return TwitterWrapper.deleteProfileBannerImage(getActivity(), mAccountKey); } @Override - protected void onPostExecute(final SingleResponse result) { - super.onPostExecute(result); + protected void afterExecute(final SingleResponse result) { + super.afterExecute(result); if (result.getData() != null && result.getData()) { getUserInfo(); Toast.makeText(getActivity(), R.string.profile_banner_image_updated, Toast.LENGTH_SHORT).show(); @@ -558,14 +587,14 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On } @Override - protected void onPreExecute() { - super.onPreExecute(); + protected void beforeExecute() { + super.beforeExecute(); setUpdateState(true); } } - private class UpdateProfileBannerImageTaskInternal extends UpdateProfileBannerImageTask { + private class UpdateProfileBannerImageTaskInternal extends UpdateProfileBannerImageTask { public UpdateProfileBannerImageTaskInternal(final Context context, final UserKey accountKey, final Uri imageUri, final boolean deleteImage) { @@ -573,21 +602,44 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On } @Override - protected void onPostExecute(final SingleResponse result) { - super.onPostExecute(result); + protected void afterExecute(final SingleResponse result) { + super.afterExecute(result); setUpdateState(false); getUserInfo(); } @Override - protected void onPreExecute() { - super.onPreExecute(); + protected void beforeExecute() { + super.beforeExecute(); setUpdateState(true); } } - private class UpdateProfileImageTaskInternal extends UpdateProfileImageTask { + private class UpdateProfileBackgroundImageTaskInternal extends UpdateProfileBackgroundImageTask { + + public UpdateProfileBackgroundImageTaskInternal(final Context context, final UserKey accountKey, + final Uri imageUri, final boolean tile, + final boolean deleteImage) { + super(context, accountKey, imageUri, tile, deleteImage); + } + + @Override + protected void afterExecute(final SingleResponse result) { + super.afterExecute(result); + setUpdateState(false); + getUserInfo(); + } + + @Override + protected void beforeExecute() { + super.beforeExecute(); + setUpdateState(true); + } + + } + + private class UpdateProfileImageTaskInternal extends UpdateProfileImageTask { public UpdateProfileImageTaskInternal(final Context context, final UserKey accountKey, final Uri imageUri, final boolean deleteImage) { @@ -595,8 +647,8 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On } @Override - protected void onPostExecute(final SingleResponse result) { - super.onPostExecute(result); + protected void afterExecute(SingleResponse result) { + super.afterExecute(result); if (result != null && result.getData() != null) { displayUser(result.getData()); } @@ -604,8 +656,8 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On } @Override - protected void onPreExecute() { - super.onPreExecute(); + protected void beforeExecute() { + super.beforeExecute(); setUpdateState(true); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/IntentActivitiesLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/IntentActivitiesLoader.java deleted file mode 100644 index 88e8f172e..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/loader/IntentActivitiesLoader.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2014 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 org.mariotaku.twidere.loader; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.os.Build; -import android.support.v4.content.AsyncTaskLoader; - -import org.apache.commons.lang3.ArrayUtils; -import org.mariotaku.twidere.Constants; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class IntentActivitiesLoader extends AsyncTaskLoader> implements Constants { - - private PackageIntentReceiver mPackageObserver; - private final InterestingConfigChanges mLastConfig = new InterestingConfigChanges(); - private final PackageManager mPackageManager; - private final Intent mIntent; - private final String[] mPackagesBlacklist; - private final int mFlags; - - public IntentActivitiesLoader(final Context context, final Intent intent) { - this(context, intent, null, 0); - } - - public IntentActivitiesLoader(final Context context, final Intent intent, final String[] packagesBlacklist, - final int flags) { - super(context); - mPackageManager = context.getPackageManager(); - mIntent = intent; - mPackagesBlacklist = packagesBlacklist; - mFlags = flags; - } - - @Override - public List loadInBackground() { - if (mIntent == null) return Collections.emptyList(); - final List activities = mPackageManager.queryIntentActivities(mIntent, mFlags); - final List result = new ArrayList<>(); - for (final ResolveInfo activity : activities) { - final ActivityInfo activityInfo = activity.activityInfo; - if (mPackagesBlacklist == null || !ArrayUtils.contains(mPackagesBlacklist, activityInfo.packageName)) { - result.add(activity); - } - } - return result; - } - - /** - * Handles a request to completely reset the Loader. - */ - @Override - protected void onReset() { - super.onReset(); - - // Ensure the loader is stopped - onStopLoading(); - - // Stop monitoring for changes. - if (mPackageObserver != null) { - getContext().unregisterReceiver(mPackageObserver); - mPackageObserver = null; - } - } - - /** - * Handles a request to start the Loader. - */ - @Override - protected void onStartLoading() { - - // Start watching for changes in the app data. - if (mPackageObserver == null) { - mPackageObserver = new PackageIntentReceiver(this); - } - - // Has something interesting in the configuration changed since we - // last built the app list? - final boolean configChange = mLastConfig.applyNewConfig(getContext().getResources()); - - if (takeContentChanged() || configChange) { - // If the data has changed since the last time it was loaded - // or is not currently available, start a load. - forceLoad(); - } - } - - /** - * Handles a request to stop the Loader. - */ - @Override - protected void onStopLoading() { - // Attempt to cancel the current load task if possible. - cancelLoad(); - } - - /** - * Helper for determining if the configuration has changed in an interesting - * way so we need to rebuild the app list. - */ - public static class InterestingConfigChanges { - - final Configuration mLastConfiguration = new Configuration(); - int mLastDensity; - - boolean applyNewConfig(final Resources res) { - final int configChanges = mLastConfiguration.updateFrom(res.getConfiguration()); - final boolean densityChanged = mLastDensity != res.getDisplayMetrics().densityDpi; - if (densityChanged - || (configChanges & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_UI_MODE | ActivityInfo.CONFIG_SCREEN_LAYOUT)) != 0) { - mLastDensity = res.getDisplayMetrics().densityDpi; - return true; - } - return false; - } - } - - /** - * Helper class to look for interesting changes to the installed apps so - * that the loader can be updated. - */ - public static class PackageIntentReceiver extends BroadcastReceiver { - - final IntentActivitiesLoader mLoader; - - public PackageIntentReceiver(final IntentActivitiesLoader loader) { - mLoader = loader; - final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); - filter.addAction(Intent.ACTION_PACKAGE_REMOVED); - filter.addAction(Intent.ACTION_PACKAGE_CHANGED); - filter.addDataScheme("package"); - mLoader.getContext().registerReceiver(this, filter); - // Register for events related to sdcard installation. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) { - final IntentFilter sdFilter = new IntentFilter(); - sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); - sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); - mLoader.getContext().registerReceiver(this, sdFilter); - } - } - - @Override - public void onReceive(final Context context, final Intent intent) { - // Tell the loader about the change. - mLoader.onContentChanged(); - } - } - -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/AbsFriendshipOperationTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/AbsFriendshipOperationTask.java index dc398be1c..4792cf79f 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/task/AbsFriendshipOperationTask.java +++ b/twidere/src/main/java/org/mariotaku/twidere/task/AbsFriendshipOperationTask.java @@ -52,7 +52,8 @@ public abstract class AbsFriendshipOperationTask extends AbstractTask extends AbstractTask, ResultHandler> implements Constants { + + @Inject + protected Bus mBus; + + private final UserKey mAccountKey; + private final Uri mImageUri; + private boolean mTile; + private final boolean mDeleteImage; + private final Context mContext; + + public UpdateProfileBackgroundImageTask(final Context context, final UserKey accountKey, + final Uri imageUri, final boolean tile, + final boolean deleteImage) { + //noinspection unchecked + GeneralComponentHelper.build(context).inject((UpdateProfileBackgroundImageTask) this); + mContext = context; + mAccountKey = accountKey; + mImageUri = imageUri; + mDeleteImage = deleteImage; + mTile = tile; + } + + @Override + protected void afterExecute(SingleResponse result) { + super.afterExecute(result); + if (result.hasData()) { + Utils.showOkMessage(mContext, R.string.profile_banner_image_updated, false); + mBus.post(new ProfileUpdatedEvent(result.getData())); + } else { + Utils.showErrorMessage(mContext, R.string.action_updating_profile_background_image, + result.getException(), + true); + } + } + + @Override + protected SingleResponse doLongOperation(final Object params) { + try { + final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountKey, + true); + TwitterWrapper.updateProfileBackgroundImage(mContext, twitter, mImageUri, mTile, + mDeleteImage); + // Wait for 5 seconds, see + // https://dev.twitter.com/docs/api/1.1/post/account/update_profile_image + try { + Thread.sleep(5000L); + } catch (InterruptedException e) { + Log.w(LOGTAG, e); + } + final User user = twitter.verifyCredentials(); + return SingleResponse.getInstance(ParcelableUserUtils.fromUser(user, mAccountKey)); + } catch (TwitterException | IOException e) { + return SingleResponse.getInstance(e); + } + } + + +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/task/UpdateProfileBannerImageTask.java b/twidere/src/main/java/org/mariotaku/twidere/task/UpdateProfileBannerImageTask.java index 04f35aa3c..dfb3a7d0a 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/task/UpdateProfileBannerImageTask.java +++ b/twidere/src/main/java/org/mariotaku/twidere/task/UpdateProfileBannerImageTask.java @@ -4,6 +4,10 @@ import android.content.Context; import android.net.Uri; import android.util.Log; +import com.squareup.otto.Bus; + +import org.mariotaku.abstask.library.AbstractTask; +import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.R; import org.mariotaku.twidere.api.twitter.Twitter; import org.mariotaku.twidere.api.twitter.TwitterException; @@ -16,13 +20,20 @@ import org.mariotaku.twidere.model.util.ParcelableUserUtils; import org.mariotaku.twidere.util.TwitterAPIFactory; import org.mariotaku.twidere.util.TwitterWrapper; import org.mariotaku.twidere.util.Utils; +import org.mariotaku.twidere.util.dagger.GeneralComponentHelper; -import java.io.FileNotFoundException; +import java.io.IOException; + +import javax.inject.Inject; /** * Created by mariotaku on 16/3/11. */ -public class UpdateProfileBannerImageTask extends ManagedAsyncTask> { +public class UpdateProfileBannerImageTask extends AbstractTask, ResultHandler> implements Constants { + + @Inject + protected Bus mBus; private final UserKey mAccountKey; private final Uri mImageUri; @@ -31,7 +42,8 @@ public class UpdateProfileBannerImageTask extends ManagedAsyncTask) this); mContext = context; mAccountKey = accountKey; mImageUri = imageUri; @@ -39,11 +51,11 @@ public class UpdateProfileBannerImageTask extends ManagedAsyncTask result) { - super.onPostExecute(result); + protected void afterExecute(final SingleResponse result) { + super.afterExecute(result); if (result.hasData()) { Utils.showOkMessage(mContext, R.string.profile_banner_image_updated, false); - bus.post(new ProfileUpdatedEvent(result.getData())); + mBus.post(new ProfileUpdatedEvent(result.getData())); } else { Utils.showErrorMessage(mContext, R.string.action_updating_profile_banner_image, result.getException(), true); @@ -51,7 +63,7 @@ public class UpdateProfileBannerImageTask extends ManagedAsyncTask doInBackground(final Object... params) { + protected SingleResponse doLongOperation(final Object params) { try { final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountKey, true); @@ -65,7 +77,7 @@ public class UpdateProfileBannerImageTask extends ManagedAsyncTask> { + public static class UpdateProfileImageTask extends AbstractTask, ResultHandler> { + + @Inject + protected Bus mBus; private final UserKey mAccountKey; private final Uri mImageUri; @@ -561,7 +568,8 @@ public class AsyncTwitterWrapper extends TwitterWrapper { public UpdateProfileImageTask(final Context context, final UserKey accountKey, final Uri imageUri, final boolean deleteImage) { - super(context); + //noinspection unchecked + GeneralComponentHelper.build(context).inject((UpdateProfileImageTask) this); this.mContext = context; this.mAccountKey = accountKey; this.mImageUri = imageUri; @@ -569,7 +577,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper { } @Override - protected SingleResponse doInBackground(final Object... params) { + protected SingleResponse doLongOperation(final Object params) { try { final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, mAccountKey, true); TwitterWrapper.updateProfileImage(mContext, twitter, mImageUri, mDeleteImage); @@ -582,17 +590,17 @@ public class AsyncTwitterWrapper extends TwitterWrapper { } final User user = twitter.verifyCredentials(); return SingleResponse.getInstance(ParcelableUserUtils.fromUser(user, mAccountKey)); - } catch (TwitterException | FileNotFoundException e) { + } catch (TwitterException | IOException e) { return SingleResponse.getInstance(e); } } @Override - protected void onPostExecute(final SingleResponse result) { - super.onPostExecute(result); + protected void afterExecute(SingleResponse result) { + super.afterExecute(result); if (result.hasData()) { Utils.showOkMessage(mContext, R.string.profile_image_updated, false); - bus.post(new ProfileUpdatedEvent(result.getData())); + mBus.post(new ProfileUpdatedEvent(result.getData())); } else { Utils.showErrorMessage(mContext, R.string.action_updating_profile_image, result.getException(), true); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/IntentUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/IntentUtils.java index 2acf5e185..081510316 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/IntentUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/IntentUtils.java @@ -4,6 +4,7 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -35,6 +36,7 @@ import org.mariotaku.twidere.model.util.ParcelableLocationUtils; import java.util.ArrayList; import java.util.List; +import java.util.Random; import static android.text.TextUtils.isEmpty; @@ -195,6 +197,27 @@ public class IntentUtils implements Constants { } } + public static String getDefaultBrowserPackage(Context context) { + Uri.Builder builder = new Uri.Builder(); + builder.scheme(SCHEME_HTTP); + StringBuilder sb = new StringBuilder(); + Random random = new Random(); + int range = 'z' - 'a'; + for (int i = 0; i < 20; i++) { + sb.append((char) ('a' + (Math.abs(random.nextInt()) % range))); + } + sb.append(".com"); + builder.authority(sb.toString()); + final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build()); + intent.addCategory(Intent.CATEGORY_BROWSABLE); + List info = context.getPackageManager().queryIntentActivities(intent, 0); + if (info.isEmpty()) return null; + for (ResolveInfo item : info) { + if (item.isDefault) return item.activityInfo.packageName; + } + return info.get(0).activityInfo.packageName; + } + public static void openMediaDirectly(@NonNull final Context context, @Nullable final UserKey accountKey, final ParcelableDirectMessage message, final ParcelableMedia current, diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/MediaLoaderWrapper.java b/twidere/src/main/java/org/mariotaku/twidere/util/MediaLoaderWrapper.java index d61bba309..c06346843 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/MediaLoaderWrapper.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/MediaLoaderWrapper.java @@ -222,12 +222,8 @@ public class MediaLoaderWrapper implements Constants { } - public void displayImage(final ImageView view, final String url, DisplayImageOptions options) { - mImageLoader.displayImage(url, view, options); - } - - public DisplayImageOptions getProfileImageDisplayOptions() { - return mProfileImageDisplayOptions; + public void displayImage(final ImageView view, final String url) { + mImageLoader.displayImage(url, view); } public void displayProfileImage(final ImageView view, final String url, final ImageLoadingListener listener) { diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/TwitterWrapper.java b/twidere/src/main/java/org/mariotaku/twidere/util/TwitterWrapper.java index 2a89e43c0..1d6a5a65e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/TwitterWrapper.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/TwitterWrapper.java @@ -19,13 +19,16 @@ package org.mariotaku.twidere.util; +import android.content.ContentResolver; import android.content.Context; import android.net.Uri; import android.support.annotation.NonNull; import android.support.v4.util.SimpleArrayMap; import android.text.TextUtils; import android.util.Log; +import android.webkit.MimeTypeMap; +import org.mariotaku.restfu.http.ContentType; import org.mariotaku.restfu.http.mime.FileBody; import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.api.twitter.Twitter; @@ -44,6 +47,7 @@ import org.mariotaku.twidere.provider.TwidereDataStore.UnreadCounts; import java.io.File; import java.io.FileNotFoundException; +import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Set; @@ -174,13 +178,34 @@ public class TwitterWrapper implements Constants { public static void updateProfileBannerImage(final Context context, final Twitter twitter, final Uri imageUri, final boolean deleteImage) - throws FileNotFoundException, TwitterException { - InputStream is = null; + throws IOException, TwitterException { + FileBody fileBody = null; try { - is = context.getContentResolver().openInputStream(imageUri); - twitter.updateProfileBannerImage(new FileBody(is, "image", -1, null)); + fileBody = getFileBody(context, imageUri); + twitter.updateProfileBannerImage(fileBody); } finally { - Utils.closeSilently(is); + Utils.closeSilently(fileBody); + if (deleteImage && "file".equals(imageUri.getScheme())) { + final File file = new File(imageUri.getPath()); + if (!file.delete()) { + Log.w(LOGTAG, String.format("Unable to delete %s", file)); + } + } + } + } + + public static void updateProfileBackgroundImage(@NonNull final Context context, + @NonNull final Twitter twitter, + @NonNull final Uri imageUri, + final boolean tile, + final boolean deleteImage) + throws IOException, TwitterException { + FileBody fileBody = null; + try { + fileBody = getFileBody(context, imageUri); + twitter.updateProfileBackgroundImage(fileBody, tile); + } finally { + Utils.closeSilently(fileBody); if (deleteImage && "file".equals(imageUri.getScheme())) { final File file = new File(imageUri.getPath()); if (!file.delete()) { @@ -192,13 +217,13 @@ public class TwitterWrapper implements Constants { public static User updateProfileImage(final Context context, final Twitter twitter, final Uri imageUri, final boolean deleteImage) - throws FileNotFoundException, TwitterException { - InputStream is = null; + throws IOException, TwitterException { + FileBody fileBody = null; try { - is = context.getContentResolver().openInputStream(imageUri); - return twitter.updateProfileImage(new FileBody(is, "image", -1, null)); + fileBody = getFileBody(context, imageUri); + return twitter.updateProfileImage(fileBody); } finally { - Utils.closeSilently(is); + Utils.closeSilently(fileBody); if (deleteImage && "file".equals(imageUri.getScheme())) { final File file = new File(imageUri.getPath()); if (!file.delete()) { @@ -208,6 +233,33 @@ public class TwitterWrapper implements Constants { } } + private static FileBody getFileBody(Context context, Uri imageUri) throws IOException { + final ContentResolver cr = context.getContentResolver(); + String type = cr.getType(imageUri); + if (type == null) { + type = Utils.getImageMimeType(cr, imageUri); + } + final ContentType contentType; + final String extension; + if (type != null) { + contentType = ContentType.parse(type); + extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(type); + } else { + contentType = null; + extension = null; + } + final InputStream is = cr.openInputStream(imageUri); + if (is == null) throw new FileNotFoundException(imageUri.toString()); + + final String fileName; + if (extension != null) { + fileName = "image." + extension; + } else { + fileName = "image"; + } + return new FileBody(is, fileName, is.available(), contentType); + } + public static final class MessageListResponse extends TwitterListResponse { public MessageListResponse(final UserKey accountKey, final Exception exception) { diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java b/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java index f21be9181..374beda44 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/Utils.java @@ -41,7 +41,6 @@ import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.PorterDuff.Mode; import android.graphics.Rect; -import android.graphics.Typeface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.NinePatchDrawable; @@ -75,13 +74,10 @@ import android.support.v4.view.GravityCompat; import android.support.v4.view.accessibility.AccessibilityEventCompat; import android.support.v7.app.AppCompatActivity; import android.system.ErrnoException; -import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.format.DateFormat; import android.text.format.DateUtils; import android.text.format.Time; -import android.text.style.CharacterStyle; -import android.text.style.StyleSpan; import android.transition.Transition; import android.transition.TransitionInflater; import android.util.Log; @@ -1239,6 +1235,23 @@ public final class Utils implements Constants { return o.outMimeType; } + @Nullable + public static String getImageMimeType(ContentResolver cr, final Uri uri) { + if (uri == null) return null; + final BitmapFactory.Options o = new BitmapFactory.Options(); + o.inJustDecodeBounds = true; + InputStream is = null; + try { + is = cr.openInputStream(uri); + BitmapFactory.decodeStream(is, null, o); + return o.outMimeType; + } catch (IOException e) { + return null; + } finally { + closeSilently(is); + } + } + public static String getImagePathFromUri(final Context context, final Uri uri) { if (context == null || uri == null) return null; @@ -1290,28 +1303,6 @@ public final class Utils implements Constants { return new File(context.getCacheDir(), cacheDirName); } - public static CharSequence getKeywordBoldedText(final CharSequence orig, final String... keywords) { - return getKeywordHighlightedText(orig, new StyleSpan(Typeface.BOLD), keywords); - } - - public static CharSequence getKeywordHighlightedText(final CharSequence orig, final CharacterStyle style, - final String... keywords) { - if (keywords == null || keywords.length == 0 || orig == null) return orig; - final SpannableStringBuilder sb = SpannableStringBuilder.valueOf(orig); - final StringBuilder patternBuilder = new StringBuilder(); - for (int i = 0, j = keywords.length; i < j; i++) { - if (i != 0) { - patternBuilder.append('|'); - } - patternBuilder.append(Pattern.quote(keywords[i])); - } - final Matcher m = Pattern.compile(patternBuilder.toString(), Pattern.CASE_INSENSITIVE).matcher(orig); - while (m.find()) { - sb.setSpan(style, m.start(), m.end(), SpannableStringBuilder.SPAN_INCLUSIVE_INCLUSIVE); - } - return sb; - } - public static String getLinkHighlightingStyleName(final Context context) { if (context == null) return null; final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); @@ -1785,7 +1776,7 @@ public final class Utils implements Constants { if (absListView == null) return; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { if (absListView instanceof ListView) { - final ListView listView = ((ListView) absListView); + final ListView listView = (ListView) absListView; listView.setSelectionFromTop(position, offset); } else { absListView.setSelection(position); @@ -1794,7 +1785,7 @@ public final class Utils implements Constants { } else { stopListView(absListView); if (absListView instanceof ListView) { - final ListView listView = ((ListView) absListView); + final ListView listView = (ListView) absListView; listView.setSelectionFromTop(position, offset); } else { absListView.setSelection(position); @@ -1929,6 +1920,9 @@ public final class Utils implements Constants { .getMessage(context, te.getStatusCode(), te.getErrorCode()); message = context.getString(R.string.error_message_with_action, action, msg != null ? msg : trimLineBreak(te.getMessage())); + } else if (!TextUtils.isEmpty(te.getErrorMessage())) { + message = context.getString(R.string.error_message_with_action, action, + trimLineBreak(te.getErrorMessage())); } else if (te.getCause() instanceof SSLException) { final String msg = te.getCause().getMessage(); if (msg != null && msg.contains("!=")) { @@ -2148,8 +2142,8 @@ public final class Utils implements Constants { public static boolean isCustomConsumerKeySecret(String consumerKey, String consumerSecret) { if (TextUtils.isEmpty(consumerKey) || TextUtils.isEmpty(consumerSecret)) return false; - return (!TWITTER_CONSUMER_KEY.equals(consumerKey) && !TWITTER_CONSUMER_SECRET.equals(consumerKey)) - && (!TWITTER_CONSUMER_KEY_LEGACY.equals(consumerKey) && !TWITTER_CONSUMER_SECRET_LEGACY.equals(consumerSecret)); + return !TWITTER_CONSUMER_KEY.equals(consumerKey) && !TWITTER_CONSUMER_SECRET.equals(consumerKey) + && !TWITTER_CONSUMER_KEY_LEGACY.equals(consumerKey) && !TWITTER_CONSUMER_SECRET_LEGACY.equals(consumerSecret); } public static boolean isStreamingEnabled() { diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/dagger/GeneralComponent.java b/twidere/src/main/java/org/mariotaku/twidere/util/dagger/GeneralComponent.java index e36456aa5..e26b4c28d 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/dagger/GeneralComponent.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/dagger/GeneralComponent.java @@ -32,9 +32,9 @@ import org.mariotaku.twidere.adapter.ComposeAutoCompleteAdapter; import org.mariotaku.twidere.adapter.DraftsAdapter; import org.mariotaku.twidere.adapter.DummyItemAdapter; import org.mariotaku.twidere.adapter.UserAutoCompleteAdapter; +import org.mariotaku.twidere.fragment.BaseFiltersFragment; import org.mariotaku.twidere.fragment.BaseListFragment; import org.mariotaku.twidere.fragment.BasePreferenceFragment; -import org.mariotaku.twidere.fragment.BaseFiltersFragment; import org.mariotaku.twidere.fragment.BaseSupportDialogFragment; import org.mariotaku.twidere.fragment.BaseSupportFragment; import org.mariotaku.twidere.fragment.MessagesConversationFragment; @@ -51,10 +51,13 @@ import org.mariotaku.twidere.task.AbsFriendshipOperationTask; import org.mariotaku.twidere.task.GetDirectMessagesTask; import org.mariotaku.twidere.task.GetTrendsTask; import org.mariotaku.twidere.task.ManagedAsyncTask; +import org.mariotaku.twidere.task.UpdateProfileBackgroundImageTask; +import org.mariotaku.twidere.task.UpdateProfileBannerImageTask; import org.mariotaku.twidere.task.twitter.GetActivitiesTask; import org.mariotaku.twidere.task.twitter.GetStatusesTask; import org.mariotaku.twidere.text.util.EmojiEditableFactory; import org.mariotaku.twidere.text.util.EmojiSpannableFactory; +import org.mariotaku.twidere.util.AsyncTwitterWrapper; import org.mariotaku.twidere.util.MultiSelectEventHandler; import javax.inject.Singleton; @@ -138,4 +141,10 @@ public interface GeneralComponent { void inject(ParcelableStatusLoader loader); void inject(GetTrendsTask task); + + void inject(UpdateProfileBackgroundImageTask task); + + void inject(UpdateProfileBannerImageTask task); + + void inject(AsyncTwitterWrapper.UpdateProfileImageTask task); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/theme/MaterialEditTextViewProcessor.java b/twidere/src/main/java/org/mariotaku/twidere/util/theme/MaterialEditTextViewProcessor.java new file mode 100644 index 000000000..ed5f26c01 --- /dev/null +++ b/twidere/src/main/java/org/mariotaku/twidere/util/theme/MaterialEditTextViewProcessor.java @@ -0,0 +1,21 @@ +package org.mariotaku.twidere.util.theme; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.afollestad.appthemeengine.Config; +import com.afollestad.appthemeengine.viewprocessors.ViewProcessor; +import com.rengwuxian.materialedittext.MaterialEditText; + +/** + * Created by mariotaku on 16/4/1. + */ +public class MaterialEditTextViewProcessor implements ViewProcessor { + @Override + public void process(@NonNull Context context, @Nullable String key, @Nullable MaterialEditText target, @Nullable Void extra) { + if (target == null) return; + int accentColor = Config.accentColor(context, key); + target.setPrimaryColor(accentColor); + } +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/HomeDrawerLayout.java b/twidere/src/main/java/org/mariotaku/twidere/view/HomeDrawerLayout.java index 344bfed32..343bc5a72 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/HomeDrawerLayout.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/HomeDrawerLayout.java @@ -40,6 +40,9 @@ public class HomeDrawerLayout extends DrawerLayout implements ViewInterface { } private void init(Context context, @Nullable ATEActivity keyContext) { + if (keyContext == null && context instanceof ATEActivity) { + keyContext = (ATEActivity) context; + } final String key = keyContext != null ? keyContext.getATEKey() : null; if (Config.coloredStatusBar(context, key)) { // Sets the status bar overlayed by the DrawerLayout diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/themed/BackgroundTintMaterialEditText.java b/twidere/src/main/java/org/mariotaku/twidere/view/themed/BackgroundTintMaterialEditText.java deleted file mode 100644 index 9371f54b1..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/view/themed/BackgroundTintMaterialEditText.java +++ /dev/null @@ -1,53 +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 org.mariotaku.twidere.view.themed; - -import android.content.Context; -import android.content.res.ColorStateList; -import android.support.annotation.NonNull; -import android.util.AttributeSet; - -import com.rengwuxian.materialedittext.MaterialEditText; - -import org.mariotaku.twidere.view.iface.IThemeBackgroundTintView; - -/** - * TextView with tint background support - */ -public class BackgroundTintMaterialEditText extends MaterialEditText implements IThemeBackgroundTintView { - - public BackgroundTintMaterialEditText(Context context) { - super(context); - } - - public BackgroundTintMaterialEditText(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public BackgroundTintMaterialEditText(Context context, AttributeSet attrs, int style) { - super(context, attrs, style); - } - - @Override - public void setBackgroundTintColor(@NonNull ColorStateList color) { - setPrimaryColor(color.getDefaultColor()); - } - -} diff --git a/twidere/src/main/res/layout/activity_activity_picker.xml b/twidere/src/main/res/layout/activity_activity_picker.xml deleted file mode 100644 index b6b8e9d8f..000000000 --- a/twidere/src/main/res/layout/activity_activity_picker.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/twidere/src/main/res/layout/dialog_user_list_detail_editor.xml b/twidere/src/main/res/layout/dialog_user_list_detail_editor.xml index 5460baf88..1e9707d9e 100644 --- a/twidere/src/main/res/layout/dialog_user_list_detail_editor.xml +++ b/twidere/src/main/res/layout/dialog_user_list_detail_editor.xml @@ -24,7 +24,7 @@ android:layout_height="match_parent" android:padding="@dimen/element_spacing_normal"> - - + android:scaleType="centerCrop" + tools:src="@drawable/ic_launcher_web"/> + android:padding="@dimen/element_spacing_normal" + android:visibility="gone" + tools:visibility="visible"> + android:scaleType="centerCrop" + tools:src="@drawable/nyan_stars_background_tile"/> + + + + + + + + - + app:met_maxCharacters="20" + app:met_primaryColor="?colorAccent" + tools:text="TwidereProject"/> - + app:met_maxCharacters="160" + app:met_primaryColor="?colorAccent" + tools:text="@string/sample_status_text"/> - + app:met_maxCharacters="30" + app:met_primaryColor="?colorAccent" + tools:text="Earth"/> - + app:met_maxCharacters="100" + app:met_primaryColor="?colorAccent" + tools:text="https://github.com/TwidereProject/"/> + android:layout_weight="0" + tools:color="@color/branding_color"/> + android:layout_weight="0" + tools:color="@color/branding_color"/> updating profile updating profile image updating profile header image + updating profile background image removing profile header image updating details blocking @@ -588,6 +589,7 @@ Function Replies Profile banner + Profile background Profile Listed Blocking