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.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Rect;
import android.net.Uri;
@ -36,6 +37,7 @@ import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.function.Consumer;
import gr.thmmy.mthmmy.R;
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.TopicTask;
import gr.thmmy.mthmmy.base.BaseActivity;
import gr.thmmy.mthmmy.base.BaseApplication;
import gr.thmmy.mthmmy.editorview.EmojiKeyboard;
import gr.thmmy.mthmmy.model.Bookmark;
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.HTMLUtils;
import gr.thmmy.mthmmy.utils.NetworkResultCodes;
import gr.thmmy.mthmmy.utils.NetworkTask;
import gr.thmmy.mthmmy.utils.parsing.ParseHelpers;
import gr.thmmy.mthmmy.viewmodel.TopicViewModel;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import timber.log.Timber;
import static gr.thmmy.mthmmy.activities.topic.Posting.replyStatus;
import static gr.thmmy.mthmmy.services.NotificationService.NEW_POST_TAG;
/**
@ -517,7 +520,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
}
@Override
public void onReplyTaskFinished(boolean success) {
public void onReplyTaskFinished(Posting.REPLY_STATUS replyStatus) {
View view = getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@ -526,22 +529,49 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
progressBar.setVisibility(ProgressBar.GONE);
if (success) {
Timber.i("Post reply successful");
replyFAB.show();
bottomNavBar.setVisibility(View.VISIBLE);
viewModel.setWritingReply(false);
if ((((Post) topicItems.get(topicItems.size() - 1)).getPostNumber() + 1) % 15 == 0) {
Timber.i("Reply was posted in new page. Switching to last page.");
viewModel.loadUrl(ParseHelpers.getBaseURL(viewModel.getTopicUrl()) + "." + 2147483647);
} else {
viewModel.reloadPage();
}
} else {
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);
switch (replyStatus) {
case SUCCESSFUL:
BaseApplication.getInstance().logFirebaseAnalyticsEvent("post_creation", null);
Timber.i("Post reply successful");
replyFAB.show();
bottomNavBar.setVisibility(View.VISIBLE);
viewModel.setWritingReply(false);
if ((((Post) topicItems.get(topicItems.size() - 1)).getPostNumber() + 1) % 15 == 0) {
Timber.i("Reply was posted in new page. Switching to last page.");
viewModel.loadUrl(ParseHelpers.getBaseURL(viewModel.getTopicUrl()) + "." + 2147483647);
} else {
viewModel.reloadPage();
}
case NEW_REPLY_WHILE_POSTING:
Timber.i("New reply while writing a reply");
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;
holder.question.setText(poll.getQuestion());
holder.optionsLayout.removeAllViews();
holder.errorTooManySelected.setVisibility(View.GONE);
if (poll.getAvailableVoteCount() > 1) {
for (Poll.Entry entry : entries) {
CheckBox checkBox = new CheckBox(context);
@ -237,7 +238,13 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
holder.hidePollResultsButton.setVisibility(View.VISIBLE);
} else holder.hidePollResultsButton.setVisibility(View.GONE);
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);
} else holder.submitButton.setVisibility(View.GONE);
} 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 secondColumn = secondRow.child(1);
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();
if (form != null) {
// english poll in vote mode
// poll in vote mode
pollFormUrl = form.attr("action");
sc = form.select("input[name=sc]").first().attr("value");
@ -530,7 +531,7 @@ public class TopicParser {
showVoteResultsUrl = links.first().attr("href");
}
} else {
// english poll in results mode
// poll in results mode
Elements optionRows = secondColumn.child(0).child(0).select("table").first().child(0).children();
for (int j = 0; j < optionRows.size(); j++) {
String optionName = optionRows.get(j).child(0).text();
@ -539,7 +540,7 @@ public class TopicParser {
integerMatcher.find();
int voteCount = Integer.parseInt(voteCountDescription.substring(integerMatcher.start(),
integerMatcher.end()));
entries.add(new Poll.Entry(optionName, voteCount));
entries.add(0, new Poll.Entry(optionName, voteCount));
}
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 gr.thmmy.mthmmy.activities.topic.Posting;
import gr.thmmy.mthmmy.base.BaseApplication;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
@ -14,7 +15,7 @@ import timber.log.Timber;
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 boolean includeAppSignature;
@ -29,7 +30,7 @@ public class ReplyTask extends AsyncTask<String, Void, Boolean> {
}
@Override
protected Boolean doInBackground(String... args) {
protected Posting.REPLY_STATUS doInBackground(String... args) {
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]"
: "";
@ -52,30 +53,20 @@ public class ReplyTask extends AsyncTask<String, Void, Boolean> {
OkHttpClient client = BaseApplication.getInstance().getClient();
client.newCall(post).execute();
Response response = client.newCall(post).execute();
switch (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;
}
return replyStatus(response);
} catch (IOException e) {
Timber.e(e, "Post failed.");
return false;
return Posting.REPLY_STATUS.OTHER_ERROR;
}
}
@Override
protected void onPostExecute(Boolean result) {
protected void onPostExecute(Posting.REPLY_STATUS result) {
listener.onReplyTaskFinished(result);
}
public interface ReplyTaskCallbacks {
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) {
LayoutInflater.from(context).inflate(R.layout.emoji_keyboard, this, true);
setOrientation(VERTICAL);
setBackgroundColor(getResources().getColor(R.color.primary));
RecyclerView emojiRecyclerview = findViewById(R.id.emoji_recyclerview);
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);
}
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 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!");
ArrayList<Integer> votes = new ArrayList<>();
if (optionsLayout.getChildAt(0) instanceof RadioGroup) {
@ -142,10 +153,12 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
int[] votesArray = new int[votes.size()];
for (int i = 0; i < votes.size(); i++) votesArray[i] = votes.get(i);
Poll poll = (Poll) topicItems.getValue().get(0);
if (poll.getAvailableVoteCount() < votesArray.length) return false;
SubmitVoteTask submitVoteTask = new SubmitVoteTask(votesArray);
submitVoteTask.setOnTaskStartedListener(voteTaskStartedListener);
submitVoteTask.setOnNetworkTaskFinishedListener(voteTaskFinishedListener);
submitVoteTask.execute(poll.getPollFormUrl(), poll.getSc());
return true;
}
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:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/error_too_many_checked"
android:textColor="@color/red"
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="remove_vote_button">Remove vote</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>
<!--Profile Activity-->

Loading…
Cancel
Save