diff --git a/Clover/app/src/main/java/org/floens/chan/core/manager/ReplyManager.java b/Clover/app/src/main/java/org/floens/chan/core/manager/ReplyManager.java index d6773ef8..e993ca55 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/manager/ReplyManager.java +++ b/Clover/app/src/main/java/org/floens/chan/core/manager/ReplyManager.java @@ -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); diff --git a/Clover/app/src/main/java/org/floens/chan/core/model/Reply.java b/Clover/app/src/main/java/org/floens/chan/core/model/Reply.java index e68097f5..8f91486c 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/model/Reply.java +++ b/Clover/app/src/main/java/org/floens/chan/core/model/Reply.java @@ -36,4 +36,5 @@ public class Reply { public String password = ""; public boolean usePass = false; public String passId = ""; + public boolean spoilerImage = false; } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/activity/ReplyActivity.java b/Clover/app/src/main/java/org/floens/chan/ui/activity/ReplyActivity.java index 3114c7d0..ca94e195 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/activity/ReplyActivity.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/activity/ReplyActivity.java @@ -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()) { diff --git a/Clover/app/src/main/java/org/floens/chan/ui/fragment/ReplyFragment.java b/Clover/app/src/main/java/org/floens/chan/ui/fragment/ReplyFragment.java index 5610a01c..3059910d 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/fragment/ReplyFragment.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/fragment/ReplyFragment.java @@ -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.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,29 +261,26 @@ 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) { - ChanApplication.getReplyManager().pickFile(new ReplyManager.FileListener() { - @Override - public void onFile(String name, File file) { - setFile(name, file); - } - - @Override - public void onFileLoading() { - imageViewContainer.setView(null); - } - }); - } - }); + if (draft.file == null) { + ChanApplication.getReplyManager().pickFile(new ReplyManager.FileListener() { + @Override + public void onFile(String name, File file) { + setFile(name, file); + } - fileDeleteButton = (Button) container.findViewById(R.id.reply_file_delete); - fileDeleteButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View view) { - setFile(null, null); + @Override + public void onFileLoading() { + imageViewContainer.setVisibility(View.VISIBLE); + imageViewContainer.setView(null); + } + }); + } else { + setFile(null, null); + } } }); @@ -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); - - String extension = MimeTypeMap.getFileExtensionFromUrl(name); - if (extension != null) { - String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); - if (mimeType != null && mimeType.contains("image")) { - new Thread(new Runnable() { - @Override - public void run() { - if (context == null) - return; - - final Bitmap bitmap = ImageDecoder.decodeFile(file, imageViewContainer.getWidth(), 3000); - context.runOnUiThread(new Runnable() { - @Override - public void run() { - if (context != null && bitmap != null) { - imageView.setImageBitmap(bitmap); + Board b = ChanApplication.getBoardManager().getBoardByValue(loadable.board); + spoilerImageView.setVisibility(b != null && b.spoilers ? View.VISIBLE : View.GONE); + + 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(), imageViewContainer.getWidth()); + + context.runOnUiThread(new Runnable() { + @Override + public void run() { + 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(); + }); + } + }).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,11 +499,9 @@ 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; - } + String n = fileNameView.getText().toString(); + if (!TextUtils.isEmpty(n)) { + draft.fileName = n; } draft.resto = loadable.isThreadMode() ? loadable.no : -1; @@ -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) { diff --git a/Clover/app/src/main/java/org/floens/chan/ui/view/ThumbnailImageView.java b/Clover/app/src/main/java/org/floens/chan/ui/view/ThumbnailImageView.java index 6b10c00c..a2864ff3 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/view/ThumbnailImageView.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/view/ThumbnailImageView.java @@ -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,25 +133,7 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener @Override public void onSuccess(File file) { - final CustomScaleImageView image = new CustomScaleImageView(getContext()); - image.setImageFile(file.getAbsolutePath()); - image.setOnClickListener(ThumbnailImageView.this); - - addView(image); - - image.setInitCallback(new CustomScaleImageView.InitedCallback() { - @Override - public void onInit() { - Utils.runOnUiThread(new Runnable() { - @Override - public void run() { - removeAllViews(); - addView(image); - callback.setProgress(false); - } - }); - } - }); + setBigImageFile(file); } @Override @@ -166,6 +147,28 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener }); } + public void setBigImageFile(File file) { + final CustomScaleImageView image = new CustomScaleImageView(getContext()); + image.setImageFile(file.getAbsolutePath()); + image.setOnClickListener(ThumbnailImageView.this); + + addView(image); + + image.setInitCallback(new CustomScaleImageView.InitedCallback() { + @Override + public void onInit() { + Utils.runOnUiThread(new Runnable() { + @Override + public void run() { + removeAllViews(); + addView(image); + callback.setProgress(false); + } + }); + } + }); + } + public void setGif(String gifUrl) { if (getWidth() == 0 || getHeight() == 0) { Logger.e(TAG, "getWidth() or getHeight() returned 0, not loading"); @@ -187,19 +190,7 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener @Override public void onSuccess(File file) { - GifDrawable drawable; - try { - drawable = new GifDrawable(file.getAbsolutePath()); - } catch (IOException e) { - e.printStackTrace(); - onError(); - return; - } - - GifImageView view = new GifImageView(getContext()); - view.setImageDrawable(drawable); - view.setLayoutParams(Utils.MATCH_PARAMS); - setView(view, false); + setGifFile(file); } @Override @@ -213,6 +204,22 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener }); } + public void setGifFile(File file) { + GifDrawable drawable; + try { + drawable = new GifDrawable(file.getAbsolutePath()); + } catch (IOException e) { + e.printStackTrace(); + onError(); + return; + } + + GifImageView view = new GifImageView(getContext()); + view.setImageDrawable(drawable); + view.setLayoutParams(Utils.MATCH_PARAMS); + setView(view, false); + } + public void setVideo(String videoUrl) { callback.setProgress(true); ionRequest = ChanApplication.getFileCache().downloadFile(getContext(), videoUrl, new FileCache.DownloadedCallback() { @@ -228,48 +235,8 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener } @Override - public void onSuccess(final File file) { - if (ChanPreferences.getVideoExternal()) { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setDataAndType(Uri.fromFile(file), "video/*"); - - try { - getContext().startActivity(intent); - } catch (ActivityNotFoundException e) { - Toast.makeText(getContext(), R.string.open_link_failed, Toast.LENGTH_SHORT).show(); - } - } else { - videoView = new VideoView(getContext()); - videoView.setZOrderOnTop(true); - videoView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, - LayoutParams.MATCH_PARENT)); - videoView.setLayoutParams(Utils.MATCH_PARAMS); - LayoutParams par = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); - par.gravity = Gravity.CENTER; - videoView.setLayoutParams(par); - - videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { - @Override - public void onPrepared(MediaPlayer mp) { - mp.setLooping(true); - callback.onVideoLoaded(); - } - }); - videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() { - @Override - public boolean onError(MediaPlayer mp, int what, int extra) { - callback.onVideoError(file); - - return true; - } - }); - - videoView.setVideoPath(file.getAbsolutePath()); - - setView(videoView, false); - - videoView.start(); - } + public void onSuccess(File file) { + setVideoFile(file); } @Override @@ -283,6 +250,50 @@ public class ThumbnailImageView extends LoadView implements View.OnClickListener }); } + public void setVideoFile(final File file) { + if (ChanPreferences.getVideoExternal()) { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setDataAndType(Uri.fromFile(file), "video/*"); + + try { + getContext().startActivity(intent); + } catch (ActivityNotFoundException e) { + Toast.makeText(getContext(), R.string.open_link_failed, Toast.LENGTH_SHORT).show(); + } + } else { + videoView = new VideoView(getContext()); + videoView.setZOrderOnTop(true); + videoView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, + LayoutParams.MATCH_PARENT)); + videoView.setLayoutParams(Utils.MATCH_PARAMS); + LayoutParams par = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); + par.gravity = Gravity.CENTER; + videoView.setLayoutParams(par); + + videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + @Override + public void onPrepared(MediaPlayer mp) { + mp.setLooping(true); + callback.onVideoLoaded(); + } + }); + videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() { + @Override + public boolean onError(MediaPlayer mp, int what, int extra) { + callback.onVideoError(file); + + return true; + } + }); + + videoView.setVideoPath(file.getAbsolutePath()); + + setView(videoView, false); + + videoView.start(); + } + } + public VideoView getVideoView() { return videoView; } diff --git a/Clover/app/src/main/res/drawable-hdpi/ic_action_attachment.png b/Clover/app/src/main/res/drawable-hdpi/ic_action_attachment.png new file mode 100644 index 00000000..175adeb4 Binary files /dev/null and b/Clover/app/src/main/res/drawable-hdpi/ic_action_attachment.png differ diff --git a/Clover/app/src/main/res/drawable-hdpi/ic_action_attachment_dark.png b/Clover/app/src/main/res/drawable-hdpi/ic_action_attachment_dark.png new file mode 100644 index 00000000..34fd62b1 Binary files /dev/null and b/Clover/app/src/main/res/drawable-hdpi/ic_action_attachment_dark.png differ diff --git a/Clover/app/src/main/res/drawable-mdpi/ic_action_attachment.png b/Clover/app/src/main/res/drawable-mdpi/ic_action_attachment.png new file mode 100644 index 00000000..7f00efdb Binary files /dev/null and b/Clover/app/src/main/res/drawable-mdpi/ic_action_attachment.png differ diff --git a/Clover/app/src/main/res/drawable-mdpi/ic_action_attachment_dark.png b/Clover/app/src/main/res/drawable-mdpi/ic_action_attachment_dark.png new file mode 100644 index 00000000..d0d8051a Binary files /dev/null and b/Clover/app/src/main/res/drawable-mdpi/ic_action_attachment_dark.png differ diff --git a/Clover/app/src/main/res/drawable-xhdpi/ic_action_attachment.png b/Clover/app/src/main/res/drawable-xhdpi/ic_action_attachment.png new file mode 100644 index 00000000..860dd0ad Binary files /dev/null and b/Clover/app/src/main/res/drawable-xhdpi/ic_action_attachment.png differ diff --git a/Clover/app/src/main/res/drawable-xhdpi/ic_action_attachment_dark.png b/Clover/app/src/main/res/drawable-xhdpi/ic_action_attachment_dark.png new file mode 100644 index 00000000..e01e86a8 Binary files /dev/null and b/Clover/app/src/main/res/drawable-xhdpi/ic_action_attachment_dark.png differ diff --git a/Clover/app/src/main/res/drawable-xxhdpi/ic_action_attachment.png b/Clover/app/src/main/res/drawable-xxhdpi/ic_action_attachment.png new file mode 100644 index 00000000..0c5e44fe Binary files /dev/null and b/Clover/app/src/main/res/drawable-xxhdpi/ic_action_attachment.png differ diff --git a/Clover/app/src/main/res/drawable-xxhdpi/ic_action_attachment_dark.png b/Clover/app/src/main/res/drawable-xxhdpi/ic_action_attachment_dark.png new file mode 100644 index 00000000..305bc41a Binary files /dev/null and b/Clover/app/src/main/res/drawable-xxhdpi/ic_action_attachment_dark.png differ diff --git a/Clover/app/src/main/res/layout/reply_captcha.xml b/Clover/app/src/main/res/layout/reply_captcha.xml index c31b41b0..6116a878 100644 --- a/Clover/app/src/main/res/layout/reply_captcha.xml +++ b/Clover/app/src/main/res/layout/reply_captcha.xml @@ -1,5 +1,4 @@ - - - + android:padding="16dp"> + android:textSize="16sp" /> + android:layout_gravity="center" /> + android:inputType="textNoSuggestions|textVisiblePassword" /> diff --git a/Clover/app/src/main/res/layout/reply_input.xml b/Clover/app/src/main/res/layout/reply_input.xml index 746e5b06..b8ed1484 100644 --- a/Clover/app/src/main/res/layout/reply_input.xml +++ b/Clover/app/src/main/res/layout/reply_input.xml @@ -1,5 +1,4 @@ - - - + android:orientation="vertical" + android:paddingBottom="16dp" + android:paddingLeft="16dp" + android:paddingRight="16dp"> + android:minHeight="48dp" + android:textSize="16sp" /> + android:minHeight="48dp" + android:textSize="16sp" /> + android:minHeight="48dp" + android:textSize="16sp" /> . android:imeActionLabel="@string/reply_submit" android:inputType="textMultiLine|textCapSentences|textAutoCorrect" android:minLines="4" - android:textSize="16sp"/> + android:textSize="16sp" /> + android:orientation="horizontal"> - - -