Update reply screen

Also add spoilers
captchafix
Floens 11 years ago
parent 67d666f778
commit 16418a8b5c
  1. 4
      Clover/app/src/main/java/org/floens/chan/core/manager/ReplyManager.java
  2. 1
      Clover/app/src/main/java/org/floens/chan/core/model/Reply.java
  3. 11
      Clover/app/src/main/java/org/floens/chan/ui/activity/ReplyActivity.java
  4. 116
      Clover/app/src/main/java/org/floens/chan/ui/fragment/ReplyFragment.java
  5. 81
      Clover/app/src/main/java/org/floens/chan/ui/view/ThumbnailImageView.java
  6. BIN
      Clover/app/src/main/res/drawable-hdpi/ic_action_attachment.png
  7. BIN
      Clover/app/src/main/res/drawable-hdpi/ic_action_attachment_dark.png
  8. BIN
      Clover/app/src/main/res/drawable-mdpi/ic_action_attachment.png
  9. BIN
      Clover/app/src/main/res/drawable-mdpi/ic_action_attachment_dark.png
  10. BIN
      Clover/app/src/main/res/drawable-xhdpi/ic_action_attachment.png
  11. BIN
      Clover/app/src/main/res/drawable-xhdpi/ic_action_attachment_dark.png
  12. BIN
      Clover/app/src/main/res/drawable-xxhdpi/ic_action_attachment.png
  13. BIN
      Clover/app/src/main/res/drawable-xxhdpi/ic_action_attachment_dark.png
  14. 14
      Clover/app/src/main/res/layout/reply_captcha.xml
  15. 61
      Clover/app/src/main/res/layout/reply_input.xml
  16. 17
      Clover/app/src/main/res/layout/reply_view.xml
  17. 4
      Clover/app/src/main/res/values/strings.xml

@ -346,6 +346,10 @@ public class ReplyManager {
entity.addTextBody("resto", Integer.toString(reply.resto));
}
if (reply.spoilerImage) {
entity.addTextBody("spoiler", "on");
}
entity.addTextBody("recaptcha_challenge_field", reply.captchaChallenge);
entity.addTextBody("recaptcha_response_field", reply.captchaResponse, TEXT_UTF_8);

@ -36,4 +36,5 @@ public class Reply {
public String password = "";
public boolean usePass = false;
public String passId = "";
public boolean spoilerImage = false;
}

@ -18,6 +18,7 @@
package org.floens.chan.ui.activity;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.MenuItem;
@ -46,7 +47,7 @@ public class ReplyActivity extends Activity {
getActionBar().setDisplayHomeAsUpEnabled(true);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(android.R.id.content, ReplyFragment.newInstance(loadable, false));
ft.replace(android.R.id.content, ReplyFragment.newInstance(loadable, false), "reply");
ft.commitAllowingStateLoss();
loadable = null;
@ -56,6 +57,14 @@ public class ReplyActivity extends Activity {
}
}
@Override
public void onBackPressed() {
Fragment f = getFragmentManager().findFragmentByTag("reply");
if (f != null && ((ReplyFragment)f).onBackPressed()) {
super.onBackPressed();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {

@ -32,14 +32,13 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.webkit.MimeTypeMap;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;
@ -56,12 +55,14 @@ import org.floens.chan.chan.ChanUrls;
import org.floens.chan.core.ChanPreferences;
import org.floens.chan.core.manager.ReplyManager;
import org.floens.chan.core.manager.ReplyManager.ReplyResponse;
import org.floens.chan.core.model.Board;
import org.floens.chan.core.model.Loadable;
import org.floens.chan.core.model.Reply;
import org.floens.chan.ui.ViewFlipperAnimations;
import org.floens.chan.ui.view.LoadView;
import org.floens.chan.utils.ImageDecoder;
import org.floens.chan.utils.Logger;
import org.floens.chan.utils.ThemeHelper;
import org.floens.chan.utils.Utils;
import java.io.File;
@ -84,14 +85,14 @@ public class ReplyFragment extends DialogFragment {
private View container;
private ViewFlipper flipper;
private Button cancelButton;
private Button fileButton;
private Button fileDeleteButton;
private ImageButton fileButton;
private Button submitButton;
private EditText nameView;
private EditText emailView;
private EditText subjectView;
private EditText commentView;
private EditText fileNameView;
private CheckBox spoilerImageView;
private LoadView imageViewContainer;
private LoadView captchaContainer;
private TextView captchaInput;
@ -142,10 +143,7 @@ public class ReplyFragment extends DialogFragment {
@Override
public boolean onKey(DialogInterface dialogInterface, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (page == 1)
flipPage(0);
else if (page == 2)
closeReply();
onBackPressed();
return true;
} else
return false;
@ -170,6 +168,7 @@ public class ReplyFragment extends DialogFragment {
// To the end of the comment
Selection.setSelection(commentView.getText(), commentView.getText().length());
setFile(draft.fileName, draft.file);
spoilerImageView.setChecked(draft.spoilerImage);
if (loadable.isThreadMode()) {
subjectView.setVisibility(View.GONE);
@ -199,10 +198,8 @@ public class ReplyFragment extends DialogFragment {
draft.email = emailView.getText().toString();
draft.subject = subjectView.getText().toString();
draft.comment = commentView.getText().toString();
if (fileNameView != null) {
draft.fileName = fileNameView.getText().toString();
}
draft.spoilerImage = spoilerImageView.isChecked();
replyManager.setReplyDraft(draft);
} else {
@ -232,6 +229,8 @@ public class ReplyFragment extends DialogFragment {
subjectView = (EditText) container.findViewById(R.id.reply_subject);
commentView = (EditText) container.findViewById(R.id.reply_comment);
commentView.requestFocus();
fileNameView = (EditText) container.findViewById(R.id.reply_file_name);
spoilerImageView = (CheckBox) container.findViewById(R.id.reply_spoiler_image);
imageViewContainer = (LoadView) container.findViewById(R.id.reply_image);
responseContainer = (LoadView) container.findViewById(R.id.reply_response);
@ -262,10 +261,11 @@ public class ReplyFragment extends DialogFragment {
}
});
fileButton = (Button) container.findViewById(R.id.reply_file);
fileButton = (ImageButton) container.findViewById(R.id.reply_file);
fileButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
if (draft.file == null) {
ChanApplication.getReplyManager().pickFile(new ReplyManager.FileListener() {
@Override
public void onFile(String name, File file) {
@ -274,18 +274,14 @@ public class ReplyFragment extends DialogFragment {
@Override
public void onFileLoading() {
imageViewContainer.setVisibility(View.VISIBLE);
imageViewContainer.setView(null);
}
});
}
});
fileDeleteButton = (Button) container.findViewById(R.id.reply_file_delete);
fileDeleteButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
} else {
setFile(null, null);
}
}
});
submitButton = (Button) container.findViewById(R.id.reply_submit);
@ -304,6 +300,17 @@ public class ReplyFragment extends DialogFragment {
return container;
}
public boolean onBackPressed() {
if (page == 1) {
flipPage(0);
return false;
} else if (page == 2) {
return false;
} else {
return true;
}
}
private void closeReply() {
if (getDialog() != null) {
dismiss();
@ -365,56 +372,72 @@ public class ReplyFragment extends DialogFragment {
draft.fileName = name;
if (file == null) {
fileDeleteButton.setEnabled(false);
fileButton.setImageResource(ThemeHelper.getInstance().getTheme().isLightTheme ? R.drawable.ic_action_attachment : R.drawable.ic_action_attachment_dark);
imageViewContainer.removeAllViews();
fileNameView = null;
imageViewContainer.setVisibility(View.GONE);
fileNameView.setText("");
fileNameView.setVisibility(View.GONE);
spoilerImageView.setVisibility(View.GONE);
spoilerImageView.setChecked(false);
} else {
fileDeleteButton.setEnabled(true);
LinearLayout wrapper = new LinearLayout(context);
wrapper.setLayoutParams(Utils.MATCH_WRAP_PARAMS);
wrapper.setOrientation(LinearLayout.VERTICAL);
fileNameView = new EditText(context);
fileNameView.setSingleLine();
fileNameView.setHint(R.string.reply_file_name);
fileNameView.setTextSize(16f);
fileButton.setImageResource(ThemeHelper.getInstance().getTheme().isLightTheme ? R.drawable.ic_action_cancel : R.drawable.ic_action_cancel_dark);
fileNameView.setVisibility(View.VISIBLE);
fileNameView.setText(name);
wrapper.addView(fileNameView);
final ImageView imageView = new ImageView(context);
imageView.setScaleType(ScaleType.CENTER_INSIDE);
wrapper.addView(imageView);
imageViewContainer.setView(wrapper);
Board b = ChanApplication.getBoardManager().getBoardByValue(loadable.board);
spoilerImageView.setVisibility(b != null && b.spoilers ? View.VISIBLE : View.GONE);
String extension = MimeTypeMap.getFileExtensionFromUrl(name);
if (extension != null) {
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
if (mimeType != null && mimeType.contains("image")) {
imageViewContainer.setVisibility(View.VISIBLE);
imageViewContainer.setView(null);
imageViewContainer.post(new Runnable() {
public void run() {
if (file.length() < 10 * 1024 * 1024) {
new Thread(new Runnable() {
@Override
public void run() {
if (context == null)
return;
final Bitmap bitmap = ImageDecoder.decodeFile(file, imageViewContainer.getWidth(), 3000);
final Bitmap bitmap = ImageDecoder.decodeFile(file, imageViewContainer.getWidth(), imageViewContainer.getWidth());
context.runOnUiThread(new Runnable() {
@Override
public void run() {
if (context != null && bitmap != null) {
if (context != null) {
if (bitmap != null) {
ImageView imageView = new ImageView(context);
imageViewContainer.setView(imageView);
imageView.setAdjustViewBounds(true);
imageView.setMaxWidth(imageViewContainer.getWidth());
imageView.setMaxHeight(imageViewContainer.getWidth());
imageView.setImageBitmap(bitmap);
} else {
noPreview(imageViewContainer);
}
}
}
});
}
}).start();
} else {
noPreview(imageViewContainer);
}
}
});
}
}
private void noPreview(LoadView loadView) {
TextView text = new TextView(context);
text.setLayoutParams(Utils.MATCH_WRAP_PARAMS);
text.setGravity(Gravity.CENTER);
text.setText(R.string.reply_no_preview);
text.setTextSize(16f);
int padding = Utils.dp(16);
text.setPadding(padding, padding, padding, padding);
loadView.setView(text);
}
private void getCaptcha() {
if (gettingCaptcha)
return;
@ -476,12 +499,10 @@ public class ReplyFragment extends DialogFragment {
draft.captchaResponse = captchaInput.getText().toString();
draft.fileName = "image";
if (fileNameView != null) {
String n = fileNameView.getText().toString();
if (!TextUtils.isEmpty(n)) {
draft.fileName = n;
}
}
draft.resto = loadable.isThreadMode() ? loadable.no : -1;
draft.board = loadable.board;
@ -491,6 +512,9 @@ public class ReplyFragment extends DialogFragment {
draft.passId = ChanPreferences.getPassId();
}
Board b = ChanApplication.getBoardManager().getBoardByValue(loadable.board);
draft.spoilerImage = b != null && b.spoilers && spoilerImageView.isChecked();
ChanApplication.getReplyManager().sendReply(draft, new ReplyManager.ReplyListener() {
@Override
public void onResponse(ReplyResponse response) {

@ -32,7 +32,6 @@ import android.widget.VideoView;
import com.android.volley.Request;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader.ImageContainer;
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
import com.koushikdutta.async.future.Future;
import org.floens.chan.ChanApplication;
@ -134,6 +133,21 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener
@Override
public void onSuccess(File file) {
setBigImageFile(file);
}
@Override
public void onFail(boolean notFound) {
if (notFound) {
onNotFoundError();
} else {
onError();
}
}
});
}
public void setBigImageFile(File file) {
final CustomScaleImageView image = new CustomScaleImageView(getContext());
image.setImageFile(file.getAbsolutePath());
image.setOnClickListener(ThumbnailImageView.this);
@ -155,17 +169,6 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener
});
}
@Override
public void onFail(boolean notFound) {
if (notFound) {
onNotFoundError();
} else {
onError();
}
}
});
}
public void setGif(String gifUrl) {
if (getWidth() == 0 || getHeight() == 0) {
Logger.e(TAG, "getWidth() or getHeight() returned 0, not loading");
@ -187,6 +190,21 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener
@Override
public void onSuccess(File file) {
setGifFile(file);
}
@Override
public void onFail(boolean notFound) {
if (notFound) {
onNotFoundError();
} else {
onError();
}
}
});
}
public void setGifFile(File file) {
GifDrawable drawable;
try {
drawable = new GifDrawable(file.getAbsolutePath());
@ -202,17 +220,6 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener
setView(view, false);
}
@Override
public void onFail(boolean notFound) {
if (notFound) {
onNotFoundError();
} else {
onError();
}
}
});
}
public void setVideo(String videoUrl) {
callback.setProgress(true);
ionRequest = ChanApplication.getFileCache().downloadFile(getContext(), videoUrl, new FileCache.DownloadedCallback() {
@ -228,7 +235,22 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener
}
@Override
public void onSuccess(final File file) {
public void onSuccess(File file) {
setVideoFile(file);
}
@Override
public void onFail(boolean notFound) {
if (notFound) {
onNotFoundError();
} else {
onError();
}
}
});
}
public void setVideoFile(final File file) {
if (ChanPreferences.getVideoExternal()) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "video/*");
@ -272,17 +294,6 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener
}
}
@Override
public void onFail(boolean notFound) {
if (notFound) {
onNotFoundError();
} else {
onError();
}
}
});
}
public VideoView getVideoView() {
return videoView;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 926 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
Clover - 4chan browser https://github.com/Floens/Clover/
Copyright (C) 2014 Floens
@ -16,31 +15,30 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp">
android:padding="16dp">
<TextView
android:id="@+id/reply_captcha_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/reply_captcha_tap_to_reload"
android:textSize="16sp"/>
android:textSize="16sp" />
<org.floens.chan.ui.view.LoadView
android:id="@+id/reply_captcha_container"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_gravity="center"/>
android:layout_gravity="center" />
<EditText
android:id="@+id/reply_captcha"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/reply_captcha"
android:inputType="textNoSuggestions|textVisiblePassword"/>
android:inputType="textNoSuggestions|textVisiblePassword" />
</LinearLayout>

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
Clover - 4chan browser https://github.com/Floens/Clover/
Copyright (C) 2014 Floens
@ -16,35 +15,38 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:floatlabel="http://schemas.android.com/apk/res-auto"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/reply_data"
style="?android:attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp">
<EditText
android:id="@+id/reply_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/reply_name"
android:textSize="16sp"/>
android:minHeight="48dp"
android:textSize="16sp" />
<EditText
android:id="@+id/reply_subject"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/reply_subject"
android:textSize="16sp"/>
android:minHeight="48dp"
android:textSize="16sp" />
<EditText
android:id="@+id/reply_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/reply_email"
android:textSize="16sp"/>
android:minHeight="48dp"
android:textSize="16sp" />
<EditText
android:id="@+id/reply_comment"
@ -54,40 +56,37 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
android:imeActionLabel="@string/reply_submit"
android:inputType="textMultiLine|textCapSentences|textAutoCorrect"
android:minLines="4"
android:textSize="16sp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:textSize="16sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/reply_file"
<EditText
android:id="@+id/reply_file_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/reply_file"/>
android:hint="@string/reply_file_name"
android:minHeight="48dp"
android:textSize="16sp" />
<ImageButton
android:id="@+id/reply_file"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/reply_file_delete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/reply_file_delete"/>
</LinearLayout>
<org.floens.chan.ui.view.LoadView
android:id="@+id/reply_image"
<CheckBox
android:id="@+id/reply_spoiler_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:minHeight="48dp"
android:scaleType="centerCrop"/>
</LinearLayout>
android:text="@string/reply_spoiler_image" />
<org.floens.chan.ui.view.LoadView
android:id="@+id/reply_image"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
Clover - 4chan browser https://github.com/Floens/Clover/
Copyright (C) 2014 Floens
@ -16,8 +15,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="?android:attr/dividerHorizontal"
@ -41,7 +39,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/reply_input"/>
<include layout="@layout/reply_input" />
</ScrollView>
<!-- captcha view: -->
@ -50,7 +48,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/reply_captcha"/>
<include layout="@layout/reply_captcha" />
</ScrollView>
<!-- response view: -->
@ -59,8 +57,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
android:id="@+id/reply_response"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</org.floens.chan.ui.view.LoadView>
android:orientation="vertical" />
</ViewFlipper>
<LinearLayout
@ -75,7 +72,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/cancel"/>
android:text="@string/cancel" />
<Button
android:id="@+id/reply_submit"
@ -83,7 +80,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/reply_submit"/>
android:text="@string/reply_submit" />
</LinearLayout>
</LinearLayout>

@ -114,9 +114,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<string name="reply_email">Options</string>
<string name="reply_subject">Subject</string>
<string name="reply_comment">Comment</string>
<string name="reply_file">Pick file</string>
<string name="reply_file_delete">Remove file</string>
<string name="reply_file_name">File name</string>
<string name="reply_spoiler_image">Spoiler image</string>
<string name="reply_no_preview">No preview available</string>
<string name="reply_submit">Submit</string>
<string name="reply_captcha">Enter the text</string>
<string name="reply_error">Error sending reply</string>

Loading…
Cancel
Save