M build.gradle => build.gradle +1 -0
@@ 66,6 66,7 @@ dependencies {
implementation "com.leinardi.android:speed-dial:2.0.1"
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
+ implementation 'com.google.guava:guava:27.1-android'
quicksyImplementation 'io.michaelrocks:libphonenumber-android:8.10.1'
}
M proguard-rules.pro => proguard-rules.pro +2 -0
@@ 18,3 18,5 @@
-dontwarn org.bouncycastle.cert.dane.**
-dontwarn rocks.xmpp.addr.**
-dontwarn com.google.firebase.analytics.connector.AnalyticsConnector
+-dontwarn java.lang.**
+-dontwarn javax.lang.**
M src/main/java/eu/siacs/conversations/http/services/MuclumbusService.java => src/main/java/eu/siacs/conversations/http/services/MuclumbusService.java +17 -4
@@ 1,5 1,7 @@
package eu.siacs.conversations.http.services;
+import com.google.common.base.Objects;
+
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ 31,12 33,8 @@ public interface MuclumbusService {
class Room implements AvatarService.Avatarable {
public String address;
- public int nusers;
- public boolean is_open;
- public String anonymity_mode;
public String name;
public String description;
- public String language;
public String getName() {
return name;
@@ 59,6 57,21 @@ public interface MuclumbusService {
Jid room = getRoom();
return UIHelper.getColorForName(room != null ? room.asBareJid().toEscapedString() : name);
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Room room = (Room) o;
+ return Objects.equal(address, room.address) &&
+ Objects.equal(name, room.name) &&
+ Objects.equal(description, room.description);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(address, name, description);
+ }
}
class SearchRequest {
A src/main/java/eu/siacs/conversations/services/ChannelDiscoveryService.java => src/main/java/eu/siacs/conversations/services/ChannelDiscoveryService.java +106 -0
@@ 0,0 1,106 @@
+package eu.siacs.conversations.services;
+
+import android.util.Log;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import eu.siacs.conversations.Config;
+import eu.siacs.conversations.http.services.MuclumbusService;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.converter.gson.GsonConverterFactory;
+
+public class ChannelDiscoveryService {
+
+ private final XmppConnectionService service;
+
+
+ private final MuclumbusService muclumbusService;
+
+ private final Cache<String, List<MuclumbusService.Room>> cache;
+
+ public ChannelDiscoveryService(XmppConnectionService service) {
+ this.service = service;
+ Retrofit retrofit = new Retrofit.Builder()
+ .baseUrl(Config.CHANNEL_DISCOVERY)
+ .addConverterFactory(GsonConverterFactory.create())
+ .callbackExecutor(Executors.newSingleThreadExecutor())
+ .build();
+ this.muclumbusService = retrofit.create(MuclumbusService.class);
+ this.cache = CacheBuilder.newBuilder().expireAfterWrite(5, TimeUnit.MINUTES).build();
+ }
+
+ public void discover(String query, OnChannelSearchResultsFound onChannelSearchResultsFound) {
+ final boolean all = query == null || query.trim().isEmpty();
+ Log.d(Config.LOGTAG, "discover channels. query=" + query);
+ List<MuclumbusService.Room> result = cache.getIfPresent(all ? "" : query);
+ if (result != null) {
+ onChannelSearchResultsFound.onChannelSearchResultsFound(result);
+ return;
+ }
+ if (all) {
+ discoverChannels(onChannelSearchResultsFound);
+ } else {
+ discoverChannels(query, onChannelSearchResultsFound);
+ }
+ }
+
+ private void discoverChannels(OnChannelSearchResultsFound listener) {
+ Call<MuclumbusService.Rooms> call = muclumbusService.getRooms(1);
+ try {
+ call.enqueue(new Callback<MuclumbusService.Rooms>() {
+ @Override
+ public void onResponse(Call<MuclumbusService.Rooms> call, Response<MuclumbusService.Rooms> response) {
+ final MuclumbusService.Rooms body = response.body();
+ if (body == null) {
+ return;
+ }
+ cache.put("", body.items);
+ listener.onChannelSearchResultsFound(body.items);
+ }
+
+ @Override
+ public void onFailure(Call<MuclumbusService.Rooms> call, Throwable throwable) {
+
+ }
+ });
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void discoverChannels(final String query, OnChannelSearchResultsFound listener) {
+ Call<MuclumbusService.SearchResult> searchResultCall = muclumbusService.search(new MuclumbusService.SearchRequest(query));
+
+ searchResultCall.enqueue(new Callback<MuclumbusService.SearchResult>() {
+ @Override
+ public void onResponse(Call<MuclumbusService.SearchResult> call, Response<MuclumbusService.SearchResult> response) {
+ System.out.println(response.message());
+ MuclumbusService.SearchResult body = response.body();
+ if (body == null) {
+ return;
+ }
+ cache.put(query, body.result.items);
+ listener.onChannelSearchResultsFound(body.result.items);
+ }
+
+ @Override
+ public void onFailure(Call<MuclumbusService.SearchResult> call, Throwable throwable) {
+ throwable.printStackTrace();
+ }
+ });
+ }
+
+ public interface OnChannelSearchResultsFound {
+ void onChannelSearchResultsFound(List<MuclumbusService.Room> results);
+ }
+}
M src/main/java/eu/siacs/conversations/services/XmppConnectionService.java => src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +3 -63
@@ 209,6 209,7 @@ public class XmppConnectionService extends Service {
private FileBackend fileBackend = new FileBackend(this);
private MemorizingTrustManager mMemorizingTrustManager;
private NotificationService mNotificationService = new NotificationService(this);
+ private ChannelDiscoveryService mChannelDiscoveryService = new ChannelDiscoveryService(this);
private ShortcutService mShortcutService = new ShortcutService(this);
private AtomicBoolean mInitialAddressbookSyncCompleted = new AtomicBoolean(false);
private AtomicBoolean mForceForegroundService = new AtomicBoolean(false);
@@ 242,7 243,6 @@ public class XmppConnectionService extends Service {
private AvatarService mAvatarService = new AvatarService(this);
private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this);
private PushManagementService mPushManagementService = new PushManagementService(this);
- private MuclumbusService muclumbusService;
private QuickConversationsService mQuickConversationsService = new QuickConversationsService(this);
private final ConversationsFileObserver fileObserver = new ConversationsFileObserver(
Environment.getExternalStorageDirectory().getAbsolutePath()
@@ 805,61 805,8 @@ public class XmppConnectionService extends Service {
return pingNow;
}
- public void discoverChannels(String query, OnChannelSearchResultsFound onChannelSearchResultsFound) {
- Log.d(Config.LOGTAG,"discover channels. query="+query);
- if (query == null || query.trim().isEmpty()) {
- discoverChannelsInternal(onChannelSearchResultsFound);
- } else {
- discoverChannelsInternal(query, onChannelSearchResultsFound);
- }
- }
-
- private void discoverChannelsInternal(OnChannelSearchResultsFound listener) {
- Call<MuclumbusService.Rooms> call = muclumbusService.getRooms(1);
- try {
- call.enqueue(new Callback<MuclumbusService.Rooms>() {
- @Override
- public void onResponse(Call<MuclumbusService.Rooms> call, Response<MuclumbusService.Rooms> response) {
- final MuclumbusService.Rooms body = response.body();
- if (body == null) {
- return;
- }
- listener.onChannelSearchResultsFound(body.items);
- }
-
- @Override
- public void onFailure(Call<MuclumbusService.Rooms> call, Throwable throwable) {
-
- }
- });
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- private void discoverChannelsInternal(String query, OnChannelSearchResultsFound listener) {
- Call<MuclumbusService.SearchResult> searchResultCall = muclumbusService.search(new MuclumbusService.SearchRequest(query));
-
- searchResultCall.enqueue(new Callback<MuclumbusService.SearchResult>() {
- @Override
- public void onResponse(Call<MuclumbusService.SearchResult> call, Response<MuclumbusService.SearchResult> response) {
- System.out.println(response.message());
- MuclumbusService.SearchResult body = response.body();
- if (body == null) {
- return;
- }
- listener.onChannelSearchResultsFound(body.result.items);
- }
-
- @Override
- public void onFailure(Call<MuclumbusService.SearchResult> call, Throwable throwable) {
- throwable.printStackTrace();
- }
- });
- }
-
- public interface OnChannelSearchResultsFound {
- void onChannelSearchResultsFound(List<MuclumbusService.Room> results);
+ public void discoverChannels(String query, ChannelDiscoveryService.OnChannelSearchResultsFound onChannelSearchResultsFound) {
+ mChannelDiscoveryService.discover(query, onChannelSearchResultsFound);
}
public boolean isDataSaverDisabled() {
@@ 1130,13 1077,6 @@ public class XmppConnectionService extends Service {
}
mForceDuringOnCreate.set(false);
toggleForegroundService();
-
- Retrofit retrofit = new Retrofit.Builder()
- .baseUrl(Config.CHANNEL_DISCOVERY)
- .addConverterFactory(GsonConverterFactory.create())
- .callbackExecutor(Executors.newSingleThreadExecutor())
- .build();
- muclumbusService = retrofit.create(MuclumbusService.class);
}
private void checkForDeletedFiles() {
M src/main/java/eu/siacs/conversations/ui/ChannelDiscoveryActivity.java => src/main/java/eu/siacs/conversations/ui/ChannelDiscoveryActivity.java +17 -7
@@ 2,7 2,6 @@ package eu.siacs.conversations.ui;
import android.app.AlertDialog;
import android.content.Context;
-import android.content.Intent;
import android.content.SharedPreferences;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
@@ 25,19 24,21 @@ import eu.siacs.conversations.databinding.ActivityChannelDiscoveryBinding;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.http.services.MuclumbusService;
-import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.services.ChannelDiscoveryService;
import eu.siacs.conversations.ui.adapter.ChannelSearchResultAdapter;
import eu.siacs.conversations.ui.util.PendingItem;
import eu.siacs.conversations.ui.util.SoftKeyboardUtils;
import eu.siacs.conversations.utils.AccountUtils;
import rocks.xmpp.addr.Jid;
-public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.OnActionExpandListener, TextView.OnEditorActionListener, XmppConnectionService.OnChannelSearchResultsFound, ChannelSearchResultAdapter.OnChannelSearchResultSelected {
+public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.OnActionExpandListener, TextView.OnEditorActionListener, ChannelDiscoveryService.OnChannelSearchResultsFound, ChannelSearchResultAdapter.OnChannelSearchResultSelected {
private static final String CHANNEL_DISCOVERY_OPT_IN = "channel_discovery_opt_in";
private final ChannelSearchResultAdapter adapter = new ChannelSearchResultAdapter();
+ private ActivityChannelDiscoveryBinding binding;
+
private final PendingItem<String> mInitialSearchValue = new PendingItem<>();
private MenuItem mMenuSearchView;
@@ 66,7 67,7 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- ActivityChannelDiscoveryBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_channel_discovery);
+ binding = DataBindingUtil.setContentView(this, R.layout.activity_channel_discovery);
setSupportActionBar((Toolbar) binding.toolbar);
configureActionBar(getSupportActionBar(), true);
binding.list.setAdapter(this.adapter);
@@ 116,13 117,18 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
mSearchEditText.setText("");
- adapter.submitList(Collections.emptyList());
+ toggleLoadingScreen();
if (optedIn) {
xmppConnectionService.discoverChannels(null, this);
}
return true;
}
+ private void toggleLoadingScreen() {
+ adapter.submitList(Collections.emptyList());
+ binding.progressBar.setVisibility(View.VISIBLE);
+ }
+
@Override
public void onStart() {
super.onStart();
@@ 159,14 165,18 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
if (optedIn) {
xmppConnectionService.discoverChannels(v.getText().toString(), this);
}
- adapter.submitList(Collections.emptyList());
+ toggleLoadingScreen();
SoftKeyboardUtils.hideSoftKeyboard(this);
return true;
}
@Override
public void onChannelSearchResultsFound(List<MuclumbusService.Room> results) {
- runOnUiThread(() -> adapter.submitList(results));
+ runOnUiThread(() -> {
+ adapter.submitList(results);
+ binding.list.setVisibility(View.VISIBLE);
+ binding.progressBar.setVisibility(View.GONE);
+ });
}
M src/main/java/eu/siacs/conversations/ui/adapter/ChannelSearchResultAdapter.java => src/main/java/eu/siacs/conversations/ui/adapter/ChannelSearchResultAdapter.java +1 -1
@@ 22,7 22,7 @@ public class ChannelSearchResultAdapter extends ListAdapter<MuclumbusService.Roo
private static final DiffUtil.ItemCallback<MuclumbusService.Room> DIFF = new DiffUtil.ItemCallback<MuclumbusService.Room>() {
@Override
public boolean areItemsTheSame(@NonNull MuclumbusService.Room a, @NonNull MuclumbusService.Room b) {
- return false;
+ return a.address != null && a.address.equals(b.address);
}
@Override
M src/main/java/eu/siacs/conversations/ui/adapter/MediaPreviewAdapter.java => src/main/java/eu/siacs/conversations/ui/adapter/MediaPreviewAdapter.java +0 -4
@@ 1,6 1,5 @@
package eu.siacs.conversations.ui.adapter;
-import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.databinding.DataBindingUtil;
@@ 8,7 7,6 @@ import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
-import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
@@ 17,7 15,6 @@ import android.widget.ImageView;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.concurrent.RejectedExecutionException;
@@ 26,7 23,6 @@ import eu.siacs.conversations.databinding.MediaPreviewBinding;
import eu.siacs.conversations.ui.ConversationFragment;
import eu.siacs.conversations.ui.XmppActivity;
import eu.siacs.conversations.ui.util.Attachment;
-import eu.siacs.conversations.ui.util.StyledAttributes;
public class MediaPreviewAdapter extends RecyclerView.Adapter<MediaPreviewAdapter.MediaPreviewViewHolder> {
M src/main/res/layout/activity_channel_discovery.xml => src/main/res/layout/activity_channel_discovery.xml +9 -1
@@ 14,18 14,26 @@
layout="@layout/toolbar" />
+ <ProgressBar
+ android:id="@+id/progressBar"
+ style="?android:attr/progressBarStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:layout_anchor="@+id/list"
+ android:layout_gravity="center_horizontal"/>
+
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/color_background_primary">
-
<android.support.v7.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/color_background_primary"
android:orientation="vertical"
+ android:visibility="gone"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" />
</android.support.design.widget.CoordinatorLayout>