2014-10-31 20:02:29 +01:00
/ *
2019-01-23 18:03:33 +01:00
* This is the source code of Telegram for Android v . 5 . x . x .
2014-10-31 20:02:29 +01:00
* It is licensed under GNU GPL v . 2 or later .
* You should have received a copy of the license in this archive ( see LICENSE ) .
*
2019-01-23 18:03:33 +01:00
* Copyright Nikolai Kudashov , 2013 - 2018 .
2014-10-31 20:02:29 +01:00
* /
package org.telegram.ui.Adapters ;
import android.content.Context ;
2017-03-31 01:58:05 +02:00
import android.text.SpannableStringBuilder ;
import android.text.Spanned ;
2014-12-01 18:56:31 +01:00
import android.text.TextUtils ;
2017-03-31 01:58:05 +02:00
import android.text.style.ForegroundColorSpan ;
2018-07-30 04:07:02 +02:00
import android.util.LongSparseArray ;
2016-05-25 23:49:47 +02:00
import android.view.MotionEvent ;
2014-10-31 20:02:29 +01:00
import android.view.View ;
import android.view.ViewGroup ;
2019-07-18 15:01:39 +02:00
import org.telegram.PhoneFormat.PhoneFormat ;
2014-10-31 20:02:29 +01:00
import org.telegram.SQLite.SQLiteCursor ;
2015-08-13 11:23:31 +02:00
import org.telegram.SQLite.SQLitePreparedStatement ;
2015-09-24 22:52:02 +02:00
import org.telegram.messenger.AndroidUtilities ;
2015-11-26 22:04:02 +01:00
import org.telegram.messenger.ChatObject ;
2015-09-24 22:52:02 +02:00
import org.telegram.messenger.ContactsController ;
2019-07-18 15:01:39 +02:00
import org.telegram.messenger.MediaDataController ;
2015-09-24 22:52:02 +02:00
import org.telegram.messenger.LocaleController ;
import org.telegram.messenger.MessageObject ;
import org.telegram.messenger.MessagesController ;
import org.telegram.messenger.MessagesStorage ;
2017-12-08 18:35:59 +01:00
import org.telegram.messenger.UserConfig ;
2019-01-23 18:03:33 +01:00
import org.telegram.messenger.UserObject ;
2019-05-14 14:08:05 +02:00
import org.telegram.messenger.Utilities ;
2014-10-31 20:02:29 +01:00
import org.telegram.messenger.FileLog ;
import org.telegram.messenger.R ;
2015-09-24 22:52:02 +02:00
import org.telegram.tgnet.ConnectionsManager ;
import org.telegram.tgnet.NativeByteBuffer ;
import org.telegram.tgnet.TLObject ;
import org.telegram.tgnet.TLRPC ;
2017-03-31 01:58:05 +02:00
import org.telegram.ui.ActionBar.Theme ;
2014-10-31 20:02:29 +01:00
import org.telegram.ui.Cells.DialogCell ;
2017-03-31 01:58:05 +02:00
import org.telegram.ui.Cells.GraySectionCell ;
2015-03-26 18:34:47 +01:00
import org.telegram.ui.Cells.HashtagSearchCell ;
2016-05-25 23:49:47 +02:00
import org.telegram.ui.Cells.HintDialogCell ;
2014-11-19 02:23:46 +01:00
import org.telegram.ui.Cells.LoadingCell ;
2014-11-10 12:05:22 +01:00
import org.telegram.ui.Cells.ProfileSearchCell ;
2019-07-18 15:01:39 +02:00
import org.telegram.ui.Cells.TextCell ;
2016-05-25 23:49:47 +02:00
import org.telegram.ui.Components.RecyclerListView ;
2014-10-31 20:02:29 +01:00
import java.util.ArrayList ;
2014-12-01 18:56:31 +01:00
import java.util.Collections ;
import java.util.HashMap ;
import java.util.Locale ;
2016-06-24 12:27:15 +02:00
import java.util.concurrent.ConcurrentHashMap ;
2014-10-31 20:02:29 +01:00
2019-05-14 14:08:05 +02:00
import androidx.recyclerview.widget.LinearLayoutManager ;
import androidx.recyclerview.widget.RecyclerView ;
2017-03-31 01:58:05 +02:00
public class DialogsSearchAdapter extends RecyclerListView . SelectionAdapter {
2014-12-01 18:56:31 +01:00
2014-10-31 20:02:29 +01:00
private Context mContext ;
2019-05-14 14:08:05 +02:00
private Runnable searchRunnable ;
private Runnable searchRunnable2 ;
2015-01-02 23:15:07 +01:00
private ArrayList < TLObject > searchResult = new ArrayList < > ( ) ;
private ArrayList < CharSequence > searchResultNames = new ArrayList < > ( ) ;
private ArrayList < MessageObject > searchResultMessages = new ArrayList < > ( ) ;
2015-03-26 18:34:47 +01:00
private ArrayList < String > searchResultHashtags = new ArrayList < > ( ) ;
2014-11-06 22:34:47 +01:00
private String lastSearchText ;
2019-06-04 12:14:50 +02:00
private boolean searchWas ;
2015-09-24 22:52:02 +02:00
private int reqId = 0 ;
2014-10-31 20:02:29 +01:00
private int lastReqId ;
2016-05-25 23:49:47 +02:00
private DialogsSearchAdapterDelegate delegate ;
2015-03-19 00:09:45 +01:00
private int needMessagesSearch ;
2014-11-19 02:23:46 +01:00
private boolean messagesSearchEndReached ;
private String lastMessagesSearchString ;
2019-06-04 12:14:50 +02:00
private int nextSearchRate ;
2020-01-23 07:15:40 +01:00
private int lastSearchId ;
private int lastGlobalSearchId ;
private int lastLocalSearchId ;
private int lastMessagesSearchId ;
2015-08-13 11:23:31 +02:00
private int dialogsType ;
2017-03-31 01:58:05 +02:00
private SearchAdapterHelper searchAdapterHelper ;
private RecyclerListView innerListView ;
2017-12-08 18:35:59 +01:00
private int selfUserId ;
2019-07-18 15:01:39 +02:00
2018-07-30 04:07:02 +02:00
private int currentAccount = UserConfig . selectedAccount ;
2015-08-13 11:23:31 +02:00
private ArrayList < RecentSearchObject > recentSearchObjects = new ArrayList < > ( ) ;
2018-07-30 04:07:02 +02:00
private LongSparseArray < RecentSearchObject > recentSearchObjectsById = new LongSparseArray < > ( ) ;
2014-10-31 20:02:29 +01:00
2020-03-30 14:00:09 +02:00
private static class DialogSearchResult {
2014-12-01 18:56:31 +01:00
public TLObject object ;
public int date ;
public CharSequence name ;
}
2015-08-13 11:23:31 +02:00
protected static class RecentSearchObject {
TLObject object ;
int date ;
long did ;
}
2016-05-25 23:49:47 +02:00
public interface DialogsSearchAdapterDelegate {
2015-03-19 00:09:45 +01:00
void searchStateChanged ( boolean searching ) ;
2019-07-18 15:01:39 +02:00
2017-12-08 18:35:59 +01:00
void didPressedOnSubDialog ( long did ) ;
2019-07-18 15:01:39 +02:00
2016-05-25 23:49:47 +02:00
void needRemoveHint ( int did ) ;
2019-07-18 15:01:39 +02:00
2019-06-04 12:14:50 +02:00
void needClearList ( ) ;
2016-05-25 23:49:47 +02:00
}
2017-03-31 01:58:05 +02:00
private class CategoryAdapterRecycler extends RecyclerListView . SelectionAdapter {
2016-05-25 23:49:47 +02:00
public void setIndex ( int value ) {
notifyDataSetChanged ( ) ;
}
@Override
public RecyclerView . ViewHolder onCreateViewHolder ( ViewGroup parent , int viewType ) {
View view = new HintDialogCell ( mContext ) ;
2019-01-23 18:03:33 +01:00
view . setLayoutParams ( new RecyclerView . LayoutParams ( AndroidUtilities . dp ( 80 ) , AndroidUtilities . dp ( 86 ) ) ) ;
2017-03-31 01:58:05 +02:00
return new RecyclerListView . Holder ( view ) ;
}
@Override
public boolean isEnabled ( RecyclerView . ViewHolder holder ) {
return true ;
2016-05-25 23:49:47 +02:00
}
@Override
public void onBindViewHolder ( RecyclerView . ViewHolder holder , int position ) {
HintDialogCell cell = ( HintDialogCell ) holder . itemView ;
2019-07-18 15:01:39 +02:00
TLRPC . TL_topPeer peer = MediaDataController . getInstance ( currentAccount ) . hints . get ( position ) ;
2019-05-14 14:08:05 +02:00
TLRPC . Dialog dialog = new TLRPC . TL_dialog ( ) ;
2016-05-25 23:49:47 +02:00
TLRPC . Chat chat = null ;
TLRPC . User user = null ;
int did = 0 ;
if ( peer . peer . user_id ! = 0 ) {
did = peer . peer . user_id ;
2018-07-30 04:07:02 +02:00
user = MessagesController . getInstance ( currentAccount ) . getUser ( peer . peer . user_id ) ;
2016-05-25 23:49:47 +02:00
} else if ( peer . peer . channel_id ! = 0 ) {
did = - peer . peer . channel_id ;
2018-07-30 04:07:02 +02:00
chat = MessagesController . getInstance ( currentAccount ) . getChat ( peer . peer . channel_id ) ;
2016-05-25 23:49:47 +02:00
} else if ( peer . peer . chat_id ! = 0 ) {
did = - peer . peer . chat_id ;
2018-07-30 04:07:02 +02:00
chat = MessagesController . getInstance ( currentAccount ) . getChat ( peer . peer . chat_id ) ;
2016-05-25 23:49:47 +02:00
}
cell . setTag ( did ) ;
String name = " " ;
if ( user ! = null ) {
2019-01-23 18:03:33 +01:00
name = UserObject . getFirstName ( user ) ;
2016-05-25 23:49:47 +02:00
} else if ( chat ! = null ) {
name = chat . title ;
}
2016-10-11 13:57:01 +02:00
cell . setDialog ( did , true , name ) ;
2016-05-25 23:49:47 +02:00
}
@Override
public int getItemCount ( ) {
2019-07-18 15:01:39 +02:00
return MediaDataController . getInstance ( currentAccount ) . hints . size ( ) ;
2016-05-25 23:49:47 +02:00
}
2014-10-31 20:02:29 +01:00
}
2015-08-13 11:23:31 +02:00
public DialogsSearchAdapter ( Context context , int messagesSearch , int type ) {
2018-07-30 04:07:02 +02:00
searchAdapterHelper = new SearchAdapterHelper ( false ) ;
2017-03-31 01:58:05 +02:00
searchAdapterHelper . setDelegate ( new SearchAdapterHelper . SearchAdapterHelperDelegate ( ) {
@Override
2020-01-23 07:15:40 +01:00
public void onDataSetChanged ( int searchId ) {
lastGlobalSearchId = searchId ;
if ( lastLocalSearchId ! = searchId ) {
searchResult . clear ( ) ;
}
if ( lastMessagesSearchId ! = searchId ) {
searchResultMessages . clear ( ) ;
}
2019-06-04 12:14:50 +02:00
searchWas = true ;
2020-04-30 21:07:00 +02:00
if ( ! searchAdapterHelper . isSearchInProgress ( ) & & delegate ! = null & & reqId = = 0 ) {
2019-06-04 12:14:50 +02:00
delegate . searchStateChanged ( false ) ;
}
2017-03-31 01:58:05 +02:00
notifyDataSetChanged ( ) ;
}
@Override
public void onSetHashtags ( ArrayList < SearchAdapterHelper . HashtagObject > arrayList , HashMap < String , SearchAdapterHelper . HashtagObject > hashMap ) {
for ( int a = 0 ; a < arrayList . size ( ) ; a + + ) {
searchResultHashtags . add ( arrayList . get ( a ) . hashtag ) ;
}
if ( delegate ! = null ) {
delegate . searchStateChanged ( false ) ;
}
notifyDataSetChanged ( ) ;
}
2020-01-23 07:15:40 +01:00
@Override
public boolean canApplySearchResults ( int searchId ) {
return searchId = = lastSearchId ;
}
2017-03-31 01:58:05 +02:00
} ) ;
2014-10-31 20:02:29 +01:00
mContext = context ;
2014-11-17 23:04:31 +01:00
needMessagesSearch = messagesSearch ;
2015-08-13 11:23:31 +02:00
dialogsType = type ;
2018-07-30 04:07:02 +02:00
selfUserId = UserConfig . getInstance ( currentAccount ) . getClientUserId ( ) ;
2015-08-13 11:23:31 +02:00
loadRecentSearch ( ) ;
2019-07-18 15:01:39 +02:00
MediaDataController . getInstance ( currentAccount ) . loadHints ( true ) ;
2014-10-31 20:02:29 +01:00
}
2017-03-31 01:58:05 +02:00
public RecyclerListView getInnerListView ( ) {
return innerListView ;
}
2016-05-25 23:49:47 +02:00
public void setDelegate ( DialogsSearchAdapterDelegate delegate ) {
2014-10-31 20:02:29 +01:00
this . delegate = delegate ;
}
2014-11-19 02:23:46 +01:00
public boolean isMessagesSearchEndReached ( ) {
return messagesSearchEndReached ;
}
public void loadMoreSearchMessages ( ) {
2020-04-30 21:07:00 +02:00
if ( reqId ! = 0 ) {
return ;
}
2020-01-23 07:15:40 +01:00
searchMessagesInternal ( lastMessagesSearchString , lastMessagesSearchId ) ;
2014-11-19 02:23:46 +01:00
}
2015-03-26 18:34:47 +01:00
public String getLastSearchString ( ) {
return lastMessagesSearchString ;
}
2020-01-23 07:15:40 +01:00
private void searchMessagesInternal ( final String query , int searchId ) {
2019-06-04 12:14:50 +02:00
if ( needMessagesSearch = = 0 | | TextUtils . isEmpty ( lastMessagesSearchString ) & & TextUtils . isEmpty ( query ) ) {
2014-11-17 23:04:31 +01:00
return ;
}
2014-10-31 20:02:29 +01:00
if ( reqId ! = 0 ) {
2018-07-30 04:07:02 +02:00
ConnectionsManager . getInstance ( currentAccount ) . cancelRequest ( reqId , true ) ;
2014-10-31 20:02:29 +01:00
reqId = 0 ;
}
2019-06-04 12:14:50 +02:00
if ( TextUtils . isEmpty ( query ) ) {
2014-10-31 20:02:29 +01:00
searchResultMessages . clear ( ) ;
lastReqId = 0 ;
2014-11-19 02:23:46 +01:00
lastMessagesSearchString = null ;
2019-06-04 12:14:50 +02:00
searchWas = false ;
2014-10-31 20:02:29 +01:00
notifyDataSetChanged ( ) ;
if ( delegate ! = null ) {
delegate . searchStateChanged ( false ) ;
}
return ;
}
2015-11-26 22:04:02 +01:00
final TLRPC . TL_messages_searchGlobal req = new TLRPC . TL_messages_searchGlobal ( ) ;
2014-11-19 02:23:46 +01:00
req . limit = 20 ;
2014-10-31 20:02:29 +01:00
req . q = query ;
2019-01-23 18:03:33 +01:00
if ( query . equals ( lastMessagesSearchString ) & & ! searchResultMessages . isEmpty ( ) ) {
2015-11-26 22:04:02 +01:00
MessageObject lastMessage = searchResultMessages . get ( searchResultMessages . size ( ) - 1 ) ;
req . offset_id = lastMessage . getId ( ) ;
2019-06-04 12:14:50 +02:00
req . offset_rate = nextSearchRate ;
2015-11-26 22:04:02 +01:00
int id ;
if ( lastMessage . messageOwner . to_id . channel_id ! = 0 ) {
id = - lastMessage . messageOwner . to_id . channel_id ;
} else if ( lastMessage . messageOwner . to_id . chat_id ! = 0 ) {
id = - lastMessage . messageOwner . to_id . chat_id ;
} else {
id = lastMessage . messageOwner . to_id . user_id ;
}
2018-07-30 04:07:02 +02:00
req . offset_peer = MessagesController . getInstance ( currentAccount ) . getInputPeer ( id ) ;
2015-11-26 22:04:02 +01:00
} else {
2019-06-04 12:14:50 +02:00
req . offset_rate = 0 ;
2015-11-26 22:04:02 +01:00
req . offset_id = 0 ;
req . offset_peer = new TLRPC . TL_inputPeerEmpty ( ) ;
2014-11-19 02:23:46 +01:00
}
lastMessagesSearchString = query ;
2014-10-31 20:02:29 +01:00
final int currentReqId = + + lastReqId ;
2019-06-04 12:14:50 +02:00
/ * if ( delegate ! = null ) {
2014-10-31 20:02:29 +01:00
delegate . searchStateChanged ( true ) ;
2019-06-04 12:14:50 +02:00
} * /
2018-08-27 10:33:11 +02:00
reqId = ConnectionsManager . getInstance ( currentAccount ) . sendRequest ( req , ( response , error ) - > AndroidUtilities . runOnUIThread ( ( ) - > {
2020-01-23 07:15:40 +01:00
if ( currentReqId = = lastReqId & & ( searchId < = 0 | | searchId = = lastSearchId ) ) {
2018-08-27 10:33:11 +02:00
if ( error = = null ) {
TLRPC . messages_Messages res = ( TLRPC . messages_Messages ) response ;
MessagesStorage . getInstance ( currentAccount ) . putUsersAndChats ( res . users , res . chats , true , true ) ;
MessagesController . getInstance ( currentAccount ) . putUsers ( res . users , false ) ;
MessagesController . getInstance ( currentAccount ) . putChats ( res . chats , false ) ;
if ( req . offset_id = = 0 ) {
searchResultMessages . clear ( ) ;
}
2019-06-04 12:14:50 +02:00
nextSearchRate = res . next_rate ;
2018-08-27 10:33:11 +02:00
for ( int a = 0 ; a < res . messages . size ( ) ; a + + ) {
TLRPC . Message message = res . messages . get ( a ) ;
2020-01-23 07:15:40 +01:00
long did = MessageObject . getDialogId ( message ) ;
Integer maxId = MessagesController . getInstance ( currentAccount ) . deletedHistory . get ( did ) ;
if ( maxId ! = null & & message . id < = maxId ) {
continue ;
}
2018-08-27 10:33:11 +02:00
searchResultMessages . add ( new MessageObject ( currentAccount , message , false ) ) ;
long dialog_id = MessageObject . getDialogId ( message ) ;
ConcurrentHashMap < Long , Integer > read_max = message . out ? MessagesController . getInstance ( currentAccount ) . dialogs_read_outbox_max : MessagesController . getInstance ( currentAccount ) . dialogs_read_inbox_max ;
Integer value = read_max . get ( dialog_id ) ;
if ( value = = null ) {
value = MessagesStorage . getInstance ( currentAccount ) . getDialogReadMax ( message . out , dialog_id ) ;
read_max . put ( dialog_id , value ) ;
2014-10-31 20:02:29 +01:00
}
2018-08-27 10:33:11 +02:00
message . unread = value < message . id ;
2014-10-31 20:02:29 +01:00
}
2019-06-04 12:14:50 +02:00
searchWas = true ;
2018-08-27 10:33:11 +02:00
messagesSearchEndReached = res . messages . size ( ) ! = 20 ;
2020-01-23 07:15:40 +01:00
if ( searchId > 0 ) {
lastMessagesSearchId = searchId ;
if ( lastLocalSearchId ! = searchId ) {
searchResult . clear ( ) ;
}
if ( lastGlobalSearchId ! = searchId ) {
searchAdapterHelper . clear ( ) ;
}
}
2018-08-27 10:33:11 +02:00
notifyDataSetChanged ( ) ;
}
2014-10-31 20:02:29 +01:00
}
2020-04-30 21:07:00 +02:00
reqId = 0 ;
if ( ! searchAdapterHelper . isSearchInProgress ( ) & & delegate ! = null ) {
2018-08-27 10:33:11 +02:00
delegate . searchStateChanged ( false ) ;
}
} ) , ConnectionsManager . RequestFlagFailOnServerErrors ) ;
2014-10-31 20:02:29 +01:00
}
2015-08-13 11:23:31 +02:00
public boolean hasRecentRearch ( ) {
2020-01-23 07:15:40 +01:00
return dialogsType ! = 2 & & dialogsType ! = 4 & & dialogsType ! = 5 & & dialogsType ! = 6 & & ( ! recentSearchObjects . isEmpty ( ) | | ! MediaDataController . getInstance ( currentAccount ) . hints . isEmpty ( ) ) ;
2015-08-13 11:23:31 +02:00
}
public boolean isRecentSearchDisplayed ( ) {
2020-01-23 07:15:40 +01:00
return needMessagesSearch ! = 2 & & ! searchWas & & ( ! recentSearchObjects . isEmpty ( ) | | ! MediaDataController . getInstance ( currentAccount ) . hints . isEmpty ( ) ) & & dialogsType ! = 2 & & dialogsType ! = 4 & & dialogsType ! = 5 & & dialogsType ! = 6 ;
2015-08-13 11:23:31 +02:00
}
2015-09-24 22:52:02 +02:00
public void loadRecentSearch ( ) {
2018-08-27 10:33:11 +02:00
MessagesStorage . getInstance ( currentAccount ) . getStorageQueue ( ) . postRunnable ( ( ) - > {
try {
SQLiteCursor cursor = MessagesStorage . getInstance ( currentAccount ) . getDatabase ( ) . queryFinalized ( " SELECT did, date FROM search_recent WHERE 1 " ) ;
ArrayList < Integer > usersToLoad = new ArrayList < > ( ) ;
ArrayList < Integer > chatsToLoad = new ArrayList < > ( ) ;
ArrayList < Integer > encryptedToLoad = new ArrayList < > ( ) ;
ArrayList < TLRPC . User > encUsers = new ArrayList < > ( ) ;
final ArrayList < RecentSearchObject > arrayList = new ArrayList < > ( ) ;
final LongSparseArray < RecentSearchObject > hashMap = new LongSparseArray < > ( ) ;
while ( cursor . next ( ) ) {
long did = cursor . longValue ( 0 ) ;
boolean add = false ;
int lower_id = ( int ) did ;
int high_id = ( int ) ( did > > 32 ) ;
if ( lower_id ! = 0 ) {
2019-09-10 12:56:11 +02:00
if ( lower_id > 0 ) {
if ( dialogsType ! = 2 & & ! usersToLoad . contains ( lower_id ) ) {
usersToLoad . add ( lower_id ) ;
2018-08-27 10:33:11 +02:00
add = true ;
}
} else {
2019-09-10 12:56:11 +02:00
if ( ! chatsToLoad . contains ( - lower_id ) ) {
chatsToLoad . add ( - lower_id ) ;
add = true ;
2015-08-13 11:23:31 +02:00
}
}
2019-05-14 14:08:05 +02:00
} else if ( dialogsType = = 0 | | dialogsType = = 3 ) {
2018-08-27 10:33:11 +02:00
if ( ! encryptedToLoad . contains ( high_id ) ) {
encryptedToLoad . add ( high_id ) ;
add = true ;
2015-08-13 11:23:31 +02:00
}
}
2018-08-27 10:33:11 +02:00
if ( add ) {
RecentSearchObject recentSearchObject = new RecentSearchObject ( ) ;
recentSearchObject . did = did ;
recentSearchObject . date = cursor . intValue ( 1 ) ;
arrayList . add ( recentSearchObject ) ;
hashMap . put ( recentSearchObject . did , recentSearchObject ) ;
}
}
cursor . dispose ( ) ;
2015-08-13 11:23:31 +02:00
2018-08-27 10:33:11 +02:00
ArrayList < TLRPC . User > users = new ArrayList < > ( ) ;
2015-08-13 11:23:31 +02:00
2018-08-27 10:33:11 +02:00
if ( ! encryptedToLoad . isEmpty ( ) ) {
ArrayList < TLRPC . EncryptedChat > encryptedChats = new ArrayList < > ( ) ;
MessagesStorage . getInstance ( currentAccount ) . getEncryptedChatsInternal ( TextUtils . join ( " , " , encryptedToLoad ) , encryptedChats , usersToLoad ) ;
for ( int a = 0 ; a < encryptedChats . size ( ) ; a + + ) {
hashMap . get ( ( long ) encryptedChats . get ( a ) . id < < 32 ) . object = encryptedChats . get ( a ) ;
2015-08-13 11:23:31 +02:00
}
2018-08-27 10:33:11 +02:00
}
2015-08-13 11:23:31 +02:00
2018-08-27 10:33:11 +02:00
if ( ! chatsToLoad . isEmpty ( ) ) {
ArrayList < TLRPC . Chat > chats = new ArrayList < > ( ) ;
MessagesStorage . getInstance ( currentAccount ) . getChatsInternal ( TextUtils . join ( " , " , chatsToLoad ) , chats ) ;
for ( int a = 0 ; a < chats . size ( ) ; a + + ) {
TLRPC . Chat chat = chats . get ( a ) ;
2019-09-10 12:56:11 +02:00
long did = - chat . id ;
2018-08-27 10:33:11 +02:00
if ( chat . migrated_to ! = null ) {
RecentSearchObject recentSearchObject = hashMap . get ( did ) ;
hashMap . remove ( did ) ;
2015-08-13 11:23:31 +02:00
if ( recentSearchObject ! = null ) {
2018-08-27 10:33:11 +02:00
arrayList . remove ( recentSearchObject ) ;
2015-08-13 11:23:31 +02:00
}
2018-08-27 10:33:11 +02:00
} else {
hashMap . get ( did ) . object = chat ;
2015-08-13 11:23:31 +02:00
}
}
2018-08-27 10:33:11 +02:00
}
2015-08-13 11:23:31 +02:00
2018-08-27 10:33:11 +02:00
if ( ! usersToLoad . isEmpty ( ) ) {
MessagesStorage . getInstance ( currentAccount ) . getUsersInternal ( TextUtils . join ( " , " , usersToLoad ) , users ) ;
for ( int a = 0 ; a < users . size ( ) ; a + + ) {
TLRPC . User user = users . get ( a ) ;
2020-03-30 14:00:09 +02:00
RecentSearchObject recentSearchObject = hashMap . get ( user . id ) ;
2018-08-27 10:33:11 +02:00
if ( recentSearchObject ! = null ) {
recentSearchObject . object = user ;
2015-08-13 11:23:31 +02:00
}
2018-08-27 10:33:11 +02:00
}
2015-08-13 11:23:31 +02:00
}
2018-08-27 10:33:11 +02:00
Collections . sort ( arrayList , ( lhs , rhs ) - > {
if ( lhs . date < rhs . date ) {
return 1 ;
} else if ( lhs . date > rhs . date ) {
return - 1 ;
} else {
return 0 ;
}
} ) ;
AndroidUtilities . runOnUIThread ( ( ) - > setRecentSearch ( arrayList , hashMap ) ) ;
} catch ( Exception e ) {
FileLog . e ( e ) ;
2015-08-13 11:23:31 +02:00
}
} ) ;
}
public void putRecentSearch ( final long did , TLObject object ) {
RecentSearchObject recentSearchObject = recentSearchObjectsById . get ( did ) ;
if ( recentSearchObject = = null ) {
recentSearchObject = new RecentSearchObject ( ) ;
recentSearchObjectsById . put ( did , recentSearchObject ) ;
} else {
recentSearchObjects . remove ( recentSearchObject ) ;
}
recentSearchObjects . add ( 0 , recentSearchObject ) ;
recentSearchObject . did = did ;
recentSearchObject . object = object ;
2016-04-22 15:49:00 +02:00
recentSearchObject . date = ( int ) ( System . currentTimeMillis ( ) / 1000 ) ;
2015-08-13 11:23:31 +02:00
notifyDataSetChanged ( ) ;
2018-08-27 10:33:11 +02:00
MessagesStorage . getInstance ( currentAccount ) . getStorageQueue ( ) . postRunnable ( ( ) - > {
try {
SQLitePreparedStatement state = MessagesStorage . getInstance ( currentAccount ) . getDatabase ( ) . executeFast ( " REPLACE INTO search_recent VALUES(?, ?) " ) ;
state . requery ( ) ;
state . bindLong ( 1 , did ) ;
state . bindInteger ( 2 , ( int ) ( System . currentTimeMillis ( ) / 1000 ) ) ;
state . step ( ) ;
state . dispose ( ) ;
} catch ( Exception e ) {
FileLog . e ( e ) ;
2015-08-13 11:23:31 +02:00
}
} ) ;
}
public void clearRecentSearch ( ) {
2018-07-30 04:07:02 +02:00
recentSearchObjectsById = new LongSparseArray < > ( ) ;
2015-08-13 11:23:31 +02:00
recentSearchObjects = new ArrayList < > ( ) ;
notifyDataSetChanged ( ) ;
2018-08-27 10:33:11 +02:00
MessagesStorage . getInstance ( currentAccount ) . getStorageQueue ( ) . postRunnable ( ( ) - > {
try {
MessagesStorage . getInstance ( currentAccount ) . getDatabase ( ) . executeFast ( " DELETE FROM search_recent WHERE 1 " ) . stepThis ( ) . dispose ( ) ;
} catch ( Exception e ) {
FileLog . e ( e ) ;
2015-08-13 11:23:31 +02:00
}
} ) ;
}
2020-03-30 14:00:09 +02:00
public void removeRecentSearch ( long did ) {
RecentSearchObject object = recentSearchObjectsById . get ( did ) ;
if ( object = = null ) {
return ;
}
recentSearchObjectsById . remove ( did ) ;
recentSearchObjects . remove ( object ) ;
notifyDataSetChanged ( ) ;
MessagesStorage . getInstance ( currentAccount ) . getStorageQueue ( ) . postRunnable ( ( ) - > {
try {
MessagesStorage . getInstance ( currentAccount ) . getDatabase ( ) . executeFast ( " DELETE FROM search_recent WHERE did = " + did ) . stepThis ( ) . dispose ( ) ;
} catch ( Exception e ) {
FileLog . e ( e ) ;
}
} ) ;
}
2017-03-31 01:58:05 +02:00
public void addHashtagsFromMessage ( CharSequence message ) {
searchAdapterHelper . addHashtagsFromMessage ( message ) ;
}
2018-07-30 04:07:02 +02:00
private void setRecentSearch ( ArrayList < RecentSearchObject > arrayList , LongSparseArray < RecentSearchObject > hashMap ) {
2015-08-13 11:23:31 +02:00
recentSearchObjects = arrayList ;
recentSearchObjectsById = hashMap ;
for ( int a = 0 ; a < recentSearchObjects . size ( ) ; a + + ) {
RecentSearchObject recentSearchObject = recentSearchObjects . get ( a ) ;
if ( recentSearchObject . object instanceof TLRPC . User ) {
2018-07-30 04:07:02 +02:00
MessagesController . getInstance ( currentAccount ) . putUser ( ( TLRPC . User ) recentSearchObject . object , true ) ;
2015-08-13 11:23:31 +02:00
} else if ( recentSearchObject . object instanceof TLRPC . Chat ) {
2018-07-30 04:07:02 +02:00
MessagesController . getInstance ( currentAccount ) . putChat ( ( TLRPC . Chat ) recentSearchObject . object , true ) ;
2015-08-13 11:23:31 +02:00
} else if ( recentSearchObject . object instanceof TLRPC . EncryptedChat ) {
2018-07-30 04:07:02 +02:00
MessagesController . getInstance ( currentAccount ) . putEncryptedChat ( ( TLRPC . EncryptedChat ) recentSearchObject . object , true ) ;
2015-08-13 11:23:31 +02:00
}
}
notifyDataSetChanged ( ) ;
}
private void searchDialogsInternal ( final String query , final int searchId ) {
2015-03-19 00:09:45 +01:00
if ( needMessagesSearch = = 2 ) {
return ;
}
2018-08-27 10:33:11 +02:00
MessagesStorage . getInstance ( currentAccount ) . getStorageQueue ( ) . postRunnable ( ( ) - > {
try {
String savedMessages = LocaleController . getString ( " SavedMessages " , R . string . SavedMessages ) . toLowerCase ( ) ;
String search1 = query . trim ( ) . toLowerCase ( ) ;
if ( search1 . length ( ) = = 0 ) {
2020-01-23 07:15:40 +01:00
lastSearchId = 0 ;
2018-08-27 10:33:11 +02:00
updateSearchResults ( new ArrayList < > ( ) , new ArrayList < > ( ) , new ArrayList < > ( ) , lastSearchId ) ;
return ;
}
String search2 = LocaleController . getInstance ( ) . getTranslitString ( search1 ) ;
if ( search1 . equals ( search2 ) | | search2 . length ( ) = = 0 ) {
search2 = null ;
}
2019-05-14 14:08:05 +02:00
String [ ] search = new String [ 1 + ( search2 ! = null ? 1 : 0 ) ] ;
2018-08-27 10:33:11 +02:00
search [ 0 ] = search1 ;
if ( search2 ! = null ) {
search [ 1 ] = search2 ;
}
2014-12-01 18:56:31 +01:00
2018-08-27 10:33:11 +02:00
ArrayList < Integer > usersToLoad = new ArrayList < > ( ) ;
ArrayList < Integer > chatsToLoad = new ArrayList < > ( ) ;
ArrayList < Integer > encryptedToLoad = new ArrayList < > ( ) ;
ArrayList < TLRPC . User > encUsers = new ArrayList < > ( ) ;
int resultCount = 0 ;
LongSparseArray < DialogSearchResult > dialogsResult = new LongSparseArray < > ( ) ;
SQLiteCursor cursor = MessagesStorage . getInstance ( currentAccount ) . getDatabase ( ) . queryFinalized ( " SELECT did, date FROM dialogs ORDER BY date DESC LIMIT 600 " ) ;
while ( cursor . next ( ) ) {
long id = cursor . longValue ( 0 ) ;
DialogSearchResult dialogSearchResult = new DialogSearchResult ( ) ;
dialogSearchResult . date = cursor . intValue ( 1 ) ;
dialogsResult . put ( id , dialogSearchResult ) ;
int lower_id = ( int ) id ;
int high_id = ( int ) ( id > > 32 ) ;
if ( lower_id ! = 0 ) {
2019-09-10 12:56:11 +02:00
if ( lower_id > 0 ) {
if ( dialogsType = = 4 & & lower_id = = selfUserId ) {
2019-07-18 15:01:39 +02:00
continue ;
}
2019-09-10 12:56:11 +02:00
if ( dialogsType ! = 2 & & ! usersToLoad . contains ( lower_id ) ) {
usersToLoad . add ( lower_id ) ;
2018-08-27 10:33:11 +02:00
}
} else {
2019-09-10 12:56:11 +02:00
if ( dialogsType = = 4 ) {
continue ;
}
if ( ! chatsToLoad . contains ( - lower_id ) ) {
chatsToLoad . add ( - lower_id ) ;
2014-12-01 18:56:31 +01:00
}
2018-08-27 10:33:11 +02:00
}
2019-05-14 14:08:05 +02:00
} else if ( dialogsType = = 0 | | dialogsType = = 3 ) {
2018-08-27 10:33:11 +02:00
if ( ! encryptedToLoad . contains ( high_id ) ) {
encryptedToLoad . add ( high_id ) ;
2014-10-31 20:02:29 +01:00
}
2014-12-01 18:56:31 +01:00
}
2018-08-27 10:33:11 +02:00
}
cursor . dispose ( ) ;
2019-12-31 14:08:08 +01:00
if ( dialogsType ! = 4 & & savedMessages . startsWith ( search1 ) ) {
2018-08-27 10:33:11 +02:00
TLRPC . User user = UserConfig . getInstance ( currentAccount ) . getCurrentUser ( ) ;
DialogSearchResult dialogSearchResult = new DialogSearchResult ( ) ;
dialogSearchResult . date = Integer . MAX_VALUE ;
dialogSearchResult . name = savedMessages ;
dialogSearchResult . object = user ;
2020-03-30 14:00:09 +02:00
dialogsResult . put ( user . id , dialogSearchResult ) ;
2018-08-27 10:33:11 +02:00
resultCount + + ;
}
2017-12-08 18:35:59 +01:00
2018-08-27 10:33:11 +02:00
if ( ! usersToLoad . isEmpty ( ) ) {
cursor = MessagesStorage . getInstance ( currentAccount ) . getDatabase ( ) . queryFinalized ( String . format ( Locale . US , " SELECT data, status, name FROM users WHERE uid IN(%s) " , TextUtils . join ( " , " , usersToLoad ) ) ) ;
while ( cursor . next ( ) ) {
String name = cursor . stringValue ( 2 ) ;
String tName = LocaleController . getInstance ( ) . getTranslitString ( name ) ;
if ( name . equals ( tName ) ) {
tName = null ;
}
String username = null ;
int usernamePos = name . lastIndexOf ( " ;;; " ) ;
if ( usernamePos ! = - 1 ) {
username = name . substring ( usernamePos + 3 ) ;
}
int found = 0 ;
for ( String q : search ) {
if ( name . startsWith ( q ) | | name . contains ( " " + q ) | | tName ! = null & & ( tName . startsWith ( q ) | | tName . contains ( " " + q ) ) ) {
found = 1 ;
} else if ( username ! = null & & username . startsWith ( q ) ) {
found = 2 ;
2014-12-01 18:56:31 +01:00
}
2018-08-27 10:33:11 +02:00
if ( found ! = 0 ) {
NativeByteBuffer data = cursor . byteBufferValue ( 0 ) ;
if ( data ! = null ) {
TLRPC . User user = TLRPC . User . TLdeserialize ( data , data . readInt32 ( false ) , false ) ;
data . reuse ( ) ;
2020-03-30 14:00:09 +02:00
DialogSearchResult dialogSearchResult = dialogsResult . get ( user . id ) ;
2018-08-27 10:33:11 +02:00
if ( user . status ! = null ) {
user . status . expires = cursor . intValue ( 1 ) ;
2014-10-31 20:02:29 +01:00
}
2018-08-27 10:33:11 +02:00
if ( found = = 1 ) {
dialogSearchResult . name = AndroidUtilities . generateSearchName ( user . first_name , user . last_name , q ) ;
} else {
dialogSearchResult . name = AndroidUtilities . generateSearchName ( " @ " + user . username , null , " @ " + q ) ;
}
dialogSearchResult . object = user ;
resultCount + + ;
2014-12-01 18:56:31 +01:00
}
2018-08-27 10:33:11 +02:00
break ;
2014-12-01 18:56:31 +01:00
}
}
}
2018-08-27 10:33:11 +02:00
cursor . dispose ( ) ;
}
2014-12-01 18:56:31 +01:00
2018-08-27 10:33:11 +02:00
if ( ! chatsToLoad . isEmpty ( ) ) {
cursor = MessagesStorage . getInstance ( currentAccount ) . getDatabase ( ) . queryFinalized ( String . format ( Locale . US , " SELECT data, name FROM chats WHERE uid IN(%s) " , TextUtils . join ( " , " , chatsToLoad ) ) ) ;
while ( cursor . next ( ) ) {
String name = cursor . stringValue ( 1 ) ;
String tName = LocaleController . getInstance ( ) . getTranslitString ( name ) ;
if ( name . equals ( tName ) ) {
tName = null ;
}
for ( String q : search ) {
if ( name . startsWith ( q ) | | name . contains ( " " + q ) | | tName ! = null & & ( tName . startsWith ( q ) | | tName . contains ( " " + q ) ) ) {
NativeByteBuffer data = cursor . byteBufferValue ( 0 ) ;
if ( data ! = null ) {
TLRPC . Chat chat = TLRPC . Chat . TLdeserialize ( data , data . readInt32 ( false ) , false ) ;
data . reuse ( ) ;
if ( ! ( chat = = null | | chat . deactivated | | ChatObject . isChannel ( chat ) & & ChatObject . isNotInChat ( chat ) ) ) {
2019-09-10 12:56:11 +02:00
long dialog_id = - chat . id ;
2018-08-27 10:33:11 +02:00
DialogSearchResult dialogSearchResult = dialogsResult . get ( dialog_id ) ;
dialogSearchResult . name = AndroidUtilities . generateSearchName ( chat . title , null , q ) ;
dialogSearchResult . object = chat ;
resultCount + + ;
2014-10-31 20:02:29 +01:00
}
}
2018-08-27 10:33:11 +02:00
break ;
2014-10-31 20:02:29 +01:00
}
}
}
2018-08-27 10:33:11 +02:00
cursor . dispose ( ) ;
}
2014-10-31 20:02:29 +01:00
2018-08-27 10:33:11 +02:00
if ( ! encryptedToLoad . isEmpty ( ) ) {
cursor = MessagesStorage . getInstance ( currentAccount ) . getDatabase ( ) . queryFinalized ( String . format ( Locale . US , " SELECT q.data, u.name, q.user, q.g, q.authkey, q.ttl, u.data, u.status, q.layer, q.seq_in, q.seq_out, q.use_count, q.exchange_id, q.key_date, q.fprint, q.fauthkey, q.khash, q.in_seq_no, q.admin_id, q.mtproto_seq FROM enc_chats as q INNER JOIN users as u ON q.user = u.uid WHERE q.uid IN(%s) " , TextUtils . join ( " , " , encryptedToLoad ) ) ) ;
while ( cursor . next ( ) ) {
String name = cursor . stringValue ( 1 ) ;
String tName = LocaleController . getInstance ( ) . getTranslitString ( name ) ;
if ( name . equals ( tName ) ) {
tName = null ;
}
2014-10-31 20:02:29 +01:00
2018-08-27 10:33:11 +02:00
String username = null ;
int usernamePos = name . lastIndexOf ( " ;;; " ) ;
if ( usernamePos ! = - 1 ) {
username = name . substring ( usernamePos + 2 ) ;
}
int found = 0 ;
for ( int a = 0 ; a < search . length ; a + + ) {
String q = search [ a ] ;
if ( name . startsWith ( q ) | | name . contains ( " " + q ) | | tName ! = null & & ( tName . startsWith ( q ) | | tName . contains ( " " + q ) ) ) {
found = 1 ;
} else if ( username ! = null & & username . startsWith ( q ) ) {
found = 2 ;
2014-10-31 20:02:29 +01:00
}
2018-08-27 10:33:11 +02:00
if ( found ! = 0 ) {
TLRPC . EncryptedChat chat = null ;
TLRPC . User user = null ;
NativeByteBuffer data = cursor . byteBufferValue ( 0 ) ;
if ( data ! = null ) {
chat = TLRPC . EncryptedChat . TLdeserialize ( data , data . readInt32 ( false ) , false ) ;
data . reuse ( ) ;
}
data = cursor . byteBufferValue ( 6 ) ;
if ( data ! = null ) {
user = TLRPC . User . TLdeserialize ( data , data . readInt32 ( false ) , false ) ;
data . reuse ( ) ;
}
if ( chat ! = null & & user ! = null ) {
DialogSearchResult dialogSearchResult = dialogsResult . get ( ( long ) chat . id < < 32 ) ;
chat . user_id = cursor . intValue ( 2 ) ;
chat . a_or_b = cursor . byteArrayValue ( 3 ) ;
chat . auth_key = cursor . byteArrayValue ( 4 ) ;
chat . ttl = cursor . intValue ( 5 ) ;
chat . layer = cursor . intValue ( 8 ) ;
chat . seq_in = cursor . intValue ( 9 ) ;
chat . seq_out = cursor . intValue ( 10 ) ;
int use_count = cursor . intValue ( 11 ) ;
chat . key_use_count_in = ( short ) ( use_count > > 16 ) ;
chat . key_use_count_out = ( short ) ( use_count ) ;
chat . exchange_id = cursor . longValue ( 12 ) ;
chat . key_create_date = cursor . intValue ( 13 ) ;
chat . future_key_fingerprint = cursor . longValue ( 14 ) ;
chat . future_auth_key = cursor . byteArrayValue ( 15 ) ;
chat . key_hash = cursor . byteArrayValue ( 16 ) ;
chat . in_seq_no = cursor . intValue ( 17 ) ;
int admin_id = cursor . intValue ( 18 ) ;
if ( admin_id ! = 0 ) {
chat . admin_id = admin_id ;
2016-05-25 23:49:47 +02:00
}
2018-08-27 10:33:11 +02:00
chat . mtproto_seq = cursor . intValue ( 19 ) ;
2015-02-01 19:51:02 +01:00
2018-08-27 10:33:11 +02:00
if ( user . status ! = null ) {
user . status . expires = cursor . intValue ( 7 ) ;
2014-10-31 20:02:29 +01:00
}
2018-08-27 10:33:11 +02:00
if ( found = = 1 ) {
dialogSearchResult . name = new SpannableStringBuilder ( ContactsController . formatName ( user . first_name , user . last_name ) ) ;
( ( SpannableStringBuilder ) dialogSearchResult . name ) . setSpan ( new ForegroundColorSpan ( Theme . getColor ( Theme . key_chats_secretName ) ) , 0 , dialogSearchResult . name . length ( ) , Spanned . SPAN_EXCLUSIVE_EXCLUSIVE ) ;
} else {
dialogSearchResult . name = AndroidUtilities . generateSearchName ( " @ " + user . username , null , " @ " + q ) ;
}
dialogSearchResult . object = chat ;
encUsers . add ( user ) ;
resultCount + + ;
2014-10-31 20:02:29 +01:00
}
2018-08-27 10:33:11 +02:00
break ;
2014-10-31 20:02:29 +01:00
}
}
}
2018-08-27 10:33:11 +02:00
cursor . dispose ( ) ;
}
2014-10-31 20:02:29 +01:00
2018-08-27 10:33:11 +02:00
ArrayList < DialogSearchResult > searchResults = new ArrayList < > ( resultCount ) ;
for ( int a = 0 ; a < dialogsResult . size ( ) ; a + + ) {
DialogSearchResult dialogSearchResult = dialogsResult . valueAt ( a ) ;
if ( dialogSearchResult . object ! = null & & dialogSearchResult . name ! = null ) {
searchResults . add ( dialogSearchResult ) ;
2014-12-01 18:56:31 +01:00
}
2018-08-27 10:33:11 +02:00
}
2014-12-01 18:56:31 +01:00
2018-08-27 10:33:11 +02:00
Collections . sort ( searchResults , ( lhs , rhs ) - > {
if ( lhs . date < rhs . date ) {
return 1 ;
} else if ( lhs . date > rhs . date ) {
return - 1 ;
}
return 0 ;
} ) ;
2014-12-01 18:56:31 +01:00
2018-08-27 10:33:11 +02:00
ArrayList < TLObject > resultArray = new ArrayList < > ( ) ;
ArrayList < CharSequence > resultArrayNames = new ArrayList < > ( ) ;
2014-12-01 18:56:31 +01:00
2018-08-27 10:33:11 +02:00
for ( int a = 0 ; a < searchResults . size ( ) ; a + + ) {
DialogSearchResult dialogSearchResult = searchResults . get ( a ) ;
resultArray . add ( dialogSearchResult . object ) ;
resultArrayNames . add ( dialogSearchResult . name ) ;
}
2014-12-01 18:56:31 +01:00
2018-08-27 10:33:11 +02:00
if ( dialogsType ! = 2 ) {
cursor = MessagesStorage . getInstance ( currentAccount ) . getDatabase ( ) . queryFinalized ( " SELECT u.data, u.status, u.name, u.uid FROM users as u INNER JOIN contacts as c ON u.uid = c.uid " ) ;
while ( cursor . next ( ) ) {
int uid = cursor . intValue ( 3 ) ;
2020-03-30 14:00:09 +02:00
if ( dialogsResult . indexOfKey ( uid ) > = 0 ) {
2018-08-27 10:33:11 +02:00
continue ;
}
String name = cursor . stringValue ( 2 ) ;
String tName = LocaleController . getInstance ( ) . getTranslitString ( name ) ;
if ( name . equals ( tName ) ) {
tName = null ;
}
String username = null ;
int usernamePos = name . lastIndexOf ( " ;;; " ) ;
if ( usernamePos ! = - 1 ) {
username = name . substring ( usernamePos + 3 ) ;
}
int found = 0 ;
for ( String q : search ) {
if ( name . startsWith ( q ) | | name . contains ( " " + q ) | | tName ! = null & & ( tName . startsWith ( q ) | | tName . contains ( " " + q ) ) ) {
found = 1 ;
} else if ( username ! = null & & username . startsWith ( q ) ) {
found = 2 ;
2015-06-29 19:12:11 +02:00
}
2018-08-27 10:33:11 +02:00
if ( found ! = 0 ) {
NativeByteBuffer data = cursor . byteBufferValue ( 0 ) ;
if ( data ! = null ) {
TLRPC . User user = TLRPC . User . TLdeserialize ( data , data . readInt32 ( false ) , false ) ;
data . reuse ( ) ;
if ( user . status ! = null ) {
user . status . expires = cursor . intValue ( 1 ) ;
2014-12-01 18:56:31 +01:00
}
2018-08-27 10:33:11 +02:00
if ( found = = 1 ) {
resultArrayNames . add ( AndroidUtilities . generateSearchName ( user . first_name , user . last_name , q ) ) ;
} else {
resultArrayNames . add ( AndroidUtilities . generateSearchName ( " @ " + user . username , null , " @ " + q ) ) ;
}
resultArray . add ( user ) ;
2014-10-31 20:02:29 +01:00
}
2018-08-27 10:33:11 +02:00
break ;
2014-10-31 20:02:29 +01:00
}
}
}
2018-08-27 10:33:11 +02:00
cursor . dispose ( ) ;
2014-10-31 20:02:29 +01:00
}
2018-08-27 10:33:11 +02:00
updateSearchResults ( resultArray , resultArrayNames , encUsers , searchId ) ;
} catch ( Exception e ) {
FileLog . e ( e ) ;
2014-10-31 20:02:29 +01:00
}
} ) ;
}
2014-11-21 01:14:44 +01:00
private void updateSearchResults ( final ArrayList < TLObject > result , final ArrayList < CharSequence > names , final ArrayList < TLRPC . User > encUsers , final int searchId ) {
2018-08-27 10:33:11 +02:00
AndroidUtilities . runOnUIThread ( ( ) - > {
if ( searchId ! = lastSearchId ) {
return ;
}
2020-01-23 07:15:40 +01:00
lastLocalSearchId = searchId ;
if ( lastGlobalSearchId ! = searchId ) {
searchAdapterHelper . clear ( ) ;
}
if ( lastMessagesSearchId ! = searchId ) {
searchResultMessages . clear ( ) ;
}
2019-06-04 12:14:50 +02:00
searchWas = true ;
2018-08-27 10:33:11 +02:00
for ( int a = 0 ; a < result . size ( ) ; a + + ) {
TLObject obj = result . get ( a ) ;
if ( obj instanceof TLRPC . User ) {
TLRPC . User user = ( TLRPC . User ) obj ;
MessagesController . getInstance ( currentAccount ) . putUser ( user , true ) ;
} else if ( obj instanceof TLRPC . Chat ) {
TLRPC . Chat chat = ( TLRPC . Chat ) obj ;
MessagesController . getInstance ( currentAccount ) . putChat ( chat , true ) ;
} else if ( obj instanceof TLRPC . EncryptedChat ) {
TLRPC . EncryptedChat chat = ( TLRPC . EncryptedChat ) obj ;
MessagesController . getInstance ( currentAccount ) . putEncryptedChat ( chat , true ) ;
2014-10-31 20:02:29 +01:00
}
}
2018-08-27 10:33:11 +02:00
MessagesController . getInstance ( currentAccount ) . putUsers ( encUsers , true ) ;
searchResult = result ;
searchResultNames = names ;
searchAdapterHelper . mergeResults ( searchResult ) ;
notifyDataSetChanged ( ) ;
2019-06-04 12:14:50 +02:00
if ( delegate ! = null ) {
if ( getItemCount ( ) = = 0 & & ( searchRunnable2 ! = null | | searchAdapterHelper . isSearchInProgress ( ) ) ) {
delegate . searchStateChanged ( true ) ;
} else {
delegate . searchStateChanged ( false ) ;
}
}
2014-10-31 20:02:29 +01:00
} ) ;
}
2019-07-18 15:01:39 +02:00
public boolean isHashtagSearch ( ) {
return ! searchResultHashtags . isEmpty ( ) ;
}
2015-03-26 18:34:47 +01:00
public void clearRecentHashtags ( ) {
2017-03-31 01:58:05 +02:00
searchAdapterHelper . clearRecentHashtags ( ) ;
2015-03-26 18:34:47 +01:00
searchResultHashtags . clear ( ) ;
notifyDataSetChanged ( ) ;
}
2019-06-04 12:14:50 +02:00
public void searchDialogs ( String text ) {
if ( text ! = null & & text . equals ( lastSearchText ) ) {
2014-10-31 20:02:29 +01:00
return ;
}
2019-06-04 12:14:50 +02:00
lastSearchText = text ;
2019-05-14 14:08:05 +02:00
if ( searchRunnable ! = null ) {
Utilities . searchQueue . cancelRunnable ( searchRunnable ) ;
searchRunnable = null ;
}
if ( searchRunnable2 ! = null ) {
AndroidUtilities . cancelRunOnUIThread ( searchRunnable2 ) ;
searchRunnable2 = null ;
2014-10-31 20:02:29 +01:00
}
2019-06-04 12:14:50 +02:00
String query ;
if ( text ! = null ) {
query = text . trim ( ) ;
} else {
query = null ;
}
2019-01-23 18:03:33 +01:00
if ( TextUtils . isEmpty ( query ) ) {
2017-03-31 01:58:05 +02:00
searchAdapterHelper . unloadRecentHashtags ( ) ;
2014-11-06 22:34:47 +01:00
searchResult . clear ( ) ;
searchResultNames . clear ( ) ;
2015-03-26 18:34:47 +01:00
searchResultHashtags . clear ( ) ;
2017-12-08 18:35:59 +01:00
searchAdapterHelper . mergeResults ( null ) ;
2015-03-19 00:09:45 +01:00
if ( needMessagesSearch ! = 2 ) {
2020-01-23 07:15:40 +01:00
searchAdapterHelper . queryServerSearch ( null , true , true , true , true , dialogsType = = 2 , 0 , dialogsType = = 0 , 0 , 0 ) ;
2015-03-19 00:09:45 +01:00
}
2019-06-04 12:14:50 +02:00
searchWas = false ;
2020-01-23 07:15:40 +01:00
lastSearchId = 0 ;
searchMessagesInternal ( null , 0 ) ;
2014-10-31 20:02:29 +01:00
notifyDataSetChanged ( ) ;
} else {
2015-06-29 19:12:11 +02:00
if ( needMessagesSearch ! = 2 & & ( query . startsWith ( " # " ) & & query . length ( ) = = 1 ) ) {
2015-03-26 18:34:47 +01:00
messagesSearchEndReached = true ;
2017-03-31 01:58:05 +02:00
if ( searchAdapterHelper . loadRecentHashtags ( ) ) {
searchResultMessages . clear ( ) ;
searchResultHashtags . clear ( ) ;
ArrayList < SearchAdapterHelper . HashtagObject > hashtags = searchAdapterHelper . getHashtags ( ) ;
for ( int a = 0 ; a < hashtags . size ( ) ; a + + ) {
searchResultHashtags . add ( hashtags . get ( a ) . hashtag ) ;
}
if ( delegate ! = null ) {
delegate . searchStateChanged ( false ) ;
}
} else {
2019-06-04 12:14:50 +02:00
/ * if ( delegate ! = null ) {
2015-03-26 18:34:47 +01:00
delegate . searchStateChanged ( true ) ;
2019-06-04 12:14:50 +02:00
} * /
2015-03-26 18:34:47 +01:00
}
notifyDataSetChanged ( ) ;
} else {
searchResultHashtags . clear ( ) ;
2016-10-11 13:57:01 +02:00
notifyDataSetChanged ( ) ;
2015-03-26 18:34:47 +01:00
}
2014-11-21 01:14:44 +01:00
final int searchId = + + lastSearchId ;
2019-06-04 12:14:50 +02:00
Utilities . searchQueue . postRunnable ( searchRunnable = ( ) - > {
2019-05-14 14:08:05 +02:00
searchRunnable = null ;
searchDialogsInternal ( query , searchId ) ;
AndroidUtilities . runOnUIThread ( searchRunnable2 = ( ) - > {
searchRunnable2 = null ;
2019-06-04 12:14:50 +02:00
if ( searchId ! = lastSearchId ) {
return ;
}
2019-05-14 14:08:05 +02:00
if ( needMessagesSearch ! = 2 ) {
2020-01-23 07:15:40 +01:00
searchAdapterHelper . queryServerSearch ( query , true , dialogsType ! = 4 , true , dialogsType ! = 4 , dialogsType = = 2 , 0 , dialogsType = = 0 , 0 , searchId ) ;
2014-10-31 20:02:29 +01:00
}
2020-01-23 07:15:40 +01:00
searchMessagesInternal ( text , searchId ) ;
2019-05-14 14:08:05 +02:00
} ) ;
} , 300 ) ;
2014-10-31 20:02:29 +01:00
}
}
@Override
2015-05-21 23:27:27 +02:00
public int getItemCount ( ) {
2016-05-25 23:49:47 +02:00
if ( isRecentSearchDisplayed ( ) ) {
2019-07-18 15:01:39 +02:00
return ( ! recentSearchObjects . isEmpty ( ) ? recentSearchObjects . size ( ) + 1 : 0 ) + ( ! MediaDataController . getInstance ( currentAccount ) . hints . isEmpty ( ) ? 2 : 0 ) ;
2015-08-13 11:23:31 +02:00
}
2015-03-26 18:34:47 +01:00
if ( ! searchResultHashtags . isEmpty ( ) ) {
return searchResultHashtags . size ( ) + 1 ;
}
2014-11-06 22:34:47 +01:00
int count = searchResult . size ( ) ;
2018-07-30 04:07:02 +02:00
int localServerCount = searchAdapterHelper . getLocalServerSearch ( ) . size ( ) ;
2017-03-31 01:58:05 +02:00
int globalCount = searchAdapterHelper . getGlobalSearch ( ) . size ( ) ;
2019-07-18 15:01:39 +02:00
int phoneCount = searchAdapterHelper . getPhoneSearch ( ) . size ( ) ;
2014-11-06 22:34:47 +01:00
int messagesCount = searchResultMessages . size ( ) ;
2018-07-30 04:07:02 +02:00
count + = localServerCount ;
2014-11-06 22:34:47 +01:00
if ( globalCount ! = 0 ) {
count + = globalCount + 1 ;
}
2019-07-18 15:01:39 +02:00
if ( phoneCount ! = 0 ) {
count + = phoneCount ;
}
2014-11-06 22:34:47 +01:00
if ( messagesCount ! = 0 ) {
2014-11-19 02:23:46 +01:00
count + = messagesCount + 1 + ( messagesSearchEndReached ? 0 : 1 ) ;
2014-10-31 20:02:29 +01:00
}
2014-11-06 22:34:47 +01:00
return count ;
2014-10-31 20:02:29 +01:00
}
public Object getItem ( int i ) {
2016-05-25 23:49:47 +02:00
if ( isRecentSearchDisplayed ( ) ) {
2019-07-18 15:01:39 +02:00
int offset = ( ! MediaDataController . getInstance ( currentAccount ) . hints . isEmpty ( ) ? 2 : 0 ) ;
2016-05-25 23:49:47 +02:00
if ( i > offset & & i - 1 - offset < recentSearchObjects . size ( ) ) {
TLObject object = recentSearchObjects . get ( i - 1 - offset ) . object ;
2015-11-26 22:04:02 +01:00
if ( object instanceof TLRPC . User ) {
2018-07-30 04:07:02 +02:00
TLRPC . User user = MessagesController . getInstance ( currentAccount ) . getUser ( ( ( TLRPC . User ) object ) . id ) ;
2015-11-26 22:04:02 +01:00
if ( user ! = null ) {
object = user ;
}
} else if ( object instanceof TLRPC . Chat ) {
2018-07-30 04:07:02 +02:00
TLRPC . Chat chat = MessagesController . getInstance ( currentAccount ) . getChat ( ( ( TLRPC . Chat ) object ) . id ) ;
2015-11-26 22:04:02 +01:00
if ( chat ! = null ) {
object = chat ;
}
}
return object ;
2015-08-13 11:23:31 +02:00
} else {
return null ;
}
}
2015-03-26 18:34:47 +01:00
if ( ! searchResultHashtags . isEmpty ( ) ) {
2015-08-13 11:23:31 +02:00
if ( i > 0 ) {
return searchResultHashtags . get ( i - 1 ) ;
} else {
return null ;
}
2015-03-26 18:34:47 +01:00
}
2017-03-31 01:58:05 +02:00
ArrayList < TLObject > globalSearch = searchAdapterHelper . getGlobalSearch ( ) ;
2018-07-30 04:07:02 +02:00
ArrayList < TLObject > localServerSearch = searchAdapterHelper . getLocalServerSearch ( ) ;
2019-07-18 15:01:39 +02:00
ArrayList < Object > phoneSearch = searchAdapterHelper . getPhoneSearch ( ) ;
2014-11-06 22:34:47 +01:00
int localCount = searchResult . size ( ) ;
2018-07-30 04:07:02 +02:00
int localServerCount = localServerSearch . size ( ) ;
2019-07-18 15:01:39 +02:00
int phoneCount = phoneSearch . size ( ) ;
2014-11-06 22:34:47 +01:00
int globalCount = globalSearch . isEmpty ( ) ? 0 : globalSearch . size ( ) + 1 ;
int messagesCount = searchResultMessages . isEmpty ( ) ? 0 : searchResultMessages . size ( ) + 1 ;
if ( i > = 0 & & i < localCount ) {
return searchResult . get ( i ) ;
2019-07-18 15:01:39 +02:00
} else {
i - = localCount ;
if ( i > = 0 & & i < localServerCount ) {
return localServerSearch . get ( i ) ;
} else {
i - = localServerCount ;
if ( i > = 0 & & i < phoneCount ) {
return phoneSearch . get ( i ) ;
} else {
i - = phoneCount ;
if ( i > 0 & & i < globalCount ) {
return globalSearch . get ( i - 1 ) ;
} else {
i - = globalCount ;
if ( i > 0 & & i < messagesCount ) {
return searchResultMessages . get ( i - 1 ) ;
}
}
}
}
2014-10-31 20:02:29 +01:00
}
return null ;
}
2018-07-30 04:07:02 +02:00
public boolean isGlobalSearch ( int i ) {
if ( isRecentSearchDisplayed ( ) ) {
return false ;
}
if ( ! searchResultHashtags . isEmpty ( ) ) {
return false ;
}
ArrayList < TLObject > globalSearch = searchAdapterHelper . getGlobalSearch ( ) ;
ArrayList < TLObject > localServerSearch = searchAdapterHelper . getLocalServerSearch ( ) ;
int localCount = searchResult . size ( ) ;
int localServerCount = localServerSearch . size ( ) ;
2019-07-18 15:01:39 +02:00
int phoneCount = searchAdapterHelper . getPhoneSearch ( ) . size ( ) ;
2018-07-30 04:07:02 +02:00
int globalCount = globalSearch . isEmpty ( ) ? 0 : globalSearch . size ( ) + 1 ;
int messagesCount = searchResultMessages . isEmpty ( ) ? 0 : searchResultMessages . size ( ) + 1 ;
2019-07-18 15:01:39 +02:00
2018-07-30 04:07:02 +02:00
if ( i > = 0 & & i < localCount ) {
return false ;
2019-07-18 15:01:39 +02:00
} else {
i - = localCount ;
if ( i > = 0 & & i < localServerCount ) {
return false ;
} else {
i - = localServerCount ;
if ( i > 0 & & i < phoneCount ) {
return false ;
} else {
i - = phoneCount ;
if ( i > 0 & & i < globalCount ) {
return true ;
} else {
i - = globalCount ;
if ( i > 0 & & i < messagesCount ) {
return false ;
}
}
}
}
2018-07-30 04:07:02 +02:00
}
return false ;
}
2014-10-31 20:02:29 +01:00
@Override
public long getItemId ( int i ) {
return i ;
}
2017-03-31 01:58:05 +02:00
@Override
public boolean isEnabled ( RecyclerView . ViewHolder holder ) {
int type = holder . getItemViewType ( ) ;
return type ! = 1 & & type ! = 3 ;
}
2014-10-31 20:02:29 +01:00
@Override
2015-05-21 23:27:27 +02:00
public RecyclerView . ViewHolder onCreateViewHolder ( ViewGroup parent , int viewType ) {
View view = null ;
switch ( viewType ) {
case 0 :
view = new ProfileSearchCell ( mContext ) ;
break ;
case 1 :
2017-03-31 01:58:05 +02:00
view = new GraySectionCell ( mContext ) ;
2015-05-21 23:27:27 +02:00
break ;
case 2 :
2019-06-04 12:14:50 +02:00
view = new DialogCell ( mContext , false , true ) ;
2015-05-21 23:27:27 +02:00
break ;
case 3 :
view = new LoadingCell ( mContext ) ;
break ;
case 4 :
view = new HashtagSearchCell ( mContext ) ;
break ;
2016-05-25 23:49:47 +02:00
case 5 :
RecyclerListView horizontalListView = new RecyclerListView ( mContext ) {
@Override
public boolean onInterceptTouchEvent ( MotionEvent e ) {
if ( getParent ( ) ! = null & & getParent ( ) . getParent ( ) ! = null ) {
2020-01-02 16:08:53 +01:00
getParent ( ) . getParent ( ) . requestDisallowInterceptTouchEvent ( canScrollHorizontally ( - 1 ) ) ;
2016-05-25 23:49:47 +02:00
}
return super . onInterceptTouchEvent ( e ) ;
}
} ;
2016-06-24 12:27:15 +02:00
horizontalListView . setTag ( 9 ) ;
2016-05-25 23:49:47 +02:00
horizontalListView . setItemAnimator ( null ) ;
horizontalListView . setLayoutAnimation ( null ) ;
LinearLayoutManager layoutManager = new LinearLayoutManager ( mContext ) {
@Override
public boolean supportsPredictiveItemAnimations ( ) {
return false ;
}
} ;
layoutManager . setOrientation ( LinearLayoutManager . HORIZONTAL ) ;
horizontalListView . setLayoutManager ( layoutManager ) ;
//horizontalListView.setDisallowInterceptTouchEvents(true);
horizontalListView . setAdapter ( new CategoryAdapterRecycler ( ) ) ;
2018-08-27 10:33:11 +02:00
horizontalListView . setOnItemClickListener ( ( view1 , position ) - > {
if ( delegate ! = null ) {
delegate . didPressedOnSubDialog ( ( Integer ) view1 . getTag ( ) ) ;
2016-05-25 23:49:47 +02:00
}
} ) ;
2018-08-27 10:33:11 +02:00
horizontalListView . setOnItemLongClickListener ( ( view12 , position ) - > {
if ( delegate ! = null ) {
delegate . needRemoveHint ( ( Integer ) view12 . getTag ( ) ) ;
2016-05-25 23:49:47 +02:00
}
2018-08-27 10:33:11 +02:00
return true ;
2016-05-25 23:49:47 +02:00
} ) ;
view = horizontalListView ;
2017-03-31 01:58:05 +02:00
innerListView = horizontalListView ;
2019-02-08 03:30:32 +01:00
break ;
2019-07-18 15:01:39 +02:00
case 6 :
2019-12-31 14:08:08 +01:00
view = new TextCell ( mContext , 16 , false ) ;
2019-07-18 15:01:39 +02:00
break ;
2016-05-25 23:49:47 +02:00
}
if ( viewType = = 5 ) {
2019-01-23 18:03:33 +01:00
view . setLayoutParams ( new RecyclerView . LayoutParams ( RecyclerView . LayoutParams . MATCH_PARENT , AndroidUtilities . dp ( 86 ) ) ) ;
2016-05-25 23:49:47 +02:00
} else {
view . setLayoutParams ( new RecyclerView . LayoutParams ( RecyclerView . LayoutParams . MATCH_PARENT , RecyclerView . LayoutParams . WRAP_CONTENT ) ) ;
2015-05-21 23:27:27 +02:00
}
2017-03-31 01:58:05 +02:00
return new RecyclerListView . Holder ( view ) ;
2014-10-31 20:02:29 +01:00
}
@Override
2015-05-21 23:27:27 +02:00
public void onBindViewHolder ( RecyclerView . ViewHolder holder , int position ) {
switch ( holder . getItemViewType ( ) ) {
case 0 : {
ProfileSearchCell cell = ( ProfileSearchCell ) holder . itemView ;
2014-10-31 20:02:29 +01:00
2015-05-21 23:27:27 +02:00
TLRPC . User user = null ;
TLRPC . Chat chat = null ;
TLRPC . EncryptedChat encryptedChat = null ;
2015-08-13 11:23:31 +02:00
CharSequence username = null ;
CharSequence name = null ;
boolean isRecent = false ;
2015-09-24 22:52:02 +02:00
String un = null ;
2015-05-21 23:27:27 +02:00
Object obj = getItem ( position ) ;
2015-08-13 11:23:31 +02:00
2015-05-21 23:27:27 +02:00
if ( obj instanceof TLRPC . User ) {
2014-10-31 20:02:29 +01:00
user = ( TLRPC . User ) obj ;
2015-09-24 22:52:02 +02:00
un = user . username ;
2015-05-21 23:27:27 +02:00
} else if ( obj instanceof TLRPC . Chat ) {
2018-07-30 04:07:02 +02:00
chat = MessagesController . getInstance ( currentAccount ) . getChat ( ( ( TLRPC . Chat ) obj ) . id ) ;
2015-09-24 22:52:02 +02:00
if ( chat = = null ) {
chat = ( TLRPC . Chat ) obj ;
}
un = chat . username ;
2015-05-21 23:27:27 +02:00
} else if ( obj instanceof TLRPC . EncryptedChat ) {
2018-07-30 04:07:02 +02:00
encryptedChat = MessagesController . getInstance ( currentAccount ) . getEncryptedChat ( ( ( TLRPC . EncryptedChat ) obj ) . id ) ;
user = MessagesController . getInstance ( currentAccount ) . getUser ( encryptedChat . user_id ) ;
2015-05-21 23:27:27 +02:00
}
2014-10-31 20:02:29 +01:00
2016-05-25 23:49:47 +02:00
if ( isRecentSearchDisplayed ( ) ) {
2015-08-13 11:23:31 +02:00
isRecent = true ;
cell . useSeparator = position ! = getItemCount ( ) - 1 ;
} else {
2017-03-31 01:58:05 +02:00
ArrayList < TLObject > globalSearch = searchAdapterHelper . getGlobalSearch ( ) ;
2019-07-18 15:01:39 +02:00
ArrayList < Object > phoneSearch = searchAdapterHelper . getPhoneSearch ( ) ;
2015-08-13 11:23:31 +02:00
int localCount = searchResult . size ( ) ;
2018-07-30 04:07:02 +02:00
int localServerCount = searchAdapterHelper . getLocalServerSearch ( ) . size ( ) ;
2019-07-18 15:01:39 +02:00
int phoneCount = phoneSearch . size ( ) ;
int phoneCount2 = phoneCount ;
if ( phoneCount > 0 & & phoneSearch . get ( phoneCount - 1 ) instanceof String ) {
phoneCount2 - = 2 ;
}
2015-08-13 11:23:31 +02:00
int globalCount = globalSearch . isEmpty ( ) ? 0 : globalSearch . size ( ) + 1 ;
2019-07-18 15:01:39 +02:00
cell . useSeparator = ( position ! = getItemCount ( ) - 1 & & position ! = localCount + phoneCount2 + localServerCount - 1 & & position ! = localCount + globalCount + phoneCount + localServerCount - 1 ) ;
2015-08-13 11:23:31 +02:00
if ( position < searchResult . size ( ) ) {
name = searchResultNames . get ( position ) ;
if ( name ! = null & & user ! = null & & user . username ! = null & & user . username . length ( ) > 0 ) {
if ( name . toString ( ) . startsWith ( " @ " + user . username ) ) {
username = name ;
name = null ;
}
}
2018-07-30 04:07:02 +02:00
} else {
2017-03-31 01:58:05 +02:00
String foundUserName = searchAdapterHelper . getLastFoundUsername ( ) ;
2018-07-30 04:07:02 +02:00
if ( ! TextUtils . isEmpty ( foundUserName ) ) {
String nameSearch = null ;
String nameSearchLower = null ;
int index ;
if ( user ! = null ) {
nameSearch = ContactsController . formatName ( user . first_name , user . last_name ) ;
} else if ( chat ! = null ) {
nameSearch = chat . title ;
}
2019-07-18 15:01:39 +02:00
if ( nameSearch ! = null & & ( index = AndroidUtilities . indexOfIgnoreCase ( nameSearch , foundUserName ) ) ! = - 1 ) {
2018-07-30 04:07:02 +02:00
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder ( nameSearch ) ;
spannableStringBuilder . setSpan ( new ForegroundColorSpan ( Theme . getColor ( Theme . key_windowBackgroundWhiteBlueText4 ) ) , index , index + foundUserName . length ( ) , Spanned . SPAN_EXCLUSIVE_EXCLUSIVE ) ;
name = spannableStringBuilder ;
} else if ( un ! = null ) {
if ( foundUserName . startsWith ( " @ " ) ) {
foundUserName = foundUserName . substring ( 1 ) ;
}
try {
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder ( ) ;
spannableStringBuilder . append ( " @ " ) ;
spannableStringBuilder . append ( un ) ;
2019-07-18 15:01:39 +02:00
if ( ( index = AndroidUtilities . indexOfIgnoreCase ( un , foundUserName ) ) ! = - 1 ) {
2018-07-30 04:07:02 +02:00
int len = foundUserName . length ( ) ;
if ( index = = 0 ) {
len + + ;
} else {
index + + ;
}
spannableStringBuilder . setSpan ( new ForegroundColorSpan ( Theme . getColor ( Theme . key_windowBackgroundWhiteBlueText4 ) ) , index , index + len , Spanned . SPAN_EXCLUSIVE_EXCLUSIVE ) ;
}
username = spannableStringBuilder ;
} catch ( Exception e ) {
username = un ;
FileLog . e ( e ) ;
}
2017-12-08 18:35:59 +01:00
}
2015-05-21 23:27:27 +02:00
}
2014-10-31 20:02:29 +01:00
}
}
2017-12-08 18:35:59 +01:00
boolean savedMessages = false ;
if ( user ! = null & & user . id = = selfUserId ) {
name = LocaleController . getString ( " SavedMessages " , R . string . SavedMessages ) ;
username = null ;
savedMessages = true ;
}
if ( chat ! = null & & chat . participants_count ! = 0 ) {
String membersString ;
if ( ChatObject . isChannel ( chat ) & & ! chat . megagroup ) {
membersString = LocaleController . formatPluralString ( " Subscribers " , chat . participants_count ) ;
} else {
membersString = LocaleController . formatPluralString ( " Members " , chat . participants_count ) ;
}
if ( username instanceof SpannableStringBuilder ) {
( ( SpannableStringBuilder ) username ) . append ( " , " ) . append ( membersString ) ;
} else if ( ! TextUtils . isEmpty ( username ) ) {
username = TextUtils . concat ( username , " , " , membersString ) ;
} else {
username = membersString ;
}
}
cell . setData ( user ! = null ? user : chat , encryptedChat , name , username , isRecent , savedMessages ) ;
2015-05-21 23:27:27 +02:00
break ;
}
case 1 : {
2017-03-31 01:58:05 +02:00
GraySectionCell cell = ( GraySectionCell ) holder . itemView ;
2016-05-25 23:49:47 +02:00
if ( isRecentSearchDisplayed ( ) ) {
2019-07-18 15:01:39 +02:00
int offset = ( ! MediaDataController . getInstance ( currentAccount ) . hints . isEmpty ( ) ? 2 : 0 ) ;
2016-05-25 23:49:47 +02:00
if ( position < offset ) {
2019-01-23 18:03:33 +01:00
cell . setText ( LocaleController . getString ( " ChatHints " , R . string . ChatHints ) ) ;
2016-05-25 23:49:47 +02:00
} else {
2019-06-04 12:14:50 +02:00
cell . setText ( LocaleController . getString ( " Recent " , R . string . Recent ) , LocaleController . getString ( " ClearButton " , R . string . ClearButton ) , v - > {
if ( delegate ! = null ) {
delegate . needClearList ( ) ;
}
} ) ;
2016-05-25 23:49:47 +02:00
}
2015-08-13 11:23:31 +02:00
} else if ( ! searchResultHashtags . isEmpty ( ) ) {
2019-06-04 12:14:50 +02:00
cell . setText ( LocaleController . getString ( " Hashtags " , R . string . Hashtags ) , LocaleController . getString ( " ClearButton " , R . string . ClearButton ) , v - > {
if ( delegate ! = null ) {
delegate . needClearList ( ) ;
}
} ) ;
2015-05-21 23:27:27 +02:00
} else {
2019-07-18 15:01:39 +02:00
ArrayList < TLObject > globalSearch = searchAdapterHelper . getGlobalSearch ( ) ;
int localCount = searchResult . size ( ) ;
int localServerCount = searchAdapterHelper . getLocalServerSearch ( ) . size ( ) ;
int phoneCount = searchAdapterHelper . getPhoneSearch ( ) . size ( ) ;
int globalCount = globalSearch . isEmpty ( ) ? 0 : globalSearch . size ( ) + 1 ;
int messagesCount = searchResultMessages . isEmpty ( ) ? 0 : searchResultMessages . size ( ) + 1 ;
position - = localCount + localServerCount ;
if ( position > = 0 & & position < phoneCount ) {
cell . setText ( LocaleController . getString ( " PhoneNumberSearch " , R . string . PhoneNumberSearch ) ) ;
} else {
position - = phoneCount ;
if ( position > = 0 & & position < globalCount ) {
cell . setText ( LocaleController . getString ( " GlobalSearch " , R . string . GlobalSearch ) ) ;
} else {
cell . setText ( LocaleController . getString ( " SearchMessages " , R . string . SearchMessages ) ) ;
}
}
2014-10-31 20:02:29 +01:00
}
2015-05-21 23:27:27 +02:00
break ;
2014-10-31 20:02:29 +01:00
}
2015-05-21 23:27:27 +02:00
case 2 : {
DialogCell cell = ( DialogCell ) holder . itemView ;
cell . useSeparator = ( position ! = getItemCount ( ) - 1 ) ;
2019-07-18 15:01:39 +02:00
MessageObject messageObject = ( MessageObject ) getItem ( position ) ;
2019-12-31 14:08:08 +01:00
cell . setDialog ( messageObject . getDialogId ( ) , messageObject , messageObject . messageOwner . date , false ) ;
2015-05-21 23:27:27 +02:00
break ;
2014-10-31 20:02:29 +01:00
}
2015-05-21 23:27:27 +02:00
case 4 : {
HashtagSearchCell cell = ( HashtagSearchCell ) holder . itemView ;
cell . setText ( searchResultHashtags . get ( position - 1 ) ) ;
cell . setNeedDivider ( position ! = searchResultHashtags . size ( ) ) ;
break ;
2015-03-26 18:34:47 +01:00
}
2016-05-25 23:49:47 +02:00
case 5 : {
RecyclerListView recyclerListView = ( RecyclerListView ) holder . itemView ;
( ( CategoryAdapterRecycler ) recyclerListView . getAdapter ( ) ) . setIndex ( position / 2 ) ;
break ;
}
2019-07-18 15:01:39 +02:00
case 6 : {
String str = ( String ) getItem ( position ) ;
TextCell cell = ( TextCell ) holder . itemView ;
cell . setColors ( null , Theme . key_windowBackgroundWhiteBlueText2 ) ;
cell . setText ( LocaleController . formatString ( " AddContactByPhone " , R . string . AddContactByPhone , PhoneFormat . getInstance ( ) . format ( " + " + str ) ) , false ) ;
break ;
}
2014-10-31 20:02:29 +01:00
}
}
@Override
public int getItemViewType ( int i ) {
2016-05-25 23:49:47 +02:00
if ( isRecentSearchDisplayed ( ) ) {
2019-07-18 15:01:39 +02:00
int offset = ( ! MediaDataController . getInstance ( currentAccount ) . hints . isEmpty ( ) ? 2 : 0 ) ;
2016-05-25 23:49:47 +02:00
if ( i < = offset ) {
if ( i = = offset | | i % 2 = = 0 ) {
return 1 ;
} else {
return 5 ;
}
}
return 0 ;
2015-08-13 11:23:31 +02:00
}
2015-03-26 18:34:47 +01:00
if ( ! searchResultHashtags . isEmpty ( ) ) {
return i = = 0 ? 1 : 4 ;
}
2017-03-31 01:58:05 +02:00
ArrayList < TLObject > globalSearch = searchAdapterHelper . getGlobalSearch ( ) ;
2014-11-06 22:34:47 +01:00
int localCount = searchResult . size ( ) ;
2018-07-30 04:07:02 +02:00
int localServerCount = searchAdapterHelper . getLocalServerSearch ( ) . size ( ) ;
2019-07-18 15:01:39 +02:00
int phoneCount = searchAdapterHelper . getPhoneSearch ( ) . size ( ) ;
2014-11-06 22:34:47 +01:00
int globalCount = globalSearch . isEmpty ( ) ? 0 : globalSearch . size ( ) + 1 ;
int messagesCount = searchResultMessages . isEmpty ( ) ? 0 : searchResultMessages . size ( ) + 1 ;
2019-07-18 15:01:39 +02:00
if ( i > = 0 & & i < localCount ) {
2014-10-31 20:02:29 +01:00
return 0 ;
2019-07-18 15:01:39 +02:00
} else {
i - = localCount ;
if ( i > = 0 & & i < localServerCount ) {
return 0 ;
} else {
i - = localServerCount ;
if ( i > = 0 & & i < phoneCount ) {
Object object = getItem ( i ) ;
if ( object instanceof String ) {
String str = ( String ) object ;
if ( " section " . equals ( str ) ) {
return 1 ;
} else {
return 6 ;
}
}
return 0 ;
} else {
i - = phoneCount ;
if ( i > = 0 & & i < globalCount ) {
if ( i = = 0 ) {
return 1 ;
} else {
return 0 ;
}
} else {
i - = globalCount ;
if ( i > = 0 & & i < messagesCount ) {
if ( i = = 0 ) {
return 1 ;
} else {
return 2 ;
}
}
}
}
}
2014-10-31 20:02:29 +01:00
}
2019-07-18 15:01:39 +02:00
return 3 ;
2014-10-31 20:02:29 +01:00
}
}