diff --git a/Chan/res/values/dimens.xml b/Chan/res/values/dimens.xml
index 5fe9aa2f..92fe81a2 100644
--- a/Chan/res/values/dimens.xml
+++ b/Chan/res/values/dimens.xml
@@ -3,7 +3,8 @@
10dp
11dp
- 6dp
+ 6dp
+
70dp
24dp
14dp
diff --git a/Chan/res/values/strings.xml b/Chan/res/values/strings.xml
index 80f3ebf6..ccf2f858 100644
--- a/Chan/res/values/strings.xml
+++ b/Chan/res/values/strings.xml
@@ -87,6 +87,7 @@
Info
+ - Reply
- Quote
- Info
- Show clickables
diff --git a/Chan/src/org/floens/chan/activity/BoardActivity.java b/Chan/src/org/floens/chan/activity/BoardActivity.java
index f0286ac9..3faaa200 100644
--- a/Chan/src/org/floens/chan/activity/BoardActivity.java
+++ b/Chan/src/org/floens/chan/activity/BoardActivity.java
@@ -4,7 +4,6 @@ import java.util.ArrayList;
import java.util.List;
import org.floens.chan.R;
-import org.floens.chan.fragment.ReplyFragment;
import org.floens.chan.fragment.ThreadFragment;
import org.floens.chan.manager.BoardManager;
import org.floens.chan.manager.PinnedManager;
@@ -207,10 +206,10 @@ public class BoardActivity extends BaseActivity implements ActionBar.OnNavigatio
return true;
case R.id.action_reply:
if (threadPane.isOpen()) {
- startReply(threadPane.isSlideable(), boardLoadable);
+ boardFragment.getThreadManager().openReply(true); // todo if tablet
} else {
if (threadFragment.getThreadManager().hasThread()) {
- startReply(threadPane.isSlideable(), threadLoadable);
+ threadFragment.getThreadManager().openReply(true); // todo if tablet
}
}
@@ -255,17 +254,6 @@ public class BoardActivity extends BaseActivity implements ActionBar.OnNavigatio
updateActionBarState();
}
- private void startReply(boolean startInActivity, Loadable loadable) {
- if (startInActivity) {
- ReplyActivity.setLoadable(loadable);
- Intent i = new Intent(this, ReplyActivity.class);
- startActivity(i);
- } else {
- ReplyFragment reply = ReplyFragment.newInstance(loadable);
- reply.show(getFragmentManager(), "replyDialog");
- }
- }
-
private void startLoadingBoard(Loadable loadable) {
this.boardLoadable = loadable;
diff --git a/Chan/src/org/floens/chan/manager/ThreadManager.java b/Chan/src/org/floens/chan/manager/ThreadManager.java
index 8a35d39f..cb801c53 100644
--- a/Chan/src/org/floens/chan/manager/ThreadManager.java
+++ b/Chan/src/org/floens/chan/manager/ThreadManager.java
@@ -4,7 +4,9 @@ import java.util.ArrayList;
import java.util.List;
import org.floens.chan.R;
+import org.floens.chan.activity.ReplyActivity;
import org.floens.chan.fragment.PostRepliesFragment;
+import org.floens.chan.fragment.ReplyFragment;
import org.floens.chan.model.Loadable;
import org.floens.chan.model.Post;
import org.floens.chan.model.PostLinkable;
@@ -128,16 +130,19 @@ public class ThreadManager {
@Override
public void onClick(DialogInterface dialog, int which) {
switch(which) {
- case 0: // Quote
+ case 0: // Reply
+ openReply(true); // todo if tablet
+ // Pass through
+ case 1: // Quote
ReplyManager.getInstance().quote(post.no);
break;
- case 1: // Info
+ case 2: // Info
showPostInfo(post);
break;
- case 2: // Show clickables
+ case 3: // Show clickables
showPostLinkables(post);
break;
- case 3: // Copy text
+ case 4: // Copy text
copyText(post.comment.toString());
break;
}
@@ -147,6 +152,17 @@ public class ThreadManager {
builder.create().show();
}
+ public void openReply(boolean startInActivity) {
+ if (startInActivity) {
+ ReplyActivity.setLoadable(loadable);
+ Intent i = new Intent(activity, ReplyActivity.class);
+ activity.startActivity(i);
+ } else {
+ ReplyFragment reply = ReplyFragment.newInstance(loadable);
+ reply.show(activity.getFragmentManager(), "replyDialog");
+ }
+ }
+
public void onPostLinkableClicked(PostLinkable linkable) {
handleLinkableSelected(linkable);
}
@@ -205,6 +221,10 @@ public class ThreadManager {
text += "\nCountry: " + post.countryName;
}
+ if (!TextUtils.isEmpty(post.capcode)) {
+ text += "\nCapcode: " + post.capcode;
+ }
+
AlertDialog dialog = new AlertDialog.Builder(activity)
.setTitle(R.string.post_info)
.setMessage(text)
@@ -380,8 +400,3 @@ public class ThreadManager {
public void onThumbnailClicked(Post post);
}
}
-
-
-
-
-
diff --git a/Chan/src/org/floens/chan/model/Post.java b/Chan/src/org/floens/chan/model/Post.java
index e5af4f09..5b3b8ade 100644
--- a/Chan/src/org/floens/chan/model/Post.java
+++ b/Chan/src/org/floens/chan/model/Post.java
@@ -45,6 +45,7 @@ public class Post {
public boolean closed = false;
public String tripcode = "";
public String id = "";
+ public String capcode = "";
public String country = "";
public String countryName = "";
public long time = 0;
diff --git a/Chan/src/org/floens/chan/net/ChanReaderRequest.java b/Chan/src/org/floens/chan/net/ChanReaderRequest.java
index 000adf3f..0108f4a2 100644
--- a/Chan/src/org/floens/chan/net/ChanReaderRequest.java
+++ b/Chan/src/org/floens/chan/net/ChanReaderRequest.java
@@ -78,7 +78,7 @@ public class ChanReaderRequest extends JsonReaderRequest> {
// Thread array
while (reader.hasNext()) {
// Thread object
- list.add(readThreadObject(reader, loadable.board));
+ list.add(readPostObject(reader, loadable.board));
}
reader.endArray();
} else {
@@ -115,7 +115,7 @@ public class ChanReaderRequest extends JsonReaderRequest> {
if (reader.nextName().equals("posts")) {
reader.beginArray();
- list.add(readThreadObject(reader, loadable.board));
+ list.add(readPostObject(reader, loadable.board));
// Only consume one post
while (reader.hasNext()) reader.skipValue();
@@ -162,7 +162,7 @@ public class ChanReaderRequest extends JsonReaderRequest> {
reader.beginArray(); // Threads array
while (reader.hasNext()) {
- list.add(readThreadObject(reader, loadable.board));
+ list.add(readPostObject(reader, loadable.board));
}
reader.endArray();
@@ -189,7 +189,7 @@ public class ChanReaderRequest extends JsonReaderRequest> {
return list;
}
- private Post readThreadObject(JsonReader reader, String board) throws IllegalStateException, NumberFormatException, IOException {
+ private Post readPostObject(JsonReader reader, String board) throws IllegalStateException, NumberFormatException, IOException {
Post post = new Post();
post.board = board;
@@ -242,6 +242,8 @@ public class ChanReaderRequest extends JsonReaderRequest> {
post.countryName = reader.nextString();
} else if (key.equals("id")) {
post.id = reader.nextString();
+ } else if (key.equals("capcode")) {
+ post.capcode = reader.nextString();
} else {
// Unknown/ignored key
// log("Unknown/ignored key: " + key + ".");
diff --git a/Chan/src/org/floens/chan/utils/ViewUtils.java b/Chan/src/org/floens/chan/utils/ViewUtils.java
new file mode 100644
index 00000000..ff9a7721
--- /dev/null
+++ b/Chan/src/org/floens/chan/utils/ViewUtils.java
@@ -0,0 +1,19 @@
+package org.floens.chan.utils;
+
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+
+public class ViewUtils {
+ @SuppressWarnings("deprecation")
+ public static void setPressedDrawable(View view) {
+ TypedArray arr = view.getContext().obtainStyledAttributes(
+ new int[] {android.R.attr.selectableItemBackground});
+
+ Drawable drawable = arr.getDrawable(0);
+
+ view.setBackgroundDrawable(drawable);
+
+ arr.recycle();
+ }
+}
diff --git a/Chan/src/org/floens/chan/view/PostView.java b/Chan/src/org/floens/chan/view/PostView.java
index 26817b0d..583e72d5 100644
--- a/Chan/src/org/floens/chan/view/PostView.java
+++ b/Chan/src/org/floens/chan/view/PostView.java
@@ -7,17 +7,18 @@ import org.floens.chan.model.Post;
import org.floens.chan.model.PostLinkable;
import org.floens.chan.net.ChanUrls;
import org.floens.chan.utils.IconCache;
+import org.floens.chan.utils.ViewUtils;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
-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.BackgroundColorSpan;
import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet;
import android.view.View;
@@ -80,7 +81,6 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
}
}
- @SuppressWarnings("deprecation")
public void setPost(final Post post, final ThreadManager manager) {
this.post = post;
this.manager = manager;
@@ -116,6 +116,22 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
total = TextUtils.concat(total, tripcode, " ");
}
+ if (!TextUtils.isEmpty(post.id)) {
+ SpannableString id = new SpannableString(" ID: " + post.id + " ");
+ IDColor c = computeIDColor(post.id);
+ id.setSpan(new ForegroundColorSpan(c.color), 0, id.length(), 0);
+ id.setSpan(new BackgroundColorSpan(c.backgroundColor), 0, id.length(), 0);
+ id.setSpan(new AbsoluteSizeSpan(10, true), 0, id.length(), 0);
+ total = TextUtils.concat(total, id, " ");
+ }
+
+ if (!TextUtils.isEmpty(post.capcode)) {
+ SpannableString tripcode = new SpannableString("Capcode: " + post.capcode);
+ tripcode.setSpan(new ForegroundColorSpan(Color.argb(255, 255, 0, 0)), 0, tripcode.length(), 0);
+ tripcode.setSpan(new AbsoluteSizeSpan(10, true), 0, tripcode.length(), 0);
+ total = TextUtils.concat(total, tripcode, " ");
+ }
+
CharSequence relativeTime = DateUtils.getRelativeTimeSpanString(post.time * 1000L, System.currentTimeMillis(),
DateUtils.SECOND_IN_MILLIS, 0);
@@ -207,10 +223,7 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
setClickable(true);
setFocusable(true);
- int[] attr = new int[] {android.R.attr.selectableItemBackground};
- Drawable drawable = context.obtainStyledAttributes(attr).getDrawable(0);
-
- setBackgroundDrawable(drawable);
+ ViewUtils.setPressedDrawable(this);
}
}
@@ -224,8 +237,9 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
isBuild = true;
Resources resources = context.getResources();
+ int postPadding = resources.getDimensionPixelSize(R.dimen.post_padding);
int commentPadding = resources.getDimensionPixelSize(R.dimen.post_comment_padding);
- int textPadding = resources.getDimensionPixelSize(R.dimen.post_text_padding);
+ int iconPadding = resources.getDimensionPixelSize(R.dimen.post_icon_padding);
int iconWidth = resources.getDimensionPixelSize(R.dimen.post_icon_width);
int iconHeight = resources.getDimensionPixelSize(R.dimen.post_icon_height);
int imageSize = resources.getDimensionPixelSize(R.dimen.thumbnail_size);
@@ -257,21 +271,20 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
LinearLayout right = new LinearLayout(context);
right.setOrientation(VERTICAL);
- right.setPadding(commentPadding, commentPadding, commentPadding, commentPadding);
LinearLayout header = new LinearLayout(context);
header.setOrientation(HORIZONTAL);
titleView = new TextView(context);
titleView.setTextSize(14);
- titleView.setPadding(0, 0, 0, textPadding);
+ titleView.setPadding(postPadding, postPadding, postPadding, 0);
header.addView(titleView, wrapParams);
right.addView(header, matchWrapParams);
iconView = new LinearLayout(context);
iconView.setOrientation(HORIZONTAL);
- iconView.setPadding(0, 0, 0, textPadding);
+ iconView.setPadding(postPadding, iconPadding, postPadding, 0);
stickyView = new ImageView(context);
stickyView.setImageBitmap(IconCache.stickyIcon);
@@ -285,18 +298,34 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
commentView = new TextView(context);
commentView.setTextSize(15);
+ commentView.setPadding(postPadding, commentPadding, postPadding, commentPadding);
right.addView(commentView, matchWrapParams);
repliesCountView = new TextView(context);
repliesCountView.setTextColor(Color.argb(255, 100, 100, 100));
- repliesCountView.setPadding(0, textPadding, 0, 0);
+ repliesCountView.setPadding(postPadding, postPadding, postPadding, postPadding);
repliesCountView.setTextSize(14);
+ ViewUtils.setPressedDrawable(repliesCountView);
- right.addView(repliesCountView, matchWrapParams);
+ right.addView(repliesCountView, wrapParams);
full.addView(right, matchWrapParams);
- addView(full, wrapParams);
+ addView(full, matchParams);
+ }
+
+ private IDColor computeIDColor(String id) {
+ // Stolen from the 4chan extension
+ int hash = post.id.hashCode();
+
+ int r = (hash >> 24) & 0xff;
+ int g = (hash >> 16) & 0xff;
+ int b = (hash >> 8) & 0xff;
+
+ IDColor c = new IDColor();
+ c.color = (0xff << 24) + (r << 16) + (g << 8) + b;
+ c.backgroundColor = ((r * 0.299f) + (g * 0.587f) + (b * 0.114f)) > 125 ? 0xff636363 : 0x00000000;
+ return c;
}
public void onLinkableClick(PostLinkable linkable) {
@@ -314,6 +343,11 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
return true;
}
+
+ private static class IDColor {
+ public int color;
+ public int backgroundColor;
+ }
}