Show related messages (parents, replies)

This commit is contained in:
Christian Basler 2017-04-16 22:35:26 +02:00
parent 8770575c95
commit f77bbe1a43
6 changed files with 190 additions and 17 deletions

View File

@ -18,8 +18,10 @@ package ch.dissem.apps.abit;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.IdRes;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.util.Linkify;
import android.view.LayoutInflater;
@ -47,12 +49,14 @@ import ch.dissem.apps.abit.util.Drawables;
import ch.dissem.apps.abit.util.Labels;
import ch.dissem.bitmessage.entity.BitmessageAddress;
import ch.dissem.bitmessage.entity.Plaintext;
import ch.dissem.bitmessage.entity.valueobject.InventoryVector;
import ch.dissem.bitmessage.entity.valueobject.Label;
import ch.dissem.bitmessage.ports.MessageRepository;
import static android.text.util.Linkify.WEB_URLS;
import static ch.dissem.apps.abit.util.Constants.BITMESSAGE_ADDRESS_PATTERN;
import static ch.dissem.apps.abit.util.Constants.BITMESSAGE_URL_SCHEMA;
import static ch.dissem.apps.abit.util.Strings.normalizeWhitespaces;
/**
@ -143,16 +147,30 @@ public class MessageDetailFragment extends Fragment {
removed = true;
}
}
MessageRepository messageRepo = Singleton.getMessageRepository(inflater.getContext());
if (removed) {
if (getActivity() instanceof ActionBarListener) {
((ActionBarListener) getActivity()).updateUnread();
}
Singleton.getMessageRepository(inflater.getContext()).save(item);
messageRepo.save(item);
}
List<Plaintext> parents = new ArrayList<>(item.getParents().size());
for (InventoryVector parentIV : item.getParents()) {
parents.add(messageRepo.getMessage(parentIV));
}
showRelatedMessages(rootView, R.id.parents, parents);
showRelatedMessages(rootView, R.id.responses, messageRepo.findResponses(item));
}
return rootView;
}
private void showRelatedMessages(View rootView, @IdRes int id, List<Plaintext> messages) {
RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.parents);
RelatedMessageAdapter adapter = new RelatedMessageAdapter(getActivity(), messages);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.message, menu);
@ -211,6 +229,61 @@ public class MessageDetailFragment extends Fragment {
return false;
}
private static class RelatedMessageAdapter extends RecyclerView.Adapter<RelatedMessageAdapter.ViewHolder> {
private final List<Plaintext> messages;
private final Context ctx;
private RelatedMessageAdapter(Context ctx, List<Plaintext> messages) {
this.messages = messages;
this.ctx = ctx;
}
@Override
public RelatedMessageAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
// Inflate the custom layout
View contactView = inflater.inflate(R.layout.item_message_minimized, parent, false);
// Return a new holder instance
return new RelatedMessageAdapter.ViewHolder(contactView);
}
// Involves populating data into the item through holder
@Override
public void onBindViewHolder(RelatedMessageAdapter.ViewHolder viewHolder, int position) {
// Get the data model based on position
Plaintext message = messages.get(position);
viewHolder.avatar.setImageDrawable(new Identicon(message.getFrom()));
viewHolder.status.setImageResource(Assets.getStatusDrawable(message.getStatus()));
viewHolder.sender.setText(message.getFrom().toString());
viewHolder.extract.setText(normalizeWhitespaces(message.getText()));
}
// Returns the total count of items in the list
@Override
public int getItemCount() {
return messages.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
private final ImageView avatar;
private final ImageView status;
private final TextView sender;
private final TextView extract;
ViewHolder(View itemView) {
super(itemView);
avatar = (ImageView) itemView.findViewById(R.id.avatar);
status = (ImageView) itemView.findViewById(R.id.status);
sender = (TextView) itemView.findViewById(R.id.sender);
extract = (TextView) itemView.findViewById(R.id.text);
}
}
}
private static class LabelAdapter extends
RecyclerView.Adapter<LabelAdapter.ViewHolder> {

View File

@ -42,6 +42,7 @@ import ch.dissem.bitmessage.networking.nio.NioNetworkHandler;
import ch.dissem.bitmessage.ports.AddressRepository;
import ch.dissem.bitmessage.ports.MessageRepository;
import ch.dissem.bitmessage.ports.ProofOfWorkRepository;
import ch.dissem.bitmessage.utils.ConversationService;
import ch.dissem.bitmessage.utils.TTL;
import static ch.dissem.bitmessage.utils.UnixTime.DAY;
@ -51,6 +52,7 @@ import static ch.dissem.bitmessage.utils.UnixTime.DAY;
*/
public class Singleton {
private static BitmessageContext bitmessageContext;
private static ConversationService conversationService;
private static MessageListener messageListener;
private static BitmessageAddress identity;
private static AndroidProofOfWorkRepository powRepo;
@ -160,4 +162,16 @@ public class Singleton {
throw new IllegalArgumentException("Identity expected, but no private key available");
Singleton.identity = identity;
}
public static ConversationService getConversationService(Context ctx) {
if (conversationService == null) {
final BitmessageContext bmc = getBitmessageContext(ctx);
synchronized (Singleton.class) {
if (conversationService == null) {
conversationService = new ConversationService(bmc.messages());
}
}
}
return conversationService;
}
}

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:top="1dp" android:bottom="1dp">
<shape
android:shape="rectangle">
<stroke android:width="1dp" android:color="#FFDDDDDD" />
<solid android:color="#00000000" />
</shape>
</item>
</layer-list>

View File

@ -78,12 +78,20 @@
android:paddingRight="8dp"
tools:text="Recipient" />
<android.support.v7.widget.RecyclerView
android:id="@+id/parents"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/avatar"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp" />
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_below="@+id/avatar"
android:layout_below="@+id/parents"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="32dp"
@ -98,5 +106,13 @@
android:layout_below="@+id/text"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp" />
<android.support.v7.widget.RecyclerView
android:id="@+id/responses"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/text"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp" />
</RelativeLayout>
</ScrollView>

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/border_bottom">
<ImageView
android:id="@+id/avatar"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_margin="16dp"
android:src="@color/colorPrimaryDark"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/sender"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignTop="@+id/avatar"
android:layout_marginTop="-5dp"
android:layout_toEndOf="@+id/avatar"
android:ellipsize="end"
android:lines="1"
android:paddingBottom="0dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingTop="0dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold"
tools:text="Sender" />
<TextView
android:id="@+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_below="@+id/sender"
android:layout_toEndOf="@+id/avatar"
android:ellipsize="end"
android:gravity="center_vertical"
android:lines="1"
android:paddingBottom="8dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:text="Text" />
<ImageView
android:id="@+id/status"
android:layout_width="24dp"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/avatar"
android:layout_alignEnd="@+id/avatar"
android:layout_marginBottom="-8dp"
android:layout_marginEnd="-8dp"
android:tint="@color/colorAccent"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_notification_proof_of_work" />
</RelativeLayout>

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright 2015 Christian Basler
~
~ Licensed under the Apache License, Version 2.0 (the "License");
@ -15,8 +14,7 @@
~ limitations under the License.
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -31,8 +29,7 @@
android:foreground="?attr/selectableItemBackground"
tools:ignore="UselessParent">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground">
@ -45,7 +42,7 @@
android:layout_alignParentTop="true"
android:layout_margin="16dp"
android:src="@color/colorPrimaryDark"
tools:ignore="ContentDescription"/>
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/sender"
@ -63,8 +60,7 @@
android:paddingTop="0dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold"
tools:text="Sender"
/>
tools:text="Sender" />
<TextView
android:id="@+id/subject"
@ -78,7 +74,7 @@
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:text="Subject"/>
tools:text="Subject" />
<TextView
android:id="@+id/text"
@ -94,7 +90,7 @@
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:text="Text"/>
tools:text="Text" />
<ImageView
android:id="@+id/status"
@ -106,7 +102,7 @@
android:layout_marginEnd="-8dp"
android:tint="@color/colorAccent"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_notification_proof_of_work"/>
tools:src="@drawable/ic_notification_proof_of_work" />
</RelativeLayout>