smartlist: add progress indicator
- Rename to SmartList to match all clients convention.
- Separate SmartListAdapter from its fragment.
Change-Id: Ia696d351092419f6132a19816d775c18a95b2007
Tuleap: #468
diff --git a/ring-android/app/src/main/java/cx/ring/adapters/SmartListAdapter.java b/ring-android/app/src/main/java/cx/ring/adapters/SmartListAdapter.java
new file mode 100644
index 0000000..5f35ed4
--- /dev/null
+++ b/ring-android/app/src/main/java/cx/ring/adapters/SmartListAdapter.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2004-2016 Savoir-faire Linux Inc.
+ *
+ * Authors: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
+ * Romain Bertozzi <romain.bertozzi@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package cx.ring.adapters;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Typeface;
+import android.text.format.DateUtils;
+import android.util.Log;
+import android.util.LruCache;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AnimationUtils;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.concurrent.ExecutorService;
+
+import cx.ring.R;
+import cx.ring.model.Conversation;
+
+public class SmartListAdapter extends BaseAdapter {
+ private static String TAG = SmartListAdapter.class.getSimpleName();
+
+ final private ArrayList<Conversation> mCalls = new ArrayList<>();
+ final private ExecutorService mInfosFetcher;
+ final private LruCache<Long, Bitmap> mMemoryCache;
+ final private HashMap<Long, WeakReference<ContactPictureTask>> mRunningTasks = new HashMap<>();
+
+ final private Context mContext;
+
+ public SmartListAdapter(Context act, LruCache<Long, Bitmap> cache, ExecutorService pool) {
+ super();
+ mContext = act;
+ mMemoryCache = cache;
+ mInfosFetcher = pool;
+ }
+
+ public void updateDataset(final Collection<Conversation> list) {
+ Log.i(TAG, "updateDataset " + list.size());
+
+ if (list.size() == 0 && mCalls.size() == 0) {
+ return;
+ }
+
+ mCalls.clear();
+ for (Conversation c : list) {
+ if (!c.getContact().isUnknown() || !c.getAccountsUsed().isEmpty() || c.getCurrentCall() != null)
+ mCalls.add(c);
+ }
+
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return mCalls.size();
+ }
+
+ @Override
+ public Conversation getItem(int position) {
+ return mCalls.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return 0;
+ }
+
+ public class ViewHolder {
+ TextView conv_participants;
+ TextView conv_status;
+ TextView conv_time;
+ ImageView photo;
+ int position;
+ public Conversation conv;
+ }
+
+ @Override
+ public View getView(final int position, View convertView, ViewGroup parent) {
+ if (convertView == null)
+ convertView = LayoutInflater.from(mContext).inflate(cx.ring.R.layout.item_calllist, null);
+
+ ViewHolder holder = (ViewHolder) convertView.getTag();
+ if (holder == null) {
+ holder = new ViewHolder();
+ holder.photo = (ImageView) convertView.findViewById(R.id.photo);
+ holder.conv_participants = (TextView) convertView.findViewById(R.id.conv_participant);
+ holder.conv_status = (TextView) convertView.findViewById(R.id.conv_last_item);
+ holder.conv_time = (TextView) convertView.findViewById(R.id.conv_last_time);
+ holder.position = -1;
+ convertView.setTag(holder);
+ }
+ final ViewHolder h = holder;
+ h.conv = mCalls.get(position);
+ h.position = position;
+ h.conv_participants.setText(h.conv.getContact().getDisplayName());
+ long last_interaction = h.conv.getLastInteraction().getTime();
+ h.conv_time.setText(last_interaction == 0 ? "" : DateUtils.getRelativeTimeSpanString(last_interaction, System.currentTimeMillis(), 0L, DateUtils.FORMAT_ABBREV_ALL));
+ h.conv_status.setText(h.conv.getLastInteractionSumary(mContext.getResources()));
+ if (h.conv.hasUnreadTextMessages()) {
+ h.conv_participants.setTypeface(null, Typeface.BOLD);
+ h.conv_time.setTypeface(null, Typeface.BOLD);
+ h.conv_status.setTypeface(null, Typeface.BOLD);
+ } else {
+ h.conv_participants.setTypeface(null, Typeface.NORMAL);
+ h.conv_time.setTypeface(null, Typeface.NORMAL);
+ h.conv_status.setTypeface(null, Typeface.NORMAL);
+ }
+
+ final Long cid = h.conv.getContact().getId();
+ Bitmap bmp = mMemoryCache.get(cid);
+ if (bmp != null) {
+ h.photo.setImageBitmap(bmp);
+ } else {
+ holder.photo.setImageBitmap(mMemoryCache.get(-1l));
+ final WeakReference<ViewHolder> wh = new WeakReference<>(holder);
+ final ContactPictureTask.PictureLoadedCallback cb = new ContactPictureTask.PictureLoadedCallback() {
+ @Override
+ public void onPictureLoaded(final Bitmap bmp) {
+ final ViewHolder fh = wh.get();
+ if (fh == null || fh.photo.getParent() == null)
+ return;
+ if (fh.conv.getContact().getId() == cid) {
+ fh.photo.post(new Runnable() {
+ @Override
+ public void run() {
+ fh.photo.setImageBitmap(bmp);
+ fh.photo.startAnimation(AnimationUtils.loadAnimation(fh.photo.getContext(), R.anim.contact_fadein));
+ }
+ });
+ }
+ }
+ };
+ WeakReference<ContactPictureTask> wtask = mRunningTasks.get(cid);
+ ContactPictureTask task = wtask == null ? null : wtask.get();
+ if (task != null) {
+ task.addCallback(cb);
+ } else {
+ task = new ContactPictureTask(mContext, h.photo, h.conv.getContact(), new ContactPictureTask.PictureLoadedCallback() {
+ @Override
+ public void onPictureLoaded(Bitmap bmp) {
+ mMemoryCache.put(cid, bmp);
+ mRunningTasks.remove(cid);
+ }
+ });
+ task.addCallback(cb);
+ mRunningTasks.put(cid, new WeakReference<>(task));
+ mInfosFetcher.execute(task);
+ }
+ }
+ return convertView;
+ }
+}
diff --git a/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java b/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
index 7260d92..c0f45b4 100644
--- a/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
+++ b/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java
@@ -31,7 +31,7 @@
import cx.ring.R;
import cx.ring.fragments.AboutFragment;
import cx.ring.fragments.AccountsManagementFragment;
-import cx.ring.fragments.CallListFragment;
+import cx.ring.fragments.SmartListFragment;
import cx.ring.fragments.ContactListFragment;
import cx.ring.views.MenuHeaderView;
import cx.ring.fragments.SettingsFragment;
@@ -426,7 +426,7 @@
FragmentManager fm = getFragmentManager();
fContent = fm.findFragmentById(R.id.main_frame);
if (fContent == null) {
- fContent = new CallListFragment();
+ fContent = new SmartListFragment();
fm.beginTransaction().replace(R.id.main_frame, fContent, "Home").addToBackStack("Home").commit();
} else if (fContent instanceof Refreshable) {
fm.beginTransaction().replace(R.id.main_frame, fContent).addToBackStack("Home").commit();
@@ -529,7 +529,7 @@
switch (pos.getItemId()) {
case R.id.menuitem_home:
- if (fContent instanceof CallListFragment)
+ if (fContent instanceof SmartListFragment)
break;
if (getFragmentManager().getBackStackEntryCount() == 1)
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/CallListFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/SmartListFragment.java
similarity index 73%
rename from ring-android/app/src/main/java/cx/ring/fragments/CallListFragment.java
rename to ring-android/app/src/main/java/cx/ring/fragments/SmartListFragment.java
index 1da4b16..a171714 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/CallListFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/SmartListFragment.java
@@ -28,35 +28,37 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.Loader;
-import android.graphics.Bitmap;
-import android.graphics.Typeface;
import android.net.Uri;
-import android.os.*;
+import android.os.Bundle;
+import android.os.RemoteException;
import android.provider.ContactsContract;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
-import android.text.format.DateUtils;
import android.util.Log;
-import android.util.LruCache;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-import android.view.animation.AnimationUtils;
import android.view.inputmethod.EditorInfo;
-import android.widget.*;
+import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
+import android.widget.GridView;
+import android.widget.LinearLayout;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
import cx.ring.R;
-import cx.ring.adapters.ContactPictureTask;
import cx.ring.adapters.ContactsAdapter;
+import cx.ring.adapters.SmartListAdapter;
import cx.ring.adapters.StarredContactsAdapter;
import cx.ring.client.ConversationActivity;
import cx.ring.client.HomeActivity;
@@ -64,22 +66,17 @@
import cx.ring.loaders.LoaderConstants;
import cx.ring.model.CallContact;
import cx.ring.model.Conference;
-import cx.ring.model.Conversation;
import cx.ring.service.LocalService;
import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.concurrent.ExecutorService;
-
-public class CallListFragment extends Fragment implements SearchView.OnQueryTextListener, LoaderManager.LoaderCallbacks<ContactsLoader.Result>, HomeActivity.Refreshable {
-
- private static final String TAG = CallListFragment.class.getSimpleName();
+public class SmartListFragment extends Fragment implements SearchView.OnQueryTextListener,
+ LoaderManager.LoaderCallbacks<ContactsLoader.Result>,
+ HomeActivity.Refreshable
+{
+ private static final String TAG = SmartListFragment.class.getSimpleName();
private LocalService.Callbacks mCallbacks = LocalService.DUMMY_CALLBACKS;
- private CallListAdapter mConferenceAdapter;
+ private SmartListAdapter mSmartListAdapter;
private ContactsAdapter mListAdapter;
private StarredContactsAdapter mGridAdapter;
@@ -91,6 +88,8 @@
private ListView list = null;
private StickyListHeadersListView contactList = null;
+ private View mLoader = null;
+ private TextView mEmptyTextView = null;
private LinearLayout llMain;
private GridView mStarredGrid;
@@ -106,6 +105,7 @@
super.onStart();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(LocalService.ACTION_CONF_UPDATE);
+ intentFilter.addAction(LocalService.ACTION_CONF_LOADED);
intentFilter.addAction(LocalService.ACTION_ACCOUNT_UPDATE);
getActivity().registerReceiver(receiver, intentFilter);
}
@@ -121,6 +121,9 @@
@Override
public void onReceive(Context context, Intent intent) {
Log.w(TAG, "onReceive " + intent.getAction() + " " + intent.getDataString());
+ if (LocalService.ACTION_CONF_LOADED.equals(intent.getAction())) {
+ setLoading(false);
+ }
refresh();
}
};
@@ -146,9 +149,14 @@
Log.e(TAG, "refresh: null service");
return;
}
- if (mConferenceAdapter == null)
+
+ if (mSmartListAdapter == null) {
bindService(getActivity(), service);
- mConferenceAdapter.updateDataset(service.getConversations());
+ }
+ else {
+ mSmartListAdapter.updateDataset(service.getConversations());
+ }
+
if (service.isConnected()) {
error_msg_pane.setVisibility(View.GONE);
} else {
@@ -174,7 +182,6 @@
public void onPause() {
Log.i(TAG, "onPause");
super.onPause();
- //mHandler.removeCallbacks(mUpdateTimeTask);
}
@Override
@@ -200,24 +207,24 @@
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
dialpadMenuItem.setVisible(false);
- list.setAdapter(mConferenceAdapter);
- //listSwitcher.setDisplayedChild(0);
+ list.setAdapter(mSmartListAdapter);
list.setVisibility(View.VISIBLE);
contactList.setAdapter(null);
contactList.setVisibility(View.GONE);
newconv_btn.setVisibility(View.VISIBLE);
+ setLoading(false);
return true;
}
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
dialpadMenuItem.setVisible(true);
contactList.setAdapter(mListAdapter);
- //listSwitcher.setDisplayedChild(1);
contactList.setVisibility(View.VISIBLE);
list.setAdapter(null);
list.setVisibility(View.GONE);
newconv_btn.setVisibility(View.GONE);
onLoadFinished(null, mCallbacks.getService().getSortedContacts());
+ setLoading(false);
return true;
}
});
@@ -302,10 +309,12 @@
}
});
-
list = (ListView) inflatedView.findViewById(cx.ring.R.id.confs_list);
list.setOnItemClickListener(callClickListener);
- //list.setOnItemLongClickListener(mItemLongClickListener);
+
+ this.mEmptyTextView = (TextView) inflatedView.findViewById(R.id.emptyTextView);
+ this.mLoader = inflatedView.findViewById(android.R.id.empty);
+ this.setLoading(true);
mHeader = (LinearLayout) inflater.inflate(R.layout.frag_contact_list_header, null);
contactList = (StickyListHeadersListView) inflatedView.findViewById(R.id.contacts_stickylv);
@@ -349,19 +358,29 @@
contactList.setVisibility(View.GONE);
LocalService service = mCallbacks.getService();
- if (service != null)
+ if (service != null) {
bindService(inflater.getContext(), service);
+ if (service.areConversationsLoaded()) {
+ setLoading(false);
+ }
+ }
return inflatedView;
}
public void bindService(final Context ctx, final LocalService service) {
- mConferenceAdapter = new CallListAdapter(ctx, service.get40dpContactCache(), service.getThreadPool());
- mListAdapter = new ContactsAdapter(ctx, (HomeActivity)getActivity(), service.get40dpContactCache(), service.getThreadPool());
+ mSmartListAdapter = new SmartListAdapter(ctx,
+ service.get40dpContactCache(),
+ service.getThreadPool());
+ mListAdapter = new ContactsAdapter(ctx,
+ (HomeActivity)getActivity(),
+ service.get40dpContactCache(),
+ service.getThreadPool());
mGridAdapter = new StarredContactsAdapter(ctx);
- mConferenceAdapter.updateDataset(service.getConversations());
- list.setAdapter(mConferenceAdapter);
+ mSmartListAdapter.updateDataset(service.getConversations());
+
+ list.setAdapter(mSmartListAdapter);
}
private void startConversation(CallContact c) {
@@ -369,15 +388,13 @@
.setClass(getActivity(), ConversationActivity.class)
.setAction(Intent.ACTION_VIEW)
.setData(Uri.withAppendedPath(ConversationActivity.CONTENT_URI, c.getIds().get(0)));
- //intent.putExtra("resuming", true);
startActivityForResult(intent, HomeActivity.REQUEST_CODE_CONVERSATION);
}
private final OnItemClickListener callClickListener = new OnItemClickListener() {
-
@Override
public void onItemClick(AdapterView<?> arg0, View v, int arg2, long arg3) {
- startConversation(((CallListAdapter.ViewHolder) v.getTag()).conv.getContact());
+ startConversation(((SmartListAdapter.ViewHolder) v.getTag()).conv.getContact());
}
};
@@ -410,7 +427,6 @@
Log.i(TAG, "onLoadFinished with " + data.contacts.size() + " contacts, " + data.starred.size() + " starred.");
mListAdapter.setData(data.contacts);
- //setListViewListeners();
mGridAdapter.setData(data.starred);
if (data.starred.isEmpty()) {
@@ -459,135 +475,6 @@
@Override
public void onLoaderReset(Loader<ContactsLoader.Result> loader) {
-
- }
-
- public class CallListAdapter extends BaseAdapter {
- final private ArrayList<Conversation> calls = new ArrayList<>();
- final private ExecutorService infos_fetcher;
- final private LruCache<Long, Bitmap> mMemoryCache;
- final private HashMap<Long, WeakReference<ContactPictureTask>> running_tasks = new HashMap<>();
-
- final private Context mContext;
-
- public CallListAdapter(Context act, LruCache<Long, Bitmap> cache, ExecutorService pool) {
- super();
- mContext = act;
- mMemoryCache = cache;
- infos_fetcher = pool;
- }
-
- public void updateDataset(final Collection<Conversation> list) {
- Log.i(TAG, "updateDataset " + list.size());
- if (list.size() == 0 && calls.size() == 0)
- return;
- calls.clear();
- for (Conversation c : list) {
- if (!c.getContact().isUnknown() || !c.getAccountsUsed().isEmpty() || c.getCurrentCall() != null)
- calls.add(c);
- }
- notifyDataSetChanged();
- }
-
- @Override
- public int getCount() {
- return calls.size();
- }
-
- @Override
- public Conversation getItem(int position) {
- return calls.get(position);
- }
-
- @Override
- public long getItemId(int position) {
- return 0;
- }
-
- private class ViewHolder {
- TextView conv_participants;
- TextView conv_status;
- TextView conv_time;
- ImageView photo;
- int position;
- Conversation conv;
- }
-
- @Override
- public View getView(final int position, View convertView, ViewGroup parent) {
- if (convertView == null)
- convertView = LayoutInflater.from(mContext).inflate(cx.ring.R.layout.item_calllist, null);
-
- ViewHolder holder = (ViewHolder) convertView.getTag();
- if (holder == null) {
- holder = new ViewHolder();
- holder.photo = (ImageView) convertView.findViewById(R.id.photo);
- holder.conv_participants = (TextView) convertView.findViewById(R.id.conv_participant);
- holder.conv_status = (TextView) convertView.findViewById(R.id.conv_last_item);
- holder.conv_time = (TextView) convertView.findViewById(R.id.conv_last_time);
- holder.position = -1;
- convertView.setTag(holder);
- }
- final ViewHolder h = holder;
- h.conv = calls.get(position);
- h.position = position;
- h.conv_participants.setText(h.conv.getContact().getDisplayName());
- long last_interaction = h.conv.getLastInteraction().getTime();
- h.conv_time.setText(last_interaction == 0 ? "" : DateUtils.getRelativeTimeSpanString(last_interaction, System.currentTimeMillis(), 0L, DateUtils.FORMAT_ABBREV_ALL));
- h.conv_status.setText(h.conv.getLastInteractionSumary(getResources()));
- if (h.conv.hasUnreadTextMessages()) {
- h.conv_participants.setTypeface(null, Typeface.BOLD);
- h.conv_time.setTypeface(null, Typeface.BOLD);
- h.conv_status.setTypeface(null, Typeface.BOLD);
- } else {
- h.conv_participants.setTypeface(null, Typeface.NORMAL);
- h.conv_time.setTypeface(null, Typeface.NORMAL);
- h.conv_status.setTypeface(null, Typeface.NORMAL);
- }
-
- final Long cid = h.conv.getContact().getId();
- Bitmap bmp = mMemoryCache.get(cid);
- if (bmp != null) {
- h.photo.setImageBitmap(bmp);
- } else {
- holder.photo.setImageBitmap(mMemoryCache.get(-1l));
- final WeakReference<ViewHolder> wh = new WeakReference<>(holder);
- final ContactPictureTask.PictureLoadedCallback cb = new ContactPictureTask.PictureLoadedCallback() {
- @Override
- public void onPictureLoaded(final Bitmap bmp) {
- final ViewHolder fh = wh.get();
- if (fh == null || fh.photo.getParent() == null)
- return;
- if (fh.conv.getContact().getId() == cid) {
- fh.photo.post(new Runnable() {
- @Override
- public void run() {
- fh.photo.setImageBitmap(bmp);
- fh.photo.startAnimation(AnimationUtils.loadAnimation(fh.photo.getContext(), R.anim.contact_fadein));
- }
- });
- }
- }
- };
- WeakReference<ContactPictureTask> wtask = running_tasks.get(cid);
- ContactPictureTask task = wtask == null ? null : wtask.get();
- if (task != null) {
- task.addCallback(cb);
- } else {
- task = new ContactPictureTask(mContext, h.photo, h.conv.getContact(), new ContactPictureTask.PictureLoadedCallback() {
- @Override
- public void onPictureLoaded(Bitmap bmp) {
- mMemoryCache.put(cid, bmp);
- running_tasks.remove(cid);
- }
- });
- task.addCallback(cb);
- running_tasks.put(cid, new WeakReference<>(task));
- infos_fetcher.execute(task);
- }
- }
- return convertView;
- }
}
@Override
@@ -601,7 +488,7 @@
transfer = data.getParcelableExtra("transfer");
try {
mCallbacks.getService().getRemoteService().attendedTransfer(transfer.getParticipants().get(0).getCallId(), c.getParticipants().get(0).getCallId());
- mConferenceAdapter.notifyDataSetChanged();
+ mSmartListAdapter.notifyDataSetChanged();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
@@ -678,4 +565,30 @@
}
}
+ private void setLoading(boolean loading) {
+ if (null != this.mLoader) {
+ int loaderVisibility = (loading) ? View.VISIBLE : View.GONE;
+ this.mLoader.setVisibility(loaderVisibility);
+ this.initEmptyTextViewWhileLoading(loading);
+ }
+ }
+
+ private void initEmptyTextViewWhileLoading(boolean loading) {
+ if (null != this.contactList && this.contactList.getVisibility() == View.VISIBLE) {
+ this.mEmptyTextView.setText("");
+ }
+ else {
+ if (loading) {
+ this.mEmptyTextView.setText("");
+ }
+ else {
+ String emptyText = getResources().getQuantityString(R.plurals.home_conferences_title, 0, 0);
+ this.mEmptyTextView.setText(emptyText);
+ }
+ }
+
+ if (null != list) {
+ list.setEmptyView(this.mEmptyTextView);
+ }
+ }
}
diff --git a/ring-android/app/src/main/java/cx/ring/service/LocalService.java b/ring-android/app/src/main/java/cx/ring/service/LocalService.java
index d60e86b..336c7a7 100644
--- a/ring-android/app/src/main/java/cx/ring/service/LocalService.java
+++ b/ring-android/app/src/main/java/cx/ring/service/LocalService.java
@@ -102,6 +102,7 @@
// Emitting events
static public final String ACTION_CONF_UPDATE = BuildConfig.APPLICATION_ID + ".action.CONF_UPDATE";
+ static public final String ACTION_CONF_LOADED = BuildConfig.APPLICATION_ID + ".action.CONF_LOADED";
static public final String ACTION_ACCOUNT_UPDATE = BuildConfig.APPLICATION_ID + ".action.ACCOUNT_UPDATE";
static public final String ACTION_CONV_READ = BuildConfig.APPLICATION_ID + ".action.CONV_READ";
@@ -148,6 +149,8 @@
private boolean canUseContacts = true;
private boolean canUseMobile = false;
+ private boolean mAreConversationsLoaded = false;
+
public ContactsLoader.Result getSortedContacts() {
Log.w(TAG, "getSortedContacts " + lastContactLoaderResult.contacts.size() + " contacts, " + lastContactLoaderResult.starred.size() + " starred.");
return lastContactLoaderResult;
@@ -1025,6 +1028,8 @@
updateAudioState();
updateTextNotifications();
sendBroadcast(new Intent(ACTION_CONF_UPDATE));
+ sendBroadcast(new Intent(ACTION_CONF_LOADED));
+ this.mAreConversationsLoaded = true;
}
public class AccountsLoader extends AsyncTaskLoader<ArrayList<Account>> {
@@ -1447,4 +1452,7 @@
getContentResolver().unregisterContentObserver(contactContentObserver);
}
+ public boolean areConversationsLoaded() {
+ return mAreConversationsLoaded;
+ }
}
diff --git a/ring-android/app/src/main/res/layout/frag_call_list.xml b/ring-android/app/src/main/res/layout/frag_call_list.xml
index 81d153c..a9488ee 100644
--- a/ring-android/app/src/main/res/layout/frag_call_list.xml
+++ b/ring-android/app/src/main/res/layout/frag_call_list.xml
@@ -77,6 +77,22 @@
android:paddingTop="8dp"
tools:listitem="@layout/item_calllist" />
+ <ProgressBar
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@android:id/empty"
+ android:layout_centerVertical="true"
+ android:layout_centerHorizontal="true" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text=""
+ android:id="@+id/emptyTextView"
+ android:layout_centerInParent="true"
+ android:layout_alignParentEnd="false"
+ android:gravity="center" />
+
<android.support.design.widget.FloatingActionButton
android:id="@+id/newconv_fab"
android:layout_width="wrap_content"