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. 42
      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-array name="post_options">
<item>Show clickables</item>
<item>Info</item>
<item>Quote</item>
<item>Copy text</item>

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

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

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

@ -1,18 +1,38 @@
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.
*/
public class PostLinkable {
public class PostLinkable extends ClickableSpan {
public static enum Type {QUOTE, LINK};
public final Post post;
public final String key;
public final String value;
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.value = value;
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
public void onPostClicked(Post post) {
if (loadable.isThreadMode()) {
threadManager.showPostLinkables(post);
} else {
baseActivity.onOPClicked(post);
}
baseActivity.onOPClicked(post);
}
@Override

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

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

@ -85,7 +85,7 @@ public class ThreadLoader {
private void onError(VolleyError error) {
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
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.R;
import org.floens.chan.entity.Post;
import org.floens.chan.entity.PostLinkable;
import org.floens.chan.manager.ThreadManager;
import org.floens.chan.net.ChanUrls;
import org.floens.chan.utils.IconCache;
@ -15,6 +16,7 @@ import android.graphics.drawable.Drawable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet;
@ -69,6 +71,15 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
init();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (post != null) {
post.setLinkableListener(null);
}
}
@SuppressWarnings("deprecation")
public void setPost(Post post, ThreadManager manager) {
this.post = post;
@ -118,6 +129,24 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
if (!TextUtils.isEmpty(post.comment)) {
commentView.setVisibility(View.VISIBLE);
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()) {
int maxHeight = context.getResources().getDimensionPixelSize(R.dimen.post_max_height);
@ -128,6 +157,9 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
} else {
commentView.setVisibility(View.GONE);
commentView.setText("");
commentView.setOnClickListener(null);
commentView.setOnLongClickListener(null);
post.setLinkableListener(null);
}
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);
commentView = new TextView(context);
commentView.setTextSize(15);
right.addView(commentView, matchWrapParams);
repliesView = new TextView(context);
@ -254,6 +287,10 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
addView(full, wrapParams);
}
public void onLinkableClick(PostLinkable linkable) {
manager.onPostLinkableClicked(linkable);
}
@Override
public void onClick(View v) {
manager.onPostClicked(post);

Loading…
Cancel
Save