From 78e3fe4763d589df494e4604277ecedc91df762a Mon Sep 17 00:00:00 2001 From: Florens Douwes Date: Fri, 20 Jun 2014 22:01:30 +0200 Subject: [PATCH] Changed long holding a post to an overflow button to view options --- .../chan/core/manager/ThreadManager.java | 109 +++++++----------- .../org/floens/chan/ui/view/PostView.java | 53 ++++++--- .../main/res/drawable-hdpi/ic_overflow.png | Bin 0 -> 221 bytes .../res/drawable-hdpi/ic_overflow_black.png | Bin 0 -> 338 bytes .../main/res/drawable-mdpi/ic_overflow.png | Bin 0 -> 274 bytes .../res/drawable-mdpi/ic_overflow_black.png | Bin 0 -> 253 bytes .../main/res/drawable-xhdpi/ic_overflow.png | Bin 0 -> 466 bytes .../res/drawable-xhdpi/ic_overflow_black.png | Bin 0 -> 454 bytes .../main/res/drawable-xxhdpi/ic_overflow.png | Bin 0 -> 206 bytes .../res/drawable-xxhdpi/ic_overflow_black.png | Bin 0 -> 425 bytes Clover/app/src/main/res/values/strings.xml | 1 + 11 files changed, 85 insertions(+), 78 deletions(-) create mode 100644 Clover/app/src/main/res/drawable-hdpi/ic_overflow.png create mode 100644 Clover/app/src/main/res/drawable-hdpi/ic_overflow_black.png create mode 100644 Clover/app/src/main/res/drawable-mdpi/ic_overflow.png create mode 100644 Clover/app/src/main/res/drawable-mdpi/ic_overflow_black.png create mode 100644 Clover/app/src/main/res/drawable-xhdpi/ic_overflow.png create mode 100644 Clover/app/src/main/res/drawable-xhdpi/ic_overflow_black.png create mode 100644 Clover/app/src/main/res/drawable-xxhdpi/ic_overflow.png create mode 100644 Clover/app/src/main/res/drawable-xxhdpi/ic_overflow_black.png diff --git a/Clover/app/src/main/java/org/floens/chan/core/manager/ThreadManager.java b/Clover/app/src/main/java/org/floens/chan/core/manager/ThreadManager.java index 4c2667ba..42aeb294 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/manager/ThreadManager.java +++ b/Clover/app/src/main/java/org/floens/chan/core/manager/ThreadManager.java @@ -28,7 +28,10 @@ import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.text.TextUtils; +import android.view.Menu; +import android.view.MenuItem; import android.widget.CheckBox; +import android.widget.PopupMenu; import android.widget.Toast; import com.android.volley.VolleyError; @@ -52,7 +55,6 @@ import org.floens.chan.utils.Logger; import org.floens.chan.utils.Utils; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; /** @@ -64,7 +66,7 @@ public class ThreadManager implements Loader.LoaderListener { private static final String TAG = "ThreadManager"; private final Activity activity; - private final ThreadManager.ThreadManagerListener threadManagerListener; + private final ThreadManagerListener threadManagerListener; private final List popupQueue = new ArrayList<>(); private PostRepliesFragment currentPopupFragment; private int highlightedPost = -1; @@ -214,31 +216,31 @@ public class ThreadManager implements Loader.LoaderListener { } } - public void onPostLongClicked(final Post post) { - AlertDialog.Builder builder = new AlertDialog.Builder(activity); + public void showPostOptions(final Post post, PopupMenu popupMenu) { + Menu menu = popupMenu.getMenu(); - List options = new ArrayList<>(Arrays.asList(activity.getResources().getStringArray(R.array.post_options))); + String[] baseOptions = activity.getResources().getStringArray(R.array.post_options); + for (int i = 0; i < baseOptions.length; i++) { + menu.add(Menu.NONE, i, Menu.NONE, baseOptions[i]); + } - final boolean id = !TextUtils.isEmpty(post.id); - if (id) { - options.add(activity.getString(R.string.post_highlight_id)); + if (!TextUtils.isEmpty(post.id)) { + menu.add(Menu.NONE, 5, Menu.NONE, activity.getString(R.string.post_highlight_id)); } // Only add the delete option when the post is a saved reply - final boolean delete = ChanApplication.getDatabaseManager().isSavedReply(post.board, post.no); - if (delete) { - options.add(activity.getString(R.string.delete)); + if (ChanApplication.getDatabaseManager().isSavedReply(post.board, post.no)) { + menu.add(Menu.NONE, 6, Menu.NONE, activity.getString(R.string.delete)); } - final boolean saved = ChanPreferences.getDeveloper(); - if (saved) { - options.add("Make this a saved reply"); + if (ChanPreferences.getDeveloper()) { + menu.add(Menu.NONE, 7, Menu.NONE, "Make this a saved reply"); } - builder.setItems(options.toArray(new String[options.size()]), new DialogInterface.OnClickListener() { + popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override - public void onClick(DialogInterface dialog, int which) { - switch (which) { + public boolean onMenuItemClick(final MenuItem item) { + switch (item.getItemId()) { case 0: // Quick reply openReply(false); // Pass through @@ -254,38 +256,20 @@ public class ThreadManager implements Loader.LoaderListener { case 4: // Copy text copyToClipboard(post.comment.toString()); break; - default: - // all optional, but with this order, starting at 5: - // id - // delete - // saved - - int idIndex = 5; - int deleteIndex = 5; - int savedIndex = 5; - - if (id) { - deleteIndex++; - savedIndex++; - } - - if (delete) { - savedIndex++; - } - - if (id && which == idIndex) { - highlightedId = post.id; - threadManagerListener.onRefreshView(); - } else if (delete && which == deleteIndex) { - deletePost(post); - } else if (saved && which == savedIndex) { - ChanApplication.getDatabaseManager().saveReply(new SavedReply(post.board, post.no, "foo")); - } + case 5: // Id + highlightedId = post.id; + threadManagerListener.onRefreshView(); + break; + case 6: // Delete + deletePost(post); + break; + case 7: // Save reply + ChanApplication.getDatabaseManager().saveReply(new SavedReply(post.board, post.no, "foo")); + break; } + return false; } }); - - builder.create().show(); } public void openReply(boolean startInActivity) { @@ -326,6 +310,7 @@ public class ThreadManager implements Loader.LoaderListener { ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE); ClipData clip = ClipData.newPlainText("Post text", comment); clipboard.setPrimaryClip(clip); + Toast.makeText(activity, R.string.post_text_copied_to_clipboard, Toast.LENGTH_SHORT).show(); } private void showPostInfo(Post post) { @@ -369,9 +354,7 @@ public class ThreadManager implements Loader.LoaderListener { } /** - * When the user clicks a post: a. when there's one linkable, open the - * linkable. b. when there's more than one linkable, show the user multiple - * options to select from. + * Show a list of things that can be clicked in a list to the user. * * @param post The post that was clicked. */ @@ -380,24 +363,20 @@ public class ThreadManager implements Loader.LoaderListener { final ArrayList linkables = post.linkables; if (linkables.size() > 0) { - if (linkables.size() == 1) { - handleLinkableSelected(linkables.get(0)); - } else { - String[] keys = new String[linkables.size()]; - for (int i = 0; i < linkables.size(); i++) { - keys[i] = linkables.get(i).key; - } + String[] keys = new String[linkables.size()]; + for (int i = 0; i < linkables.size(); i++) { + keys[i] = linkables.get(i).key; + } - builder.setItems(keys, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - handleLinkableSelected(linkables.get(which)); - } - }); + builder.setItems(keys, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + handleLinkableSelected(linkables.get(which)); + } + }); - AlertDialog dialog = builder.create(); - dialog.show(); - } + AlertDialog dialog = builder.create(); + dialog.show(); } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/view/PostView.java b/Clover/app/src/main/java/org/floens/chan/ui/view/PostView.java index 9cacec3a..a3839809 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/view/PostView.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/view/PostView.java @@ -38,6 +38,8 @@ import android.view.MotionEvent; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.PopupMenu; +import android.widget.RelativeLayout; import android.widget.TextView; import com.android.volley.toolbox.NetworkImageView; @@ -49,10 +51,11 @@ import org.floens.chan.core.manager.ThreadManager; import org.floens.chan.core.model.Post; import org.floens.chan.core.model.PostLinkable; import org.floens.chan.utils.IconCache; +import org.floens.chan.utils.ThemeHelper; import org.floens.chan.utils.Time; import org.floens.chan.utils.Utils; -public class PostView extends LinearLayout implements View.OnClickListener, View.OnLongClickListener { +public class PostView extends LinearLayout implements View.OnClickListener { private final static LinearLayout.LayoutParams matchParams = new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); private final static LinearLayout.LayoutParams wrapParams = new LinearLayout.LayoutParams( @@ -78,6 +81,7 @@ public class PostView extends LinearLayout implements View.OnClickListener, View private ImageView stickyView; private ImageView closedView; private NetworkImageView countryView; + private ImageView optionsView; private View lastSeen; private int thumbnailBackground; @@ -181,7 +185,6 @@ public class PostView extends LinearLayout implements View.OnClickListener, View } commentView.setOnClickListener(this); - commentView.setOnLongClickListener(this); if (manager.getLoadable().isThreadMode()) { post.setLinkableListener(this); @@ -345,9 +348,12 @@ public class PostView extends LinearLayout implements View.OnClickListener, View int iconHeight = resources.getDimensionPixelSize(R.dimen.post_icon_height); int imageSize = resources.getDimensionPixelSize(R.dimen.thumbnail_size); + RelativeLayout wrapper = new RelativeLayout(context); + wrapper.setLayoutParams(matchParams); + full = new LinearLayout(context); - full.setLayoutParams(matchParams); full.setOrientation(HORIZONTAL); + wrapper.addView(full, matchParams); // Create thumbnail imageView = new CustomNetworkImageView(context); @@ -375,6 +381,8 @@ public class PostView extends LinearLayout implements View.OnClickListener, View LinearLayout header = new LinearLayout(context); header.setOrientation(HORIZONTAL); + // 25 padding to give optionsView some space + header.setPadding(0, 0, Utils.dp(25), 0); titleView = new TextView(context); titleView.setTextSize(14); @@ -424,10 +432,36 @@ public class PostView extends LinearLayout implements View.OnClickListener, View full.addView(right, matchWrapParams); - addView(full, matchParams); + optionsView = new ImageView(context); + optionsView.setImageResource(R.drawable.ic_overflow); + Utils.setPressedDrawable(optionsView); + optionsView.setPadding(Utils.dp(15), Utils.dp(5), Utils.dp(5), Utils.dp(15)); + optionsView.setOnClickListener(new OnClickListener() { + @Override + public void onClick(final View v) { + PopupMenu popupMenu = new PopupMenu(context, v); + manager.showPostOptions(post, popupMenu); + popupMenu.show(); + if (ThemeHelper.getInstance().getTheme().isLightTheme) { + optionsView.setImageResource(R.drawable.ic_overflow_black); + popupMenu.setOnDismissListener(new PopupMenu.OnDismissListener() { + @Override + public void onDismiss(final PopupMenu menu) { + optionsView.setImageResource(R.drawable.ic_overflow); + } + }); + } + } + }); + wrapper.addView(optionsView, wrapParams); + RelativeLayout.LayoutParams optionsParams = (RelativeLayout.LayoutParams) optionsView.getLayoutParams(); + optionsParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); + optionsParams.addRule(RelativeLayout.ALIGN_PARENT_TOP); + optionsView.setLayoutParams(optionsParams); + + addView(wrapper, matchParams); - full.setOnClickListener(this); - full.setOnLongClickListener(this); + wrapper.setOnClickListener(this); } public void setOnClickListeners(View.OnClickListener listener) { @@ -444,13 +478,6 @@ public class PostView extends LinearLayout implements View.OnClickListener, View manager.onPostClicked(post); } - @Override - public boolean onLongClick(View v) { - manager.onPostLongClicked(post); - - return true; - } - private class PostViewMovementMethod extends LinkMovementMethod { @Override public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { diff --git a/Clover/app/src/main/res/drawable-hdpi/ic_overflow.png b/Clover/app/src/main/res/drawable-hdpi/ic_overflow.png new file mode 100644 index 0000000000000000000000000000000000000000..175e73f211b186978686293ef18181cc582e8f72 GIT binary patch literal 221 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-s>H$6>u0VPZ5n$;q(Val0yd^~XnmbA(pem_yvs_kZn2UpYUviaPTL`0rd?{?fT#F9O2T}WL??bEH%xZU^zjVg*)Uc8W^P*^0S*7oD11~6kvS4Y7 zxwQM`XOUUcj<4b_kAA$1CHus)$!~S_C+u1DN$|qkwQ`$U_8;YD{mR;!b6RmF(2)$D Lu6{1-oD!MuxJaf6YRz(?D&4B|(0{ z3=E7+Z2H$(7X4?=@fMsqaoWTehvk5h8J;eVAr`0a23hhQFyP@j_wvsF`rOs;4#q}5 z;Z-@Xt@uBy0+YeL?uvCBjUVLx!QKh>x*BuMddS}T!Hi+`U0W54C+8z)k=c= zf*BYXnYcB#eNh*?`u`G(-_L(x4uAjrVrE;Aw}w+YIQ31U&ZmzdOTHU82?BMz^mK6y zi8%arnzzs)1p$}L50fpVdgKi*N|=897d|CoUc#-`&`)9;7HNMmF*a12eDaU_2C*ZV zk0%tktz?WyFssf#b^dtG#uz;=i@6P3pLz+sz7#q20Nd0bZ?Ac`_698w)Aw8)#{K47 z`{R!r?rX9NJj(p^K%{vSSLd?a*_qd$CpgV+7I8T8+0tpg3rmgIR`%)ZcE7MK*zry2 zFYhTWmOJu~_VSdoq)s?iE|eOgK2gLYTw;Z`%KN-2oi&m-6>1evJxQL`S9Jd7QT3|< zFQ$EKUFNl|^z|uI(}*B@jTIN&_`|FAe72XE>GN!PB_qR3K3A(pm+k^R&EV^{@(!C3{zvpZ|81@p?F-p&^Za`qoESEz##vC~*XFHj z=T>V(c8c$wb-Q)V5rf7@W%Jh;?4KC^;YM$@c+>4~9eEpEX*}v^W0dN2JAI!>%iVv56WXW#hW-RDC*aGx8gQu&X%Q~lo FCIF89r;`8x literal 0 HcmV?d00001 diff --git a/Clover/app/src/main/res/drawable-xxhdpi/ic_overflow.png b/Clover/app/src/main/res/drawable-xxhdpi/ic_overflow.png new file mode 100644 index 0000000000000000000000000000000000000000..17dc0f292806caa024c0f09c69ee082f0a9bb0b7 GIT binary patch literal 206 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD3?#3*wSy!?1AIbU|Ns9FWbQ!)A{&oe0Y%wM zg8YIR7#iOH7dSsv{*xt8DACi!F(l*O+pCS74F)`}j+c+Tv)`m}i&x3xy;wy;^#4Kz zh6CwJZedS5GPve!&fBbQ@XBx&(@(ZdngOTdncvP|@pr=F-?O&aZ;4=GdDCdSf&JTo o^L_{9ZZKDG_$|l4u%VSZd@jpOv4{750xe_kboFyt=akR{0PGJ@M*si- literal 0 HcmV?d00001 diff --git a/Clover/app/src/main/res/drawable-xxhdpi/ic_overflow_black.png b/Clover/app/src/main/res/drawable-xxhdpi/ic_overflow_black.png new file mode 100644 index 0000000000000000000000000000000000000000..61f33d2110ca864f97efab487ba873327c4c6cb8 GIT binary patch literal 425 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD3?#3*wSy!Q0(?ST|Ns9FWE#^9FzN-a0$QL@ z666=mz+k%MdcnW{_S-*vJD$k6H0KVV|Nc*%2fhUK9K0RxV5az3Yd=u!4Nn)xkc@k8 zuSfDVD~Plv3W~bVd7k-y_nNkQs&kfYdtU!xqP}4q%lYIU!($T3Z;~~izE-%fFGxe7 z=S--`qJ|rLx*Z*q9GIAb7=r{Ra877!h-r{v5n&QhI4~{m@1;f04uowrEKN;pF1u>- zU6^AB#~*_WWwrOWS|k)Sn=NPv+tww<(!Rj h6rdw}48Mu*WjOE1t. Copy text Highlight ID + Text copied to clipboard Reply to Make thread in