Add labels to message detail view

This commit is contained in:
Christian Basler 2017-03-23 16:59:36 +01:00
parent 6be31c9f4e
commit a203af654b
7 changed files with 215 additions and 82 deletions

View File

@ -38,11 +38,12 @@ android {
//ext.jabitVersion = '2.0.4' //ext.jabitVersion = '2.0.4'
ext.jabitVersion = 'feature-extended-encoding-SNAPSHOT' ext.jabitVersion = 'feature-extended-encoding-SNAPSHOT'
ext.supportVersion = '25.2.0'
dependencies { dependencies {
compile fileTree(dir: 'libs', include: ['*.jar']) compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:25.3.0' compile "com.android.support:appcompat-v7:$supportVersion"
compile 'com.android.support:support-v4:25.3.0' compile "com.android.support:support-v4:$supportVersion"
compile 'com.android.support:design:25.3.0' compile "com.android.support:design:$supportVersion"
compile "ch.dissem.jabit:jabit-core:$jabitVersion" compile "ch.dissem.jabit:jabit-core:$jabitVersion"
compile "ch.dissem.jabit:jabit-networking:$jabitVersion" compile "ch.dissem.jabit:jabit-networking:$jabitVersion"
@ -59,7 +60,8 @@ dependencies {
compile('com.mikepenz:aboutlibraries:5.9.4@aar') { compile('com.mikepenz:aboutlibraries:5.9.4@aar') {
transitive = true transitive = true
} }
compile 'com.mikepenz:iconics:1.6.2@aar' compile "com.mikepenz:iconics-core:2.8.2@aar"
compile 'com.mikepenz:google-material-typeface:3.0.1.0.original@aar'
compile 'com.mikepenz:community-material-typeface:1.8.36.1@aar' compile 'com.mikepenz:community-material-typeface:1.8.36.1@aar'
compile 'com.journeyapps:zxing-android-embedded:3.3.0@aar' compile 'com.journeyapps:zxing-android-embedded:3.3.0@aar'
@ -71,6 +73,7 @@ dependencies {
} }
compile 'com.github.angads25:filepicker:1.1.0' compile 'com.github.angads25:filepicker:1.1.0'
compile 'com.android.support.constraint:constraint-layout:1.0.2' compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'org.solovyev.android.views:linear-layout-manager:0.5@aar'
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:2.7.19' testCompile 'org.mockito:mockito-core:2.7.19'

View File

@ -48,14 +48,10 @@ import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
import com.mikepenz.materialdrawer.model.interfaces.IProfile; import com.mikepenz.materialdrawer.model.interfaces.IProfile;
import com.mikepenz.materialdrawer.model.interfaces.Nameable; import com.mikepenz.materialdrawer.model.interfaces.Nameable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable; import java.io.Serializable;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import ch.dissem.apps.abit.dialog.AddIdentityDialogFragment; import ch.dissem.apps.abit.dialog.AddIdentityDialogFragment;
import ch.dissem.apps.abit.dialog.FullNodeDialogActivity; import ch.dissem.apps.abit.dialog.FullNodeDialogActivity;
@ -65,6 +61,7 @@ import ch.dissem.apps.abit.repository.AndroidMessageRepository;
import ch.dissem.apps.abit.service.BitmessageService; import ch.dissem.apps.abit.service.BitmessageService;
import ch.dissem.apps.abit.service.Singleton; import ch.dissem.apps.abit.service.Singleton;
import ch.dissem.apps.abit.synchronization.SyncAdapter; import ch.dissem.apps.abit.synchronization.SyncAdapter;
import ch.dissem.apps.abit.util.Labels;
import ch.dissem.apps.abit.util.Preferences; import ch.dissem.apps.abit.util.Preferences;
import ch.dissem.bitmessage.BitmessageContext; import ch.dissem.bitmessage.BitmessageContext;
import ch.dissem.bitmessage.entity.BitmessageAddress; import ch.dissem.bitmessage.entity.BitmessageAddress;
@ -100,7 +97,6 @@ public class MainActivity extends AppCompatActivity
public static final String EXTRA_REPLY_TO_MESSAGE = "ch.dissem.abit.ReplyToMessage"; public static final String EXTRA_REPLY_TO_MESSAGE = "ch.dissem.abit.ReplyToMessage";
public static final String ACTION_SHOW_INBOX = "ch.dissem.abit.ShowInbox"; public static final String ACTION_SHOW_INBOX = "ch.dissem.abit.ShowInbox";
private static final Logger LOG = LoggerFactory.getLogger(MainActivity.class);
private static final int ADD_IDENTITY = 1; private static final int ADD_IDENTITY = 1;
private static final int MANAGE_IDENTITY = 2; private static final int MANAGE_IDENTITY = 2;
@ -437,37 +433,9 @@ public class MainActivity extends AppCompatActivity
public void addLabelEntry(Label label) { public void addLabelEntry(Label label) {
PrimaryDrawerItem item = new PrimaryDrawerItem() PrimaryDrawerItem item = new PrimaryDrawerItem()
.withName(label.toString()) .withName(label.toString())
.withTag(label); .withTag(label)
if (label.getType() == null) { .withIcon(Labels.getIcon(label))
item.withIcon(CommunityMaterial.Icon.cmd_label) .withIconColor(Labels.getColor(label));
.withIconColor(label.getColor());
} else {
switch (label.getType()) {
case INBOX:
item.withIcon(GoogleMaterial.Icon.gmd_inbox);
break;
case DRAFT:
item.withIcon(CommunityMaterial.Icon.cmd_file);
break;
case OUTBOX:
item.withIcon(CommunityMaterial.Icon.cmd_inbox_arrow_up);
break;
case SENT:
item.withIcon(CommunityMaterial.Icon.cmd_send);
break;
case BROADCAST:
item.withIcon(CommunityMaterial.Icon.cmd_rss);
break;
case UNREAD:
item.withIcon(GoogleMaterial.Icon.gmd_markunread_mailbox);
break;
case TRASH:
item.withIcon(GoogleMaterial.Icon.gmd_delete);
break;
default:
item.withIcon(CommunityMaterial.Icon.cmd_label);
}
}
drawer.addItemAtPosition(item, drawer.getDrawerItems().size() - 3); drawer.addItemAtPosition(item, drawer.getDrawerItems().size() - 3);
} }

View File

@ -16,8 +16,11 @@
package ch.dissem.apps.abit; package ch.dissem.apps.abit;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.util.Linkify; import android.text.util.Linkify;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
@ -29,14 +32,19 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.mikepenz.google_material_typeface_library.GoogleMaterial; import com.mikepenz.google_material_typeface_library.GoogleMaterial;
import com.mikepenz.iconics.view.IconicsImageView;
import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import ch.dissem.apps.abit.listener.ActionBarListener; import ch.dissem.apps.abit.listener.ActionBarListener;
import ch.dissem.apps.abit.service.Singleton; import ch.dissem.apps.abit.service.Singleton;
import ch.dissem.apps.abit.util.Assets; import ch.dissem.apps.abit.util.Assets;
import ch.dissem.apps.abit.util.Drawables; 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.BitmessageAddress;
import ch.dissem.bitmessage.entity.Plaintext; import ch.dissem.bitmessage.entity.Plaintext;
import ch.dissem.bitmessage.entity.valueobject.Label; import ch.dissem.bitmessage.entity.valueobject.Label;
@ -106,6 +114,11 @@ public class MessageDetailFragment extends Fragment {
} else if (item.getType() == Plaintext.Type.BROADCAST) { } else if (item.getType() == Plaintext.Type.BROADCAST) {
((TextView) rootView.findViewById(R.id.recipient)).setText(R.string.broadcast); ((TextView) rootView.findViewById(R.id.recipient)).setText(R.string.broadcast);
} }
RecyclerView labelView = (RecyclerView) rootView.findViewById(R.id.labels);
LabelAdapter labelAdapter = new LabelAdapter(getActivity(), item.getLabels());
labelView.setAdapter(labelAdapter);
labelView.setLayoutManager(new GridLayoutManager(getActivity(), 2));
TextView messageBody = (TextView) rootView.findViewById(R.id.text); TextView messageBody = (TextView) rootView.findViewById(R.id.text);
messageBody.setText(item.getText()); messageBody.setText(item.getText());
@ -197,4 +210,65 @@ public class MessageDetailFragment extends Fragment {
} }
return false; return false;
} }
private static class LabelAdapter extends
RecyclerView.Adapter<LabelAdapter.ViewHolder> {
private final List<Label> labels;
private final Context ctx;
private LabelAdapter(Context ctx, Set<Label> labels) {
this.labels = new ArrayList<>(labels);
this.ctx = ctx;
}
@Override
public LabelAdapter.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_label, parent, false);
// Return a new holder instance
return new ViewHolder(contactView);
}
// Involves populating data into the item through holder
@Override
public void onBindViewHolder(LabelAdapter.ViewHolder viewHolder, int position) {
// Get the data model based on position
Label label = labels.get(position);
viewHolder.icon.setColor(Labels.getColor(label));
viewHolder.icon.setIcon(Labels.getIcon(label));
viewHolder.label.setText(Labels.getText(label, ctx));
}
// Returns the total count of items in the list
@Override
public int getItemCount() {
return labels.size();
}
// Provide a direct reference to each of the views within a data item
// Used to cache the views within the item layout for fast access
static class ViewHolder extends RecyclerView.ViewHolder {
// Your holder should contain a member variable
// for any view that will be set as you render a row
public IconicsImageView icon;
public TextView label;
// We also create a constructor that accepts the entire item row
// and does the view lookups to find each subview
ViewHolder(View itemView) {
// Stores the itemView in a public final member variable that can be used
// to access the context from any ViewHolder instance.
super(itemView);
icon = (IconicsImageView) itemView.findViewById(R.id.icon);
label = (TextView) itemView.findViewById(R.id.label);
}
}
}
} }

View File

@ -33,7 +33,7 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import ch.dissem.apps.abit.R; import ch.dissem.apps.abit.util.Labels;
import ch.dissem.apps.abit.util.UuidUtils; import ch.dissem.apps.abit.util.UuidUtils;
import ch.dissem.bitmessage.entity.Plaintext; import ch.dissem.bitmessage.entity.Plaintext;
import ch.dissem.bitmessage.entity.valueobject.InventoryVector; import ch.dissem.bitmessage.entity.valueobject.InventoryVector;
@ -129,35 +129,9 @@ public class AndroidMessageRepository extends AbstractMessageRepository {
private Label getLabel(Cursor c) { private Label getLabel(Cursor c) {
String typeName = c.getString(c.getColumnIndex(LBL_COLUMN_TYPE)); String typeName = c.getString(c.getColumnIndex(LBL_COLUMN_TYPE));
Label.Type type = typeName == null ? null : Label.Type.valueOf(typeName); Label.Type type = typeName == null ? null : Label.Type.valueOf(typeName);
String text; String text = Labels.getText(type, null, context);
if (type == null) { if (text == null) {
text = c.getString(c.getColumnIndex(LBL_COLUMN_LABEL)); text = c.getString(c.getColumnIndex(LBL_COLUMN_LABEL));
} else {
switch (type) {
case INBOX:
text = context.getString(R.string.inbox);
break;
case DRAFT:
text = context.getString(R.string.draft);
break;
case OUTBOX:
text = context.getString(R.string.outbox);
break;
case SENT:
text = context.getString(R.string.sent);
break;
case UNREAD:
text = context.getString(R.string.unread);
break;
case TRASH:
text = context.getString(R.string.trash);
break;
case BROADCAST:
text = context.getString(R.string.broadcasts);
break;
default:
text = c.getString(c.getColumnIndex(LBL_COLUMN_LABEL));
}
} }
Label label = new Label( Label label = new Label(
text, text,

View File

@ -0,0 +1,77 @@
package ch.dissem.apps.abit.util;
import android.content.Context;
import android.support.annotation.ColorInt;
import com.mikepenz.community_material_typeface_library.CommunityMaterial;
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
import com.mikepenz.iconics.typeface.IIcon;
import ch.dissem.apps.abit.R;
import ch.dissem.bitmessage.entity.valueobject.Label;
/**
* Helper class to help with translating the default labels, getting label colors and so on.
*/
public class Labels {
public static String getText(Label label, Context ctx) {
return getText(label.getType(), label.toString(), ctx);
}
public static String getText(Label.Type type, String alternative, Context ctx) {
if (type == null) {
return alternative;
} else {
switch (type) {
case INBOX:
return ctx.getString(R.string.inbox);
case DRAFT:
return ctx.getString(R.string.draft);
case OUTBOX:
return ctx.getString(R.string.outbox);
case SENT:
return ctx.getString(R.string.sent);
case UNREAD:
return ctx.getString(R.string.unread);
case TRASH:
return ctx.getString(R.string.trash);
case BROADCAST:
return ctx.getString(R.string.broadcasts);
default:
return alternative;
}
}
}
public static IIcon getIcon(Label label) {
if (label.getType() == null) {
return CommunityMaterial.Icon.cmd_label;
}
switch (label.getType()) {
case INBOX:
return GoogleMaterial.Icon.gmd_inbox;
case DRAFT:
return CommunityMaterial.Icon.cmd_file;
case OUTBOX:
return CommunityMaterial.Icon.cmd_inbox_arrow_up;
case SENT:
return CommunityMaterial.Icon.cmd_send;
case BROADCAST:
return CommunityMaterial.Icon.cmd_rss;
case UNREAD:
return GoogleMaterial.Icon.gmd_markunread_mailbox;
case TRASH:
return GoogleMaterial.Icon.gmd_delete;
default:
return CommunityMaterial.Icon.cmd_label;
}
}
@ColorInt
public static int getColor(Label label) {
if (label.getType() == null) {
return label.getColor();
}
return 0xFF000000;
}
}

View File

@ -9,6 +9,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
android:focusableInTouchMode="true" android:focusableInTouchMode="true"
android:paddingBottom="64dp"
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
@ -24,7 +25,7 @@
android:padding="16dp" android:padding="16dp"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge"
tools:ignore="UnusedAttribute" tools:ignore="UnusedAttribute"
tools:text="Subject"/> tools:text="Subject" />
<ImageView <ImageView
android:id="@+id/status" android:id="@+id/status"
@ -32,17 +33,17 @@
android:layout_height="60dp" android:layout_height="60dp"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:tint="@color/colorAccent"
tools:src="@drawable/ic_notification_proof_of_work"
android:padding="16dp" android:padding="16dp"
tools:ignore="ContentDescription"/> android:tint="@color/colorAccent"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_notification_proof_of_work" />
<View <View
android:id="@+id/divider" android:id="@+id/divider"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_below="@id/subject" android:layout_below="@id/subject"
android:background="@color/divider"/> android:background="@color/divider" />
<ImageView <ImageView
android:id="@+id/avatar" android:id="@+id/avatar"
@ -52,7 +53,7 @@
android:layout_below="@+id/divider" android:layout_below="@+id/divider"
android:layout_margin="16dp" android:layout_margin="16dp"
android:src="@color/colorAccent" android:src="@color/colorAccent"
tools:ignore="ContentDescription"/> tools:ignore="ContentDescription" />
<TextView <TextView
android:id="@+id/sender" android:id="@+id/sender"
@ -64,7 +65,7 @@
android:paddingLeft="8dp" android:paddingLeft="8dp"
android:paddingRight="8dp" android:paddingRight="8dp"
android:textStyle="bold" android:textStyle="bold"
tools:text="Sender"/> tools:text="Sender" />
<TextView <TextView
android:id="@+id/recipient" android:id="@+id/recipient"
@ -75,7 +76,7 @@
android:gravity="center_vertical" android:gravity="center_vertical"
android:paddingLeft="8dp" android:paddingLeft="8dp"
android:paddingRight="8dp" android:paddingRight="8dp"
tools:text="Recipient"/> tools:text="Recipient" />
<TextView <TextView
android:id="@+id/text" android:id="@+id/text"
@ -86,8 +87,16 @@
android:layout_marginLeft="16dp" android:layout_marginLeft="16dp"
android:layout_marginRight="16dp" android:layout_marginRight="16dp"
android:layout_marginTop="32dp" android:layout_marginTop="32dp"
android:paddingBottom="64dp" android:paddingBottom="16dp"
android:text="New Text" android:text="New Text"
android:textIsSelectable="true"/> android:textIsSelectable="true" />
<android.support.v7.widget.RecyclerView
android:id="@+id/labels"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/text"
android:paddingEnd="16dp"
android:paddingStart="16dp" />
</RelativeLayout> </RelativeLayout>
</ScrollView> </ScrollView>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<com.mikepenz.iconics.view.IconicsImageView
android:id="@+id/icon"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
app:iiv_color="@android:color/black"
app:iiv_icon="cmd-label" />
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="8dp"
android:paddingEnd="24dp"
tools:text="Label"
android:layout_alignParentTop="true"
android:layout_toEndOf="@+id/icon" />
</RelativeLayout>