Improved the reply window to correctly use loadables. Now it won't crash on restoring the state.

captchafix
Florens Douwes 12 years ago
parent 224aab1f17
commit a185eaadff
  1. 1
      Chan/AndroidManifest.xml
  2. 2
      Chan/res/layout/activity_base.xml
  3. 54
      Chan/res/layout/reply_view.xml
  4. 1
      Chan/res/values/strings.xml
  5. 12
      Chan/src/org/floens/chan/activity/BoardActivity.java
  6. 14
      Chan/src/org/floens/chan/activity/ReplyActivity.java
  7. 2
      Chan/src/org/floens/chan/activity/ThreadActivity.java
  8. 18
      Chan/src/org/floens/chan/entity/Loadable.java
  9. 141
      Chan/src/org/floens/chan/fragment/ReplyFragment.java

@ -53,6 +53,7 @@
</activity> </activity>
<activity <activity
android:name="org.floens.chan.activity.ReplyActivity" android:name="org.floens.chan.activity.ReplyActivity"
android:windowSoftInputMode="adjustResize"
android:configChanges="keyboardHidden|orientation|screenSize" > android:configChanges="keyboardHidden|orientation|screenSize" >
</activity> </activity>
<activity <activity

@ -11,7 +11,7 @@
<FrameLayout <FrameLayout
android:id="@+id/left_pane" android:id="@+id/left_pane"
android:layout_width="300dp" android:layout_width="320dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="#FFFFFFFF" /> android:background="#FFFFFFFF" />

@ -2,8 +2,8 @@
<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_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:minWidth="500dp" android:minWidth="600dp"
android:minHeight="400dp" android:minHeight="500dp"
android:orientation="vertical" android:orientation="vertical"
android:divider="?android:attr/dividerHorizontal" android:divider="?android:attr/dividerHorizontal"
android:showDividers="middle" > android:showDividers="middle" >
@ -84,26 +84,36 @@
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>
<LinearLayout <ScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent" >
android:padding="8dp" <LinearLayout
android:orientation="vertical" > android:layout_width="match_parent"
android:layout_height="wrap_content"
<org.floens.chan.utils.LoadView android:padding="8dp"
android:id="@+id/reply_captcha_container" android:orientation="vertical" >
android:layout_width="300dp"
android:layout_height="60dp" <org.floens.chan.utils.LoadView
android:layout_gravity="center" /> android:id="@+id/reply_captcha_container"
android:layout_width="match_parent"
<EditText android:layout_height="200dp"
android:id="@+id/reply_captcha" android:layout_gravity="center" />
android:hint="@string/reply_captcha"
android:inputType="textNoSuggestions" <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content"
android:textSize="16sp"
</LinearLayout> android:text="@string/reply_captcha_tap_to_reload" />
<EditText
android:id="@+id/reply_captcha"
android:hint="@string/reply_captcha"
android:inputType="textNoSuggestions"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
<org.floens.chan.utils.LoadView <org.floens.chan.utils.LoadView
android:id="@+id/reply_response" android:id="@+id/reply_response"
android:layout_width="match_parent" android:layout_width="match_parent"

@ -70,6 +70,7 @@
<string name="reply_error_file">No file selected</string> <string name="reply_error_file">No file selected</string>
<string name="reply_success">Post Successful</string> <string name="reply_success">Post Successful</string>
<string name="reply_captcha_load_error">Failed to load captcha</string> <string name="reply_captcha_load_error">Failed to load captcha</string>
<string name="reply_captcha_tap_to_reload">Tap to reload the captcha</string>
<string name="open_link_confirmation_preference">Ask before opening links</string> <string name="open_link_confirmation_preference">Ask before opening links</string>
<string name="open_link_confirmation">Open link?</string> <string name="open_link_confirmation">Open link?</string>

@ -209,10 +209,10 @@ public class BoardActivity extends BaseActivity implements ActionBar.OnNavigatio
return true; return true;
case R.id.action_reply: case R.id.action_reply:
if (pane.isOpen()) { if (pane.isOpen()) {
startReply(pane.isSlideable(), boardFragment); startReply(pane.isSlideable(), boardLoadable);
} else { } else {
if (threadFragment.getThreadManager().hasThread()) { if (threadFragment.getThreadManager().hasThread()) {
startReply(pane.isSlideable(), threadFragment); startReply(pane.isSlideable(), threadLoadable);
} }
} }
@ -257,13 +257,13 @@ public class BoardActivity extends BaseActivity implements ActionBar.OnNavigatio
updateActionBarState(); updateActionBarState();
} }
private void startReply(boolean inActivity, ThreadFragment fragment) { private void startReply(boolean startInActivity, Loadable loadable) {
if (inActivity) { if (startInActivity) {
ReplyActivity.setThreadFragment(fragment); ReplyActivity.setLoadable(loadable);
Intent i = new Intent(this, ReplyActivity.class); Intent i = new Intent(this, ReplyActivity.class);
startActivity(i); startActivity(i);
} else { } else {
ReplyFragment reply = ReplyFragment.newInstance(fragment); ReplyFragment reply = ReplyFragment.newInstance(loadable);
reply.show(getFragmentManager(), "replyDialog"); reply.show(getFragmentManager(), "replyDialog");
} }
} }

@ -1,7 +1,7 @@
package org.floens.chan.activity; package org.floens.chan.activity;
import org.floens.chan.entity.Loadable;
import org.floens.chan.fragment.ReplyFragment; import org.floens.chan.fragment.ReplyFragment;
import org.floens.chan.fragment.ThreadFragment;
import android.app.Activity; import android.app.Activity;
import android.app.FragmentTransaction; import android.app.FragmentTransaction;
@ -10,24 +10,24 @@ import android.util.Log;
import android.view.MenuItem; import android.view.MenuItem;
public class ReplyActivity extends Activity { public class ReplyActivity extends Activity {
private static ThreadFragment threadFragment; private static Loadable loadable;
public static void setThreadFragment(ThreadFragment tf) { public static void setLoadable(Loadable l) {
threadFragment = tf; loadable = l;
} }
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
if (threadFragment != null) { if (loadable != null) {
getActionBar().setDisplayHomeAsUpEnabled(true); getActionBar().setDisplayHomeAsUpEnabled(true);
FragmentTransaction ft = getFragmentManager().beginTransaction(); FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(android.R.id.content, ReplyFragment.newInstance(threadFragment)); ft.replace(android.R.id.content, ReplyFragment.newInstance(loadable));
ft.commitAllowingStateLoss(); ft.commitAllowingStateLoss();
threadFragment = null; loadable = null;
} else { } else {
Log.e("Chan", "ThreadFragment was null, exiting!"); Log.e("Chan", "ThreadFragment was null, exiting!");
finish(); finish();

@ -68,7 +68,7 @@ public class ThreadActivity extends BaseActivity {
return true; return true;
case R.id.action_reply: case R.id.action_reply:
ReplyFragment reply = ReplyFragment.newInstance(threadFragment); ReplyFragment reply = ReplyFragment.newInstance(loadable);
reply.show(getFragmentManager(), "replyDialog"); reply.show(getFragmentManager(), "replyDialog");
return true; return true;

@ -7,7 +7,7 @@ import android.os.Bundle;
* Something that can be loaded, like a board or thread. * Something that can be loaded, like a board or thread.
*/ */
public class Loadable { public class Loadable {
public Mode mode = Mode.INVALID; public int mode = Mode.INVALID;
public String board = ""; public String board = "";
public int no = -1; public int no = -1;
public String title = ""; public String title = "";
@ -84,31 +84,29 @@ public class Loadable {
public void readFromBundle(Context context, Bundle bundle) { public void readFromBundle(Context context, Bundle bundle) {
String p = context.getPackageName(); String p = context.getPackageName();
mode = bundle.getInt(p + ".mode", Mode.INVALID);
board = bundle.getString(p + ".board", ""); board = bundle.getString(p + ".board", "");
no = bundle.getInt(p + ".no", -1); no = bundle.getInt(p + ".no", -1);
title = bundle.getString(p + ".subject", ""); title = bundle.getString(p + ".subject", "");
listViewIndex = bundle.getInt(p + ".listViewIndex"); listViewIndex = bundle.getInt(p + ".listViewIndex");
listViewTop = bundle.getInt(p + ".listViewTop"); listViewTop = bundle.getInt(p + ".listViewTop");
// Log.e("Chan", "Read: " + board + ", " + no);
} }
public void writeToBundle(Context context, Bundle bundle) { public void writeToBundle(Context context, Bundle bundle) {
String p = context.getPackageName(); String p = context.getPackageName();
bundle.putInt(p + ".mode", mode);
bundle.putString(p + ".board", board); bundle.putString(p + ".board", board);
bundle.putInt(p + ".no", no); bundle.putInt(p + ".no", no);
bundle.putString(p + ".subject", title); bundle.putString(p + ".subject", title);
bundle.putInt(p + ".listViewIndex", listViewIndex); bundle.putInt(p + ".listViewIndex", listViewIndex);
bundle.putInt(p + ".listViewTop", listViewTop); bundle.putInt(p + ".listViewTop", listViewTop);
// Log.e("Chan", "Write: " + board + ", " + no);
} }
public static enum Mode { public static class Mode {
INVALID, public static final int INVALID = -1;
THREAD, public static final int THREAD = 0;
BOARD, public static final int BOARD = 1;
CATALOG public static final int CATALOG = 2;
} }
} }

@ -8,7 +8,6 @@ import org.floens.chan.entity.Loadable;
import org.floens.chan.entity.Reply; import org.floens.chan.entity.Reply;
import org.floens.chan.manager.ReplyManager; import org.floens.chan.manager.ReplyManager;
import org.floens.chan.manager.ReplyManager.ReplyResponse; import org.floens.chan.manager.ReplyManager.ReplyResponse;
import org.floens.chan.manager.ThreadManager;
import org.floens.chan.net.ChanUrls; import org.floens.chan.net.ChanUrls;
import org.floens.chan.utils.ImageDecoder; import org.floens.chan.utils.ImageDecoder;
import org.floens.chan.utils.LoadView; import org.floens.chan.utils.LoadView;
@ -21,6 +20,7 @@ import android.content.DialogInterface;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity; import android.view.Gravity;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -45,8 +45,7 @@ import com.android.volley.toolbox.StringRequest;
public class ReplyFragment extends DialogFragment { public class ReplyFragment extends DialogFragment {
private int page = 0; private int page = 0;
private ThreadManager threadManager; private Loadable loadable;
private ThreadFragment threadFragment;
private final Reply draft = new Reply(); private final Reply draft = new Reply();
private boolean shouldSaveDraft = true; private boolean shouldSaveDraft = true;
@ -70,28 +69,83 @@ public class ReplyFragment extends DialogFragment {
private TextView captchaText; private TextView captchaText;
private LoadView responseContainer; private LoadView responseContainer;
public static ReplyFragment newInstance(ThreadFragment fragment) { public static ReplyFragment newInstance(Loadable loadable) {
ReplyFragment reply = new ReplyFragment(); ReplyFragment reply = new ReplyFragment();
reply.threadFragment = fragment; reply.loadable = loadable;
reply.threadManager = fragment.getThreadManager();
return reply; return reply;
} }
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
loadable.writeToBundle(getActivity(), outState);
}
@Override @Override
public void onActivityCreated(Bundle savedInstanceState) { public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); super.onActivityCreated(savedInstanceState);
if (threadManager == null) return; if (loadable == null && savedInstanceState != null) {
loadable = new Loadable();
loadable.readFromBundle(getActivity(), savedInstanceState);
}
getCaptcha(); if (loadable != null) {
setClosable(true);
Dialog dialog = getDialog();
Context context = getActivity();
String title = loadable.isThreadMode() ?
context.getString(R.string.reply) + " /" + loadable.board + "/" + loadable.no :
context.getString(R.string.reply_to_board) + " /" + loadable.board + "/";
if (dialog == null) {
getActivity().getActionBar().setTitle(title);
} else {
dialog.setTitle(title);
}
if (getDialog() != null) {
getDialog().setOnKeyListener(new Dialog.OnKeyListener() {
@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();
return true;
} else return false;
}
});
}
Reply draft = ReplyManager.getInstance().getReplyDraft();
if (TextUtils.isEmpty(draft.name)) {
draft.name = ChanApplication.getPreferences().getString("preference_default_name", "");
}
if (TextUtils.isEmpty(draft.email)) {
draft.email = ChanApplication.getPreferences().getString("preference_default_email", "");
}
nameView.setText(draft.name);
emailView.setText(draft.email);
subjectView.setText(draft.subject);
commentView.setText(draft.comment);
setFile(draft.file);
getCaptcha();
} else {
Log.e("Chan", "Loadable in ReplyFragment was null");
closeReply();
}
} }
@Override @Override
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
if (threadManager == null) return;
ReplyManager replyManager = ReplyManager.getInstance(); ReplyManager replyManager = ReplyManager.getInstance();
if (shouldSaveDraft) { if (shouldSaveDraft) {
@ -105,32 +159,18 @@ public class ReplyFragment extends DialogFragment {
replyManager.removeReplyDraft(); replyManager.removeReplyDraft();
setFile(null); setFile(null);
} }
}
@Override
public void onDestroy() {
super.onDestroy();
ReplyManager replyManager = ReplyManager.getInstance();
replyManager.removeFileListener(); replyManager.removeFileListener();
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
if (threadManager == null) {
closeReply();
return new View(inflater.getContext());
}
Dialog dialog = getDialog();
Loadable l = threadManager.getLoadable();
Context context = inflater.getContext();
String title = l.isThreadMode() ?
context.getString(R.string.reply) + " /" + l.board + "/" + l.no :
context.getString(R.string.reply_to_board) + " /" + l.board + "/";
if (dialog == null) {
getActivity().getActionBar().setTitle(title);
} else {
dialog.setTitle(title);
}
setClosable(true);
// Setup the views with listeners // Setup the views with listeners
container = inflater.inflate(R.layout.reply_view, null); container = inflater.inflate(R.layout.reply_view, null);
flipper = (ViewFlipper)container.findViewById(R.id.reply_flipper); flipper = (ViewFlipper)container.findViewById(R.id.reply_flipper);
@ -201,41 +241,6 @@ public class ReplyFragment extends DialogFragment {
} }
}); });
if (dialog != null) {
dialog.setOnKeyListener(new Dialog.OnKeyListener() {
@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();
}
return true;
} else {
return false;
}
}
});
}
Reply draft = ReplyManager.getInstance().getReplyDraft();
if (TextUtils.isEmpty(draft.name)) {
draft.name = ChanApplication.getPreferences().getString("preference_default_name", "");
}
if (TextUtils.isEmpty(draft.email)) {
draft.email = ChanApplication.getPreferences().getString("preference_default_email", "");
}
nameView.setText(draft.name);
emailView.setText(draft.email);
subjectView.setText(draft.subject);
commentView.setText(draft.comment);
setFile(draft.file);
return container; return container;
} }
@ -308,7 +313,7 @@ public class ReplyFragment extends DialogFragment {
@Override @Override
public void run() { public void run() {
// Other thread // Other thread
final Bitmap bitmap = ImageDecoder.decodeFile(file, imageViewContainer.getWidth(), 1000); final Bitmap bitmap = ImageDecoder.decodeFile(file, imageViewContainer.getWidth(), 3000);
getActivity().runOnUiThread(new Runnable() { getActivity().runOnUiThread(new Runnable() {
@Override @Override
@ -377,8 +382,6 @@ public class ReplyFragment extends DialogFragment {
responseContainer.setView(null); responseContainer.setView(null);
Loadable loadable = threadManager.getLoadable();
draft.name = nameView.getText().toString(); draft.name = nameView.getText().toString();
draft.email = emailView.getText().toString(); draft.email = emailView.getText().toString();
draft.subject = subjectView.getText().toString(); draft.subject = subjectView.getText().toString();
@ -415,7 +418,7 @@ public class ReplyFragment extends DialogFragment {
} else if (response.isSuccessful) { } else if (response.isSuccessful) {
shouldSaveDraft = false; shouldSaveDraft = false;
Toast.makeText(getActivity(), R.string.reply_success, Toast.LENGTH_SHORT).show(); Toast.makeText(getActivity(), R.string.reply_success, Toast.LENGTH_SHORT).show();
threadFragment.reload(); // threadFragment.reload(); // TODO
closeReply(); closeReply();
} else { } else {
if (isVisible()) { if (isVisible()) {

Loading…
Cancel
Save