diff --git a/README.markdown b/README.markdown index 8946ca980c..b779bf70d5 100644 --- a/README.markdown +++ b/README.markdown @@ -88,7 +88,9 @@ I started a crowdin project, so anyone can do something for Twidere. Visit this **Donation methods** -PayPal & AliPay: "mariotaku.lee#gmail.com".replace("#", "@"); +PayPal & AliPay: String.format("%s@%s", "mariotaku.lee", "gmail.com"); + +PayPal & AliPay: String.format("%s@%s", "pay", "uucky.me"); Bitcoin: 1FHAVAzge7cj1LfCTMfnLL49DgA3mVUCuW diff --git a/twidere.component.twitter4j/src/main/java/twitter4j/TwitterImpl.java b/twidere.component.twitter4j/src/main/java/twitter4j/TwitterImpl.java index 6028695f4d..f0c29513c9 100644 --- a/twidere.component.twitter4j/src/main/java/twitter4j/TwitterImpl.java +++ b/twidere.component.twitter4j/src/main/java/twitter4j/TwitterImpl.java @@ -1333,9 +1333,9 @@ public ResponseList reverseGeoCode(final GeoQuery query) throws TwitterEx public QueryResult search(final Query query) throws TwitterException { final String url = conf.getRestBaseURL() + ENDPOINT_SEARCH_TWEETS; final String signUrl = conf.getSigningRestBaseURL() + ENDPOINT_SEARCH_TWEETS; - return factory.createQueryResult(get(url, signUrl, - query.asHttpParameterArray(INCLUDE_ENTITIES, INCLUDE_RTS, INCLUDE_REPLY_COUNT, - INCLUDE_DESCENDENT_REPLY_COUNT)), query); + final HttpParameter[] params = query.asHttpParameterArray(INCLUDE_ENTITIES, INCLUDE_RTS, INCLUDE_REPLY_COUNT, + INCLUDE_DESCENDENT_REPLY_COUNT, INCLUDE_MY_RETWEET, INCLUDE_CARDS, CARDS_PLATFORM); + return factory.createQueryResult(get(url, signUrl, params), query); } @Override diff --git a/twidere.component.twitter4j/src/main/java/twitter4j/User.java b/twidere.component.twitter4j/src/main/java/twitter4j/User.java index ea8c82595d..e8de1b507b 100644 --- a/twidere.component.twitter4j/src/main/java/twitter4j/User.java +++ b/twidere.component.twitter4j/src/main/java/twitter4j/User.java @@ -100,7 +100,7 @@ public interface User extends Comparable, TwitterResponse, Serializable { * * @return the profile image url of the user */ - String getProfileImageURL(); + String getProfileImageUrl(); /** * Returns the profile image url of the user, served over SSL diff --git a/twidere.component.twitter4j/src/main/java/twitter4j/internal/json/UserJSONImpl.java b/twidere.component.twitter4j/src/main/java/twitter4j/internal/json/UserJSONImpl.java index 1375fb8d6f..1c88db4e85 100644 --- a/twidere.component.twitter4j/src/main/java/twitter4j/internal/json/UserJSONImpl.java +++ b/twidere.component.twitter4j/src/main/java/twitter4j/internal/json/UserJSONImpl.java @@ -232,7 +232,7 @@ public String getProfileBannerImageUrl() { * {@inheritDoc} */ @Override - public String getProfileImageURL() { + public String getProfileImageUrl() { return profileImageUrl; } diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java index c1be659d7b..1baaa6ea19 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/support/HomeActivity.java @@ -224,7 +224,7 @@ public boolean getSystemWindowsInsets(Rect insets) { @Override public void setControlBarOffset(float offset) { - mTabsContainer.setTranslationY(mTabColumns > 1 ? 1 : getControlBarHeight() * (offset - 1)); + mTabsContainer.setTranslationY(mTabColumns > 1 ? 0 : getControlBarHeight() * (offset - 1)); final ViewGroup.LayoutParams lp = mActionsButton.getLayoutParams(); if (lp instanceof MarginLayoutParams) { mActionsButton.setTranslationY((((MarginLayoutParams) lp).bottomMargin + mActionsButton.getHeight()) * (1 - offset)); diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsActivitiesAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsActivitiesAdapter.java index 5f2f51573f..31bbd59ae0 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsActivitiesAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsActivitiesAdapter.java @@ -206,7 +206,7 @@ public void onStatusClick(StatusViewHolder holder, int position) { } @Override - public void onMediaClick(StatusViewHolder holder, ParcelableMedia media, int position) { + public void onMediaClick(StatusViewHolder holder, View view, ParcelableMedia media, int position) { } diff --git a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsStatusesAdapter.java b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsStatusesAdapter.java index 4c12b977c9..006d7a812b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsStatusesAdapter.java +++ b/twidere/src/main/java/org/mariotaku/twidere/adapter/AbsStatusesAdapter.java @@ -1,10 +1,7 @@ package org.mariotaku.twidere.adapter; import android.content.Context; -import android.os.Bundle; import android.support.annotation.NonNull; -import android.support.v4.app.FragmentActivity; -import android.support.v4.util.Pair; import android.support.v7.widget.CardView; import android.support.v7.widget.RecyclerView.ViewHolder; import android.view.LayoutInflater; @@ -15,7 +12,6 @@ import org.mariotaku.twidere.R; import org.mariotaku.twidere.adapter.iface.IStatusesAdapter; import org.mariotaku.twidere.app.TwidereApplication; -import org.mariotaku.twidere.fragment.support.UserFragment; import org.mariotaku.twidere.model.ParcelableMedia; import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.util.AsyncTwitterWrapper; @@ -185,14 +181,14 @@ public final void onStatusClick(StatusViewHolder holder, int position) { } @Override - public void onMediaClick(StatusViewHolder holder, final ParcelableMedia media, int position) { + public void onMediaClick(StatusViewHolder holder, View view, final ParcelableMedia media, int position) { if (mStatusAdapterListener == null) return; - mStatusAdapterListener.onMediaClick(holder, media, position); + mStatusAdapterListener.onMediaClick(holder, view, media, position); } @Override public void onUserProfileClick(final StatusViewHolder holder, final int position) { - if (mStatusAdapterListener==null)return; + if (mStatusAdapterListener == null) return; final ParcelableStatus status = getStatus(position); if (status == null) return; mStatusAdapterListener.onUserProfileClick(holder, status, position); @@ -301,7 +297,7 @@ public void setShowAccountsColor(boolean showAccountsColor) { public static interface StatusAdapterListener { void onGapClick(GapViewHolder holder, int position); - void onMediaClick(StatusViewHolder holder, ParcelableMedia media, int position); + void onMediaClick(StatusViewHolder holder, View view, ParcelableMedia media, int position); void onStatusActionClick(StatusViewHolder holder, int id, int position); diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java index af295a7589..21da44ca3e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/AbsStatusesFragment.java @@ -3,9 +3,11 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.graphics.Bitmap; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.v4.app.ActivityOptionsCompat; import android.support.v4.app.FragmentActivity; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.Loader; @@ -242,12 +244,15 @@ public void onGapClick(GapViewHolder holder, int position) { } @Override - public void onMediaClick(StatusViewHolder holder, ParcelableMedia media, int position) { + public void onMediaClick(StatusViewHolder holder, View view, ParcelableMedia media, int position) { final AbsStatusesAdapter adapter = getAdapter(); final ParcelableStatus status = adapter.getStatus(position); if (status == null) return; //TODO open media animation - Bundle options = null; + view.buildDrawingCache(); + final Bitmap drawingCache = Bitmap.createBitmap(view.getDrawingCache()); + final Bundle options = ActivityOptionsCompat.makeThumbnailScaleUpAnimation(view, drawingCache, 0, 0).toBundle(); + view.destroyDrawingCache(); Utils.openMedia(getActivity(), status, media, options); //spice SpiceProfilingUtil.log(getActivity(), diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/FileSelectorDialogFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/FileSelectorDialogFragment.java index 6b3da34644..7ccf5a7a2e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/FileSelectorDialogFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/FileSelectorDialogFragment.java @@ -87,7 +87,14 @@ public void onClick(final DialogInterface dialog, final int which) { if (isPickDirectory() && a instanceof Callback) { ((Callback) a).onFilePicked(getCurrentDirectory()); } - dismiss(); +// dismiss(); + break; + } + case DialogInterface.BUTTON_NEGATIVE: { + final FragmentActivity a = getActivity(); + if (a instanceof Callback) { + ((Callback) a).onCancelled(this); + } break; } } @@ -100,7 +107,7 @@ public Dialog onCreateDialog(final Bundle savedInstanceState) { final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setAdapter(mAdapter, this); builder.setTitle(R.string.pick_file); - builder.setNegativeButton(android.R.string.cancel, null); + builder.setNegativeButton(android.R.string.cancel, this); if (isPickDirectory()) { builder.setPositiveButton(android.R.string.ok, this); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java index 0f1c19fa16..299635afba 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java @@ -26,6 +26,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.res.Resources; +import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.Point; import android.graphics.Rect; @@ -37,6 +38,7 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.v4.app.ActivityOptionsCompat; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; @@ -107,8 +109,8 @@ import org.mariotaku.twidere.util.TwitterCardUtils; import org.mariotaku.twidere.util.UserColorNameUtils; import org.mariotaku.twidere.util.Utils; -import org.mariotaku.twidere.view.CardMediaContainer.OnMediaClickListener; import org.mariotaku.twidere.view.CardMediaContainer; +import org.mariotaku.twidere.view.CardMediaContainer.OnMediaClickListener; import org.mariotaku.twidere.view.ColorLabelRelativeLayout; import org.mariotaku.twidere.view.ForegroundColorView; import org.mariotaku.twidere.view.ShapedImageView; @@ -292,11 +294,13 @@ public void onGapClick(GapViewHolder holder, int position) { } @Override - public void onMediaClick(StatusViewHolder holder, ParcelableMedia media, int position) { + public void onMediaClick(StatusViewHolder holder, View view, ParcelableMedia media, int position) { final ParcelableStatus status = mStatusAdapter.getStatus(position); if (status == null) return; - //TODO open media animation - Bundle options = null; + view.buildDrawingCache(); + final Bitmap drawingCache = Bitmap.createBitmap(view.getDrawingCache()); + final Bundle options = ActivityOptionsCompat.makeThumbnailScaleUpAnimation(view, drawingCache, 0, 0).toBundle(); + view.destroyDrawingCache(); Utils.openMedia(getActivity(), status, media, options); SpiceProfilingUtil.log(getActivity(), status.id + ",Clicked," + status.account_id + "," + status.user_id + "," + status.text_plain.length() @@ -380,8 +384,10 @@ public void onUserProfileClick(StatusViewHolder holder, ParcelableStatus status, public void onMediaClick(View view, ParcelableMedia media, long accountId) { final ParcelableStatus status = mStatusAdapter.getStatus(); if (status == null) return; - //TODO open media animation - Bundle options = null; + view.buildDrawingCache(); + final Bitmap drawingCache = Bitmap.createBitmap(view.getDrawingCache()); + final Bundle options = ActivityOptionsCompat.makeThumbnailScaleUpAnimation(view, drawingCache, 0, 0).toBundle(); + view.destroyDrawingCache(); Utils.openMediaDirectly(getActivity(), accountId, status, media, status.media, options); //spice SpiceProfilingUtil.log(getActivity(), @@ -397,7 +403,13 @@ public void onMediaClick(View view, ParcelableMedia media, long accountId) { private void addConversation(ParcelableStatus status, int position) { mStatusAdapter.addConversation(status, position); - } @Override + } + + private StatusAdapter getAdapter() { + return mStatusAdapter; + } + + @Override public Loader> onCreateLoader(final int id, final Bundle args) { final Bundle fragmentArgs = getArguments(); final long accountId = fragmentArgs.getLong(EXTRA_ACCOUNT_ID, -1); @@ -405,10 +417,6 @@ public Loader> onCreateLoader(final int id, fin return new ParcelableStatusLoader(getActivity(), false, fragmentArgs, accountId, statusId); } - private StatusAdapter getAdapter() { - return mStatusAdapter; - } - private DividerItemDecoration getItemDecoration() { return mItemDecoration; } @@ -476,29 +484,6 @@ private void loadReplies(ParcelableStatus status) { } } //end - } @Override - public void onLoadFinished(final Loader> loader, - final SingleResponse data) { - if (data.hasData()) { - final long itemId = mStatusAdapter.getItemId(mLayoutManager.findFirstVisibleItemPosition()); - final View firstChild = mLayoutManager.getChildAt(0); - final int top = firstChild != null ? firstChild.getTop() : 0; - final ParcelableStatus status = data.getData(); - if (mStatusAdapter.setStatus(status)) { - mLayoutManager.scrollToPositionWithOffset(1, 0); - mStatusAdapter.setConversation(null); - mStatusAdapter.setReplies(null); - loadReplies(status); - loadConversation(status); - } else { - final int position = mStatusAdapter.findPositionById(itemId); - mLayoutManager.scrollToPositionWithOffset(position, top); - } - setState(STATE_LOADED); - } else { - //TODO show errors - setState(STATE_ERROR); - } } private void restoreReadPosition(@Nullable Pair position) { @@ -524,6 +509,31 @@ private Pair saveReadPosition() { return new Pair<>(itemId, positionView != null ? positionView.getTop() : -1); } + @Override + public void onLoadFinished(final Loader> loader, + final SingleResponse data) { + if (data.hasData()) { + final long itemId = mStatusAdapter.getItemId(mLayoutManager.findFirstVisibleItemPosition()); + final View firstChild = mLayoutManager.getChildAt(0); + final int top = firstChild != null ? firstChild.getTop() : 0; + final ParcelableStatus status = data.getData(); + if (mStatusAdapter.setStatus(status)) { + mLayoutManager.scrollToPositionWithOffset(1, 0); + mStatusAdapter.setConversation(null); + mStatusAdapter.setReplies(null); + loadReplies(status); + loadConversation(status); + } else { + final int position = mStatusAdapter.findPositionById(itemId); + mLayoutManager.scrollToPositionWithOffset(position, top); + } + setState(STATE_LOADED); + } else { + //TODO show errors + setState(STATE_ERROR); + } + } + private void setConversation(List data) { final Pair readPosition = saveReadPosition(); mStatusAdapter.setConversation(data); @@ -865,22 +875,23 @@ private void initViews() { mediaPreview.setStyle(adapter.getMediaPreviewStyle()); + quoteTextView.setTextIsSelectable(true); + textView.setTextIsSelectable(true); + + quoteTextView.setMovementMethod(StatusContentMovementMethod.getInstance()); textView.setMovementMethod(StatusContentMovementMethod.getInstance()); -// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - quoteTextView.setCustomSelectionActionModeCallback(new StatusActionModeCallback(quoteTextView, fragment, activity)); - textView.setCustomSelectionActionModeCallback(new StatusActionModeCallback(textView, fragment, activity)); -// } + + quoteTextView.setCustomSelectionActionModeCallback(new StatusActionModeCallback(quoteTextView, activity)); + textView.setCustomSelectionActionModeCallback(new StatusActionModeCallback(textView, activity)); } private static class StatusActionModeCallback implements Callback { private final TextView textView; - private final StatusFragment fragment; private final FragmentActivity activity; - public StatusActionModeCallback(TextView textView, StatusFragment fragment, FragmentActivity activity) { + public StatusActionModeCallback(TextView textView, FragmentActivity activity) { this.textView = textView; - this.fragment = fragment; this.activity = activity; } @@ -1388,9 +1399,9 @@ public void onItemMenuClick(ViewHolder holder, View itemView, int position) { } @Override - public void onMediaClick(StatusViewHolder holder, ParcelableMedia media, int position) { + public void onMediaClick(StatusViewHolder holder, View view, ParcelableMedia media, int position) { if (mStatusAdapterListener != null) { - mStatusAdapterListener.onMediaClick(holder, media, position); + mStatusAdapterListener.onMediaClick(holder, view, media, position); } } @@ -1519,14 +1530,11 @@ public void setOrientation(int orientation) { } + @Override public void onLoaderReset(final Loader> loader) { } - - - - } diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java index 62ac70eb23..c6bdcfa673 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java +++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java @@ -826,6 +826,7 @@ public void onPrepareOptionsMenu(final Menu menu) { } MenuUtils.setMenuItemAvailability(menu, MENU_MENTION, !isMyself); MenuUtils.setMenuItemAvailability(menu, R.id.incoming_friendships, isMyself); + MenuUtils.setMenuItemAvailability(menu, R.id.saved_searches, isMyself); // final MenuItem followItem = menu.findItem(MENU_FOLLOW); // followItem.setVisible(!isMyself); // final boolean shouldShowFollowItem = !creatingFriendship && !destroyingFriendship && !isMyself @@ -1003,6 +1004,10 @@ public boolean onOptionsItemSelected(final MenuItem item) { Utils.openUserMentions(getActivity(), user.account_id, user.screen_name); return true; } + case R.id.saved_searches: { + Utils.openSavedSearches(getActivity(), user.account_id); + return true; + } default: { if (item.getIntent() != null) { try { diff --git a/twidere/src/main/java/org/mariotaku/twidere/preference/SettingsImportExportPreference.java b/twidere/src/main/java/org/mariotaku/twidere/preference/SettingsImportExportPreference.java index 8d78f75bc6..42ed88c075 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/preference/SettingsImportExportPreference.java +++ b/twidere/src/main/java/org/mariotaku/twidere/preference/SettingsImportExportPreference.java @@ -41,6 +41,7 @@ public SettingsImportExportPreference(Context context) { public SettingsImportExportPreference(Context context, AttributeSet attrs) { super(context, attrs); + setDialogTitle(null); setPositiveButtonText(null); setNegativeButtonText(null); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/preference/ThemeBackgroundPreference.java b/twidere/src/main/java/org/mariotaku/twidere/preference/ThemeBackgroundPreference.java index 0186cc3f45..81d58ac6bd 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/preference/ThemeBackgroundPreference.java +++ b/twidere/src/main/java/org/mariotaku/twidere/preference/ThemeBackgroundPreference.java @@ -43,9 +43,6 @@ public class ThemeBackgroundPreference extends DialogPreference implements Const public void onClick(DialogInterface dialog, int which) { final String value = mBackgroundValues[which]; setValue(value); -// if (!VALUE_THEME_BACKGROUND_TRANSPARENT.equals(value)) { -// ThemeBackgroundPreference.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE); -// } } }; @@ -114,11 +111,6 @@ public String getValue() { return mValue; } - @Override - public void onClick(DialogInterface dialog, int which) { - super.onClick(dialog, which); - } - public ThemeBackgroundPreference(Context context) { this(context, null); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/text/method/StatusContentMovementMethod.java b/twidere/src/main/java/org/mariotaku/twidere/text/method/StatusContentMovementMethod.java index 45060b84a1..4f6c4707e5 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/text/method/StatusContentMovementMethod.java +++ b/twidere/src/main/java/org/mariotaku/twidere/text/method/StatusContentMovementMethod.java @@ -37,68 +37,67 @@ */ public class StatusContentMovementMethod extends ArrowKeyMovementMethod { - private static StatusContentMovementMethod sInstance; - - private static Object FROM_BELOW = new NoCopySpan.Concrete(); - - @Override - public void initialize(final TextView widget, final Spannable text) { - Selection.removeSelection(text); - text.removeSpan(FROM_BELOW); - } - - @Override - public void onTakeFocus(@NonNull final TextView view, @NonNull final Spannable text, final int dir) { - Selection.removeSelection(text); - - if ((dir & View.FOCUS_BACKWARD) != 0) { - text.setSpan(FROM_BELOW, 0, 0, Spannable.SPAN_POINT_POINT); - } else { - text.removeSpan(FROM_BELOW); - } - } - - @Override - public boolean onTouchEvent(@NonNull final TextView widget, @NonNull final Spannable buffer, @NonNull final MotionEvent event) { - final int action = event.getAction(); - - if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { - int x = (int) event.getX(); - int y = (int) event.getY(); - - x -= widget.getTotalPaddingLeft(); - y -= widget.getTotalPaddingTop(); - - x += widget.getScrollX(); - y += widget.getScrollY(); - - final Layout layout = widget.getLayout(); - final int line = layout.getLineForVertical(y); - final int off = layout.getOffsetForHorizontal(line, x); - - final ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class); - - if (link.length != 0) { - if (action == MotionEvent.ACTION_UP) { - link[0].onClick(widget); - } else if (action == MotionEvent.ACTION_DOWN) { - Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0])); - } - - return true; - } else { - Selection.removeSelection(buffer); - } - } - - return super.onTouchEvent(widget, buffer, event); - } - - public static MovementMethod getInstance() { - if (sInstance == null) { - sInstance = new StatusContentMovementMethod(); - } - - return sInstance; - } + private static StatusContentMovementMethod sInstance; + + private static Object FROM_BELOW = new NoCopySpan.Concrete(); + + @Override + public void initialize(final TextView widget, final Spannable text) { + Selection.removeSelection(text); + text.removeSpan(FROM_BELOW); + } + + @Override + public void onTakeFocus(@NonNull final TextView view, @NonNull final Spannable text, final int dir) { + Selection.removeSelection(text); + + if ((dir & View.FOCUS_BACKWARD) != 0) { + text.setSpan(FROM_BELOW, 0, 0, Spannable.SPAN_POINT_POINT); + } else { + text.removeSpan(FROM_BELOW); + } + } + + @Override + public boolean onTouchEvent(@NonNull final TextView widget, @NonNull final Spannable buffer, @NonNull final MotionEvent event) { + final int action = event.getAction(); + + if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { + int x = (int) event.getX(); + int y = (int) event.getY(); + + x -= widget.getTotalPaddingLeft(); + y -= widget.getTotalPaddingTop(); + + x += widget.getScrollX(); + y += widget.getScrollY(); + + final Layout layout = widget.getLayout(); + final int line = layout.getLineForVertical(y); + final int off = layout.getOffsetForHorizontal(line, x); + + final ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class); + + if (link.length != 0) { + if (action == MotionEvent.ACTION_UP) { + link[0].onClick(widget); + } else { + Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0])); + } + return true; + } else { + Selection.removeSelection(buffer); + } + } + + return super.onTouchEvent(widget, buffer, event); + } + + public static MovementMethod getInstance() { + if (sInstance == null) { + sInstance = new StatusContentMovementMethod(); + } + + return sInstance; + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java b/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java index cb2353a803..d89bcb2480 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java +++ b/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java @@ -33,8 +33,8 @@ import org.mariotaku.twidere.util.TwitterCardUtils; import org.mariotaku.twidere.util.UserColorNameUtils; import org.mariotaku.twidere.util.Utils; -import org.mariotaku.twidere.view.CardMediaContainer.OnMediaClickListener; import org.mariotaku.twidere.view.CardMediaContainer; +import org.mariotaku.twidere.view.CardMediaContainer.OnMediaClickListener; import org.mariotaku.twidere.view.ForegroundColorView; import org.mariotaku.twidere.view.ShapedImageView; import org.mariotaku.twidere.view.ShortTimeView; @@ -576,7 +576,7 @@ public boolean onLongClick(View v) { public void onMediaClick(View view, ParcelableMedia media, long accountId) { if (statusClickListener == null) return; final int position = getLayoutPosition(); - statusClickListener.onMediaClick(this, media, position); + statusClickListener.onMediaClick(this, view, media, position); } public void setOnClickListeners() { @@ -651,7 +651,7 @@ private boolean hasVideo(ParcelableMedia[] media) { public static interface StatusClickListener extends ContentCardClickListener { - void onMediaClick(StatusViewHolder holder, ParcelableMedia media, int position); + void onMediaClick(StatusViewHolder holder, View view, ParcelableMedia media, int position); void onStatusClick(StatusViewHolder holder, int position); @@ -835,7 +835,7 @@ public boolean onStatusLongClick(StatusViewHolder holder, int position) { } @Override - public void onMediaClick(StatusViewHolder holder, ParcelableMedia media, int position) { + public void onMediaClick(StatusViewHolder holder, View view, ParcelableMedia media, int position) { } diff --git a/twidere/src/main/res/menu/menu_user_profile.xml b/twidere/src/main/res/menu/menu_user_profile.xml index a682938fc4..59bc4e567c 100644 --- a/twidere/src/main/res/menu/menu_user_profile.xml +++ b/twidere/src/main/res/menu/menu_user_profile.xml @@ -36,6 +36,10 @@ android:id="@id/block" android:icon="@drawable/ic_action_block" android:title="@string/block"/> + + android:id="@+id/saved_searches" + android:icon="@drawable/ic_action_search" + android:title="@string/saved_searches"/> false - - - - - @color/background_color_window_dark @@ -111,18 +106,6 @@