Links inside the comment view are now clickable.

Moved the clickable selector to an long click option.
captchafix
Florens Douwes 12 years ago
parent a185eaadff
commit f7a27d1dc6
  1. 1
      Chan/res/values/strings.xml
  2. 1
      Chan/src/org/floens/chan/activity/BaseActivity.java
  3. 2
      Chan/src/org/floens/chan/activity/BoardActivity.java
  4. 48
      Chan/src/org/floens/chan/entity/Post.java
  5. 24
      Chan/src/org/floens/chan/entity/PostLinkable.java
  6. 6
      Chan/src/org/floens/chan/fragment/ThreadFragment.java
  7. 6
      Chan/src/org/floens/chan/manager/PinnedManager.java
  8. 17
      Chan/src/org/floens/chan/manager/ThreadManager.java
  9. 2
      Chan/src/org/floens/chan/net/ThreadLoader.java
  10. 37
      Chan/src/org/floens/chan/view/PostView.java

@ -82,6 +82,7 @@
<string name="post_info">Info</string> <string name="post_info">Info</string>
<string-array name="post_options"> <string-array name="post_options">
<item>Show clickables</item>
<item>Info</item> <item>Info</item>
<item>Quote</item> <item>Quote</item>
<item>Copy text</item> <item>Copy text</item>

@ -230,6 +230,7 @@ public abstract class BaseActivity extends Activity implements PanelSlideListene
if (!TextUtils.isEmpty(value)) { if (!TextUtils.isEmpty(value)) {
pin.loadable.title = value; pin.loadable.title = value;
ChanApplication.getPinnedManager().refresh();
} }
} }
}) })

@ -41,7 +41,7 @@ public class BoardActivity extends BaseActivity implements ActionBar.OnNavigatio
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
boardLoadable.mode = Loadable.Mode.BOARD; boardLoadable.mode = Loadable.Mode.BOARD;
threadLoadable.mode = Loadable.Mode.THREAD; threadLoadable.mode = Loadable.Mode.THREAD;
boardFragment = ThreadFragment.newInstance(this); boardFragment = ThreadFragment.newInstance(this);
threadFragment = ThreadFragment.newInstance(this); threadFragment = ThreadFragment.newInstance(this);

@ -4,7 +4,9 @@ import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.floens.chan.entity.PostLinkable.Type;
import org.floens.chan.net.ChanUrls; import org.floens.chan.net.ChanUrls;
import org.floens.chan.view.PostView;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
@ -48,6 +50,7 @@ public class Post {
public long time = 0; public long time = 0;
public String email = ""; public String email = "";
private PostView linkableListener;
public final ArrayList<PostLinkable> linkables = new ArrayList<PostLinkable>(); public final ArrayList<PostLinkable> linkables = new ArrayList<PostLinkable>();
public Post() { public Post() {
@ -57,6 +60,14 @@ public class Post {
rawComment = e; rawComment = e;
} }
public void setLinkableListener(PostView listener) {
linkableListener = listener;
}
public PostView getLinkableListener() {
return linkableListener;
}
/** /**
* Finish up the data * Finish up the data
* @return false if this data is invalid * @return false if this data is invalid
@ -119,18 +130,24 @@ public class Post {
String[] parts = text.split("\\s"); String[] parts = text.split("\\s");
for (String item : parts) { for (String item : parts) {
try { if (item.contains("://")) {
URL url = new URL(item); try {
URL url = new URL(item);
SpannableString link = new SpannableString(url.toString());
link.setSpan(new ForegroundColorSpan(Color.argb(255, 0, 0, 180)), 0, link.length(), 0); SpannableString link = new SpannableString(url.toString());
// link.setSpan(new ForegroundColorSpan(Color.argb(255, 0, 0, 180)), 0, link.length(), 0);
linkables.add(new PostLinkable(item, item, PostLinkable.Type.LINK));
// linkables.add(new PostLinkable(this, item, item, PostLinkable.Type.LINK));
total = TextUtils.concat(total, link, " ");
} catch(Exception e) { PostLinkable pl = new PostLinkable(this, item, item, PostLinkable.Type.LINK);
total = TextUtils.concat(total, item, " "); link.setSpan(pl, 0, link.length(), 0);
} linkables.add(pl);
total = TextUtils.concat(total, link, " ");
} catch(Exception e) {
total = TextUtils.concat(total, item, " ");
}
}
} }
} else { } else {
total = TextUtils.concat(total, text); total = TextUtils.concat(total, text);
@ -148,11 +165,12 @@ public class Post {
Element anchor = (Element)node; Element anchor = (Element)node;
SpannableString link = new SpannableString(anchor.text()); SpannableString link = new SpannableString(anchor.text());
link.setSpan(new ForegroundColorSpan(Color.argb(255, 221, 0, 0)), 0, link.length(), 0);
total = TextUtils.concat(total, link); PostLinkable pl = new PostLinkable(this, anchor.text(), anchor.attr("href"), anchor.text().contains("://") ? Type.LINK : Type.QUOTE);
link.setSpan(pl, 0, link.length(), 0);
linkables.add(pl);
linkables.add(new PostLinkable(anchor.text(), anchor.attr("href"), PostLinkable.Type.QUOTE)); total = TextUtils.concat(total, link);
} else { } else {
// Unknown tag, add the inner part // Unknown tag, add the inner part
if (node instanceof Element) { if (node instanceof Element) {

@ -1,18 +1,38 @@
package org.floens.chan.entity; package org.floens.chan.entity;
import android.graphics.Color;
import android.text.TextPaint;
import android.text.style.ClickableSpan;
import android.view.View;
/** /**
* Anything that links to something in a post uses this entity. * Anything that links to something in a post uses this entity.
*/ */
public class PostLinkable { public class PostLinkable extends ClickableSpan {
public static enum Type {QUOTE, LINK}; public static enum Type {QUOTE, LINK};
public final Post post;
public final String key; public final String key;
public final String value; public final String value;
public final Type type; public final Type type;
public PostLinkable(String key, String value, Type type) { public PostLinkable(Post post, String key, String value, Type type) {
this.post = post;
this.key = key; this.key = key;
this.value = value; this.value = value;
this.type = type; this.type = type;
} }
@Override
public void onClick(View widget) {
if (post.getLinkableListener() != null) {
post.getLinkableListener().onLinkableClick(this);
}
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setColor(type == Type.QUOTE ? Color.argb(255, 221, 0, 0) : Color.argb(255, 0, 0, 180));
ds.setUnderlineText(true);
}
} }

@ -139,11 +139,7 @@ public class ThreadFragment extends Fragment implements ThreadListener {
@Override @Override
public void onPostClicked(Post post) { public void onPostClicked(Post post) {
if (loadable.isThreadMode()) { baseActivity.onOPClicked(post);
threadManager.showPostLinkables(post);
} else {
baseActivity.onOPClicked(post);
}
} }
@Override @Override

@ -66,6 +66,12 @@ public class PinnedManager {
return tempList; return tempList;
} }
public void refresh() {
adapter.notifyDataSetChanged();
storePinnedListInPreferences("pinnedList", list);
}
public void remove(Pin pin) { public void remove(Pin pin) {
adapter.remove(pin); adapter.remove(pin);

@ -119,7 +119,9 @@ public class ThreadManager {
} }
public void onPostClicked(Post post) { public void onPostClicked(Post post) {
threadListener.onPostClicked(post); if (loadable.isBoardMode()) {
threadListener.onPostClicked(post);
}
} }
public void onPostLongClicked(final Post post) { public void onPostLongClicked(final Post post) {
@ -129,12 +131,15 @@ public class ThreadManager {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
switch(which) { switch(which) {
case 0: // Info case 0: // Show clickables
showPostLinkables(post);
break;
case 1: // Info
showPostInfo(post); showPostInfo(post);
case 1: // Quote case 2: // Quote
ReplyManager.getInstance().quote(post.no); ReplyManager.getInstance().quote(post.no);
break; break;
case 2: // Copy text case 3: // Copy text
copyText(post.comment.toString()); copyText(post.comment.toString());
break; break;
} }
@ -144,6 +149,10 @@ public class ThreadManager {
builder.create().show(); builder.create().show();
} }
public void onPostLinkableClicked(PostLinkable linkable) {
handleLinkableSelected(linkable);
}
/** /**
* Returns an TextView containing the appropiate error message * Returns an TextView containing the appropiate error message
* @param error * @param error

@ -85,7 +85,7 @@ public class ThreadLoader {
private void onError(VolleyError error) { private void onError(VolleyError error) {
if (stopped) return; if (stopped) return;
Log.e("Chan", "VolleyError: " + error.getMessage()); Log.e("Chan", "VolleyError in ThreadLoader: " + error.getMessage());
// 404 with more pages already loaded means endofline // 404 with more pages already loaded means endofline
if ((error instanceof ServerError) && loadable.isBoardMode() && loadable.no > 0) { if ((error instanceof ServerError) && loadable.isBoardMode() && loadable.no > 0) {

@ -3,6 +3,7 @@ package org.floens.chan.view;
import org.floens.chan.ChanApplication; import org.floens.chan.ChanApplication;
import org.floens.chan.R; import org.floens.chan.R;
import org.floens.chan.entity.Post; import org.floens.chan.entity.Post;
import org.floens.chan.entity.PostLinkable;
import org.floens.chan.manager.ThreadManager; import org.floens.chan.manager.ThreadManager;
import org.floens.chan.net.ChanUrls; import org.floens.chan.net.ChanUrls;
import org.floens.chan.utils.IconCache; import org.floens.chan.utils.IconCache;
@ -15,6 +16,7 @@ import android.graphics.drawable.Drawable;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.AbsoluteSizeSpan; import android.text.style.AbsoluteSizeSpan;
import android.text.style.ForegroundColorSpan; import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet; import android.util.AttributeSet;
@ -69,6 +71,15 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
init(); init();
} }
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (post != null) {
post.setLinkableListener(null);
}
}
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void setPost(Post post, ThreadManager manager) { public void setPost(Post post, ThreadManager manager) {
this.post = post; this.post = post;
@ -118,6 +129,24 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
if (!TextUtils.isEmpty(post.comment)) { if (!TextUtils.isEmpty(post.comment)) {
commentView.setVisibility(View.VISIBLE); commentView.setVisibility(View.VISIBLE);
commentView.setText(post.comment); commentView.setText(post.comment);
commentView.setMovementMethod(LinkMovementMethod.getInstance());
commentView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
PostView.this.onClick(v);
}
});
commentView.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return PostView.this.onLongClick(v);
}
});
if (manager.getLoadable().isThreadMode()) {
post.setLinkableListener(this);
}
if (manager.getLoadable().isBoardMode()) { if (manager.getLoadable().isBoardMode()) {
int maxHeight = context.getResources().getDimensionPixelSize(R.dimen.post_max_height); int maxHeight = context.getResources().getDimensionPixelSize(R.dimen.post_max_height);
@ -128,6 +157,9 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
} else { } else {
commentView.setVisibility(View.GONE); commentView.setVisibility(View.GONE);
commentView.setText(""); commentView.setText("");
commentView.setOnClickListener(null);
commentView.setOnLongClickListener(null);
post.setLinkableListener(null);
} }
if (post.isOP && post.replies > 0 && manager.getLoadable().isBoardMode()) { if (post.isOP && post.replies > 0 && manager.getLoadable().isBoardMode()) {
@ -240,6 +272,7 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
right.addView(iconView, matchWrapParams); right.addView(iconView, matchWrapParams);
commentView = new TextView(context); commentView = new TextView(context);
commentView.setTextSize(15);
right.addView(commentView, matchWrapParams); right.addView(commentView, matchWrapParams);
repliesView = new TextView(context); repliesView = new TextView(context);
@ -254,6 +287,10 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
addView(full, wrapParams); addView(full, wrapParams);
} }
public void onLinkableClick(PostLinkable linkable) {
manager.onPostLinkableClicked(linkable);
}
@Override @Override
public void onClick(View v) { public void onClick(View v) {
manager.onPostClicked(post); manager.onPostClicked(post);

Loading…
Cancel
Save