Browse Source

fixes: reverse poll results, error when too many votes, remove   when poll has expired, background of emoji keyboard

pull/61/merge
Thodoris1999 6 years ago
parent
commit
7dcda065a9
  1. 66
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
  2. 9
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
  3. 9
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java
  4. 23
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/ReplyTask.java
  5. 1
      app/src/main/java/gr/thmmy/mthmmy/editorview/EmojiKeyboard.java
  6. 15
      app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
  7. 1
      app/src/main/res/layout/activity_topic_poll.xml
  8. 5
      app/src/main/res/values/strings.xml

66
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java

@ -4,6 +4,7 @@ import android.annotation.SuppressLint;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.arch.lifecycle.ViewModelProviders; import android.arch.lifecycle.ViewModelProviders;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.graphics.Rect; import android.graphics.Rect;
import android.net.Uri; import android.net.Uri;
@ -36,6 +37,7 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.function.Consumer;
import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.topic.tasks.EditTask; import gr.thmmy.mthmmy.activities.topic.tasks.EditTask;
@ -44,6 +46,7 @@ import gr.thmmy.mthmmy.activities.topic.tasks.PrepareForReply;
import gr.thmmy.mthmmy.activities.topic.tasks.ReplyTask; import gr.thmmy.mthmmy.activities.topic.tasks.ReplyTask;
import gr.thmmy.mthmmy.activities.topic.tasks.TopicTask; import gr.thmmy.mthmmy.activities.topic.tasks.TopicTask;
import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.base.BaseActivity;
import gr.thmmy.mthmmy.base.BaseApplication;
import gr.thmmy.mthmmy.editorview.EmojiKeyboard; import gr.thmmy.mthmmy.editorview.EmojiKeyboard;
import gr.thmmy.mthmmy.model.Bookmark; import gr.thmmy.mthmmy.model.Bookmark;
import gr.thmmy.mthmmy.model.Post; import gr.thmmy.mthmmy.model.Post;
@ -52,12 +55,12 @@ import gr.thmmy.mthmmy.model.TopicItem;
import gr.thmmy.mthmmy.utils.CustomLinearLayoutManager; import gr.thmmy.mthmmy.utils.CustomLinearLayoutManager;
import gr.thmmy.mthmmy.utils.HTMLUtils; import gr.thmmy.mthmmy.utils.HTMLUtils;
import gr.thmmy.mthmmy.utils.NetworkResultCodes; import gr.thmmy.mthmmy.utils.NetworkResultCodes;
import gr.thmmy.mthmmy.utils.NetworkTask;
import gr.thmmy.mthmmy.utils.parsing.ParseHelpers; import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
import gr.thmmy.mthmmy.viewmodel.TopicViewModel; import gr.thmmy.mthmmy.viewmodel.TopicViewModel;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar; import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import timber.log.Timber; import timber.log.Timber;
import static gr.thmmy.mthmmy.activities.topic.Posting.replyStatus;
import static gr.thmmy.mthmmy.services.NotificationService.NEW_POST_TAG; import static gr.thmmy.mthmmy.services.NotificationService.NEW_POST_TAG;
/** /**
@ -517,7 +520,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
} }
@Override @Override
public void onReplyTaskFinished(boolean success) { public void onReplyTaskFinished(Posting.REPLY_STATUS replyStatus) {
View view = getCurrentFocus(); View view = getCurrentFocus();
if (view != null) { if (view != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -526,22 +529,49 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
progressBar.setVisibility(ProgressBar.GONE); progressBar.setVisibility(ProgressBar.GONE);
if (success) { switch (replyStatus) {
Timber.i("Post reply successful"); case SUCCESSFUL:
replyFAB.show(); BaseApplication.getInstance().logFirebaseAnalyticsEvent("post_creation", null);
bottomNavBar.setVisibility(View.VISIBLE); Timber.i("Post reply successful");
viewModel.setWritingReply(false); replyFAB.show();
if ((((Post) topicItems.get(topicItems.size() - 1)).getPostNumber() + 1) % 15 == 0) { bottomNavBar.setVisibility(View.VISIBLE);
Timber.i("Reply was posted in new page. Switching to last page."); viewModel.setWritingReply(false);
viewModel.loadUrl(ParseHelpers.getBaseURL(viewModel.getTopicUrl()) + "." + 2147483647); if ((((Post) topicItems.get(topicItems.size() - 1)).getPostNumber() + 1) % 15 == 0) {
} else { Timber.i("Reply was posted in new page. Switching to last page.");
viewModel.reloadPage(); viewModel.loadUrl(ParseHelpers.getBaseURL(viewModel.getTopicUrl()) + "." + 2147483647);
} } else {
} else { viewModel.reloadPage();
Timber.w("Post reply unsuccessful"); }
Toast.makeText(getBaseContext(), "Post failed!", Toast.LENGTH_SHORT).show(); case NEW_REPLY_WHILE_POSTING:
recyclerView.getChildAt(topicItems.size() - 1).setAlpha(1); Timber.i("New reply while writing a reply");
recyclerView.getChildAt(topicItems.size() - 1).setEnabled(true); TopicAdapter.QuickReplyViewHolder replyHolder = (TopicAdapter.QuickReplyViewHolder)
recyclerView.findViewHolderForAdapterPosition(topicItems.size() - 1);
String subject = replyHolder.quickReplySubject.getText().toString();
String message = replyHolder.replyEditor.getText().toString();
Runnable addReply = () -> {
viewModel.setWritingReply(true);
topicItems.add(Post.newQuickReply());
topicAdapter.notifyItemInserted(topicItems.size());
recyclerView.scrollToPosition(topicItems.size() - 1);
replyFAB.hide();
bottomNavBar.setVisibility(View.GONE);
TopicAdapter.QuickReplyViewHolder newReplyHolder = (TopicAdapter.QuickReplyViewHolder)
recyclerView.findViewHolderForAdapterPosition(topicItems.size() - 1);
newReplyHolder.quickReplySubject.setText(subject);
newReplyHolder.replyEditor.setText(message);
AlertDialog.Builder builder = new AlertDialog.Builder(TopicActivity.this,
R.style.AppCompatAlertDialogStyleAccent);
builder.setMessage("A new reply was posted before you completed your new post." +
" Please review it and send your reply again")
.setNeutralButton(getString(R.string.ok), (dialog, which) -> dialog.dismiss())
.show();
};
viewModel.reloadPageThen(addReply);
default:
Timber.w("Post reply unsuccessful");
Toast.makeText(getBaseContext(), "Post failed!", Toast.LENGTH_SHORT).show();
recyclerView.getChildAt(topicItems.size() - 1).setAlpha(1);
recyclerView.getChildAt(topicItems.size() - 1).setEnabled(true);
} }
} }
}); });

9
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java

@ -166,6 +166,7 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
PollViewHolder holder = (PollViewHolder) currentHolder; PollViewHolder holder = (PollViewHolder) currentHolder;
holder.question.setText(poll.getQuestion()); holder.question.setText(poll.getQuestion());
holder.optionsLayout.removeAllViews(); holder.optionsLayout.removeAllViews();
holder.errorTooManySelected.setVisibility(View.GONE);
if (poll.getAvailableVoteCount() > 1) { if (poll.getAvailableVoteCount() > 1) {
for (Poll.Entry entry : entries) { for (Poll.Entry entry : entries) {
CheckBox checkBox = new CheckBox(context); CheckBox checkBox = new CheckBox(context);
@ -237,7 +238,13 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
holder.hidePollResultsButton.setVisibility(View.VISIBLE); holder.hidePollResultsButton.setVisibility(View.VISIBLE);
} else holder.hidePollResultsButton.setVisibility(View.GONE); } else holder.hidePollResultsButton.setVisibility(View.GONE);
if (poll.getPollFormUrl() != null) { if (poll.getPollFormUrl() != null) {
holder.submitButton.setOnClickListener(v -> viewModel.submitVote(holder.optionsLayout)); holder.submitButton.setOnClickListener(v -> {
if (!viewModel.submitVote(holder.optionsLayout)) {
holder.errorTooManySelected.setText(context.getResources()
.getQuantityText(R.plurals.error_too_many_checked, poll.getAvailableVoteCount()));
holder.errorTooManySelected.setVisibility(View.VISIBLE);
}
});
holder.submitButton.setVisibility(View.VISIBLE); holder.submitButton.setVisibility(View.VISIBLE);
} else holder.submitButton.setVisibility(View.GONE); } else holder.submitButton.setVisibility(View.GONE);
} else { } else {

9
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java

@ -495,11 +495,12 @@ public class TopicParser {
Element secondRow = tables.get(i).select("tr[class=windowbg]").first(); Element secondRow = tables.get(i).select("tr[class=windowbg]").first();
Element secondColumn = secondRow.child(1); Element secondColumn = secondRow.child(1);
String columnString = secondColumn.outerHtml(); String columnString = secondColumn.outerHtml();
question = columnString.substring(columnString.indexOf('>') + 1, columnString.indexOf('<', 2)).trim(); question = columnString.substring(columnString.indexOf('>') + 1, columnString.indexOf('<', 2))
.replace("&nbsp;", " ").trim();
Element form = secondColumn.select("form").first(); Element form = secondColumn.select("form").first();
if (form != null) { if (form != null) {
// english poll in vote mode // poll in vote mode
pollFormUrl = form.attr("action"); pollFormUrl = form.attr("action");
sc = form.select("input[name=sc]").first().attr("value"); sc = form.select("input[name=sc]").first().attr("value");
@ -530,7 +531,7 @@ public class TopicParser {
showVoteResultsUrl = links.first().attr("href"); showVoteResultsUrl = links.first().attr("href");
} }
} else { } else {
// english poll in results mode // poll in results mode
Elements optionRows = secondColumn.child(0).child(0).select("table").first().child(0).children(); Elements optionRows = secondColumn.child(0).child(0).select("table").first().child(0).children();
for (int j = 0; j < optionRows.size(); j++) { for (int j = 0; j < optionRows.size(); j++) {
String optionName = optionRows.get(j).child(0).text(); String optionName = optionRows.get(j).child(0).text();
@ -539,7 +540,7 @@ public class TopicParser {
integerMatcher.find(); integerMatcher.find();
int voteCount = Integer.parseInt(voteCountDescription.substring(integerMatcher.start(), int voteCount = Integer.parseInt(voteCountDescription.substring(integerMatcher.start(),
integerMatcher.end())); integerMatcher.end()));
entries.add(new Poll.Entry(optionName, voteCount)); entries.add(0, new Poll.Entry(optionName, voteCount));
} }
Elements links = secondColumn.select("a"); Elements links = secondColumn.select("a");

23
app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/ReplyTask.java

@ -4,6 +4,7 @@ import android.os.AsyncTask;
import java.io.IOException; import java.io.IOException;
import gr.thmmy.mthmmy.activities.topic.Posting;
import gr.thmmy.mthmmy.base.BaseApplication; import gr.thmmy.mthmmy.base.BaseApplication;
import okhttp3.MultipartBody; import okhttp3.MultipartBody;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
@ -14,7 +15,7 @@ import timber.log.Timber;
import static gr.thmmy.mthmmy.activities.topic.Posting.replyStatus; import static gr.thmmy.mthmmy.activities.topic.Posting.replyStatus;
public class ReplyTask extends AsyncTask<String, Void, Boolean> { public class ReplyTask extends AsyncTask<String, Void, Posting.REPLY_STATUS> {
private ReplyTaskCallbacks listener; private ReplyTaskCallbacks listener;
private boolean includeAppSignature; private boolean includeAppSignature;
@ -29,7 +30,7 @@ public class ReplyTask extends AsyncTask<String, Void, Boolean> {
} }
@Override @Override
protected Boolean doInBackground(String... args) { protected Posting.REPLY_STATUS doInBackground(String... args) {
final String sentFrommTHMMY = includeAppSignature final String sentFrommTHMMY = includeAppSignature
? "\n[right][size=7pt][i]sent from [url=https://play.google.com/store/apps/details?id=gr.thmmy.mthmmy]mTHMMY[/url][/i][/size][/right]" ? "\n[right][size=7pt][i]sent from [url=https://play.google.com/store/apps/details?id=gr.thmmy.mthmmy]mTHMMY[/url][/i][/size][/right]"
: ""; : "";
@ -52,30 +53,20 @@ public class ReplyTask extends AsyncTask<String, Void, Boolean> {
OkHttpClient client = BaseApplication.getInstance().getClient(); OkHttpClient client = BaseApplication.getInstance().getClient();
client.newCall(post).execute(); client.newCall(post).execute();
Response response = client.newCall(post).execute(); Response response = client.newCall(post).execute();
switch (replyStatus(response)) { return replyStatus(response);
case SUCCESSFUL:
BaseApplication.getInstance().logFirebaseAnalyticsEvent("post_creation", null);
return true;
case NEW_REPLY_WHILE_POSTING:
//TODO this...
return true;
default:
Timber.e("Malformed post. Request string: %s", post.toString());
return true;
}
} catch (IOException e) { } catch (IOException e) {
Timber.e(e, "Post failed."); Timber.e(e, "Post failed.");
return false; return Posting.REPLY_STATUS.OTHER_ERROR;
} }
} }
@Override @Override
protected void onPostExecute(Boolean result) { protected void onPostExecute(Posting.REPLY_STATUS result) {
listener.onReplyTaskFinished(result); listener.onReplyTaskFinished(result);
} }
public interface ReplyTaskCallbacks { public interface ReplyTaskCallbacks {
void onReplyTaskStarted(); void onReplyTaskStarted();
void onReplyTaskFinished(boolean result); void onReplyTaskFinished(Posting.REPLY_STATUS result);
} }
} }

1
app/src/main/java/gr/thmmy/mthmmy/editorview/EmojiKeyboard.java

@ -152,6 +152,7 @@ public class EmojiKeyboard extends LinearLayout {
public void init(Context context, AttributeSet attrs) { public void init(Context context, AttributeSet attrs) {
LayoutInflater.from(context).inflate(R.layout.emoji_keyboard, this, true); LayoutInflater.from(context).inflate(R.layout.emoji_keyboard, this, true);
setOrientation(VERTICAL); setOrientation(VERTICAL);
setBackgroundColor(getResources().getColor(R.color.primary));
RecyclerView emojiRecyclerview = findViewById(R.id.emoji_recyclerview); RecyclerView emojiRecyclerview = findViewById(R.id.emoji_recyclerview);
emojiRecyclerview.setHasFixedSize(true); emojiRecyclerview.setHasFixedSize(true);

15
app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java

@ -104,6 +104,17 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
loadUrl(topicUrl); loadUrl(topicUrl);
} }
public void reloadPageThen(Runnable runnable) {
if (topicUrl == null) throw new NullPointerException("No topic task has been requested yet!");
Timber.i("Reloading page");
stopLoading();
currentTopicTask = new TopicTask(topicTaskObserver, result -> {
TopicViewModel.this.onTopicTaskCompleted(result);
runnable.run();
});
currentTopicTask.execute(topicUrl);
}
/** /**
* In contrasto to {@link TopicViewModel#reloadPage()} this method gets rid of any arguements * In contrasto to {@link TopicViewModel#reloadPage()} this method gets rid of any arguements
* in the url before refreshing * in the url before refreshing
@ -127,7 +138,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
} }
} }
public void submitVote(LinearLayout optionsLayout) { public boolean submitVote(LinearLayout optionsLayout) {
if (topicItems.getValue() == null) throw new NullPointerException("Topic task has not finished yet!"); if (topicItems.getValue() == null) throw new NullPointerException("Topic task has not finished yet!");
ArrayList<Integer> votes = new ArrayList<>(); ArrayList<Integer> votes = new ArrayList<>();
if (optionsLayout.getChildAt(0) instanceof RadioGroup) { if (optionsLayout.getChildAt(0) instanceof RadioGroup) {
@ -142,10 +153,12 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
int[] votesArray = new int[votes.size()]; int[] votesArray = new int[votes.size()];
for (int i = 0; i < votes.size(); i++) votesArray[i] = votes.get(i); for (int i = 0; i < votes.size(); i++) votesArray[i] = votes.get(i);
Poll poll = (Poll) topicItems.getValue().get(0); Poll poll = (Poll) topicItems.getValue().get(0);
if (poll.getAvailableVoteCount() < votesArray.length) return false;
SubmitVoteTask submitVoteTask = new SubmitVoteTask(votesArray); SubmitVoteTask submitVoteTask = new SubmitVoteTask(votesArray);
submitVoteTask.setOnTaskStartedListener(voteTaskStartedListener); submitVoteTask.setOnTaskStartedListener(voteTaskStartedListener);
submitVoteTask.setOnNetworkTaskFinishedListener(voteTaskFinishedListener); submitVoteTask.setOnNetworkTaskFinishedListener(voteTaskFinishedListener);
submitVoteTask.execute(poll.getPollFormUrl(), poll.getSc()); submitVoteTask.execute(poll.getPollFormUrl(), poll.getSc());
return true;
} }
public void removeVote() { public void removeVote() {

1
app/src/main/res/layout/activity_topic_poll.xml

@ -28,7 +28,6 @@
android:id="@+id/error_too_many_checked" android:id="@+id/error_too_many_checked"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/error_too_many_checked"
android:textColor="@color/red" android:textColor="@color/red"
android:visibility="gone" /> android:visibility="gone" />

5
app/src/main/res/values/strings.xml

@ -61,7 +61,10 @@
<string name="unauthorized_topic_error">This topic is either missing or off limits to you</string> <string name="unauthorized_topic_error">This topic is either missing or off limits to you</string>
<string name="remove_vote_button">Remove vote</string> <string name="remove_vote_button">Remove vote</string>
<string name="show_vote_results_button">show results</string> <string name="show_vote_results_button">show results</string>
<string name="error_too_many_checked">You may only select %d options</string> <plurals name="error_too_many_checked">
<item quantity="one">You may only select %d option</item>
<item quantity="other">You may only select %d options</item>
</plurals>
<string name="show_vote_options_button">hide results</string> <string name="show_vote_options_button">hide results</string>
<!--Profile Activity--> <!--Profile Activity-->

Loading…
Cancel
Save