Browse Source

maybe finished new messages functionality

new_messages
Thodoris1999 6 years ago
parent
commit
c1a1713901
  1. 5
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/NewPostSeparator.java
  2. 43
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
  3. 37
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
  4. 4
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicRecyclerViewItem.java
  5. 19
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTask.java
  6. 8
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTaskResult.java
  7. 4
      app/src/main/java/gr/thmmy/mthmmy/model/Post.java
  8. 6
      app/src/main/java/gr/thmmy/mthmmy/viewmodel/TopicViewModel.java
  9. 28
      app/src/main/res/layout/activity_topic_new_message_separator.xml

5
app/src/main/java/gr/thmmy/mthmmy/activities/topic/NewPostSeparator.java

@ -0,0 +1,5 @@
package gr.thmmy.mthmmy.activities.topic;
public class NewPostSeparator extends TopicRecyclerViewItem {
public static final int TYPE_NEW_MESSAGE_SEPARATOR = 3;
}

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

@ -80,7 +80,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
/**
* Holds a list of this topic's posts
*/
private ArrayList<Post> postsList;
private ArrayList<TopicRecyclerViewItem> topicRecyclerviewItems;
//Reply related
private FloatingActionButton replyFAB;
//Topic's pages related
@ -165,7 +165,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
progressBar = findViewById(R.id.progressBar);
emojiKeyboard = findViewById(R.id.emoji_keyboard);
postsList = new ArrayList<>();
topicRecyclerviewItems = new ArrayList<>();
recyclerView = findViewById(R.id.topic_recycler_view);
recyclerView.setHasFixedSize(true);
@ -174,7 +174,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
getApplicationContext(), topicPageUrl);
recyclerView.setLayoutManager(layoutManager);
topicAdapter = new TopicAdapter(this, postsList);
topicAdapter = new TopicAdapter(this, topicRecyclerviewItems);
recyclerView.setAdapter(topicAdapter);
replyFAB = findViewById(R.id.topic_fab);
@ -275,15 +275,15 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
}
return;
} else if (viewModel.isWritingReply()) {
postsList.remove(postsList.size() - 1);
topicAdapter.notifyItemRemoved(postsList.size());
topicRecyclerviewItems.remove(topicRecyclerviewItems.size() - 1);
topicAdapter.notifyItemRemoved(topicRecyclerviewItems.size());
topicAdapter.setBackButtonHidden();
viewModel.setWritingReply(false);
replyFAB.show();
bottomNavBar.setVisibility(View.VISIBLE);
return;
} else if (viewModel.isEditingPost()) {
postsList.get(viewModel.getPostBeingEditedPosition()).setPostType(Post.TYPE_POST);
((Post) topicRecyclerviewItems.get(viewModel.getPostBeingEditedPosition())).setPostType(Post.TYPE_POST);
topicAdapter.notifyItemChanged(viewModel.getPostBeingEditedPosition());
topicAdapter.setBackButtonHidden();
viewModel.setEditingPost(false);
@ -533,7 +533,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
replyFAB.show();
bottomNavBar.setVisibility(View.VISIBLE);
viewModel.setWritingReply(false);
if ((postsList.get(postsList.size() - 1).getPostNumber() + 1) % 15 == 0) {
if ((((Post) topicRecyclerviewItems.get(topicRecyclerviewItems.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 {
@ -542,8 +542,8 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
} else {
Timber.w("Post reply unsuccessful");
Toast.makeText(getBaseContext(), "Post failed!", Toast.LENGTH_SHORT).show();
recyclerView.getChildAt(postsList.size() - 1).setAlpha(1);
recyclerView.getChildAt(postsList.size() - 1).setEnabled(true);
recyclerView.getChildAt(topicRecyclerviewItems.size() - 1).setAlpha(1);
recyclerView.getChildAt(topicRecyclerviewItems.size() - 1).setEnabled(true);
}
}
});
@ -576,7 +576,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
if (result) {
Timber.i("Post edit successful");
postsList.get(position).setPostType(Post.TYPE_POST);
((Post) topicRecyclerviewItems.get(position)).setPostType(Post.TYPE_POST);
topicAdapter.notifyItemChanged(position);
replyFAB.show();
bottomNavBar.setVisibility(View.VISIBLE);
@ -629,20 +629,25 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
viewModel.getPostsList().observe(this, postList -> {
if (postList == null) progressBar.setVisibility(ProgressBar.VISIBLE);
recyclerView.getRecycledViewPool().clear(); //Avoid inconsistency detected bug
postsList.clear();
postsList.addAll(postList);
topicRecyclerviewItems.clear();
topicRecyclerviewItems.addAll(postList);
topicAdapter.notifyDataSetChanged();
});
/*viewModel.getFocusedPostIndex().observe(this, focusedPostIndex -> {
viewModel.getFocusedPostIndex().observe(this, focusedPostIndex -> {
if (focusedPostIndex == null) return;
recyclerView.scrollToPosition(focusedPostIndex);
});*/
if (viewModel.isFocusedPostLastSeenMessage() && focusedPostIndex != viewModel.postCount() - 1) {
topicRecyclerviewItems.add(focusedPostIndex, new NewPostSeparator());
topicAdapter.notifyItemInserted(focusedPostIndex);
}
//recyclerView.scrollToPosition(focusedPostIndex);
});
viewModel.getTopicTaskResultCode().observe(this, resultCode -> {
if (resultCode == null) return;
progressBar.setVisibility(ProgressBar.GONE);
switch (resultCode) {
case SUCCESS:
Timber.i("Successfully loaded topic with URL %s", viewModel.getTopicUrl());
Timber.i("load " + viewModel.isFocusedPostLastSeenMessage());
paginationEnabled(true);
break;
case NETWORK_ERROR:
@ -688,9 +693,9 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
Timber.i("Prepare for reply successful");
//prepare for a reply
viewModel.setWritingReply(true);
postsList.add(Post.newQuickReply());
topicAdapter.notifyItemInserted(postsList.size());
recyclerView.scrollToPosition(postsList.size() - 1);
topicRecyclerviewItems.add(Post.newQuickReply());
topicAdapter.notifyItemInserted(topicRecyclerviewItems.size());
recyclerView.scrollToPosition(topicRecyclerviewItems.size() - 1);
replyFAB.hide();
bottomNavBar.setVisibility(View.GONE);
} else {
@ -703,7 +708,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
if (result != null && result.isSuccessful()) {
Timber.i("Prepare for edit successful");
viewModel.setEditingPost(true);
postsList.get(result.getPosition()).setPostType(Post.TYPE_EDIT);
((Post) topicRecyclerviewItems.get(result.getPosition())).setPostType(Post.TYPE_EDIT);
topicAdapter.notifyItemChanged(result.getPosition());
recyclerView.scrollToPosition(result.getPosition());
replyFAB.hide();

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

@ -35,7 +35,7 @@ import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.List;
import java.util.ArrayList;
import java.util.Objects;
import gr.thmmy.mthmmy.R;
@ -74,16 +74,16 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final Context context;
private final OnPostFocusChangeListener postFocusListener;
private final EmojiKeyboard.EmojiKeyboardOwner emojiKeyboardOwner;
private final List<Post> postsList;
private final ArrayList<TopicRecyclerViewItem> topicRecyclerViewItems;
private TopicViewModel viewModel;
/**
* @param context the context of the {@link RecyclerView}
* @param postsList List of {@link Post} objects to use
* @param topicRecyclerViewItems List of {@link Post} objects to use
*/
TopicAdapter(TopicActivity context, List<Post> postsList) {
TopicAdapter(TopicActivity context, ArrayList<TopicRecyclerViewItem> topicRecyclerViewItems) {
this.context = context;
this.postsList = postsList;
this.topicRecyclerViewItems = topicRecyclerViewItems;
this.postFocusListener = context;
this.emojiKeyboardOwner = context;
@ -94,7 +94,9 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@Override
public int getItemViewType(int position) {
return postsList.get(position).getPostType();
if (topicRecyclerViewItems.get(position) instanceof NewPostSeparator)
return NewPostSeparator.TYPE_NEW_MESSAGE_SEPARATOR;
return ((Post) topicRecyclerViewItems.get(position)).getPostType();
}
@NonNull
@ -130,6 +132,10 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
editPostEdittext.requestFocus();
return new EditMessageViewHolder(view);
} else if (viewType == NewPostSeparator.TYPE_NEW_MESSAGE_SEPARATOR) {
View view = LayoutInflater.from(parent.getContext()).
inflate(R.layout.activity_topic_new_message_separator, parent, false);
return new NewMessageSeparatorViewHolder(view);
} else {
throw new IllegalArgumentException("Unknown view type");
}
@ -140,7 +146,7 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder currentHolder,
final int position) {
if (currentHolder instanceof PostViewHolder) {
final Post currentPost = postsList.get(position);
final Post currentPost = (Post) topicRecyclerViewItems.get(position);
final PostViewHolder holder = (PostViewHolder) currentHolder;
//Post's WebView parameters
@ -396,7 +402,7 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
editPostButton.setVisibility(View.GONE);
} else {
editPostButton.setOnClickListener(v -> {
viewModel.prepareForEdit(position, postsList.get(position).getPostEditURL());
viewModel.prepareForEdit(position, ((Post) topicRecyclerViewItems.get(position)).getPostEditURL());
popUp.dismiss();
});
}
@ -504,7 +510,7 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
.transform(new CircleTransform())
.into(holder.thumbnail);
holder.username.setText(getSessionManager().getUsername());
holder.editSubject.setText(postsList.get(position).getSubject());
holder.editSubject.setText(((Post) topicRecyclerViewItems.get(position)).getSubject());
holder.editEditor.setEmojiKeyboardOwner(emojiKeyboardOwner);
InputConnection ic = holder.editEditor.getInputConnection();
@ -542,7 +548,7 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@Override
public int getItemCount() {
return postsList.size();
return topicRecyclerViewItems.size();
}
/**
@ -631,6 +637,12 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
}
}
static class NewMessageSeparatorViewHolder extends RecyclerView.ViewHolder {
NewMessageSeparatorViewHolder(View itemView) {
super(itemView);
}
}
/**
* This class is used to handle link clicks in WebViews. When link url is one that the app can
* handle internally, it does. Otherwise user is prompt to open the link in a browser.
@ -674,8 +686,9 @@ class TopicAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
if (tmpUrlSbstr.contains("msg"))
tmpUrlSbstr = tmpUrlSbstr.substring(0, tmpUrlSbstr.indexOf("msg") - 1);
int testAgainst = Integer.parseInt(tmpUrlSbstr);
for (int i = 0; i < postsList.size(); i++) {
if (postsList.get(i).getPostIndex() == testAgainst) {
for (int i = 0; i < topicRecyclerViewItems.size(); i++) {
if (!(topicRecyclerViewItems.get(i) instanceof Post)) continue;
if (((Post) topicRecyclerViewItems.get(i)).getPostIndex() == testAgainst) {
//same page
Timber.e(Integer.toString(i));
postFocusListener.onPostFocusChange(i);

4
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicRecyclerViewItem.java

@ -0,0 +1,4 @@
package gr.thmmy.mthmmy.activities.topic;
public class TopicRecyclerViewItem {
}

19
app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTask.java

@ -45,13 +45,17 @@ public class TopicTask extends AsyncTask<String, Void, TopicTaskResult> {
//Finds the index of message focus if present
int postFocus = 0;
{
boolean focusedPostLastSeenMessage = false;
if (newPageUrl.contains("msg")) {
String tmp = newPageUrl.substring(newPageUrl.indexOf("msg") + 3);
if (tmp.contains(";"))
if (tmp.contains(";")) {
postFocus = Integer.parseInt(tmp.substring(0, tmp.indexOf(";")));
else if (tmp.contains("#"))
if (newPageUrl.contains("topicseen"))
focusedPostLastSeenMessage = true;
} else if (tmp.contains("#")) {
postFocus = Integer.parseInt(tmp.substring(0, tmp.indexOf("#")));
if (newPageUrl.contains("topicseen"))
focusedPostLastSeenMessage = true;
}
}
@ -105,18 +109,18 @@ public class TopicTask extends AsyncTask<String, Void, TopicTaskResult> {
}
}
return new TopicTaskResult(ResultCode.SUCCESS, topicTitle, replyPageUrl, newPostsList, loadedPageTopicId,
currentPageIndex, pageCount, focusedPostIndex, topicTreeAndMods, topicViewers);
currentPageIndex, pageCount, focusedPostIndex, topicTreeAndMods, topicViewers, focusedPostLastSeenMessage);
} catch (IOException e) {
return new TopicTaskResult(ResultCode.NETWORK_ERROR, null, null, null,
0, 0, 0, 0, null, null);
0, 0, 0, 0, null, null, false);
} catch (Exception e) {
if (isUnauthorized(topic)) {
return new TopicTaskResult(ResultCode.UNAUTHORIZED, null, null, null,
0, 0, 0, 0, null, null);
0, 0, 0, 0, null, null, false);
} else {
Timber.e(e, "Topic parse failed");
return new TopicTaskResult(ResultCode.PARSING_ERROR, null, null, null,
0, 0, 0, 0, null, null);
0, 0, 0, 0, null, null, false);
}
}
}
@ -139,6 +143,7 @@ public class TopicTask extends AsyncTask<String, Void, TopicTaskResult> {
public interface TopicTaskObserver {
void onTopicTaskStarted();
void onTopicTaskCancelled();
}

8
app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/TopicTaskResult.java

@ -36,11 +36,12 @@ public class TopicTaskResult {
//Topic's info related
private final String topicTreeAndMods;
private final String topicViewers;
private final boolean focusedPostLastSeenMessage;
public TopicTaskResult(TopicTask.ResultCode resultCode, String topicTitle,
String replyPageUrl, ArrayList<Post> newPostsList, int loadedPageTopicId,
int currentPageIndex, int pageCount, int focusedPostIndex, String topicTreeAndMods,
String topicViewers) {
String topicViewers, boolean focusedPostLastSeenMessage) {
this.resultCode = resultCode;
this.topicTitle = topicTitle;
this.replyPageUrl = replyPageUrl;
@ -51,6 +52,7 @@ public class TopicTaskResult {
this.focusedPostIndex = focusedPostIndex;
this.topicTreeAndMods = topicTreeAndMods;
this.topicViewers = topicViewers;
this.focusedPostLastSeenMessage = focusedPostLastSeenMessage;
}
public TopicTask.ResultCode getResultCode() {
@ -92,4 +94,8 @@ public class TopicTaskResult {
public String getTopicViewers() {
return topicViewers;
}
public boolean isFocusedPostLastSeenMessage() {
return focusedPostLastSeenMessage;
}
}

4
app/src/main/java/gr/thmmy/mthmmy/model/Post.java

@ -5,6 +5,8 @@ import android.support.annotation.Nullable;
import java.util.ArrayList;
import java.util.Objects;
import gr.thmmy.mthmmy.activities.topic.TopicRecyclerViewItem;
/**
* Class that defines a topic's post. All member variables are declared final (thus no setters are
* supplied). Class has two constructors and getter methods for all variables.
@ -15,7 +17,7 @@ import java.util.Objects;
* gender, number of posts, personal text and number of start to be described <b>in addition to
* previous fields</b>.</p>
*/
public class Post {
public class Post extends TopicRecyclerViewItem {
public static final int TYPE_POST = 0;
public static final int TYPE_QUICK_REPLY = 1;
public static final int TYPE_EDIT = 2;

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

@ -73,6 +73,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
private String topicUrl;
private int currentPageIndex;
private int pageCount;
private boolean focusedPostLastSeenMessage;
private MutableLiveData<PrepareForReplyResult> prepareForReplyResult = new MutableLiveData<>();
private MutableLiveData<PrepareForEditResult> prepareForEditResult = new MutableLiveData<>();
@ -187,6 +188,7 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
if (result.getResultCode() == TopicTask.ResultCode.SUCCESS) {
currentPageIndex = result.getCurrentPageIndex();
pageCount = result.getPageCount();
focusedPostLastSeenMessage = result.isFocusedPostLastSeenMessage();
topicTreeAndMods.setValue(result.getTopicTreeAndMods());
topicViewers.setValue(result.getTopicViewers());
pageTopicId.setValue(result.getLoadedPageTopicId());
@ -392,4 +394,8 @@ public class TopicViewModel extends BaseViewModel implements TopicTask.OnTopicTa
throw new NullPointerException("No page has been loaded yet!");
return postsList.getValue().size();
}
public boolean isFocusedPostLastSeenMessage() {
return focusedPostLastSeenMessage;
}
}

28
app/src/main/res/layout/activity_topic_new_message_separator.xml

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:background="@color/red"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="NEW MESSAGES"
android:textColor="@color/red"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"/>
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:background="@color/red"/>
</LinearLayout>
Loading…
Cancel
Save