mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-22 23:59:54 +01:00
New List of Forums
The adapter of the `ForumListFragment` has been changed into a `BriarRecyclerView` and all its code has been adapted and simplified accordingly. All UI of the forum list is now defined in XML layouts.
This commit is contained in:
@@ -24,6 +24,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerInParent="true"
|
android:layout_centerInParent="true"
|
||||||
|
android:padding="@dimen/margin_activity_horizontal"
|
||||||
android:textSize="@dimen/text_size_large"
|
android:textSize="@dimen/text_size_large"
|
||||||
android:text="@string/no_data"/>
|
android:text="@string/no_data"/>
|
||||||
|
|
||||||
|
|||||||
6
briar-android/res/layout/fragment_forum_list.xml
Normal file
6
briar-android/res/layout/fragment_forum_list.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<org.briarproject.android.util.BriarRecyclerView
|
||||||
|
android:id="@+id/forumList"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"/>
|
||||||
56
briar-android/res/layout/list_item_forum.xml
Normal file
56
briar-android/res/layout/list_item_forum.xml
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<?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:layout_marginLeft="@dimen/listitem_horizontal_margin"
|
||||||
|
android:layout_marginStart="@dimen/listitem_horizontal_margin"
|
||||||
|
android:paddingTop="@dimen/listitem_horizontal_margin"
|
||||||
|
android:background="?attr/selectableItemBackground">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/forumNameView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:textColor="@color/briar_text_primary"
|
||||||
|
android:textSize="@dimen/text_size_medium"
|
||||||
|
tools:text="This is a name of a forum"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/unreadView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_below="@+id/forumNameView"
|
||||||
|
android:layout_toLeftOf="@+id/dateView"
|
||||||
|
android:paddingTop="@dimen/margin_medium"
|
||||||
|
android:paddingBottom="@dimen/listitem_horizontal_margin"
|
||||||
|
android:textColor="@color/briar_text_secondary"
|
||||||
|
android:textSize="@dimen/text_size_small"
|
||||||
|
android:text="@string/no_unread_posts"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/dateView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_below="@+id/forumNameView"
|
||||||
|
android:paddingTop="@dimen/margin_medium"
|
||||||
|
android:paddingBottom="@dimen/listitem_horizontal_margin"
|
||||||
|
android:layout_marginRight="@dimen/listitem_horizontal_margin"
|
||||||
|
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
|
||||||
|
android:textColor="@color/briar_text_secondary"
|
||||||
|
android:textSize="@dimen/text_size_small"
|
||||||
|
tools:text="Dec 24"/>
|
||||||
|
|
||||||
|
<View style="@style/Divider.ForumList"
|
||||||
|
android:layout_below="@+id/unreadView"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_alignParentStart="true"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
<string name="private_message_hint">Type message</string>
|
<string name="private_message_hint">Type message</string>
|
||||||
<string name="message_sent_toast">Message sent</string>
|
<string name="message_sent_toast">Message sent</string>
|
||||||
<string name="forums_title">Forums</string>
|
<string name="forums_title">Forums</string>
|
||||||
<string name="no_forums">No forums</string>
|
<string name="no_forums">You don\'t have any forums.\n\nWhy don\'t you create a new one yourself or ask your contacts to share one with you?</string>
|
||||||
<plurals name="forums_shared">
|
<plurals name="forums_shared">
|
||||||
<item quantity="one">%d forum shared by contacts</item>
|
<item quantity="one">%d forum shared by contacts</item>
|
||||||
<item quantity="other">%d forums shared by contacts</item>
|
<item quantity="other">%d forums shared by contacts</item>
|
||||||
@@ -81,6 +81,11 @@
|
|||||||
<string name="forum_leave">Leave Forum</string>
|
<string name="forum_leave">Leave Forum</string>
|
||||||
<string name="forum_left_toast">Left Forum</string>
|
<string name="forum_left_toast">Left Forum</string>
|
||||||
<string name="no_forum_posts">No posts</string>
|
<string name="no_forum_posts">No posts</string>
|
||||||
|
<string name="no_unread_posts">no unread posts</string>
|
||||||
|
<plurals name="unread_posts">
|
||||||
|
<item quantity="one">%d unread post</item>
|
||||||
|
<item quantity="other">%d unread posts</item>
|
||||||
|
</plurals>
|
||||||
<string name="create_forum_title">New Forum</string>
|
<string name="create_forum_title">New Forum</string>
|
||||||
<string name="choose_forum_name">Choose a name for your forum:</string>
|
<string name="choose_forum_name">Choose a name for your forum:</string>
|
||||||
<string name="create_forum_button">Create Forum</string>
|
<string name="create_forum_button">Create Forum</string>
|
||||||
|
|||||||
@@ -107,6 +107,11 @@
|
|||||||
<item name="android:layout_marginLeft">@dimen/margin_large</item>
|
<item name="android:layout_marginLeft">@dimen/margin_large</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="Divider.ForumList" parent="Divider">
|
||||||
|
<item name="android:layout_width">match_parent</item>
|
||||||
|
<item name="android:layout_height">1dp</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
<style name="NavMenuButton" parent="Widget.AppCompat.Button.Borderless.Colored">
|
<style name="NavMenuButton" parent="Widget.AppCompat.Button.Borderless.Colored">
|
||||||
<item name="android:textSize">@dimen/text_size_medium</item>
|
<item name="android:textSize">@dimen/text_size_medium</item>
|
||||||
<item name="android:textColor">@android:color/tertiary_text_light</item>
|
<item name="android:textColor">@android:color/tertiary_text_light</item>
|
||||||
|
|||||||
@@ -1,70 +1,193 @@
|
|||||||
package org.briarproject.android.forum;
|
package org.briarproject.android.forum;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.Intent;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
|
import android.support.v7.util.SortedList;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.briarproject.android.util.LayoutUtils;
|
import org.briarproject.api.forum.Forum;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.Collection;
|
||||||
|
|
||||||
import static android.text.TextUtils.TruncateAt.END;
|
import static org.briarproject.android.BriarActivity.GROUP_ID;
|
||||||
import static android.widget.LinearLayout.HORIZONTAL;
|
import static org.briarproject.android.forum.ForumActivity.FORUM_NAME;
|
||||||
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP_1;
|
|
||||||
|
|
||||||
public class ForumListAdapter extends ArrayAdapter<ForumListItem> {
|
public class ForumListAdapter extends
|
||||||
|
RecyclerView.Adapter<ForumListAdapter.ForumViewHolder> {
|
||||||
|
|
||||||
private final int pad;
|
private SortedList<ForumListItem> forums = new SortedList<>(
|
||||||
|
ForumListItem.class, new SortedList.Callback<ForumListItem>() {
|
||||||
|
@Override
|
||||||
|
public int compare(ForumListItem a, ForumListItem b) {
|
||||||
|
if (a == b) return 0;
|
||||||
|
// The forum with the newest message comes first
|
||||||
|
long aTime = a.getTimestamp(), bTime = b.getTimestamp();
|
||||||
|
if (aTime > bTime) return -1;
|
||||||
|
if (aTime < bTime) return 1;
|
||||||
|
// Break ties by forum name
|
||||||
|
String aName = a.getForum().getName();
|
||||||
|
String bName = b.getForum().getName();
|
||||||
|
return String.CASE_INSENSITIVE_ORDER.compare(aName, bName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInserted(int position, int count) {
|
||||||
|
notifyItemRangeInserted(position, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRemoved(int position, int count) {
|
||||||
|
notifyItemRangeRemoved(position, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMoved(int fromPosition, int toPosition) {
|
||||||
|
notifyItemMoved(fromPosition, toPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onChanged(int position, int count) {
|
||||||
|
notifyItemRangeChanged(position, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean areContentsTheSame(ForumListItem a, ForumListItem b) {
|
||||||
|
return a.getForum().equals(b.getForum()) &&
|
||||||
|
a.getTimestamp() == b.getTimestamp() &&
|
||||||
|
a.getUnreadCount() == b.getUnreadCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean areItemsTheSame(ForumListItem a, ForumListItem b) {
|
||||||
|
return a.getForum().equals(b.getForum());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
private final Context ctx;
|
||||||
|
|
||||||
public ForumListAdapter(Context ctx) {
|
public ForumListAdapter(Context ctx) {
|
||||||
super(ctx, android.R.layout.simple_expandable_list_item_1,
|
this.ctx = ctx;
|
||||||
new ArrayList<ForumListItem>());
|
|
||||||
pad = LayoutUtils.getPadding(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
public ForumViewHolder onCreateViewHolder(ViewGroup parent,
|
||||||
ForumListItem item = getItem(position);
|
int viewType) {
|
||||||
Context ctx = getContext();
|
|
||||||
Resources res = ctx.getResources();
|
|
||||||
|
|
||||||
LinearLayout layout = new LinearLayout(ctx);
|
View v = LayoutInflater.from(ctx)
|
||||||
layout.setOrientation(HORIZONTAL);
|
.inflate(R.layout.list_item_forum, parent, false);
|
||||||
|
return new ForumViewHolder(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(ForumViewHolder ui, int position) {
|
||||||
|
final ForumListItem item = getItem(position);
|
||||||
|
|
||||||
|
// TODO add avatar. See #337
|
||||||
|
|
||||||
|
// Forum Name
|
||||||
|
ui.name.setText(item.getForum().getName());
|
||||||
|
|
||||||
|
// Unread Count
|
||||||
int unread = item.getUnreadCount();
|
int unread = item.getUnreadCount();
|
||||||
if (unread > 0)
|
if (unread > 0) {
|
||||||
layout.setBackgroundColor(res.getColor(R.color.unread_background));
|
ui.unread.setText(ctx.getResources()
|
||||||
|
.getQuantityString(R.plurals.unread_posts, unread, unread));
|
||||||
TextView name = new TextView(ctx);
|
ui.unread.setTextColor(
|
||||||
name.setLayoutParams(WRAP_WRAP_1);
|
ContextCompat.getColor(ctx, R.color.briar_button_positive));
|
||||||
name.setTextSize(18);
|
|
||||||
name.setSingleLine();
|
|
||||||
name.setEllipsize(END);
|
|
||||||
name.setPadding(pad, pad, pad, pad);
|
|
||||||
String forumName = item.getForum().getName();
|
|
||||||
if (unread > 0) name.setText(forumName + " (" + unread + ")");
|
|
||||||
else name.setText(forumName);
|
|
||||||
layout.addView(name);
|
|
||||||
|
|
||||||
if (item.isEmpty()) {
|
|
||||||
TextView noPosts = new TextView(ctx);
|
|
||||||
noPosts.setPadding(pad, 0, pad, pad);
|
|
||||||
noPosts.setTextColor(res.getColor(R.color.no_posts));
|
|
||||||
noPosts.setText(R.string.no_forum_posts);
|
|
||||||
layout.addView(noPosts);
|
|
||||||
} else {
|
} else {
|
||||||
TextView date = new TextView(ctx);
|
ui.unread.setText(ctx.getString(R.string.no_unread_posts));
|
||||||
date.setPadding(pad, 0, pad, pad);
|
ui.unread.setTextColor(
|
||||||
long timestamp = item.getTimestamp();
|
ContextCompat.getColor(ctx, R.color.briar_text_secondary));
|
||||||
date.setText(DateUtils.getRelativeTimeSpanString(ctx, timestamp));
|
|
||||||
layout.addView(date);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return layout;
|
// Date or "No Posts"
|
||||||
|
if (item.isEmpty()) {
|
||||||
|
ui.date.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
long timestamp = item.getTimestamp();
|
||||||
|
ui.date.setText(
|
||||||
|
DateUtils.getRelativeTimeSpanString(ctx, timestamp));
|
||||||
|
ui.date.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open Forum on Click
|
||||||
|
ui.layout.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent i = new Intent(ctx, ForumActivity.class);
|
||||||
|
Forum f = item.getForum();
|
||||||
|
i.putExtra(GROUP_ID, f.getId().getBytes());
|
||||||
|
i.putExtra(FORUM_NAME, f.getName());
|
||||||
|
ctx.startActivity(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return forums.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ForumListItem getItem(int position) {
|
||||||
|
return forums.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public ForumListItem getItem(GroupId g) {
|
||||||
|
for (int i = 0; i < forums.size(); i++) {
|
||||||
|
ForumListItem item = forums.get(i);
|
||||||
|
if (item.getForum().getGroup().getId().equals(g)) {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAll(Collection<ForumListItem> items) {
|
||||||
|
forums.addAll(items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateItem(ForumListItem item) {
|
||||||
|
ForumListItem oldItem = getItem(item.getForum().getGroup().getId());
|
||||||
|
int position = forums.indexOf(oldItem);
|
||||||
|
forums.updateItemAt(position, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(ForumListItem item) {
|
||||||
|
forums.remove(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
forums.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return forums.size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static class ForumViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
|
public final ViewGroup layout;
|
||||||
|
public final TextView name;
|
||||||
|
public final TextView unread;
|
||||||
|
public final TextView date;
|
||||||
|
|
||||||
|
public ForumViewHolder(View v) {
|
||||||
|
super(v);
|
||||||
|
|
||||||
|
layout = (ViewGroup) v;
|
||||||
|
name = (TextView) v.findViewById(R.id.forumNameView);
|
||||||
|
unread = (TextView) v.findViewById(R.id.unreadView);
|
||||||
|
date = (TextView) v.findViewById(R.id.dateView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,25 +5,23 @@ import android.os.Bundle;
|
|||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.design.widget.Snackbar;
|
import android.support.design.widget.Snackbar;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.briarproject.android.AndroidComponent;
|
import org.briarproject.android.AndroidComponent;
|
||||||
import org.briarproject.android.fragment.BaseEventFragment;
|
import org.briarproject.android.fragment.BaseEventFragment;
|
||||||
import org.briarproject.android.util.ListLoadingProgressBar;
|
import org.briarproject.android.util.BriarRecyclerView;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.db.NoSuchGroupException;
|
import org.briarproject.api.db.NoSuchGroupException;
|
||||||
import org.briarproject.api.event.ContactRemovedEvent;
|
import org.briarproject.api.event.ContactRemovedEvent;
|
||||||
import org.briarproject.api.event.Event;
|
import org.briarproject.api.event.Event;
|
||||||
|
import org.briarproject.api.event.ForumInvitationReceivedEvent;
|
||||||
import org.briarproject.api.event.GroupAddedEvent;
|
import org.briarproject.api.event.GroupAddedEvent;
|
||||||
import org.briarproject.api.event.GroupRemovedEvent;
|
import org.briarproject.api.event.GroupRemovedEvent;
|
||||||
import org.briarproject.api.event.MessageValidatedEvent;
|
import org.briarproject.api.event.MessageValidatedEvent;
|
||||||
@@ -34,26 +32,18 @@ import org.briarproject.api.forum.ForumSharingManager;
|
|||||||
import org.briarproject.api.sync.ClientId;
|
import org.briarproject.api.sync.ClientId;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static android.support.design.widget.Snackbar.LENGTH_INDEFINITE;
|
import static android.support.design.widget.Snackbar.LENGTH_INDEFINITE;
|
||||||
import static android.view.Gravity.CENTER;
|
|
||||||
import static android.view.Gravity.CENTER_HORIZONTAL;
|
|
||||||
import static android.view.View.GONE;
|
|
||||||
import static android.view.View.VISIBLE;
|
|
||||||
import static android.widget.LinearLayout.VERTICAL;
|
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static org.briarproject.android.BriarActivity.GROUP_ID;
|
|
||||||
import static org.briarproject.android.forum.ForumActivity.FORUM_NAME;
|
|
||||||
import static org.briarproject.android.util.CommonLayoutParams.MATCH_MATCH;
|
|
||||||
import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP_1;
|
|
||||||
|
|
||||||
public class ForumListFragment extends BaseEventFragment implements
|
public class ForumListFragment extends BaseEventFragment implements
|
||||||
AdapterView.OnItemClickListener, View.OnClickListener {
|
View.OnClickListener {
|
||||||
|
|
||||||
public final static String TAG = "ForumListFragment";
|
public final static String TAG = "ForumListFragment";
|
||||||
|
|
||||||
@@ -69,10 +59,8 @@ public class ForumListFragment extends BaseEventFragment implements
|
|||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TextView empty = null;
|
private BriarRecyclerView list;
|
||||||
private ForumListAdapter adapter = null;
|
private ForumListAdapter adapter;
|
||||||
private ListView list = null;
|
|
||||||
private ListLoadingProgressBar loading = null;
|
|
||||||
private Snackbar snackbar;
|
private Snackbar snackbar;
|
||||||
|
|
||||||
// Fields that are accessed from background threads must be volatile
|
// Fields that are accessed from background threads must be volatile
|
||||||
@@ -86,32 +74,24 @@ public class ForumListFragment extends BaseEventFragment implements
|
|||||||
|
|
||||||
setHasOptionsMenu(true);
|
setHasOptionsMenu(true);
|
||||||
|
|
||||||
LinearLayout layout = new LinearLayout(getContext());
|
View contentView =
|
||||||
layout.setLayoutParams(MATCH_MATCH);
|
inflater.inflate(R.layout.fragment_forum_list, container,
|
||||||
layout.setOrientation(VERTICAL);
|
false);
|
||||||
layout.setGravity(CENTER_HORIZONTAL);
|
|
||||||
|
|
||||||
empty = new TextView(getContext());
|
adapter = new ForumListAdapter(getActivity());
|
||||||
empty.setLayoutParams(MATCH_WRAP_1);
|
|
||||||
empty.setGravity(CENTER);
|
|
||||||
empty.setTextSize(18);
|
|
||||||
empty.setText(R.string.no_forums);
|
|
||||||
empty.setVisibility(GONE);
|
|
||||||
layout.addView(empty);
|
|
||||||
|
|
||||||
adapter = new ForumListAdapter(getContext());
|
list = (BriarRecyclerView) contentView.findViewById(R.id.forumList);
|
||||||
list = new ListView(getContext());
|
list.setLayoutManager(new LinearLayoutManager(getActivity()));
|
||||||
list.setLayoutParams(MATCH_WRAP_1);
|
|
||||||
list.setAdapter(adapter);
|
list.setAdapter(adapter);
|
||||||
list.setOnItemClickListener(this);
|
list.setEmptyText(getString(R.string.no_forums));
|
||||||
list.setVisibility(GONE);
|
|
||||||
layout.addView(list);
|
|
||||||
|
|
||||||
// Show a progress bar while the list is loading
|
snackbar = Snackbar.make(contentView, "", LENGTH_INDEFINITE);
|
||||||
loading = new ListLoadingProgressBar(getContext());
|
snackbar.getView().setBackgroundResource(R.color.briar_primary);
|
||||||
layout.addView(loading);
|
snackbar.setAction(R.string.show_forums, this);
|
||||||
|
snackbar.setActionTextColor(ContextCompat
|
||||||
|
.getColor(getContext(), R.color.briar_button_positive));
|
||||||
|
|
||||||
return layout;
|
return contentView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -128,13 +108,15 @@ public class ForumListFragment extends BaseEventFragment implements
|
|||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
snackbar = Snackbar.make(getView(), "", LENGTH_INDEFINITE);
|
loadForumHeaders();
|
||||||
snackbar.getView().setBackgroundResource(R.color.briar_primary);
|
loadAvailableForums();
|
||||||
snackbar.setAction(R.string.show_forums, this);
|
}
|
||||||
snackbar.setActionTextColor(ContextCompat
|
|
||||||
.getColor(getContext(), R.color.briar_button_positive));
|
|
||||||
|
|
||||||
loadHeaders();
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
|
||||||
|
adapter.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -157,30 +139,26 @@ public class ForumListFragment extends BaseEventFragment implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadHeaders() {
|
private void loadForumHeaders() {
|
||||||
clearHeaders();
|
|
||||||
listener.runOnDbThread(new Runnable() {
|
listener.runOnDbThread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
|
// load forums
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
boolean displayedHeaders = false;
|
Collection<ForumListItem> forums = new ArrayList<>();
|
||||||
for (Forum f : forumManager.getForums()) {
|
for (Forum f : forumManager.getForums()) {
|
||||||
try {
|
try {
|
||||||
Collection<ForumPostHeader> headers =
|
Collection<ForumPostHeader> headers =
|
||||||
forumManager.getPostHeaders(f.getId());
|
forumManager.getPostHeaders(f.getId());
|
||||||
displayHeaders(f, headers);
|
forums.add(new ForumListItem(f, headers));
|
||||||
displayedHeaders = true;
|
|
||||||
} catch (NoSuchGroupException e) {
|
} catch (NoSuchGroupException e) {
|
||||||
// Continue
|
// Continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int available =
|
displayForumHeaders(forums);
|
||||||
forumSharingManager.getAvailableForums().size();
|
|
||||||
long duration = System.currentTimeMillis() - now;
|
long duration = System.currentTimeMillis() - now;
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Full load took " + duration + " ms");
|
LOG.info("Full load took " + duration + " ms");
|
||||||
if (!displayedHeaders) displayEmpty();
|
|
||||||
displayAvailable(available);
|
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
if (LOG.isLoggable(WARNING))
|
if (LOG.isLoggable(WARNING))
|
||||||
LOG.log(WARNING, e.toString(), e);
|
LOG.log(WARNING, e.toString(), e);
|
||||||
@@ -189,45 +167,35 @@ public class ForumListFragment extends BaseEventFragment implements
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearHeaders() {
|
private void displayForumHeaders(final Collection<ForumListItem> forums) {
|
||||||
listener.runOnUiThread(new Runnable() {
|
listener.runOnUiThread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
empty.setVisibility(GONE);
|
if (forums.size() > 0) adapter.addAll(forums);
|
||||||
list.setVisibility(GONE);
|
else list.showData();
|
||||||
snackbar.dismiss();
|
|
||||||
loading.setVisibility(VISIBLE);
|
|
||||||
adapter.clear();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayHeaders(final Forum f,
|
private void loadAvailableForums() {
|
||||||
final Collection<ForumPostHeader> headers) {
|
listener.runOnDbThread(new Runnable() {
|
||||||
listener.runOnUiThread(new Runnable() {
|
|
||||||
public void run() {
|
public void run() {
|
||||||
list.setVisibility(VISIBLE);
|
try {
|
||||||
loading.setVisibility(GONE);
|
long now = System.currentTimeMillis();
|
||||||
// Remove the old item, if any
|
int available =
|
||||||
ForumListItem item = findForum(f.getId());
|
forumSharingManager.getAvailableForums().size();
|
||||||
if (item != null) adapter.remove(item);
|
long duration = System.currentTimeMillis() - now;
|
||||||
// Add a new item
|
if (LOG.isLoggable(INFO))
|
||||||
adapter.add(new ForumListItem(f, headers));
|
LOG.info("Loading available took " + duration + " ms");
|
||||||
adapter.sort(ForumListItemComparator.INSTANCE);
|
displayAvailableForums(available);
|
||||||
selectFirstUnread();
|
} catch (DbException e) {
|
||||||
|
if (LOG.isLoggable(WARNING))
|
||||||
|
LOG.log(WARNING, e.toString(), e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayEmpty() {
|
private void displayAvailableForums(final int availableCount) {
|
||||||
listener.runOnUiThread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
empty.setVisibility(VISIBLE);
|
|
||||||
loading.setVisibility(GONE);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void displayAvailable(final int availableCount) {
|
|
||||||
listener.runOnUiThread(new Runnable() {
|
listener.runOnUiThread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
if (availableCount == 0) {
|
if (availableCount == 0) {
|
||||||
@@ -242,42 +210,21 @@ public class ForumListFragment extends BaseEventFragment implements
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private ForumListItem findForum(GroupId g) {
|
|
||||||
int count = adapter.getCount();
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
ForumListItem item = adapter.getItem(i);
|
|
||||||
if (item.getForum().getId().equals(g)) return item;
|
|
||||||
}
|
|
||||||
return null; // Not found
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectFirstUnread() {
|
|
||||||
int firstUnread = -1, count = adapter.getCount();
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
if (adapter.getItem(i).getUnreadCount() > 0) {
|
|
||||||
firstUnread = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (firstUnread == -1) list.setSelection(count - 1);
|
|
||||||
else list.setSelection(firstUnread);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void eventOccurred(Event e) {
|
public void eventOccurred(Event e) {
|
||||||
if (e instanceof ContactRemovedEvent) {
|
if (e instanceof ContactRemovedEvent) {
|
||||||
LOG.info("Contact removed, reloading");
|
LOG.info("Contact removed, reloading available forums");
|
||||||
loadAvailable();
|
loadAvailableForums();
|
||||||
} else if (e instanceof GroupAddedEvent) {
|
} else if (e instanceof GroupAddedEvent) {
|
||||||
GroupAddedEvent g = (GroupAddedEvent) e;
|
GroupAddedEvent g = (GroupAddedEvent) e;
|
||||||
if (g.getGroup().getClientId().equals(forumManager.getClientId())) {
|
if (g.getGroup().getClientId().equals(forumManager.getClientId())) {
|
||||||
LOG.info("Forum added, reloading");
|
LOG.info("Forum added, reloading forums");
|
||||||
loadHeaders();
|
loadForumHeaders();
|
||||||
}
|
}
|
||||||
} else if (e instanceof GroupRemovedEvent) {
|
} else if (e instanceof GroupRemovedEvent) {
|
||||||
GroupRemovedEvent g = (GroupRemovedEvent) e;
|
GroupRemovedEvent g = (GroupRemovedEvent) e;
|
||||||
if (g.getGroup().getClientId().equals(forumManager.getClientId())) {
|
if (g.getGroup().getClientId().equals(forumManager.getClientId())) {
|
||||||
LOG.info("Forum removed, reloading");
|
LOG.info("Forum removed, removing from list");
|
||||||
loadHeaders();
|
removeForum(g.getGroup().getId());
|
||||||
}
|
}
|
||||||
} else if (e instanceof MessageValidatedEvent) {
|
} else if (e instanceof MessageValidatedEvent) {
|
||||||
MessageValidatedEvent m = (MessageValidatedEvent) e;
|
MessageValidatedEvent m = (MessageValidatedEvent) e;
|
||||||
@@ -285,17 +232,15 @@ public class ForumListFragment extends BaseEventFragment implements
|
|||||||
ClientId c = m.getClientId();
|
ClientId c = m.getClientId();
|
||||||
if (c.equals(forumManager.getClientId())) {
|
if (c.equals(forumManager.getClientId())) {
|
||||||
LOG.info("Forum post added, reloading");
|
LOG.info("Forum post added, reloading");
|
||||||
loadHeaders(m.getMessage().getGroupId());
|
loadForumHeaders(m.getMessage().getGroupId());
|
||||||
} else if (!m.isLocal()
|
|
||||||
&& c.equals(forumSharingManager.getClientId())) {
|
|
||||||
LOG.info("Available forums updated, reloading");
|
|
||||||
loadAvailable();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (e instanceof ForumInvitationReceivedEvent) {
|
||||||
|
loadAvailableForums();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadHeaders(final GroupId g) {
|
private void loadForumHeaders(final GroupId g) {
|
||||||
listener.runOnDbThread(new Runnable() {
|
listener.runOnDbThread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
@@ -306,9 +251,7 @@ public class ForumListFragment extends BaseEventFragment implements
|
|||||||
long duration = System.currentTimeMillis() - now;
|
long duration = System.currentTimeMillis() - now;
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Partial load took " + duration + " ms");
|
LOG.info("Partial load took " + duration + " ms");
|
||||||
displayHeaders(f, headers);
|
updateForum(new ForumListItem(f, headers));
|
||||||
} catch (NoSuchGroupException e) {
|
|
||||||
removeForum(g);
|
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
if (LOG.isLoggable(WARNING))
|
if (LOG.isLoggable(WARNING))
|
||||||
LOG.log(WARNING, e.toString(), e);
|
LOG.log(WARNING, e.toString(), e);
|
||||||
@@ -317,38 +260,21 @@ public class ForumListFragment extends BaseEventFragment implements
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateForum(final ForumListItem item) {
|
||||||
|
listener.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
adapter.updateItem(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void removeForum(final GroupId g) {
|
private void removeForum(final GroupId g) {
|
||||||
listener.runOnUiThread(new Runnable() {
|
listener.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
ForumListItem item = findForum(g);
|
ForumListItem item = adapter.getItem(g);
|
||||||
if (item != null) {
|
if (item != null) adapter.remove(item);
|
||||||
adapter.remove(item);
|
|
||||||
if (adapter.isEmpty()) {
|
|
||||||
empty.setVisibility(VISIBLE);
|
|
||||||
list.setVisibility(GONE);
|
|
||||||
} else {
|
|
||||||
selectFirstUnread();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadAvailable() {
|
|
||||||
listener.runOnDbThread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
int available =
|
|
||||||
forumSharingManager.getAvailableForums().size();
|
|
||||||
long duration = System.currentTimeMillis() - now;
|
|
||||||
if (LOG.isLoggable(INFO))
|
|
||||||
LOG.info("Loading available took " + duration + " ms");
|
|
||||||
displayAvailable(available);
|
|
||||||
} catch (DbException e) {
|
|
||||||
if (LOG.isLoggable(WARNING))
|
|
||||||
LOG.log(WARNING, e.toString(), e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -358,13 +284,4 @@ public class ForumListFragment extends BaseEventFragment implements
|
|||||||
startActivity(new Intent(getContext(), AvailableForumsActivity.class));
|
startActivity(new Intent(getContext(), AvailableForumsActivity.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onItemClick(AdapterView<?> parent, View view, int position,
|
|
||||||
long id) {
|
|
||||||
Intent i = new Intent(getContext(), ForumActivity.class);
|
|
||||||
Forum f = adapter.getItem(position).getForum();
|
|
||||||
i.putExtra(GROUP_ID, f.getId().getBytes());
|
|
||||||
i.putExtra(FORUM_NAME, f.getName());
|
|
||||||
startActivity(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
package org.briarproject.android.forum;
|
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
public class ForumListItemComparator implements Comparator<ForumListItem> {
|
|
||||||
|
|
||||||
public static final ForumListItemComparator INSTANCE =
|
|
||||||
new ForumListItemComparator();
|
|
||||||
|
|
||||||
public int compare(ForumListItem a, ForumListItem b) {
|
|
||||||
if (a == b) return 0;
|
|
||||||
// The forum with the newest message comes first
|
|
||||||
long aTime = a.getTimestamp(), bTime = b.getTimestamp();
|
|
||||||
if (aTime > bTime) return -1;
|
|
||||||
if (aTime < bTime) return 1;
|
|
||||||
// Break ties by forum name
|
|
||||||
String aName = a.getForum().getName();
|
|
||||||
String bName = b.getForum().getName();
|
|
||||||
return String.CASE_INSENSITIVE_ORDER.compare(aName, bName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user