refactor muc search to use http
This commit is contained in:
parent
a0f88aa9b4
commit
2fa687b8ae
|
@ -64,6 +64,8 @@ dependencies {
|
||||||
implementation 'org.conscrypt:conscrypt-android:1.3.0'
|
implementation 'org.conscrypt:conscrypt-android:1.3.0'
|
||||||
implementation 'me.drakeet.support:toastcompat:1.1.0'
|
implementation 'me.drakeet.support:toastcompat:1.1.0'
|
||||||
implementation "com.leinardi.android:speed-dial:2.0.1"
|
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'
|
||||||
quicksyImplementation 'io.michaelrocks:libphonenumber-android:8.10.1'
|
quicksyImplementation 'io.michaelrocks:libphonenumber-android:8.10.1'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ public final class Config {
|
||||||
public static final String MAGIC_CREATE_DOMAIN = "conversations.im";
|
public static final String MAGIC_CREATE_DOMAIN = "conversations.im";
|
||||||
public static final String QUICKSY_DOMAIN = "quicksy.im";
|
public static final String QUICKSY_DOMAIN = "quicksy.im";
|
||||||
|
|
||||||
public static final Jid CHANNEL_DISCOVERY = Jid.of("rodrigo.de.mucobedo@dreckshal.de");
|
public static final String CHANNEL_DISCOVERY = "https://search.jabbercat.org";
|
||||||
|
|
||||||
public static final boolean DISALLOW_REGISTRATION_IN_UI = false; //hide the register checkbox
|
public static final boolean DISALLOW_REGISTRATION_IN_UI = false; //hide the register checkbox
|
||||||
|
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
package eu.siacs.conversations.entities;
|
|
||||||
|
|
||||||
import eu.siacs.conversations.services.AvatarService;
|
|
||||||
import eu.siacs.conversations.utils.UIHelper;
|
|
||||||
import rocks.xmpp.addr.Jid;
|
|
||||||
|
|
||||||
public class ChannelSearchResult implements AvatarService.Avatarable {
|
|
||||||
|
|
||||||
private final String name;
|
|
||||||
private final String description;
|
|
||||||
private final Jid room;
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Jid getRoom() {
|
|
||||||
return room;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChannelSearchResult(String name, String description, Jid room) {
|
|
||||||
this.name = name;
|
|
||||||
this.description = description;
|
|
||||||
this.room = room;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getAvatarBackgroundColor() {
|
|
||||||
return UIHelper.getColorForName(room != null ? room.asBareJid().toEscapedString() : getName());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
package eu.siacs.conversations.http.services;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.services.AvatarService;
|
||||||
|
import eu.siacs.conversations.utils.UIHelper;
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.http.Body;
|
||||||
|
import retrofit2.http.GET;
|
||||||
|
import retrofit2.http.POST;
|
||||||
|
import retrofit2.http.Query;
|
||||||
|
import rocks.xmpp.addr.Jid;
|
||||||
|
|
||||||
|
public interface MuclumbusService {
|
||||||
|
|
||||||
|
@GET("/api/1.0/rooms/unsafe")
|
||||||
|
Call<Rooms> getRooms(@Query("p") int page);
|
||||||
|
|
||||||
|
@POST("/api/1.0/search")
|
||||||
|
Call<SearchResult> search(@Body SearchRequest searchRequest);
|
||||||
|
|
||||||
|
class Rooms {
|
||||||
|
int page;
|
||||||
|
int total;
|
||||||
|
int pages;
|
||||||
|
public List<Room> items;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Jid getRoom() {
|
||||||
|
try {
|
||||||
|
return Jid.of(address);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAvatarBackgroundColor() {
|
||||||
|
Jid room = getRoom();
|
||||||
|
return UIHelper.getColorForName(room != null ? room.asBareJid().toEscapedString() : name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SearchRequest {
|
||||||
|
|
||||||
|
public Set<String> keywords;
|
||||||
|
|
||||||
|
public SearchRequest(String keyword) {
|
||||||
|
this.keywords = Collections.singleton(keyword);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SearchResult {
|
||||||
|
|
||||||
|
public Result result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Result {
|
||||||
|
|
||||||
|
public List<Room> items;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,7 +3,6 @@ package eu.siacs.conversations.services;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
|
@ -14,7 +13,6 @@ import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.support.annotation.ColorInt;
|
import android.support.annotation.ColorInt;
|
||||||
import android.support.annotation.DrawableRes;
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.content.res.ResourcesCompat;
|
import android.support.v4.content.res.ResourcesCompat;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
@ -33,17 +31,16 @@ import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.entities.Bookmark;
|
import eu.siacs.conversations.entities.Bookmark;
|
||||||
import eu.siacs.conversations.entities.ChannelSearchResult;
|
|
||||||
import eu.siacs.conversations.entities.Contact;
|
import eu.siacs.conversations.entities.Contact;
|
||||||
import eu.siacs.conversations.entities.Conversation;
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
import eu.siacs.conversations.entities.Conversational;
|
import eu.siacs.conversations.entities.Conversational;
|
||||||
import eu.siacs.conversations.entities.ListItem;
|
import eu.siacs.conversations.entities.ListItem;
|
||||||
import eu.siacs.conversations.entities.Message;
|
import eu.siacs.conversations.entities.Message;
|
||||||
import eu.siacs.conversations.entities.MucOptions;
|
import eu.siacs.conversations.entities.MucOptions;
|
||||||
|
import eu.siacs.conversations.http.services.MuclumbusService;
|
||||||
import eu.siacs.conversations.utils.UIHelper;
|
import eu.siacs.conversations.utils.UIHelper;
|
||||||
import eu.siacs.conversations.xmpp.OnAdvancedStreamFeaturesLoaded;
|
import eu.siacs.conversations.xmpp.OnAdvancedStreamFeaturesLoaded;
|
||||||
import eu.siacs.conversations.xmpp.XmppConnection;
|
import eu.siacs.conversations.xmpp.XmppConnection;
|
||||||
import eu.siacs.conversations.xmpp.pep.Avatar;
|
|
||||||
import rocks.xmpp.addr.Jid;
|
import rocks.xmpp.addr.Jid;
|
||||||
|
|
||||||
public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
|
public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
|
@ -83,15 +80,20 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
return get((ListItem) avatarable, size, cachedOnly);
|
return get((ListItem) avatarable, size, cachedOnly);
|
||||||
} else if (avatarable instanceof MucOptions.User) {
|
} else if (avatarable instanceof MucOptions.User) {
|
||||||
return get((MucOptions.User) avatarable, size, cachedOnly);
|
return get((MucOptions.User) avatarable, size, cachedOnly);
|
||||||
} else if (avatarable instanceof ChannelSearchResult) {
|
} else if (avatarable instanceof MuclumbusService.Room) {
|
||||||
return get((ChannelSearchResult) avatarable, size, cachedOnly);
|
return get((MuclumbusService.Room) avatarable, size, cachedOnly);
|
||||||
}
|
}
|
||||||
throw new AssertionError("AvatarService does not know how to generate avatar from "+avatarable.getClass().getName());
|
throw new AssertionError("AvatarService does not know how to generate avatar from "+avatarable.getClass().getName());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Bitmap get(final ChannelSearchResult result, final int size, boolean cacheOnly) {
|
private Bitmap get(final MuclumbusService.Room result, final int size, boolean cacheOnly) {
|
||||||
return get(result.getName(), result.getRoom().asBareJid().toEscapedString(), size, cacheOnly);
|
final Jid room = result.getRoom();
|
||||||
|
Conversation conversation = room != null ? mXmppConnectionService.findFirstMuc(room) : null;
|
||||||
|
if (conversation != null) {
|
||||||
|
return get(conversation,size,cacheOnly);
|
||||||
|
}
|
||||||
|
return get(result.getName(), room != null ? room.asBareJid().toEscapedString() : result.getName(), size, cacheOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Bitmap get(final Contact contact, final int size, boolean cachedOnly) {
|
private Bitmap get(final Contact contact, final int size, boolean cachedOnly) {
|
||||||
|
|
|
@ -49,7 +49,6 @@ import org.openintents.openpgp.util.OpenPgpServiceConnection;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.channels.Channel;
|
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
|
@ -69,6 +68,9 @@ import java.util.Set;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
@ -85,7 +87,6 @@ import eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.entities.Blockable;
|
import eu.siacs.conversations.entities.Blockable;
|
||||||
import eu.siacs.conversations.entities.Bookmark;
|
import eu.siacs.conversations.entities.Bookmark;
|
||||||
import eu.siacs.conversations.entities.ChannelSearchResult;
|
|
||||||
import eu.siacs.conversations.entities.Contact;
|
import eu.siacs.conversations.entities.Contact;
|
||||||
import eu.siacs.conversations.entities.Conversation;
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
import eu.siacs.conversations.entities.Conversational;
|
import eu.siacs.conversations.entities.Conversational;
|
||||||
|
@ -102,6 +103,7 @@ import eu.siacs.conversations.generator.MessageGenerator;
|
||||||
import eu.siacs.conversations.generator.PresenceGenerator;
|
import eu.siacs.conversations.generator.PresenceGenerator;
|
||||||
import eu.siacs.conversations.http.HttpConnectionManager;
|
import eu.siacs.conversations.http.HttpConnectionManager;
|
||||||
import eu.siacs.conversations.http.CustomURLStreamHandlerFactory;
|
import eu.siacs.conversations.http.CustomURLStreamHandlerFactory;
|
||||||
|
import eu.siacs.conversations.http.services.MuclumbusService;
|
||||||
import eu.siacs.conversations.parser.AbstractParser;
|
import eu.siacs.conversations.parser.AbstractParser;
|
||||||
import eu.siacs.conversations.parser.IqParser;
|
import eu.siacs.conversations.parser.IqParser;
|
||||||
import eu.siacs.conversations.parser.MessageParser;
|
import eu.siacs.conversations.parser.MessageParser;
|
||||||
|
@ -114,7 +116,6 @@ import eu.siacs.conversations.ui.UiCallback;
|
||||||
import eu.siacs.conversations.ui.interfaces.OnAvatarPublication;
|
import eu.siacs.conversations.ui.interfaces.OnAvatarPublication;
|
||||||
import eu.siacs.conversations.ui.interfaces.OnMediaLoaded;
|
import eu.siacs.conversations.ui.interfaces.OnMediaLoaded;
|
||||||
import eu.siacs.conversations.ui.interfaces.OnSearchResultsAvailable;
|
import eu.siacs.conversations.ui.interfaces.OnSearchResultsAvailable;
|
||||||
import eu.siacs.conversations.utils.AccountUtils;
|
|
||||||
import eu.siacs.conversations.utils.Compatibility;
|
import eu.siacs.conversations.utils.Compatibility;
|
||||||
import eu.siacs.conversations.utils.ConversationsFileObserver;
|
import eu.siacs.conversations.utils.ConversationsFileObserver;
|
||||||
import eu.siacs.conversations.utils.CryptoHelper;
|
import eu.siacs.conversations.utils.CryptoHelper;
|
||||||
|
@ -154,6 +155,11 @@ import eu.siacs.conversations.xmpp.stanzas.IqPacket;
|
||||||
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
|
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
|
||||||
import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
|
import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
|
||||||
import me.leolin.shortcutbadger.ShortcutBadger;
|
import me.leolin.shortcutbadger.ShortcutBadger;
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Callback;
|
||||||
|
import retrofit2.Response;
|
||||||
|
import retrofit2.Retrofit;
|
||||||
|
import retrofit2.converter.gson.GsonConverterFactory;
|
||||||
import rocks.xmpp.addr.Jid;
|
import rocks.xmpp.addr.Jid;
|
||||||
|
|
||||||
public class XmppConnectionService extends Service {
|
public class XmppConnectionService extends Service {
|
||||||
|
@ -236,6 +242,7 @@ public class XmppConnectionService extends Service {
|
||||||
private AvatarService mAvatarService = new AvatarService(this);
|
private AvatarService mAvatarService = new AvatarService(this);
|
||||||
private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this);
|
private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this);
|
||||||
private PushManagementService mPushManagementService = new PushManagementService(this);
|
private PushManagementService mPushManagementService = new PushManagementService(this);
|
||||||
|
private MuclumbusService muclumbusService;
|
||||||
private QuickConversationsService mQuickConversationsService = new QuickConversationsService(this);
|
private QuickConversationsService mQuickConversationsService = new QuickConversationsService(this);
|
||||||
private final ConversationsFileObserver fileObserver = new ConversationsFileObserver(
|
private final ConversationsFileObserver fileObserver = new ConversationsFileObserver(
|
||||||
Environment.getExternalStorageDirectory().getAbsolutePath()
|
Environment.getExternalStorageDirectory().getAbsolutePath()
|
||||||
|
@ -798,56 +805,61 @@ public class XmppConnectionService extends Service {
|
||||||
return pingNow;
|
return pingNow;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void discoverChannels(String query, OnChannelSearchResultsFound listener) {
|
public void discoverChannels(String query, OnChannelSearchResultsFound onChannelSearchResultsFound) {
|
||||||
IqPacket packet = new IqPacket(IqPacket.TYPE.GET);
|
Log.d(Config.LOGTAG,"discover channels. query="+query);
|
||||||
packet.setTo(Config.CHANNEL_DISCOVERY);
|
if (query == null || query.trim().isEmpty()) {
|
||||||
Element search = packet.addChild("search","https://xmlns.zombofant.net/muclumbus/search/1.0");
|
discoverChannelsInternal(onChannelSearchResultsFound);
|
||||||
search.addChild("set","http://jabber.org/protocol/rsm").addChild("max").setContent("100");
|
} else {
|
||||||
Bundle bundle = new Bundle();
|
discoverChannelsInternal(query, onChannelSearchResultsFound);
|
||||||
if (!TextUtils.isEmpty(query)) {
|
|
||||||
bundle.putString("q",query);
|
|
||||||
}
|
}
|
||||||
Data data = Data.create("https://xmlns.zombofant.net/muclumbus/search/1.0#params", bundle);
|
}
|
||||||
search.addChild(data);
|
|
||||||
final Account account = AccountUtils.getFirstEnabled(this);
|
private void discoverChannelsInternal(OnChannelSearchResultsFound listener) {
|
||||||
if (account == null) {
|
Call<MuclumbusService.Rooms> call = muclumbusService.getRooms(1);
|
||||||
return;
|
try {
|
||||||
}
|
call.enqueue(new Callback<MuclumbusService.Rooms>() {
|
||||||
sendIqPacket(account, packet, new OnIqPacketReceived() {
|
@Override
|
||||||
@Override
|
public void onResponse(Call<MuclumbusService.Rooms> call, Response<MuclumbusService.Rooms> response) {
|
||||||
public void onIqPacketReceived(Account account, IqPacket response) {
|
final MuclumbusService.Rooms body = response.body();
|
||||||
ArrayList<ChannelSearchResult> searchResults = new ArrayList<>();
|
if (body == null) {
|
||||||
if (response.getType() == IqPacket.TYPE.RESULT) {
|
return;
|
||||||
Element result = response.findChild("result","https://xmlns.zombofant.net/muclumbus/search/1.0");
|
|
||||||
if (result != null) {
|
|
||||||
for(Element child : result.getChildren()) {
|
|
||||||
if ("item".equals(child.getName())) {
|
|
||||||
String name = child.findChildContent("name");
|
|
||||||
String description = child.findChildContent("description");
|
|
||||||
Jid room = child.getAttributeAsJid("address");
|
|
||||||
if (room != null) {
|
|
||||||
searchResults.add(new ChannelSearchResult(name,description,room));
|
|
||||||
} else {
|
|
||||||
Log.d(Config.LOGTAG,"skipping because room was null");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.d(Config.LOGTAG,"result was null");
|
|
||||||
}
|
}
|
||||||
} else {
|
listener.onChannelSearchResultsFound(body.items);
|
||||||
Log.d(Config.LOGTAG,response.toString());
|
|
||||||
}
|
|
||||||
if (listener != null) {
|
|
||||||
listener.onChannelSearchResultsFound(searchResults);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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 {
|
public interface OnChannelSearchResultsFound {
|
||||||
void onChannelSearchResultsFound(List<ChannelSearchResult> results);
|
void onChannelSearchResultsFound(List<MuclumbusService.Room> results);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDataSaverDisabled() {
|
public boolean isDataSaverDisabled() {
|
||||||
|
@ -1118,6 +1130,13 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
mForceDuringOnCreate.set(false);
|
mForceDuringOnCreate.set(false);
|
||||||
toggleForegroundService();
|
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() {
|
private void checkForDeletedFiles() {
|
||||||
|
|
|
@ -2,13 +2,12 @@ package eu.siacs.conversations.ui;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.databinding.DataBindingUtil;
|
import android.databinding.DataBindingUtil;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
@ -17,19 +16,18 @@ import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.databinding.ActivityChannelDiscoveryBinding;
|
import eu.siacs.conversations.databinding.ActivityChannelDiscoveryBinding;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.entities.ChannelSearchResult;
|
|
||||||
import eu.siacs.conversations.entities.Conversation;
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
|
import eu.siacs.conversations.http.services.MuclumbusService;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
import eu.siacs.conversations.ui.adapter.ChannelSearchResultAdapter;
|
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.ui.util.SoftKeyboardUtils;
|
||||||
import eu.siacs.conversations.utils.AccountUtils;
|
import eu.siacs.conversations.utils.AccountUtils;
|
||||||
import rocks.xmpp.addr.Jid;
|
import rocks.xmpp.addr.Jid;
|
||||||
|
@ -40,6 +38,9 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
|
||||||
|
|
||||||
private final ChannelSearchResultAdapter adapter = new ChannelSearchResultAdapter();
|
private final ChannelSearchResultAdapter adapter = new ChannelSearchResultAdapter();
|
||||||
|
|
||||||
|
private final PendingItem<String> mInitialSearchValue = new PendingItem<>();
|
||||||
|
|
||||||
|
private MenuItem mMenuSearchView;
|
||||||
private EditText mSearchEditText;
|
private EditText mSearchEditText;
|
||||||
|
|
||||||
private boolean optedIn = false;
|
private boolean optedIn = false;
|
||||||
|
@ -52,7 +53,13 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
|
||||||
@Override
|
@Override
|
||||||
void onBackendConnected() {
|
void onBackendConnected() {
|
||||||
if (optedIn) {
|
if (optedIn) {
|
||||||
xmppConnectionService.discoverChannels(null, this);
|
String query;
|
||||||
|
if (mMenuSearchView != null && mMenuSearchView.isActionViewExpanded()) {
|
||||||
|
query = mSearchEditText.getText().toString();
|
||||||
|
} else {
|
||||||
|
query = mInitialSearchValue.peek();
|
||||||
|
}
|
||||||
|
xmppConnectionService.discoverChannels(query, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,17 +72,32 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
|
||||||
binding.list.setAdapter(this.adapter);
|
binding.list.setAdapter(this.adapter);
|
||||||
this.adapter.setOnChannelSearchResultSelectedListener(this);
|
this.adapter.setOnChannelSearchResultSelectedListener(this);
|
||||||
optedIn = getPreferences().getBoolean(CHANNEL_DISCOVERY_OPT_IN, false);
|
optedIn = getPreferences().getBoolean(CHANNEL_DISCOVERY_OPT_IN, false);
|
||||||
|
|
||||||
|
final String search = savedInstanceState == null ? null : savedInstanceState.getString("search");
|
||||||
|
if (search != null) {
|
||||||
|
mInitialSearchValue.push(search);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(final Menu menu) {
|
public boolean onCreateOptionsMenu(final Menu menu) {
|
||||||
getMenuInflater().inflate(R.menu.muc_users_activity, menu);
|
getMenuInflater().inflate(R.menu.muc_users_activity, menu);
|
||||||
final MenuItem menuSearchView = menu.findItem(R.id.action_search);
|
mMenuSearchView = menu.findItem(R.id.action_search);
|
||||||
final View mSearchView = menuSearchView.getActionView();
|
final View mSearchView = mMenuSearchView.getActionView();
|
||||||
mSearchEditText = mSearchView.findViewById(R.id.search_field);
|
mSearchEditText = mSearchView.findViewById(R.id.search_field);
|
||||||
mSearchEditText.setHint(R.string.search_channels);
|
mSearchEditText.setHint(R.string.search_channels);
|
||||||
|
String initialSearchValue = mInitialSearchValue.pop();
|
||||||
|
if (initialSearchValue != null) {
|
||||||
|
mMenuSearchView.expandActionView();
|
||||||
|
mSearchEditText.append(initialSearchValue);
|
||||||
|
mSearchEditText.requestFocus();
|
||||||
|
if (optedIn) {
|
||||||
|
xmppConnectionService.discoverChannels(initialSearchValue, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
mSearchEditText.setOnEditorActionListener(this);
|
mSearchEditText.setOnEditorActionListener(this);
|
||||||
menuSearchView.setOnActionExpandListener(this);
|
mMenuSearchView.setOnActionExpandListener(this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,6 +139,14 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSaveInstanceState(Bundle savedInstanceState) {
|
||||||
|
if (mMenuSearchView != null && mMenuSearchView.isActionViewExpanded()) {
|
||||||
|
savedInstanceState.putString("search", mSearchEditText != null ? mSearchEditText.getText().toString() : null);
|
||||||
|
}
|
||||||
|
super.onSaveInstanceState(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
private void optIn() {
|
private void optIn() {
|
||||||
SharedPreferences preferences = getPreferences();
|
SharedPreferences preferences = getPreferences();
|
||||||
preferences.edit().putBoolean(CHANNEL_DISCOVERY_OPT_IN,true).apply();
|
preferences.edit().putBoolean(CHANNEL_DISCOVERY_OPT_IN,true).apply();
|
||||||
|
@ -135,13 +165,13 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChannelSearchResultsFound(List<ChannelSearchResult> results) {
|
public void onChannelSearchResultsFound(List<MuclumbusService.Room> results) {
|
||||||
runOnUiThread(() -> adapter.submitList(results));
|
runOnUiThread(() -> adapter.submitList(results));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChannelSearchResult(final ChannelSearchResult result) {
|
public void onChannelSearchResult(final MuclumbusService.Room result) {
|
||||||
List<String> accounts = AccountUtils.getEnabledAccounts(xmppConnectionService);
|
List<String> accounts = AccountUtils.getEnabledAccounts(xmppConnectionService);
|
||||||
if (accounts.size() == 1) {
|
if (accounts.size() == 1) {
|
||||||
joinChannelSearchResult(accounts.get(0),result);
|
joinChannelSearchResult(accounts.get(0),result);
|
||||||
|
@ -157,7 +187,7 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void joinChannelSearchResult(String accountJid, ChannelSearchResult result) {
|
public void joinChannelSearchResult(String accountJid, MuclumbusService.Room result) {
|
||||||
Account account = xmppConnectionService.findAccountByJid(Jid.of(accountJid));
|
Account account = xmppConnectionService.findAccountByJid(Jid.of(accountJid));
|
||||||
final Conversation conversation = xmppConnectionService.findOrCreateConversation(account, result.getRoom(), true, true, true);
|
final Conversation conversation = xmppConnectionService.findOrCreateConversation(account, result.getRoom(), true, true, true);
|
||||||
switchToConversation(conversation);
|
switchToConversation(conversation);
|
||||||
|
|
|
@ -12,21 +12,21 @@ import android.view.ViewGroup;
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.databinding.SearchResultItemBinding;
|
import eu.siacs.conversations.databinding.SearchResultItemBinding;
|
||||||
import eu.siacs.conversations.entities.ChannelSearchResult;
|
import eu.siacs.conversations.http.services.MuclumbusService;
|
||||||
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
|
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
|
||||||
|
|
||||||
public class ChannelSearchResultAdapter extends ListAdapter<ChannelSearchResult, ChannelSearchResultAdapter.ViewHolder> {
|
public class ChannelSearchResultAdapter extends ListAdapter<MuclumbusService.Room, ChannelSearchResultAdapter.ViewHolder> {
|
||||||
|
|
||||||
private OnChannelSearchResultSelected listener;
|
private OnChannelSearchResultSelected listener;
|
||||||
|
|
||||||
private static final DiffUtil.ItemCallback<ChannelSearchResult> DIFF = new DiffUtil.ItemCallback<ChannelSearchResult>() {
|
private static final DiffUtil.ItemCallback<MuclumbusService.Room> DIFF = new DiffUtil.ItemCallback<MuclumbusService.Room>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean areItemsTheSame(@NonNull ChannelSearchResult a, @NonNull ChannelSearchResult b) {
|
public boolean areItemsTheSame(@NonNull MuclumbusService.Room a, @NonNull MuclumbusService.Room b) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean areContentsTheSame(@NonNull ChannelSearchResult a, @NonNull ChannelSearchResult b) {
|
public boolean areContentsTheSame(@NonNull MuclumbusService.Room a, @NonNull MuclumbusService.Room b) {
|
||||||
return a.equals(b);
|
return a.equals(b);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -43,7 +43,7 @@ public class ChannelSearchResultAdapter extends ListAdapter<ChannelSearchResult,
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
|
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
|
||||||
final ChannelSearchResult searchResult = getItem(position);
|
final MuclumbusService.Room searchResult = getItem(position);
|
||||||
viewHolder.binding.name.setText(searchResult.getName());
|
viewHolder.binding.name.setText(searchResult.getName());
|
||||||
final String description = searchResult.getDescription();
|
final String description = searchResult.getDescription();
|
||||||
if (TextUtils.isEmpty(description)) {
|
if (TextUtils.isEmpty(description)) {
|
||||||
|
@ -73,6 +73,6 @@ public class ChannelSearchResultAdapter extends ListAdapter<ChannelSearchResult,
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface OnChannelSearchResultSelected {
|
public interface OnChannelSearchResultSelected {
|
||||||
void onChannelSearchResult(ChannelSearchResult result);
|
void onChannelSearchResult(MuclumbusService.Room result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -860,5 +860,5 @@
|
||||||
<string name="discover_channels">Discover channels</string>
|
<string name="discover_channels">Discover channels</string>
|
||||||
<string name="search_channels">Search channels</string>
|
<string name="search_channels">Search channels</string>
|
||||||
<string name="channel_discovery_opt_in_title">Possible privacy violation!</string>
|
<string name="channel_discovery_opt_in_title">Possible privacy violation!</string>
|
||||||
<string name="channel_discover_opt_in_message"><![CDATA[Channel discovery uses a third party service called <a href="https://search.jabber.network">search.jabber.network</a>.<br><br>Using this feature will transmit your Jabber ID and search terms to that service. See their <a href="https://search.jabber.network/privacy">Privacy Policy</a> for more information.]]></string>
|
<string name="channel_discover_opt_in_message"><![CDATA[Channel discovery uses a third party service called <a href="https://search.jabbercat.org">search.jabbercat.org</a>.<br><br>Using this feature will transmit your IP address and search terms to that service. See their <a href="https://search.jabbercat.org/privacy">Privacy Policy</a> for more information.]]></string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in New Issue