mirror of
https://github.com/ArcaneChat/android.git
synced 2026-07-03 14:05:24 +02:00
Compare commits
144 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5721b9f86d | |||
| aa090a9cd4 | |||
| 03c30bef47 | |||
| c59453f31b | |||
| 49e7f19cb7 | |||
| 469c56f1a6 | |||
| 239c56e77d | |||
| e32ca20604 | |||
| d00ef0af32 | |||
| e616e57be6 | |||
| 5485db8509 | |||
| df75d2917f | |||
| 0478ea5162 | |||
| 433e90072f | |||
| 5c646ea663 | |||
| e095d3f886 | |||
| 9a6315d0b2 | |||
| 8e81f0bb8f | |||
| d6bdebc865 | |||
| 7ddf368fd1 | |||
| 301c6a4430 | |||
| adaf91e383 | |||
| 40de9dfe98 | |||
| 18a8e2358c | |||
| e2a4008742 | |||
| 258633b672 | |||
| 96cc35b84d | |||
| 787efa3c5d | |||
| 848862ae84 | |||
| 6d3c170e96 | |||
| a921523014 | |||
| 29e5133c63 | |||
| 8d4aebe8e7 | |||
| c0139b1b49 | |||
| 920d55ee6d | |||
| 4348b80b02 | |||
| 1a62ed853b | |||
| f858cc7747 | |||
| 394b439a06 | |||
| b515660bac | |||
| 88719df0af | |||
| 495dfa0f59 | |||
| f7372819a1 | |||
| 9d622ecef7 | |||
| 221004354e | |||
| 442baa6aa9 | |||
| 2e4f748093 | |||
| 56a846ab3b | |||
| f67e24b49e | |||
| f40a3e49cb | |||
| 04b815bb49 | |||
| 3292979696 | |||
| 3e24ca9be1 | |||
| 38e5350219 | |||
| 39d5c40945 | |||
| ebcb132acf | |||
| 53447c793a | |||
| 54a2df818b | |||
| 09a3b3bd26 | |||
| f02d4cd21a | |||
| eb650ff089 | |||
| da263b1e56 | |||
| 44ee4aaef7 | |||
| 56874bd418 | |||
| bf1594fdef | |||
| e31821cf92 | |||
| 4efe3b4387 | |||
| 69d0537425 | |||
| 0852e09815 | |||
| 2fc8799241 | |||
| ea01205421 | |||
| 1ad31aa178 | |||
| 349b943a7e | |||
| 268006d027 | |||
| e2bad18153 | |||
| 4749ddf9a8 | |||
| de1c568714 | |||
| 0b90e66ad8 | |||
| 90fe75a764 | |||
| c27fd27789 | |||
| 5580f5ae62 | |||
| d4e94b2fbc | |||
| bb673dd992 | |||
| 2dfacc4858 | |||
| cce4e31b0f | |||
| 99615999b8 | |||
| cfca25d65d | |||
| 665a2cdfd0 | |||
| a2768728d3 | |||
| 2790082705 | |||
| ae8a15d524 | |||
| e39d7b5d4d | |||
| 1ae26ecfa5 | |||
| 1e58912226 | |||
| 87807db64a | |||
| 6221c97283 | |||
| 80226717b6 | |||
| 959f7af2ab | |||
| 2308990661 | |||
| 9f304f372a | |||
| 341580191f | |||
| 07065676f2 | |||
| 47c9dc6e31 | |||
| 2514494d02 | |||
| 1c28c2d475 | |||
| 41a92d56c4 | |||
| 6a6b024314 | |||
| 12c95971a2 | |||
| 62ca3b6331 | |||
| c69f2fd75d | |||
| 0fc45bc57a | |||
| 0b9614f0bd | |||
| e8a073a42c | |||
| 97b33ec9c4 | |||
| f6458870ae | |||
| 665f24db1e | |||
| a59be9d2af | |||
| 1036139cb7 | |||
| f1854e46be | |||
| bfad3e57c7 | |||
| 24ee24325b | |||
| c9f6db312f | |||
| 6f60ba113e | |||
| db112b226e | |||
| a87049e443 | |||
| 730b018b45 | |||
| 60e72f14d8 | |||
| e89b2855ce | |||
| 56fb73088e | |||
| 6623513c2a | |||
| 3da3325c9b | |||
| c73d3564d4 | |||
| 2b822ecd22 | |||
| a81c921504 | |||
| c902044cc3 | |||
| 072945b237 | |||
| ca49e9899d | |||
| f67d82452b | |||
| 1c3b7ce051 | |||
| cd6d8114ad | |||
| 1baa5a5d99 | |||
| a83dac9437 | |||
| e033c04d7a | |||
| bbd06d37da |
@@ -129,7 +129,7 @@ android {
|
||||
defaultConfig {
|
||||
minSdkVersion 14 // 14: Android 4.0 Ice Cream Sandwich 2011 (Telegram default), 21: Android 5.0 Lollipop 2014 (recommended for InstantRun)
|
||||
targetSdkVersion 23
|
||||
versionName "0.1.3"
|
||||
versionName "0.1.14"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<application
|
||||
android:allowBackup="false"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/AppNameBeta"
|
||||
android:label="@string/AppName"
|
||||
android:theme="@style/Theme.MessengerProj.Start"
|
||||
android:name=".ApplicationLoader"
|
||||
android:hardwareAccelerated="@bool/useHardwareAcceleration"
|
||||
|
||||
@@ -1606,7 +1606,9 @@ LOCAL_SRC_FILES += \
|
||||
./gifvideo.cpp \
|
||||
../../../messenger-backend/src/mrchat.c \
|
||||
../../../messenger-backend/src/mrchatlist.c \
|
||||
../../../messenger-backend/src/mrcmdline.c \
|
||||
../../../messenger-backend/src/mrcontact.c \
|
||||
../../../messenger-backend/src/mre2ee.c \
|
||||
../../../messenger-backend/src/mrimap.c \
|
||||
../../../messenger-backend/src/mrjob.c \
|
||||
../../../messenger-backend/src/mrlog.c \
|
||||
|
||||
+251
-43
@@ -1,8 +1,8 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Messenger Android Frontend
|
||||
* Copyright (C) 2016 Björn Petersen Software Design and Development
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
@@ -20,7 +20,6 @@
|
||||
*******************************************************************************
|
||||
*
|
||||
* File: mr_wrapper.c
|
||||
* Authors: Björn Petersen
|
||||
* Purpose: The C part of the Java<->C Wrapper, see also MrMailbox.java
|
||||
*
|
||||
******************************************************************************/
|
||||
@@ -37,8 +36,34 @@
|
||||
#define CHAR_UNREF(a) \
|
||||
if(a) { (*env)->ReleaseStringUTFChars(env, (a), a##Ptr); }
|
||||
|
||||
#define JSTRING_NEW(a) \
|
||||
(*env)->NewStringUTF(env, a? a : "") /*should handle NULL arguments, does not return NULL!*/
|
||||
#define JSTRING_NEW(a) jstring_new__(env, (a))
|
||||
static jstring jstring_new__(JNIEnv* env, const char* a)
|
||||
{
|
||||
if( a==NULL || a[0]==0 ) {
|
||||
return (*env)->NewStringUTF(env, "");
|
||||
}
|
||||
|
||||
/* for non-empty strings, do not use NewStringUTF() as this is buggy on some Android versions.
|
||||
Instead, create the string using `new String(ByteArray, "UTF-8);` which seems to be programmed more properly.
|
||||
(eg. on KitKat a simple "SMILING FACE WITH SMILING EYES" (U+1F60A, UTF-8 F0 9F 98 8A) will let the app crash, reporting 0xF0 is a bad UTF-8 start,
|
||||
see http://stackoverflow.com/questions/12127817/android-ics-4-0-ndk-newstringutf-is-crashing-down-the-app ) */
|
||||
static jclass s_strCls = NULL;
|
||||
static jmethodID s_strCtor = NULL;
|
||||
static jclass s_strEncode = NULL;
|
||||
if( s_strCls==NULL ) {
|
||||
s_strCls = (*env)->NewGlobalRef(env, (*env)->FindClass(env, "java/lang/String"));
|
||||
s_strCtor = (*env)->GetMethodID(env, s_strCls, "<init>", "([BLjava/lang/String;)V");
|
||||
s_strEncode = (*env)->NewGlobalRef(env, (*env)->NewStringUTF(env, "UTF-8"));
|
||||
}
|
||||
|
||||
int a_bytes = strlen(a);
|
||||
jbyteArray array = (*env)->NewByteArray(env, a_bytes);
|
||||
(*env)->SetByteArrayRegion(env, array, 0, a_bytes, a);
|
||||
jstring ret = (jstring) (*env)->NewObject(env, s_strCls, s_strCtor, array, s_strEncode);
|
||||
(*env)->DeleteLocalRef(env, array); /* we have to delete the reference as it is not returned to Java, AFAIK */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* our log handler */
|
||||
@@ -57,7 +82,7 @@ static void s_log_callback_(int type, const char* msg)
|
||||
}
|
||||
|
||||
|
||||
/* globl stuff */
|
||||
/* global stuff */
|
||||
|
||||
static JavaVM* s_jvm = NULL;
|
||||
static jclass s_MrMailbox_class = NULL;
|
||||
@@ -112,9 +137,49 @@ static jintArray carray2jintArray_n_carray_free(JNIEnv *env, const carray* ca)
|
||||
}
|
||||
|
||||
|
||||
static uint32_t* jintArray2uint32Pointer(JNIEnv* env, jintArray ja, int* ret_icnt)
|
||||
{
|
||||
uint32_t* ret = NULL;
|
||||
if( env && ja && ret_icnt )
|
||||
{
|
||||
int i, icnt = (*env)->GetArrayLength(env, ja);
|
||||
if( icnt > 0 )
|
||||
{
|
||||
const jint* temp = (*env)->GetIntArrayElements(env, ja, NULL);
|
||||
if( temp )
|
||||
{
|
||||
ret = calloc(icnt, sizeof(uint32_t));
|
||||
if( ret )
|
||||
{
|
||||
for( i = 0; i < icnt; i++ ) {
|
||||
ret[i] = (uint32_t)temp[i];
|
||||
}
|
||||
*ret_icnt = icnt;
|
||||
}
|
||||
(*env)->ReleaseIntArrayElements(env, ja, temp, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* MrMailbox
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
static mrmailbox_t* get_mrmailbox_t(JNIEnv *env, jclass cls)
|
||||
{
|
||||
static jfieldID fid = 0;
|
||||
if( fid == 0 ) {
|
||||
fid = (*env)->GetStaticFieldID(env, cls, "m_hMailbox", "J" /*Signature, J=long*/);
|
||||
}
|
||||
if( fid ) {
|
||||
return (mrmailbox_t*)(*env)->GetStaticLongField(env, cls, fid);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* MrMailbox - new/delete */
|
||||
@@ -149,20 +214,25 @@ JNIEXPORT jlong Java_com_b44t_messenger_MrMailbox_MrMailboxNew(JNIEnv *env, jcla
|
||||
|
||||
/* MrMailbox - open/configure/connect/fetch */
|
||||
|
||||
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_MrMailboxOpen(JNIEnv *env, jclass c, jlong hMailbox, jstring dbfile, jstring blobdir)
|
||||
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_open(JNIEnv *env, jclass cls, jstring dbfile)
|
||||
{
|
||||
CHAR_REF(dbfile);
|
||||
CHAR_REF(blobdir);
|
||||
jint ret = mrmailbox_open((mrmailbox_t*)hMailbox, dbfilePtr, blobdirPtr);
|
||||
CHAR_UNREF(blobdir);
|
||||
jint ret = mrmailbox_open(get_mrmailbox_t(env, cls), dbfilePtr, NULL);
|
||||
CHAR_UNREF(dbfile)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void Java_com_b44t_messenger_MrMailbox_MrMailboxClose(JNIEnv *env, jclass c, jlong hMailbox)
|
||||
JNIEXPORT void Java_com_b44t_messenger_MrMailbox_close(JNIEnv *env, jclass cls)
|
||||
{
|
||||
mrmailbox_close((mrmailbox_t*)hMailbox);
|
||||
mrmailbox_close(get_mrmailbox_t(env, cls));
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jstring Java_com_b44t_messenger_MrMailbox_getBlobdir(JNIEnv *env, jclass cls)
|
||||
{
|
||||
mrmailbox_t* ths = get_mrmailbox_t(env, cls);
|
||||
return JSTRING_NEW((ths&&ths->m_blobdir)? ths->m_blobdir : NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -196,20 +266,35 @@ JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_MrMailboxFetch(JNIEnv *env, jcl
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jstring Java_com_b44t_messenger_MrMailbox_getErrorDescr(JNIEnv *env, jclass cls)
|
||||
{
|
||||
char* c = mrmailbox_get_error_descr(get_mrmailbox_t(env, cls));
|
||||
jstring ret = JSTRING_NEW(c);
|
||||
free(c);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* MrMailbox - handle contacts */
|
||||
|
||||
JNIEXPORT jintArray Java_com_b44t_messenger_MrMailbox_MrMailboxGetKnownContacts(JNIEnv *env, jclass c, jlong hMailbox, jstring query)
|
||||
JNIEXPORT jintArray Java_com_b44t_messenger_MrMailbox_getKnownContacts(JNIEnv *env, jclass cls, jstring query)
|
||||
{
|
||||
CHAR_REF(query);
|
||||
carray* ca = mrmailbox_get_known_contacts((mrmailbox_t*)hMailbox, queryPtr);
|
||||
CHAR_REF(query);
|
||||
carray* ca = mrmailbox_get_known_contacts(get_mrmailbox_t(env, cls), queryPtr);
|
||||
CHAR_UNREF(query);
|
||||
return carray2jintArray_n_carray_free(env, ca);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jintArray Java_com_b44t_messenger_MrMailbox_MrMailboxGetBlockedContacts(JNIEnv *env, jclass c, jlong hMailbox)
|
||||
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_getBlockedCount(JNIEnv *env, jclass cls)
|
||||
{
|
||||
carray* ca = mrmailbox_get_blocked_contacts((mrmailbox_t*)hMailbox);
|
||||
return mrmailbox_get_blocked_count(get_mrmailbox_t(env, cls));
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jintArray Java_com_b44t_messenger_MrMailbox_getBlockedContacts(JNIEnv *env, jclass cls)
|
||||
{
|
||||
carray* ca = mrmailbox_get_blocked_contacts(get_mrmailbox_t(env, cls));
|
||||
return carray2jintArray_n_carray_free(env, ca);
|
||||
}
|
||||
|
||||
@@ -245,9 +330,18 @@ JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_MrMailboxDeleteContact(JNIEnv *
|
||||
|
||||
/* MrMailbox - handle chats */
|
||||
|
||||
JNIEXPORT jlong Java_com_b44t_messenger_MrMailbox_MrMailboxGetChatlist(JNIEnv *env, jclass c, jlong hMailbox)
|
||||
JNIEXPORT jlong Java_com_b44t_messenger_MrMailbox_MrMailboxGetChatlist(JNIEnv *env, jclass c, jlong hMailbox, jstring query)
|
||||
{
|
||||
return (jlong)mrmailbox_get_chatlist((mrmailbox_t*)hMailbox);
|
||||
jlong ret;
|
||||
if( query ) {
|
||||
CHAR_REF(query);
|
||||
ret = (jlong)mrmailbox_get_chatlist((mrmailbox_t*)hMailbox, queryPtr);
|
||||
CHAR_UNREF(query);
|
||||
}
|
||||
else {
|
||||
ret = (jlong)mrmailbox_get_chatlist((mrmailbox_t*)hMailbox, NULL);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -263,9 +357,15 @@ JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_MrMailboxGetChatIdByContactId(J
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_MrMailboxMarkseenChat(JNIEnv *env, jclass c, jlong hMailbox, jint chat_id)
|
||||
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_markseenMsg(JNIEnv *env, jclass cls, jint msg_id)
|
||||
{
|
||||
return (jlong)mrmailbox_markseen_chat((mrmailbox_t*)hMailbox, chat_id);
|
||||
return (jint)mrmailbox_markseen_msg(get_mrmailbox_t(env, cls), msg_id);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_markseenChat(JNIEnv *env, jclass cls, jint chat_id)
|
||||
{
|
||||
return (jlong)mrmailbox_markseen_chat(get_mrmailbox_t(env, cls), chat_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -275,9 +375,39 @@ JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_MrMailboxCreateChatByContactId(
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void Java_com_b44t_messenger_MrMailbox_MrMailboxDeleteChat(JNIEnv *env, jclass c, jlong hMailbox, jint chat_id)
|
||||
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_createGroupChat(JNIEnv *env, jclass cls, jstring name)
|
||||
{
|
||||
mrmailbox_delete_chat((mrmailbox_t*)hMailbox, chat_id);
|
||||
CHAR_REF(name);
|
||||
jint ret = (jint)mrmailbox_create_group_chat(get_mrmailbox_t(env, cls), namePtr);
|
||||
CHAR_UNREF(name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_addContactToChat(JNIEnv *env, jclass cls, jint chat_id, jint contact_id)
|
||||
{
|
||||
return (jint)mrmailbox_add_contact_to_chat(get_mrmailbox_t(env, cls), chat_id, contact_id);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_removeContactFromChat(JNIEnv *env, jclass cls, jint chat_id, jint contact_id)
|
||||
{
|
||||
return (jint)mrmailbox_remove_contact_from_chat(get_mrmailbox_t(env, cls), chat_id, contact_id);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_setChatName(JNIEnv *env, jclass cls, jint chat_id, jstring name)
|
||||
{
|
||||
CHAR_REF(name);
|
||||
jint ret = (jint)mrmailbox_set_chat_name(get_mrmailbox_t(env, cls), chat_id, namePtr);
|
||||
CHAR_UNREF(name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void Java_com_b44t_messenger_MrMailbox_deleteChat(JNIEnv *env, jclass cls, jint chat_id)
|
||||
{
|
||||
mrmailbox_delete_chat(get_mrmailbox_t(env, cls), chat_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -298,9 +428,18 @@ JNIEXPORT jstring Java_com_b44t_messenger_MrMailbox_MrMailboxGetMsgInfo(JNIEnv *
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void Java_com_b44t_messenger_MrMailbox_MrMailboxDeleteMsg(JNIEnv *env, jclass c, jlong hMailbox, jint id)
|
||||
JNIEXPORT void Java_com_b44t_messenger_MrMailbox_deleteMsg(JNIEnv *env, jclass cls, jint id)
|
||||
{
|
||||
mrmailbox_delete_msg((mrmailbox_t*)hMailbox, id);
|
||||
mrmailbox_delete_msg(get_mrmailbox_t(env, cls), id);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void Java_com_b44t_messenger_MrMailbox_forwardMsgs(JNIEnv *env, jclass cls, jintArray msg_ids, jint chat_id)
|
||||
{
|
||||
int msg_ids_cnt;
|
||||
const uint32_t* msg_ids_ptr = jintArray2uint32Pointer(env, msg_ids, &msg_ids_cnt);
|
||||
mrmailbox_forward_msgs(get_mrmailbox_t(env, cls), msg_ids_ptr, msg_ids_cnt, chat_id);
|
||||
free(msg_ids_ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -341,19 +480,19 @@ JNIEXPORT jint Java_com_b44t_messenger_MrMailbox_MrMailboxGetConfigInt(JNIEnv *e
|
||||
|
||||
/* MrMailbox - misc. */
|
||||
|
||||
JNIEXPORT jstring Java_com_b44t_messenger_MrMailbox_MrMailboxGetInfo(JNIEnv *env, jclass c, jlong hMailbox)
|
||||
JNIEXPORT jstring Java_com_b44t_messenger_MrMailbox_getInfo(JNIEnv *env, jclass cls)
|
||||
{
|
||||
char* temp = mrmailbox_get_info((mrmailbox_t*)hMailbox);
|
||||
char* temp = mrmailbox_get_info(get_mrmailbox_t(env, cls));
|
||||
jstring ret = JSTRING_NEW(temp);
|
||||
free(temp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jstring Java_com_b44t_messenger_MrMailbox_MrMailboxExecute(JNIEnv *env, jclass c, jlong hMailbox, jstring cmd)
|
||||
JNIEXPORT jstring Java_com_b44t_messenger_MrMailbox_cmdline(JNIEnv *env, jclass cls, jstring cmd)
|
||||
{
|
||||
CHAR_REF(cmd);
|
||||
char* temp = mrmailbox_execute((mrmailbox_t*)hMailbox, cmdPtr);
|
||||
char* temp = mrmailbox_cmdline(get_mrmailbox_t(env, cls), cmdPtr);
|
||||
jstring ret = JSTRING_NEW(temp);
|
||||
free(temp);
|
||||
CHAR_UNREF(cmd);
|
||||
@@ -405,42 +544,63 @@ JNIEXPORT jlong Java_com_b44t_messenger_MrChatlist_MrChatlistGetSummaryByIndex(J
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
static mrchat_t* get_mrchat_t(JNIEnv *env, jobject obj)
|
||||
{
|
||||
static jfieldID fid = 0;
|
||||
if( fid == 0 ) {
|
||||
jclass cls = (*env)->GetObjectClass(env, obj);
|
||||
fid = (*env)->GetFieldID(env, cls, "m_hChat", "J" /*Signature, J=long*/);
|
||||
}
|
||||
if( fid ) {
|
||||
return (mrchat_t*)(*env)->GetLongField(env, obj, fid);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void Java_com_b44t_messenger_MrChat_MrChatUnref(JNIEnv *env, jclass c, jlong hChat)
|
||||
{
|
||||
mrchat_unref((mrchat_t*)hChat);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jint Java_com_b44t_messenger_MrChat_MrChatGetId(JNIEnv *env, jclass c, jlong hChat)
|
||||
JNIEXPORT jint Java_com_b44t_messenger_MrChat_getId(JNIEnv *env, jclass cls)
|
||||
{
|
||||
mrchat_t* ths = (mrchat_t*)hChat; if( ths == NULL ) { return 0; }
|
||||
mrchat_t* ths = get_mrchat_t(env, cls); if( ths == NULL ) { return 0; }
|
||||
return ths->m_id;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jint Java_com_b44t_messenger_MrChat_MrChatGetType(JNIEnv *env, jclass c, jlong hChat)
|
||||
JNIEXPORT jint Java_com_b44t_messenger_MrChat_getType(JNIEnv *env, jclass cls)
|
||||
{
|
||||
mrchat_t* ths = (mrchat_t*)hChat; if( ths == NULL ) { return 0; }
|
||||
mrchat_t* ths = get_mrchat_t(env, cls); if( ths == NULL ) { return 0; }
|
||||
return ths->m_type;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jstring Java_com_b44t_messenger_MrChat_MrChatGetName(JNIEnv *env, jclass c, jlong hChat)
|
||||
JNIEXPORT jstring Java_com_b44t_messenger_MrChat_getName(JNIEnv *env, jclass cls)
|
||||
{
|
||||
mrchat_t* ths = (mrchat_t*)hChat; if( ths == NULL ) { return JSTRING_NEW(NULL); }
|
||||
mrchat_t* ths = get_mrchat_t(env, cls); if( ths == NULL ) { return JSTRING_NEW(NULL); }
|
||||
return JSTRING_NEW(ths->m_name);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jstring Java_com_b44t_messenger_MrChat_MrChatGetSubtitle(JNIEnv *env, jclass c, jlong hChat)
|
||||
JNIEXPORT jstring Java_com_b44t_messenger_MrChat_getSubtitle(JNIEnv *env, jclass cls)
|
||||
{
|
||||
const char* temp = mrchat_get_subtitle((mrchat_t*)hChat);
|
||||
const char* temp = mrchat_get_subtitle(get_mrchat_t(env, cls));
|
||||
jstring ret = JSTRING_NEW(temp);
|
||||
free(temp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jint Java_com_b44t_messenger_MrChat_getParamInt(JNIEnv *env, jclass cls, jint key, jint def)
|
||||
{
|
||||
mrchat_t* ths = get_mrchat_t(env, cls);
|
||||
return mrparam_get_int(ths? ths->m_param:NULL, key, def);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jstring Java_com_b44t_messenger_MrChat_MrChatGetDraft(JNIEnv *env, jclass c, jlong hChat) /* returns NULL for "no draft" */
|
||||
{
|
||||
mrchat_t* ths = (mrchat_t*)hChat;
|
||||
@@ -529,17 +689,32 @@ JNIEXPORT jintArray Java_com_b44t_messenger_MrMailbox_MrMailboxGetChatMedia(JNIE
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jintArray Java_com_b44t_messenger_MrMailbox_MrMailboxGetChatMsgs(JNIEnv *env, jclass c, jlong hMailbox, jint chat_id)
|
||||
JNIEXPORT jintArray Java_com_b44t_messenger_MrMailbox_getChatMsgs(JNIEnv *env, jclass cls, jint chat_id, jint flags, jint marker1before)
|
||||
{
|
||||
carray* ca = mrmailbox_get_chat_msgs((mrmailbox_t*)hMailbox, chat_id);
|
||||
carray* ca = mrmailbox_get_chat_msgs(get_mrmailbox_t(env, cls), chat_id, flags, marker1before);
|
||||
return carray2jintArray_n_carray_free(env, ca);
|
||||
}
|
||||
|
||||
|
||||
|
||||
JNIEXPORT jintArray Java_com_b44t_messenger_MrMailbox_MrMailboxGetChatContacts(JNIEnv *env, jclass c, jlong hMailbox, jint chat_id)
|
||||
JNIEXPORT jintArray Java_com_b44t_messenger_MrMailbox_searchMsgs(JNIEnv *env, jclass cls, jint chat_id, jstring query)
|
||||
{
|
||||
carray* ca = mrmailbox_get_chat_contacts((mrmailbox_t*)hMailbox, chat_id);
|
||||
CHAR_REF(query);
|
||||
carray* ca = mrmailbox_search_msgs(get_mrmailbox_t(env, cls), chat_id, queryPtr);
|
||||
CHAR_UNREF(query);
|
||||
return carray2jintArray_n_carray_free(env, ca);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jintArray Java_com_b44t_messenger_MrMailbox_getUnseenMsgs(JNIEnv *env, jclass cls)
|
||||
{
|
||||
carray* ca = mrmailbox_get_unseen_msgs(get_mrmailbox_t(env, cls));
|
||||
return carray2jintArray_n_carray_free(env, ca);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jintArray Java_com_b44t_messenger_MrMailbox_getChatContacts(JNIEnv *env, jclass cls, jint chat_id)
|
||||
{
|
||||
carray* ca = mrmailbox_get_chat_contacts(get_mrmailbox_t(env, cls), chat_id);
|
||||
return carray2jintArray_n_carray_free(env, ca);
|
||||
}
|
||||
|
||||
@@ -549,6 +724,20 @@ JNIEXPORT jintArray Java_com_b44t_messenger_MrMailbox_MrMailboxGetChatContacts(J
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
static mrmsg_t* get_mrmsg_t(JNIEnv *env, jobject obj)
|
||||
{
|
||||
static jfieldID fid = 0;
|
||||
if( fid == 0 ) {
|
||||
jclass cls = (*env)->GetObjectClass(env, obj);
|
||||
fid = (*env)->GetFieldID(env, cls, "m_hMsg", "J" /*Signature, J=long*/);
|
||||
}
|
||||
if( fid ) {
|
||||
return (mrmsg_t*)(*env)->GetLongField(env, obj, fid);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void Java_com_b44t_messenger_MrMsg_MrMsgUnref(JNIEnv *env, jclass c, jlong hMsg)
|
||||
{
|
||||
mrmsg_unref((mrmsg_t*)hMsg);
|
||||
@@ -626,7 +815,26 @@ JNIEXPORT jstring Java_com_b44t_messenger_MrMsg_MrMsgGetParam(JNIEnv *env, jclas
|
||||
JNIEXPORT jint Java_com_b44t_messenger_MrMsg_MrMsgGetParamInt(JNIEnv *env, jclass c, jlong hMsg, jint key, jint def)
|
||||
{
|
||||
mrmsg_t* ths = (mrmsg_t*)hMsg;
|
||||
return mrparam_get_int(ths? ths->m_param:NULL, key, def);
|
||||
return mrparam_get_int(ths? ths->m_param:NULL, key, def);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jint Java_com_b44t_messenger_MrMsg_getBytes(JNIEnv *env, jobject obj)
|
||||
{
|
||||
mrmsg_t* ths = get_mrmsg_t(env, obj);
|
||||
return ths? ths->m_bytes : 0;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jlong Java_com_b44t_messenger_MrMsg_getSummaryCPtr(JNIEnv *env, jobject obj, jlong hChat)
|
||||
{
|
||||
return (jlong)mrmsg_get_summary(get_mrmsg_t(env, obj), (mrchat_t*)hChat);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jint Java_com_b44t_messenger_MrMsg_getSummarytext(JNIEnv *env, jobject obj, jint approx_characters)
|
||||
{
|
||||
return JSTRING_NEW(mrmsg_get_summarytext(get_mrmsg_t(env, obj), approx_characters));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -131,15 +131,6 @@
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
|
||||
android:exported="true">
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.b44t.ui.PopupNotificationActivity"
|
||||
android:configChanges="keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
|
||||
android:excludeFromRecents="true"
|
||||
android:launchMode="singleTask"
|
||||
android:taskAffinity=""
|
||||
android:theme="@style/Theme.MessengerProj.PopupNotification"
|
||||
android:windowSoftInputMode="adjustResize|stateHidden">
|
||||
</activity>
|
||||
|
||||
<receiver
|
||||
android:name=".AutoMessageHeardReceiver"
|
||||
|
||||
Binary file not shown.
@@ -1,232 +0,0 @@
|
||||
1876;JM;Jamaica;XXX XXXX
|
||||
1869;KN;Saint Kitts & Nevis;XXX XXXX
|
||||
1868;TT;Trinidad & Tobago;XXX XXXX
|
||||
1784;VC;Saint Vincent & the Grenadines;XXX XXXX
|
||||
1767;DM;Dominica;XXX XXXX
|
||||
1758;LC;Saint Lucia;XXX XXXX
|
||||
1721;SX;Sint Maarten;XXX XXXX
|
||||
1684;AS;American Samoa;XXX XXXX
|
||||
1671;GU;Guam;XXX XXXX
|
||||
1670;MP;Northern Mariana Islands;XXX XXXX
|
||||
1664;MS;Montserrat;XXX XXXX
|
||||
1649;TC;Turks & Caicos Islands;XXX XXXX
|
||||
1473;GD;Grenada;XXX XXXX
|
||||
1441;BM;Bermuda;XXX XXXX
|
||||
1345;KY;Cayman Islands;XXX XXXX
|
||||
1340;VI;US Virgin Islands;XXX XXXX
|
||||
1284;VG;British Virgin Islands;XXX XXXX
|
||||
1268;AG;Antigua & Barbuda;XXX XXXX
|
||||
1264;AI;Anguilla;XXX XXXX
|
||||
1246;BB;Barbados;XXX XXXX
|
||||
1242;BS;Bahamas;XXX XXXX
|
||||
998;UZ;Uzbekistan;XX XXXXXXX
|
||||
996;KG;Kyrgyzstan;XXX XXXXXX
|
||||
995;GE;Georgia;XXX XXX XXX
|
||||
994;AZ;Azerbaijan;XX XXX XXXX
|
||||
993;TM;Turkmenistan;XX XXXXXX
|
||||
992;TJ;Tajikistan;XX XXX XXXX
|
||||
977;NP;Nepal;XX XXXX XXXX
|
||||
976;MN;Mongolia;XX XX XXXX
|
||||
975;BT;Bhutan;XX XXX XXX
|
||||
974;QA;Qatar;XX XXX XXX
|
||||
973;BH;Bahrain;XXXX XXXX
|
||||
972;IL;Israel;XX XXX XXXX
|
||||
971;AE;United Arab Emirates;XX XXX XXXX
|
||||
970;PS;Palestine;XXX XX XXXX
|
||||
968;OM;Oman;XXXX XXXX
|
||||
967;YE;Yemen;XXX XXX XXX
|
||||
966;SA;Saudi Arabia;XX XXX XXXX
|
||||
965;KW;Kuwait;XXXX XXXX
|
||||
964;IQ;Iraq;XXX XXX XXXX
|
||||
963;SY;Syria;XXX XXX XXX
|
||||
962;JO;Jordan;X XXXX XXXX
|
||||
961;LB;Lebanon
|
||||
960;MV;Maldives;XXX XXXX
|
||||
886;TW;Taiwan;XXX XXX XXX
|
||||
880;BD;Bangladesh
|
||||
856;LA;Laos;XX XX XXX XXX
|
||||
855;KH;Cambodia
|
||||
853;MO;Macau;XXXX XXXX
|
||||
852;HK;Hong Kong;X XXX XXXX
|
||||
850;KP;North Korea
|
||||
692;MH;Marshall Islands
|
||||
691;FM;Micronesia
|
||||
690;TK;Tokelau
|
||||
689;PF;French Polynesia
|
||||
688;TV;Tuvalu
|
||||
687;NC;New Caledonia
|
||||
686;KI;Kiribati
|
||||
685;WS;Samoa
|
||||
683;NU;Niue
|
||||
682;CK;Cook Islands
|
||||
681;WF;Wallis & Futuna
|
||||
680;PW;Palau
|
||||
679;FJ;Fiji
|
||||
678;VU;Vanuatu
|
||||
677;SB;Solomon Islands
|
||||
676;TO;Tonga
|
||||
675;PG;Papua New Guinea
|
||||
674;NR;Nauru
|
||||
673;BN;Brunei Darussalam;XXX XXXX
|
||||
672;NF;Norfolk Island
|
||||
670;TL;Timor-Leste
|
||||
599;BQ;Bonaire, Sint Eustatius & Saba
|
||||
599;CW;Curaçao
|
||||
598;UY;Uruguay;X XXX XXXX
|
||||
597;SR;Suriname;XXX XXXX
|
||||
596;MQ;Martinique
|
||||
595;PY;Paraguay;XXX XXX XXX
|
||||
594;GF;French Guiana
|
||||
593;EC;Ecuador;XX XXX XXXX
|
||||
592;GY;Guyana
|
||||
591;BO;Bolivia;X XXX XXXX
|
||||
590;GP;Guadeloupe;XXX XX XX XX
|
||||
509;HT;Haiti
|
||||
508;PM;Saint Pierre & Miquelon
|
||||
507;PA;Panama;XXXX XXXX
|
||||
506;CR;Costa Rica;XXXX XXXX
|
||||
505;NI;Nicaragua;XXXX XXXX
|
||||
504;HN;Honduras;XXXX XXXX
|
||||
503;SV;El Salvador;XXXX XXXX
|
||||
502;GT;Guatemala;X XXX XXXX
|
||||
501;BZ;Belize
|
||||
500;FK;Falkland Islands
|
||||
423;LI;Liechtenstein
|
||||
421;SK;Slovakia;XXX XXX XXX
|
||||
420;CZ;Czech Republic;XXX XXX XXX
|
||||
389;MK;Macedonia;XX XXX XXX
|
||||
387;BA;Bosnia & Herzegovina;XX XXX XXX
|
||||
386;SI;Slovenia;XX XXX XXX
|
||||
385;HR;Croatia
|
||||
382;ME;Montenegro
|
||||
381;RS;Serbia;XX XXX XXXX
|
||||
380;UA;Ukraine;XX XXX XX XX
|
||||
378;SM;San Marino;XXX XXX XXXX
|
||||
377;MC;Monaco;XXXX XXXX
|
||||
376;AD;Andorra;XX XX XX
|
||||
375;BY;Belarus;XX XXX XXXX
|
||||
374;AM;Armenia;XX XXX XXX
|
||||
373;MD;Moldova;XX XXX XXX
|
||||
372;EE;Estonia
|
||||
371;LV;Latvia;XXX XXXXX
|
||||
370;LT;Lithuania;XXX XXXXX
|
||||
359;BG;Bulgaria
|
||||
358;FI;Finland
|
||||
357;CY;Cyprus;XXXX XXXX
|
||||
356;MT;Malta;XX XX XX XX
|
||||
355;AL;Albania;XX XXX XXXX
|
||||
354;IS;Iceland;XXX XXXX
|
||||
353;IE;Ireland;XX XXX XXXX
|
||||
352;LU;Luxembourg
|
||||
351;PT;Portugal;X XXXX XXXX
|
||||
350;GI;Gibraltar;XXXX XXXX
|
||||
299;GL;Greenland;XXX XXX
|
||||
298;FO;Faroe Islands;XXX XXX
|
||||
297;AW;Aruba;XXX XXXX
|
||||
291;ER;Eritrea;X XXX XXX
|
||||
290;SH;Saint Helena;XX XXX
|
||||
269;KM;Comoros;XXX XXXX
|
||||
268;SZ;Swaziland;XXXX XXXX
|
||||
267;BW;Botswana;XX XXX XXX
|
||||
266;LS;Lesotho;XX XXX XXX
|
||||
265;MW;Malawi;77 XXX XXXX
|
||||
264;NA;Namibia;XX XXX XXXX
|
||||
263;ZW;Zimbabwe;XX XXX XXXX
|
||||
262;RE;Réunion;XXX XXX XXX
|
||||
261;MG;Madagascar;XX XX XXX XX
|
||||
260;ZM;Zambia;XX XXX XXXX
|
||||
258;MZ;Mozambique;XX XXX XXXX
|
||||
257;BI;Burundi;XX XX XXXX
|
||||
256;UG;Uganda;XX XXX XXXX
|
||||
255;TZ;Tanzania;XX XXX XXXX
|
||||
254;KE;Kenya;XXX XXX XXX
|
||||
253;DJ;Djibouti;XX XX XX XX
|
||||
252;SO;Somalia;XX XXX XXX
|
||||
251;ET;Ethiopia;XX XXX XXXX
|
||||
250;RW;Rwanda;XXX XXX XXX
|
||||
249;SD;Sudan;XX XXX XXXX
|
||||
248;SC;Seychelles;X XX XX XX
|
||||
247;SH;Saint Helena;XXXX
|
||||
246;IO;Diego Garcia;XXX XXXX
|
||||
245;GW;Guinea-Bissau;XXX XXXX
|
||||
244;AO;Angola;XXX XXX XXX
|
||||
243;CD;Congo (Dem. Rep.);XX XXX XXXX
|
||||
242;CG;Congo (Rep.);XX XXX XXXX
|
||||
241;GA;Gabon;X XX XX XX
|
||||
240;GQ;Equatorial Guinea;XXX XXX XXX
|
||||
239;ST;São Tomé & Príncipe;XX XXXXX
|
||||
238;CV;Cape Verde;XXX XXXX
|
||||
237;CM;Cameroon;XXXX XXXX
|
||||
236;CF;Central African Rep.;XX XX XX XX
|
||||
235;TD;Chad;XX XX XX XX
|
||||
234;NG;Nigeria
|
||||
233;GH;Ghana
|
||||
232;SL;Sierra Leone;XX XXX XXX
|
||||
231;LR;Liberia
|
||||
230;MU;Mauritius
|
||||
229;BJ;Benin;XX XXX XXX
|
||||
228;TG;Togo;XX XXX XXX
|
||||
227;NE;Niger;XX XX XX XX
|
||||
226;BF;Burkina Faso;XX XX XX XX
|
||||
225;CI;Côte d`Ivoire;XX XXX XXX
|
||||
224;GN;Guinea;XXX XXX XXX
|
||||
223;ML;Mali;XXXX XXXX
|
||||
222;MR;Mauritania;XXXX XXXX
|
||||
221;SN;Senegal;XX XXX XXXX
|
||||
220;GM;Gambia;XXX XXXX
|
||||
218;LY;Libya;XX XXX XXXX
|
||||
216;TN;Tunisia;XX XXX XXX
|
||||
213;DZ;Algeria;XXX XX XX XX
|
||||
212;MA;Morocco;XX XXX XXXX
|
||||
211;SS;South Sudan;XX XXX XXXX
|
||||
98;IR;Iran;XXX XXX XXXX
|
||||
95;MM;Myanmar
|
||||
94;LK;Sri Lanka;XX XXX XXXX
|
||||
93;AF;Afghanistan;XXX XXX XXX
|
||||
92;PK;Pakistan;XXX XXX XXXX
|
||||
91;IN;India;XXXXX XXXXX
|
||||
90;TR;Turkey;XXX XXX XXXX
|
||||
86;CN;China;XXX XXXX XXXX
|
||||
84;VN;Vietnam
|
||||
82;KR;South Korea
|
||||
81;JP;Japan;XX XXXX XXXX
|
||||
66;TH;Thailand;X XXXX XXXX
|
||||
65;SG;Singapore;XXXX XXXX
|
||||
64;NZ;New Zealand
|
||||
63;PH;Philippines;XXX XXX XXXX
|
||||
62;ID;Indonesia
|
||||
61;AU;Australia;XXX XXX XXX
|
||||
60;MY;Malaysia
|
||||
58;VE;Venezuela;XXX XXX XXXX
|
||||
57;CO;Colombia;XXX XXX XXXX
|
||||
56;CL;Chile;X XXXX XXXX
|
||||
55;BR;Brazil;XX XXXXX XXXX
|
||||
54;AR;Argentina
|
||||
53;CU;Cuba;XXXX XXXX
|
||||
52;MX;Mexico
|
||||
51;PE;Peru;XXX XXX XXX
|
||||
49;DE;Germany
|
||||
48;PL;Poland;XX XXX XXXX
|
||||
47;NO;Norway;XXXX XXXX
|
||||
46;SE;Sweden;XX XXX XXXX
|
||||
45;DK;Denmark;XXXX XXXX
|
||||
44;GB;United Kingdom;XXXX XXXXXX
|
||||
43;AT;Austria
|
||||
42;YL;Y-land
|
||||
41;CH;Switzerland;XX XXX XXXX
|
||||
40;RO;Romania;XXX XXX XXX
|
||||
39;IT;Italy
|
||||
36;HU;Hungary;XXX XXX XXX
|
||||
34;ES;Spain;XXX XXX XXX
|
||||
33;FR;France;X XX XX XX XX
|
||||
32;BE;Belgium;XXX XX XX XX
|
||||
31;NL;Netherlands;X XX XX XX XX
|
||||
30;GR;Greece;XXX XXX XXXX
|
||||
27;ZA;South Africa;XX XXX XXXX
|
||||
20;EG;Egypt;XX XXXX XXXX
|
||||
7;KZ;Kazakhstan;XXX XXX XX XX
|
||||
7;RU;Russian Federation;XXX XXX XXXX
|
||||
1;PR;Puerto Rico;XXX XXX XXXX
|
||||
1;DO;Dominican Rep.;XXX XXX XXXX
|
||||
1;CA;Canada;XXX XXX XXXX
|
||||
1;US;USA;XXX XXX XXXX
|
||||
Binary file not shown.
@@ -1,10 +1,24 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
@@ -83,10 +97,6 @@ public class AndroidUtilities {
|
||||
|
||||
private static final Hashtable<String, Typeface> typefaceCache = new Hashtable<>();
|
||||
private static int prevOrientation = -10;
|
||||
private static boolean waitingForSms = false;
|
||||
private static boolean waitingForCall = false;
|
||||
private static final Object smsLock = new Object();
|
||||
private static final Object callLock = new Object();
|
||||
|
||||
public static int statusBarHeight = 0;
|
||||
public static float density = 1;
|
||||
@@ -98,9 +108,6 @@ public class AndroidUtilities {
|
||||
private static Boolean isTablet = null;
|
||||
private static int adjustOwnerClassGuid = 0;
|
||||
|
||||
private static Paint roundPaint;
|
||||
private static RectF bitmapRect;
|
||||
|
||||
public static Pattern WEB_URL = null;
|
||||
static {
|
||||
try {
|
||||
@@ -247,34 +254,6 @@ public class AndroidUtilities {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isGoogleMapsInstalled(final BaseFragment fragment) {
|
||||
try {
|
||||
ApplicationLoader.applicationContext.getPackageManager().getApplicationInfo("com.google.android.apps.maps", 0);
|
||||
return true;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
if (fragment.getParentActivity() == null) {
|
||||
return false;
|
||||
}
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(fragment.getParentActivity());
|
||||
builder.setMessage("Install Google Maps?");
|
||||
builder.setCancelable(true);
|
||||
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
try {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.apps.maps"));
|
||||
fragment.getParentActivity().startActivityForResult(intent, 500);
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
|
||||
fragment.showDialog(builder.create());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isInternalUri(Uri uri) {
|
||||
String pathString = uri.getPath();
|
||||
if (pathString == null) {
|
||||
@@ -361,34 +340,6 @@ public class AndroidUtilities {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isWaitingForSms() {
|
||||
boolean value;
|
||||
synchronized (smsLock) {
|
||||
value = waitingForSms;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static void setWaitingForSms(boolean value) {
|
||||
synchronized (smsLock) {
|
||||
waitingForSms = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isWaitingForCall() {
|
||||
boolean value;
|
||||
synchronized (callLock) {
|
||||
value = waitingForCall;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static void setWaitingForCall(boolean value) {
|
||||
synchronized (callLock) {
|
||||
waitingForCall = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static void showKeyboard(View view) {
|
||||
if (view == null) {
|
||||
return;
|
||||
@@ -429,6 +380,7 @@ public class AndroidUtilities {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public static File getCacheDir() {
|
||||
String state = null;
|
||||
try {
|
||||
@@ -456,6 +408,7 @@ public class AndroidUtilities {
|
||||
}
|
||||
return new File("");
|
||||
}
|
||||
*/
|
||||
|
||||
public static int dp(float value) {
|
||||
if (value == 0) {
|
||||
@@ -502,10 +455,6 @@ public class AndroidUtilities {
|
||||
return (cm / 2.54f) * (isX ? displayMetrics.xdpi : displayMetrics.ydpi);
|
||||
}
|
||||
|
||||
public static int getPeerLayerVersion(int layer) {
|
||||
return (layer >> 16) & 0xffff;
|
||||
}
|
||||
|
||||
public static void runOnUIThread(Runnable runnable) {
|
||||
runOnUIThread(runnable, 0);
|
||||
}
|
||||
@@ -583,78 +532,6 @@ public class AndroidUtilities {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public static AlertDialog.Builder buildTTLAlert(final Context context, final TLRPC.EncryptedChat encryptedChat) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle(LocaleController.getString("MessageLifetime", R.string.MessageLifetime));
|
||||
final NumberPicker numberPicker = new NumberPicker(context);
|
||||
numberPicker.setMinValue(0);
|
||||
numberPicker.setMaxValue(20);
|
||||
if (encryptedChat.ttl > 0 && encryptedChat.ttl < 16) {
|
||||
numberPicker.setValue(encryptedChat.ttl);
|
||||
} else if (encryptedChat.ttl == 30) {
|
||||
numberPicker.setValue(16);
|
||||
} else if (encryptedChat.ttl == 60) {
|
||||
numberPicker.setValue(17);
|
||||
} else if (encryptedChat.ttl == 60 * 60) {
|
||||
numberPicker.setValue(18);
|
||||
} else if (encryptedChat.ttl == 60 * 60 * 24) {
|
||||
numberPicker.setValue(19);
|
||||
} else if (encryptedChat.ttl == 60 * 60 * 24 * 7) {
|
||||
numberPicker.setValue(20);
|
||||
} else if (encryptedChat.ttl == 0) {
|
||||
numberPicker.setValue(0);
|
||||
}
|
||||
numberPicker.setFormatter(new NumberPicker.Formatter() {
|
||||
@Override
|
||||
public String format(int value) {
|
||||
if (value == 0) {
|
||||
return LocaleController.getString("ShortMessageLifetimeForever", R.string.ShortMessageLifetimeForever);
|
||||
} else if (value >= 1 && value < 16) {
|
||||
return AndroidUtilities.formatTTLString(value);
|
||||
} else if (value == 16) {
|
||||
return AndroidUtilities.formatTTLString(30);
|
||||
} else if (value == 17) {
|
||||
return AndroidUtilities.formatTTLString(60);
|
||||
} else if (value == 18) {
|
||||
return AndroidUtilities.formatTTLString(60 * 60);
|
||||
} else if (value == 19) {
|
||||
return AndroidUtilities.formatTTLString(60 * 60 * 24);
|
||||
} else if (value == 20) {
|
||||
return AndroidUtilities.formatTTLString(60 * 60 * 24 * 7);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
});
|
||||
builder.setView(numberPicker);
|
||||
builder.setNegativeButton(LocaleController.getString("Done", R.string.Done), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
int oldValue = encryptedChat.ttl;
|
||||
which = numberPicker.getValue();
|
||||
if (which >= 0 && which < 16) {
|
||||
encryptedChat.ttl = which;
|
||||
} else if (which == 16) {
|
||||
encryptedChat.ttl = 30;
|
||||
} else if (which == 17) {
|
||||
encryptedChat.ttl = 60;
|
||||
} else if (which == 18) {
|
||||
encryptedChat.ttl = 60 * 60;
|
||||
} else if (which == 19) {
|
||||
encryptedChat.ttl = 60 * 60 * 24;
|
||||
} else if (which == 20) {
|
||||
encryptedChat.ttl = 60 * 60 * 24 * 7;
|
||||
}
|
||||
if (oldValue != encryptedChat.ttl) {
|
||||
//SecretChatHelper.getInstance().sendTTLMessage(encryptedChat, null);
|
||||
//MessagesStorage.getInstance().updateEncryptedChatTTL(encryptedChat);
|
||||
}
|
||||
}
|
||||
});
|
||||
return builder;
|
||||
}
|
||||
*/
|
||||
|
||||
public static void clearCursorDrawable(EditText editText) {
|
||||
if (editText == null) {
|
||||
return;
|
||||
@@ -681,58 +558,13 @@ public class AndroidUtilities {
|
||||
}
|
||||
}
|
||||
|
||||
private static Intent createShortcutIntent(long did, boolean forDelete) {
|
||||
private static Intent createShortcutIntent(int did, Bitmap bitmap) {
|
||||
Intent shortcutIntent = new Intent(ApplicationLoader.applicationContext, OpenChatReceiver.class);
|
||||
|
||||
/*
|
||||
int lower_id = (int) did;
|
||||
int high_id = (int) (did >> 32);
|
||||
|
||||
TLRPC.User user = null;
|
||||
TLRPC.Chat chat = null;
|
||||
if (lower_id == 0) {
|
||||
shortcutIntent.putExtra("encId", high_id);
|
||||
TLRPC.EncryptedChat encryptedChat = MessagesController.getInstance().getEncryptedChat(high_id);
|
||||
if (encryptedChat == null) {
|
||||
return null;
|
||||
}
|
||||
user = MessagesController.getInstance().getUser(encryptedChat.user_id);
|
||||
} else if (lower_id > 0) {
|
||||
shortcutIntent.putExtra("userId", lower_id);
|
||||
user = MessagesController.getInstance().getUser(lower_id);
|
||||
} else if (lower_id < 0) {
|
||||
chat = MessagesController.getInstance().getChat(-lower_id);
|
||||
shortcutIntent.putExtra("chatId", -lower_id);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
if (user == null && chat == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String name;
|
||||
TLRPC.FileLocation photo = null;
|
||||
|
||||
if (user != null) {
|
||||
name = ContactsController.formatName(user.first_name, user.last_name);
|
||||
if (user.photo != null) {
|
||||
photo = user.photo.photo_small;
|
||||
}
|
||||
} else {
|
||||
name = chat.title;
|
||||
if (chat.photo != null) {
|
||||
photo = chat.photo.photo_small;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
TLRPC.FileLocation photo = null;
|
||||
shortcutIntent.putExtra("chatId", did);
|
||||
MrChat mrChat = MrMailbox.getChat((int)did);
|
||||
MrChat mrChat = MrMailbox.getChat(did);
|
||||
if( mrChat.getId() == 0 ) { return null; }
|
||||
String name = mrChat.getName();
|
||||
|
||||
|
||||
shortcutIntent.setAction("com.b44t.messenger.openchat" + did);
|
||||
shortcutIntent.addFlags(0x4000000);
|
||||
|
||||
@@ -740,70 +572,15 @@ public class AndroidUtilities {
|
||||
addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
|
||||
addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
|
||||
addIntent.putExtra("duplicate", false);
|
||||
if (!forDelete) {
|
||||
Bitmap bitmap = null;
|
||||
if (photo != null) {
|
||||
try {
|
||||
File path = FileLoader.getPathToAttach(photo, true);
|
||||
bitmap = BitmapFactory.decodeFile(path.toString());
|
||||
if (bitmap != null) {
|
||||
int size = AndroidUtilities.dp(58);
|
||||
Bitmap result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
|
||||
result.eraseColor(Color.TRANSPARENT);
|
||||
Canvas canvas = new Canvas(result);
|
||||
BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
|
||||
if (roundPaint == null) {
|
||||
roundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
bitmapRect = new RectF();
|
||||
}
|
||||
float scale = size / (float) bitmap.getWidth();
|
||||
canvas.save();
|
||||
canvas.scale(scale, scale);
|
||||
roundPaint.setShader(shader);
|
||||
bitmapRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
|
||||
canvas.drawRoundRect(bitmapRect, bitmap.getWidth(), bitmap.getHeight(), roundPaint);
|
||||
canvas.restore();
|
||||
Drawable drawable = ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.book_logo);
|
||||
int w = AndroidUtilities.dp(15);
|
||||
int left = size - w - AndroidUtilities.dp(2);
|
||||
int top = size - w - AndroidUtilities.dp(2);
|
||||
drawable.setBounds(left, top, left + w, top + w);
|
||||
drawable.draw(canvas);
|
||||
try {
|
||||
canvas.setBitmap(null);
|
||||
} catch (Exception e) {
|
||||
//don't promt, this will crash on 2.x
|
||||
}
|
||||
bitmap = result;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
}
|
||||
if (bitmap != null) {
|
||||
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmap);
|
||||
} else {
|
||||
/*if (user != null) {
|
||||
if (user.bot) {
|
||||
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(ApplicationLoader.applicationContext, R.drawable.book_bot));
|
||||
} else {
|
||||
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(ApplicationLoader.applicationContext, R.drawable.book_user));
|
||||
}
|
||||
} else if (chat != null) {
|
||||
if (ChatObject.isChannel(chat) && !chat.megagroup) {
|
||||
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(ApplicationLoader.applicationContext, R.drawable.book_channel));
|
||||
} else {*/
|
||||
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(ApplicationLoader.applicationContext, R.drawable.book_group));
|
||||
/*}
|
||||
}*/
|
||||
}
|
||||
if( bitmap != null ) {
|
||||
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmap);
|
||||
}
|
||||
return addIntent;
|
||||
}
|
||||
|
||||
public static void installShortcut(long did) {
|
||||
public static void installShortcut(int did, Bitmap bitmap) {
|
||||
try {
|
||||
Intent addIntent = createShortcutIntent(did, false);
|
||||
Intent addIntent = createShortcutIntent(did, bitmap);
|
||||
addIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
|
||||
ApplicationLoader.applicationContext.sendBroadcast(addIntent);
|
||||
} catch (Exception e) {
|
||||
@@ -811,9 +588,9 @@ public class AndroidUtilities {
|
||||
}
|
||||
}
|
||||
|
||||
public static void uninstallShortcut(long did) {
|
||||
public static void uninstallShortcut(int did) {
|
||||
try {
|
||||
Intent addIntent = createShortcutIntent(did, true);
|
||||
Intent addIntent = createShortcutIntent(did, null);
|
||||
addIntent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
|
||||
ApplicationLoader.applicationContext.sendBroadcast(addIntent);
|
||||
} catch (Exception e) {
|
||||
@@ -1007,55 +784,6 @@ public class AndroidUtilities {
|
||||
animatorSet.start();
|
||||
}
|
||||
|
||||
/*public static String ellipsize(String text, int maxLines, int maxWidth, TextPaint paint) {
|
||||
if (text == null || paint == null) {
|
||||
return null;
|
||||
}
|
||||
int count;
|
||||
int offset = 0;
|
||||
StringBuilder result = null;
|
||||
TextView
|
||||
for (int a = 0; a < maxLines; a++) {
|
||||
count = paint.breakText(text, true, maxWidth, null);
|
||||
if (a != maxLines - 1) {
|
||||
if (result == null) {
|
||||
result = new StringBuilder(count * maxLines + 1);
|
||||
}
|
||||
boolean foundSpace = false;
|
||||
for (int c = count - 1; c >= offset; c--) {
|
||||
if (text.charAt(c) == ' ') {
|
||||
foundSpace = true;
|
||||
result.append(text.substring(offset, c - 1));
|
||||
offset = c - 1;
|
||||
}
|
||||
}
|
||||
if (!foundSpace) {
|
||||
offset = count;
|
||||
}
|
||||
text = text.substring(0, offset);
|
||||
} else if (maxLines == 1) {
|
||||
return text.substring(0, count);
|
||||
} else {
|
||||
result.append(text.substring(0, count));
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}*/
|
||||
|
||||
/*public static void turnOffHardwareAcceleration(Window window) {
|
||||
if (window == null || Build.MODEL == null) {
|
||||
return;
|
||||
}
|
||||
if (Build.MODEL.contains("GT-S5301") ||
|
||||
Build.MODEL.contains("GT-S5303") ||
|
||||
Build.MODEL.contains("GT-B5330") ||
|
||||
Build.MODEL.contains("GT-S5302") ||
|
||||
Build.MODEL.contains("GT-S6012B") ||
|
||||
Build.MODEL.contains("MegaFon_SP-AI")) {
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
|
||||
}
|
||||
}*/
|
||||
|
||||
public static void addToClipboard(CharSequence str) {
|
||||
try {
|
||||
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
@@ -223,23 +238,19 @@ public class ApplicationLoader extends Application {
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
// open() sqlite file (you can inspect the file eg. with "Tools / Android Device Monitor / File Explorer")
|
||||
// open() should be called before MessagesController.getInstance() as this also initilizes directories based upon getBlobdir().
|
||||
File dbfile = new File(getFilesDirFixed(), "messenger.db");
|
||||
MrMailbox.open(dbfile.getAbsolutePath());
|
||||
MrMailbox.connect();
|
||||
|
||||
// create other default objects
|
||||
MessagesController.getInstance();
|
||||
ConnectionsManager.getInstance().init(deviceModel, systemVersion, appVersion, langCode, configPath, FileLog.getNetworkLogPath(), UserConfig.getClientUserId(), enablePushConnection);
|
||||
if (UserConfig.getCurrentUser() != null) {
|
||||
MessagesController.getInstance().putUser(UserConfig.getCurrentUser(), true);
|
||||
SendMessagesHelper.getInstance().checkUnsentMessages();
|
||||
}
|
||||
|
||||
ApplicationLoader app = (ApplicationLoader)ApplicationLoader.applicationContext;
|
||||
FileLog.e("messenger", "app initied");
|
||||
|
||||
//ContactsController.getInstance().checkAppAccount();
|
||||
MediaController.getInstance();
|
||||
|
||||
// EDIT BY MR - open my sqlite file (you can inspect the file eg. with "Tools / Android Device Monitor / File Explorer")
|
||||
File dbfile = new File(getFilesDirFixed(), "messenger.db");
|
||||
MrMailbox.open(dbfile.getAbsolutePath(), "");
|
||||
MrMailbox.connect();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -255,45 +266,13 @@ public class ApplicationLoader extends Application {
|
||||
// however, we may want to to have a look at onPause() eg. of activities (eg. for flushing data, if needed)
|
||||
MrMailbox.MrCallback(0, 0, 0); // do not remove this call; this makes sure, the function is not removed from build or warnings are printed!
|
||||
MrMailbox.init();
|
||||
MrMailbox.MrStockAddStr(1, LocaleController.getString("NoMessages", R.string.NoMessages));
|
||||
MrMailbox.MrStockAddStr(2, LocaleController.getString("FromSelf", R.string.FromSelf));
|
||||
MrMailbox.MrStockAddStr(3, LocaleController.getString("Draft", R.string.Draft));
|
||||
MrMailbox.MrStockAddStr(4, LocaleController.getString("MemberSg", R.string.MemberSg));
|
||||
MrMailbox.MrStockAddStr(5, LocaleController.getString("MemberPl", R.string.MemberPl));
|
||||
MrMailbox.MrStockAddStr(6, LocaleController.getString("ContactSg", R.string.ContactSg));
|
||||
MrMailbox.MrStockAddStr(7, LocaleController.getString("ContactPl", R.string.ContactPl));
|
||||
MrMailbox.MrStockAddStr(8, LocaleController.getString("Deaddrop", R.string.Deaddrop));
|
||||
MrMailbox.MrStockAddStr(9, LocaleController.getString("AttachPhoto", R.string.AttachPhoto));
|
||||
MrMailbox.MrStockAddStr(10, LocaleController.getString("AttachVideo", R.string.AttachVideo));
|
||||
MrMailbox.MrStockAddStr(11, LocaleController.getString("AttachAudio", R.string.AttachAudio));
|
||||
MrMailbox.MrStockAddStr(12, LocaleController.getString("AttachDocument", R.string.AttachDocument));
|
||||
MrMailbox.MrStockAddStr(13, LocaleController.getString("DefaultStatusText", R.string.DefaultStatusText));
|
||||
MrMailbox.MrStockAddStr(14, LocaleController.getString("SubjectPrefix", R.string.SubjectPrefix));
|
||||
MrMailbox.initStockStrings();
|
||||
|
||||
applicationHandler = new Handler(applicationContext.getMainLooper());
|
||||
|
||||
startPushService();
|
||||
}
|
||||
|
||||
/*public static void sendRegIdToBackend(final String token) {
|
||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
UserConfig.pushString = token;
|
||||
UserConfig.registeredForPush = false;
|
||||
UserConfig.saveConfig(false);
|
||||
if (UserConfig.getClientUserId() != 0) {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
MessagesController.getInstance().registerForPush(token);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}*/
|
||||
|
||||
public static void startPushService() {
|
||||
SharedPreferences preferences = applicationContext.getSharedPreferences("Notifications", MODE_PRIVATE);
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
@@ -22,6 +37,7 @@ public class AutoMessageHeardReceiver extends BroadcastReceiver {
|
||||
if (dialog_id == 0 || max_id == 0) {
|
||||
return;
|
||||
}
|
||||
MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, true, false);
|
||||
MrMailbox.markseenChat((int)dialog_id);
|
||||
NotificationsController.getInstance().removeSeenMessages();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
@@ -32,7 +47,8 @@ public class AutoMessageReplyReceiver extends BroadcastReceiver {
|
||||
if (dialog_id == 0 || max_id == 0) {
|
||||
return;
|
||||
}
|
||||
SendMessagesHelper.getInstance().sendMessageText(text.toString(), dialog_id, null, null, true, null, null);
|
||||
MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, true, false);
|
||||
SendMessagesHelper.getInstance().sendMessageText(text.toString(), dialog_id, null, null);
|
||||
MrMailbox.markseenChat((int)dialog_id);
|
||||
NotificationsController.getInstance().removeSeenMessages();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,24 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
public class ChatObject {
|
||||
|
||||
public static final int CHAT_TYPE_CHAT = 0;
|
||||
|
||||
public static boolean isNotInChat(TLRPC.Chat chat) {
|
||||
return chat == null || chat instanceof TLRPC.TL_chatEmpty || chat.left || chat.kicked || chat.deactivated;
|
||||
}
|
||||
|
||||
public static boolean isChannel(TLRPC.Chat chat) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isChannel(int chatId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean canWriteToChat(TLRPC.Chat chat) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
@@ -29,6 +44,7 @@ public class ClearCacheService extends IntentService {
|
||||
protected void onHandleIntent(Intent intent) {
|
||||
ApplicationLoader.postInitApplication();
|
||||
|
||||
/*
|
||||
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
|
||||
final int keepMedia = preferences.getInt("keep_media", 2);
|
||||
if (keepMedia == 2) {
|
||||
@@ -78,5 +94,6 @@ public class ClearCacheService extends IntentService {
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,51 +1,71 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 1.3.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
*******************************************************************************
|
||||
*
|
||||
* File: ContactsController.java
|
||||
* Authors: Björn Petersen
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentUris;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.BitmapShader;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.ContactsContract;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import com.b44t.ui.Components.AvatarDrawable;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class ContactsController {
|
||||
|
||||
static ContentResolver s_cr;
|
||||
private static final String TAG = "ContactsController";
|
||||
|
||||
public static class Contact {
|
||||
public String name;
|
||||
public String email;
|
||||
}
|
||||
|
||||
private String[] projectionNames = {
|
||||
private final static String[] projectionNames = {
|
||||
ContactsContract.Data.DISPLAY_NAME,
|
||||
ContactsContract.CommonDataKinds.Email.ADDRESS
|
||||
};
|
||||
|
||||
private static volatile ContactsController Instance = null;
|
||||
|
||||
public static ContactsController getInstance() {
|
||||
ContactsController localInstance = Instance;
|
||||
if (localInstance == null) {
|
||||
synchronized (ContactsController.class) {
|
||||
localInstance = Instance;
|
||||
if (localInstance == null) {
|
||||
Instance = localInstance = new ContactsController();
|
||||
}
|
||||
}
|
||||
}
|
||||
return localInstance;
|
||||
}
|
||||
|
||||
public ContactsController() {
|
||||
}
|
||||
|
||||
public String readContactsFromPhoneBook() {
|
||||
public static String readContactsFromPhoneBook() {
|
||||
HashMap<String, String> contactsMap = new HashMap<String, String>();
|
||||
String allContacts = "";
|
||||
try {
|
||||
@@ -77,7 +97,7 @@ public class ContactsController {
|
||||
return allContacts;
|
||||
}
|
||||
|
||||
private boolean hasContactsPermission() {
|
||||
private static boolean hasContactsPermission() {
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
return ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
@@ -89,14 +109,14 @@ public class ContactsController {
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
;
|
||||
} finally {
|
||||
try {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -134,4 +154,233 @@ public class ContactsController {
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
|
||||
/* Handle contact images
|
||||
**********************************************************************************************/
|
||||
|
||||
static class AvtCacheEntry {
|
||||
public Bitmap m_avatarBitmap;
|
||||
public String m_fallbackName;
|
||||
public boolean m_needsReload;
|
||||
AvtCacheEntry(Bitmap avatarBitmap, String fallbackName) {
|
||||
m_avatarBitmap = avatarBitmap;
|
||||
m_fallbackName = fallbackName;
|
||||
m_needsReload = false;
|
||||
}
|
||||
}
|
||||
|
||||
private final static String[] s_projectionAvatars = new String[]{
|
||||
ContactsContract.Contacts._ID,
|
||||
ContactsContract.Contacts.PHOTO_ID,
|
||||
ContactsContract.CommonDataKinds.Email.ADDRESS
|
||||
//ContactsContract.CommonDataKinds.Email.DISPLAY_NAME,
|
||||
};
|
||||
private static final Object s_sync = new Object();
|
||||
private static HashMap<String, AvtCacheEntry> s_avtCache = new HashMap<>();
|
||||
|
||||
public static void cleanupAvatarCache() {
|
||||
// to detect changes of the avatar images eg. in the Contacts App,
|
||||
// this function should be called whenever the App goes to background or back to foreground.
|
||||
// instead of emptying the cache, we force a reloading (looks smarter - most times, the avatars do not change)
|
||||
synchronized (s_sync) {
|
||||
for (AvtCacheEntry cacheEntry : s_avtCache.values()) {
|
||||
cacheEntry.m_needsReload = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void setupAvatar(final View avtView,
|
||||
final ImageReceiver avtImageReceiver,
|
||||
final AvatarDrawable avtDrawable,
|
||||
MrContact mrContact,
|
||||
MrChat mrChat)
|
||||
{
|
||||
// get email/name to search avatar image for
|
||||
String tempEmail = null;
|
||||
String tempName = "";
|
||||
if (mrContact != null) {
|
||||
tempEmail = mrContact.getAddr();
|
||||
tempName = mrContact.getDisplayName();
|
||||
} else if (mrChat != null) {
|
||||
tempName = mrChat.getName();
|
||||
if (mrChat.getType() == MrChat.MR_CHAT_NORMAL) {
|
||||
int[] contact_ids = MrMailbox.getChatContacts(mrChat.getId());
|
||||
if (contact_ids.length == 1) {
|
||||
MrContact mrc = MrMailbox.getContact(contact_ids[0]);
|
||||
tempEmail = mrc.getAddr();
|
||||
tempName = mrc.getDisplayName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setupAvatarByStrings(avtView, avtImageReceiver, avtDrawable, tempEmail, tempName);
|
||||
}
|
||||
|
||||
public static void setupAvatarByStrings(final View avtView,
|
||||
final ImageReceiver avtImageReceiver,
|
||||
final AvatarDrawable avtDrawable,
|
||||
String tempEmail,
|
||||
String tempName)
|
||||
{
|
||||
if( tempEmail == null ) {
|
||||
tempEmail = "fallback:" + tempName;
|
||||
}
|
||||
|
||||
final String email = tempEmail;
|
||||
final String fallbackName = tempName;
|
||||
|
||||
// bind e-mail+name address to view object to detect overwrites and discard loading old images (may happen on fast scrolling)
|
||||
// moreover, check if the avatar is in cache
|
||||
AvtCacheEntry cacheEntry;
|
||||
synchronized (s_sync) {
|
||||
avtImageReceiver.m_userDataUnique = email+fallbackName;
|
||||
cacheEntry = s_avtCache.get(email+fallbackName);
|
||||
}
|
||||
|
||||
if( cacheEntry != null )
|
||||
{
|
||||
// can use avatar from cache, very fine
|
||||
if (cacheEntry.m_avatarBitmap != null) {
|
||||
avtImageReceiver.setImageBitmap(cacheEntry.m_avatarBitmap);
|
||||
} else {
|
||||
avtDrawable.setInfoByName(cacheEntry.m_fallbackName);
|
||||
avtImageReceiver.setImage(null, "50_50", avtDrawable, null, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// avatar is not in cache, empty the image (may be the bitmap of another use as we re-use the objects)
|
||||
avtImageReceiver.setImage(null, "50_50", null, null, false);
|
||||
}
|
||||
|
||||
if( cacheEntry==null || cacheEntry.m_needsReload )
|
||||
{
|
||||
// avatar is not in cache or needs reloading:
|
||||
// load avatar in a working thread (when loaded, we'll add it to cache and invalidate back in the GUI thread)
|
||||
Utilities.searchQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// is the avatar still desired?
|
||||
synchronized (s_sync) {
|
||||
if (!avtImageReceiver.m_userDataUnique.equals(email+fallbackName)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// try to get avatar image from the address book
|
||||
Bitmap tempBitmap = null;
|
||||
if (!email.startsWith("fallback:")) {
|
||||
try {
|
||||
if (s_cr == null) {
|
||||
s_cr = ApplicationLoader.applicationContext.getContentResolver();
|
||||
}
|
||||
Uri uri = Uri.withAppendedPath(ContactsContract.CommonDataKinds.Email.CONTENT_LOOKUP_URI, Uri.encode(email));
|
||||
Cursor pCur = s_cr.query(uri, s_projectionAvatars, null, null, null);
|
||||
if (pCur != null) {
|
||||
if (pCur.getCount() > 0) {
|
||||
while (pCur.moveToNext()) {
|
||||
int contact_id = pCur.getInt(0);
|
||||
int photo_id = pCur.getInt(1);
|
||||
String addr = pCur.getString(2);
|
||||
if (addr.equalsIgnoreCase(email) && contact_id > 0 && photo_id > 0) {
|
||||
Bitmap tempBitmap2 = loadContactPhoto(s_cr, contact_id, photo_id);
|
||||
if (tempBitmap2 != null) {
|
||||
tempBitmap = createRoundBitmap(tempBitmap2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pCur.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
final Bitmap photoBitmap = tempBitmap;
|
||||
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// is the avatar still desired?
|
||||
synchronized (s_sync) {
|
||||
if (!avtImageReceiver.m_userDataUnique.equals(email+fallbackName)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (photoBitmap != null) {
|
||||
avtImageReceiver.setImageBitmap(photoBitmap);
|
||||
} else {
|
||||
avtDrawable.setInfoByName(fallbackName);
|
||||
avtImageReceiver.setImage(null, "50_50", avtDrawable, null, false);
|
||||
}
|
||||
avtView.invalidate();
|
||||
|
||||
synchronized (s_sync) {
|
||||
s_avtCache.put(email+fallbackName, new AvtCacheEntry(photoBitmap, fallbackName));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// from http://stackoverflow.com/questions/2383580/how-do-i-load-a-contact-photo
|
||||
public static Bitmap loadContactPhoto(ContentResolver cr, long contact_id, long photo_id)
|
||||
{
|
||||
// first try using photo_id
|
||||
byte[] photoBytes = null;
|
||||
Uri photoUri = ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, photo_id);
|
||||
Cursor c = cr.query(photoUri, new String[] {ContactsContract.CommonDataKinds.Photo.PHOTO}, null, null, null);
|
||||
if( c != null ) {
|
||||
try {
|
||||
if (c.moveToFirst()) {
|
||||
photoBytes = c.getBlob(0);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
;
|
||||
} finally {
|
||||
c.close();
|
||||
}
|
||||
}
|
||||
if (photoBytes != null) {
|
||||
return BitmapFactory.decodeByteArray(photoBytes, 0, photoBytes.length);
|
||||
}
|
||||
|
||||
// second try using contact_id
|
||||
Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contact_id);
|
||||
InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(cr, uri);
|
||||
if (input != null) {
|
||||
return BitmapFactory.decodeStream(input);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Paint roundPaint;
|
||||
private static RectF bitmapRect;
|
||||
private static Bitmap createRoundBitmap(Bitmap bitmap) {
|
||||
try {
|
||||
Bitmap result = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
|
||||
result.eraseColor(Color.TRANSPARENT);
|
||||
Canvas canvas = new Canvas(result);
|
||||
BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
|
||||
if (roundPaint == null) {
|
||||
roundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
bitmapRect = new RectF();
|
||||
}
|
||||
roundPaint.setShader(shader);
|
||||
bitmapRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
|
||||
canvas.drawRoundRect(bitmapRect, bitmap.getWidth(), bitmap.getHeight(), roundPaint);
|
||||
return result;
|
||||
} catch (Throwable e) {
|
||||
;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
@@ -77,11 +92,13 @@ public class FileLoader {
|
||||
mediaDirs = dirs;
|
||||
}
|
||||
|
||||
/*
|
||||
public File checkDirectory(int type) {
|
||||
return mediaDirs.get(type);
|
||||
}
|
||||
*/
|
||||
|
||||
public File getDirectory(int type) {
|
||||
public File getDirectory(int type) { // always returns the cache directory as this is the only one set in mediaDirs[] - we do not use the other directories at the moment
|
||||
File dir = mediaDirs.get(type);
|
||||
if (dir == null && type != MEDIA_DIR_CACHE) {
|
||||
dir = mediaDirs.get(MEDIA_DIR_CACHE);
|
||||
@@ -507,7 +524,7 @@ public class FileLoader {
|
||||
if (message == null) {
|
||||
return "";
|
||||
}
|
||||
if (message instanceof TLRPC.TL_messageService) {
|
||||
/*if (message instanceof TLRPC.TL_messageService) {
|
||||
if (message.action.photo != null) {
|
||||
ArrayList<TLRPC.PhotoSize> sizes = message.action.photo.sizes;
|
||||
if (sizes.size() > 0) {
|
||||
@@ -517,7 +534,7 @@ public class FileLoader {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else*/ {
|
||||
if (message.media instanceof TLRPC.TL_messageMediaDocument) {
|
||||
return getAttachFileName(message.media.document);
|
||||
} else if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
|
||||
@@ -528,7 +545,7 @@ public class FileLoader {
|
||||
return getAttachFileName(sizeFull);
|
||||
}
|
||||
}
|
||||
} else if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
} /*else if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
if (message.media.webpage.photo != null) {
|
||||
ArrayList<TLRPC.PhotoSize> sizes = message.media.webpage.photo.sizes;
|
||||
if (sizes.size() > 0) {
|
||||
@@ -540,7 +557,7 @@ public class FileLoader {
|
||||
} else if (message.media.webpage.document != null) {
|
||||
return getAttachFileName(message.media.webpage.document);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -549,7 +566,7 @@ public class FileLoader {
|
||||
if (message == null) {
|
||||
return new File("");
|
||||
}
|
||||
if (message instanceof TLRPC.TL_messageService) {
|
||||
/*if (message instanceof TLRPC.TL_messageService) {
|
||||
if (message.action.photo != null) {
|
||||
ArrayList<TLRPC.PhotoSize> sizes = message.action.photo.sizes;
|
||||
if (sizes.size() > 0) {
|
||||
@@ -559,7 +576,7 @@ public class FileLoader {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else*/ {
|
||||
if (message.media instanceof TLRPC.TL_messageMediaDocument) {
|
||||
return getPathToAttach(message.media.document);
|
||||
} else if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
|
||||
@@ -570,7 +587,7 @@ public class FileLoader {
|
||||
return getPathToAttach(sizeFull);
|
||||
}
|
||||
}
|
||||
} else if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
} /*else if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
if (message.media.webpage.document != null) {
|
||||
return getPathToAttach(message.media.webpage.document);
|
||||
} else if (message.media.webpage.photo != null) {
|
||||
@@ -582,7 +599,7 @@ public class FileLoader {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
return new File("");
|
||||
}
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
@@ -1159,11 +1174,11 @@ public class ImageLoader {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (MediaController.getInstance().canSaveToGallery() && messengerPath != null && finalFile != null && (location.endsWith(".mp4") || location.endsWith(".jpg"))) {
|
||||
/*if (MediaController.getInstance().canSaveToGallery() && messengerPath != null && finalFile != null && (location.endsWith(".mp4") || location.endsWith(".jpg"))) {
|
||||
if (finalFile.toString().startsWith(messengerPath.toString())) {
|
||||
AndroidUtilities.addMediaToGallery(finalFile.toString());
|
||||
}
|
||||
}
|
||||
}*/
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.FileDidLoaded, location);
|
||||
ImageLoader.this.fileDidLoaded(location, finalFile, type);
|
||||
}
|
||||
@@ -1228,27 +1243,21 @@ public class ImageLoader {
|
||||
filter.addDataScheme("file");
|
||||
ApplicationLoader.applicationContext.registerReceiver(receiver, filter);
|
||||
|
||||
HashMap<Integer, File> mediaDirs = new HashMap<>();
|
||||
File cachePath = AndroidUtilities.getCacheDir();
|
||||
if (!cachePath.isDirectory()) {
|
||||
try {
|
||||
cachePath.mkdirs();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
new File(cachePath, ".nomedia").createNewFile();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
mediaDirs.put(FileLoader.MEDIA_DIR_CACHE, cachePath);
|
||||
FileLoader.getInstance().setMediaDirs(mediaDirs);
|
||||
|
||||
checkMediaPaths();
|
||||
}
|
||||
|
||||
public void checkMediaPaths() {
|
||||
HashMap<Integer, File> mediaDirs = new HashMap<>();
|
||||
File cachePath = new File(MrMailbox.getBlobdir());
|
||||
try {
|
||||
new File(cachePath, ".nomedia").createNewFile();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
mediaDirs.put(FileLoader.MEDIA_DIR_CACHE, cachePath);
|
||||
FileLoader.getInstance().setMediaDirs(mediaDirs);
|
||||
|
||||
/*
|
||||
cacheOutQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -1261,9 +1270,11 @@ public class ImageLoader {
|
||||
});
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
public HashMap<Integer, File> createMediaPaths() {
|
||||
/*
|
||||
public HashMap<Integer, File> createMediaPaths() { // not sure, but it seems as if these paths are not needed
|
||||
HashMap<Integer, File> mediaDirs = new HashMap<>();
|
||||
File cachePath = AndroidUtilities.getCacheDir();
|
||||
if (!cachePath.isDirectory()) {
|
||||
@@ -1344,6 +1355,7 @@ public class ImageLoader {
|
||||
|
||||
return mediaDirs;
|
||||
}
|
||||
*/
|
||||
|
||||
private boolean canMoveFiles(File from, File to, int type) {
|
||||
RandomAccessFile file = null;
|
||||
@@ -2230,6 +2242,7 @@ public class ImageLoader {
|
||||
return ext;
|
||||
}
|
||||
|
||||
/*
|
||||
public static void saveMessageThumbs(TLRPC.Message message) {
|
||||
TLRPC.PhotoSize photoSize = null;
|
||||
if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
|
||||
@@ -2243,16 +2256,17 @@ public class ImageLoader {
|
||||
if (message.media.document.thumb instanceof TLRPC.TL_photoCachedSize) {
|
||||
photoSize = message.media.document.thumb;
|
||||
}
|
||||
} else if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
if (message.media.webpage.photo != null) {
|
||||
for (TLRPC.PhotoSize size : message.media.webpage.photo.sizes) {
|
||||
if (size instanceof TLRPC.TL_photoCachedSize) {
|
||||
photoSize = size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//else if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
// if (message.media.webpage.photo != null) {
|
||||
// for (TLRPC.PhotoSize size : message.media.webpage.photo.sizes) {
|
||||
// if (size instanceof TLRPC.TL_photoCachedSize) {
|
||||
// photoSize = size;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
if (photoSize != null && photoSize.bytes != null && photoSize.bytes.length != 0) {
|
||||
if (photoSize.location instanceof TLRPC.TL_fileLocationUnavailable) {
|
||||
photoSize.location = new TLRPC.TL_fileLocation();
|
||||
@@ -2287,17 +2301,20 @@ public class ImageLoader {
|
||||
}
|
||||
} else if (message.media instanceof TLRPC.TL_messageMediaDocument) {
|
||||
message.media.document.thumb = newPhotoSize;
|
||||
} else if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
for (int a = 0; a < message.media.webpage.photo.sizes.size(); a++) {
|
||||
if (message.media.webpage.photo.sizes.get(a) instanceof TLRPC.TL_photoCachedSize) {
|
||||
message.media.webpage.photo.sizes.set(a, newPhotoSize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//else if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
// for (int a = 0; a < message.media.webpage.photo.sizes.size(); a++) {
|
||||
// if (message.media.webpage.photo.sizes.get(a) instanceof TLRPC.TL_photoCachedSize) {
|
||||
// message.media.webpage.photo.sizes.set(a, newPhotoSize);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
public static void saveMessagesThumbs(ArrayList<TLRPC.Message> messages) {
|
||||
if (messages == null || messages.isEmpty()) {
|
||||
return;
|
||||
@@ -2307,4 +2324,5 @@ public class ImageLoader {
|
||||
saveMessageThumbs(message);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 1.3.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
@@ -14,6 +29,7 @@ import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.graphics.Rect;
|
||||
@@ -27,6 +43,7 @@ import com.b44t.ui.Components.AnimatedFileDrawable;
|
||||
|
||||
public class ImageReceiver implements NotificationCenter.NotificationCenterDelegate {
|
||||
|
||||
|
||||
public interface ImageReceiverDelegate {
|
||||
void didSetImage(ImageReceiver imageReceiver, boolean set, boolean thumb);
|
||||
}
|
||||
@@ -43,6 +60,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
|
||||
public String ext;
|
||||
}
|
||||
|
||||
public String m_userDataUnique = ""; // used to discard images loaded and no longer required as there was a new request
|
||||
// before, we used "private static HashMap<View, String> s_viewBindings = new HashMap<>();" in ContactsController -
|
||||
// however, this was a bad idea as this resulted in _lots_ of objects that were never freed...
|
||||
|
||||
|
||||
private View parentView;
|
||||
private Integer tag;
|
||||
private Integer thumbTag;
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 1.3.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
@@ -64,8 +79,6 @@ public class LocaleController {
|
||||
private String languageOverride;
|
||||
private boolean changingConfiguration = false;
|
||||
|
||||
private HashMap<String, String> translitChars;
|
||||
|
||||
private class TimeZoneChangedReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
@@ -887,580 +900,6 @@ public class LocaleController {
|
||||
}
|
||||
*/
|
||||
|
||||
public static String formatUserStatus(TLRPC.User user) {
|
||||
if (user != null && user.status != null && user.status.expires == 0) {
|
||||
if (user.status instanceof TLRPC.TL_userStatusRecently) {
|
||||
user.status.expires = -100;
|
||||
} else if (user.status instanceof TLRPC.TL_userStatusLastWeek) {
|
||||
user.status.expires = -101;
|
||||
} else if (user.status instanceof TLRPC.TL_userStatusLastMonth) {
|
||||
user.status.expires = -102;
|
||||
}
|
||||
}
|
||||
if (user != null && user.status != null && user.status.expires <= 0) {
|
||||
if (MessagesController.getInstance().onlinePrivacy.containsKey(user.id)) {
|
||||
return getString("Online", R.string.Online);
|
||||
}
|
||||
}
|
||||
if (user == null || user.status == null || user.status.expires == 0 || UserObject.isDeleted(user) ) {
|
||||
return getString("ALongTimeAgo", R.string.ALongTimeAgo);
|
||||
} else {
|
||||
int currentTime = ConnectionsManager.getInstance().getCurrentTime();
|
||||
if (user.status.expires > currentTime) {
|
||||
return getString("Online", R.string.Online);
|
||||
} else {
|
||||
if (user.status.expires == -1) {
|
||||
return getString("Invisible", R.string.Invisible);
|
||||
} else if (user.status.expires == -100) {
|
||||
return getString("Lately", R.string.Lately);
|
||||
} else if (user.status.expires == -101) {
|
||||
return getString("WithinAWeek", R.string.WithinAWeek);
|
||||
} else if (user.status.expires == -102) {
|
||||
return getString("WithinAMonth", R.string.WithinAMonth);
|
||||
} else {
|
||||
return formatDateOnline(user.status.expires);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getTranslitString(String src) {
|
||||
if (translitChars == null) {
|
||||
translitChars = new HashMap<>(520);
|
||||
translitChars.put("ȼ", "c");
|
||||
translitChars.put("ᶇ", "n");
|
||||
translitChars.put("ɖ", "d");
|
||||
translitChars.put("ỿ", "y");
|
||||
translitChars.put("ᴓ", "o");
|
||||
translitChars.put("ø", "o");
|
||||
translitChars.put("ḁ", "a");
|
||||
translitChars.put("ʯ", "h");
|
||||
translitChars.put("ŷ", "y");
|
||||
translitChars.put("ʞ", "k");
|
||||
translitChars.put("ừ", "u");
|
||||
translitChars.put("ꜳ", "aa");
|
||||
translitChars.put("ij", "ij");
|
||||
translitChars.put("ḽ", "l");
|
||||
translitChars.put("ɪ", "i");
|
||||
translitChars.put("ḇ", "b");
|
||||
translitChars.put("ʀ", "r");
|
||||
translitChars.put("ě", "e");
|
||||
translitChars.put("ffi", "ffi");
|
||||
translitChars.put("ơ", "o");
|
||||
translitChars.put("ⱹ", "r");
|
||||
translitChars.put("ồ", "o");
|
||||
translitChars.put("ǐ", "i");
|
||||
translitChars.put("ꝕ", "p");
|
||||
translitChars.put("ý", "y");
|
||||
translitChars.put("ḝ", "e");
|
||||
translitChars.put("ₒ", "o");
|
||||
translitChars.put("ⱥ", "a");
|
||||
translitChars.put("ʙ", "b");
|
||||
translitChars.put("ḛ", "e");
|
||||
translitChars.put("ƈ", "c");
|
||||
translitChars.put("ɦ", "h");
|
||||
translitChars.put("ᵬ", "b");
|
||||
translitChars.put("ṣ", "s");
|
||||
translitChars.put("đ", "d");
|
||||
translitChars.put("ỗ", "o");
|
||||
translitChars.put("ɟ", "j");
|
||||
translitChars.put("ẚ", "a");
|
||||
translitChars.put("ɏ", "y");
|
||||
translitChars.put("л", "l");
|
||||
translitChars.put("ʌ", "v");
|
||||
translitChars.put("ꝓ", "p");
|
||||
translitChars.put("fi", "fi");
|
||||
translitChars.put("ᶄ", "k");
|
||||
translitChars.put("ḏ", "d");
|
||||
translitChars.put("ᴌ", "l");
|
||||
translitChars.put("ė", "e");
|
||||
translitChars.put("ё", "yo");
|
||||
translitChars.put("ᴋ", "k");
|
||||
translitChars.put("ċ", "c");
|
||||
translitChars.put("ʁ", "r");
|
||||
translitChars.put("ƕ", "hv");
|
||||
translitChars.put("ƀ", "b");
|
||||
translitChars.put("ṍ", "o");
|
||||
translitChars.put("ȣ", "ou");
|
||||
translitChars.put("ǰ", "j");
|
||||
translitChars.put("ᶃ", "g");
|
||||
translitChars.put("ṋ", "n");
|
||||
translitChars.put("ɉ", "j");
|
||||
translitChars.put("ǧ", "g");
|
||||
translitChars.put("dz", "dz");
|
||||
translitChars.put("ź", "z");
|
||||
translitChars.put("ꜷ", "au");
|
||||
translitChars.put("ǖ", "u");
|
||||
translitChars.put("ᵹ", "g");
|
||||
translitChars.put("ȯ", "o");
|
||||
translitChars.put("ɐ", "a");
|
||||
translitChars.put("ą", "a");
|
||||
translitChars.put("õ", "o");
|
||||
translitChars.put("ɻ", "r");
|
||||
translitChars.put("ꝍ", "o");
|
||||
translitChars.put("ǟ", "a");
|
||||
translitChars.put("ȴ", "l");
|
||||
translitChars.put("ʂ", "s");
|
||||
translitChars.put("fl", "fl");
|
||||
translitChars.put("ȉ", "i");
|
||||
translitChars.put("ⱻ", "e");
|
||||
translitChars.put("ṉ", "n");
|
||||
translitChars.put("ï", "i");
|
||||
translitChars.put("ñ", "n");
|
||||
translitChars.put("ᴉ", "i");
|
||||
translitChars.put("ʇ", "t");
|
||||
translitChars.put("ẓ", "z");
|
||||
translitChars.put("ỷ", "y");
|
||||
translitChars.put("ȳ", "y");
|
||||
translitChars.put("ṩ", "s");
|
||||
translitChars.put("ɽ", "r");
|
||||
translitChars.put("ĝ", "g");
|
||||
translitChars.put("в", "v");
|
||||
translitChars.put("ᴝ", "u");
|
||||
translitChars.put("ḳ", "k");
|
||||
translitChars.put("ꝫ", "et");
|
||||
translitChars.put("ī", "i");
|
||||
translitChars.put("ť", "t");
|
||||
translitChars.put("ꜿ", "c");
|
||||
translitChars.put("ʟ", "l");
|
||||
translitChars.put("ꜹ", "av");
|
||||
translitChars.put("û", "u");
|
||||
translitChars.put("æ", "ae");
|
||||
translitChars.put("и", "i");
|
||||
translitChars.put("ă", "a");
|
||||
translitChars.put("ǘ", "u");
|
||||
translitChars.put("ꞅ", "s");
|
||||
translitChars.put("ᵣ", "r");
|
||||
translitChars.put("ᴀ", "a");
|
||||
translitChars.put("ƃ", "b");
|
||||
translitChars.put("ḩ", "h");
|
||||
translitChars.put("ṧ", "s");
|
||||
translitChars.put("ₑ", "e");
|
||||
translitChars.put("ʜ", "h");
|
||||
translitChars.put("ẋ", "x");
|
||||
translitChars.put("ꝅ", "k");
|
||||
translitChars.put("ḋ", "d");
|
||||
translitChars.put("ƣ", "oi");
|
||||
translitChars.put("ꝑ", "p");
|
||||
translitChars.put("ħ", "h");
|
||||
translitChars.put("ⱴ", "v");
|
||||
translitChars.put("ẇ", "w");
|
||||
translitChars.put("ǹ", "n");
|
||||
translitChars.put("ɯ", "m");
|
||||
translitChars.put("ɡ", "g");
|
||||
translitChars.put("ɴ", "n");
|
||||
translitChars.put("ᴘ", "p");
|
||||
translitChars.put("ᵥ", "v");
|
||||
translitChars.put("ū", "u");
|
||||
translitChars.put("ḃ", "b");
|
||||
translitChars.put("ṗ", "p");
|
||||
translitChars.put("ь", "");
|
||||
translitChars.put("å", "a");
|
||||
translitChars.put("ɕ", "c");
|
||||
translitChars.put("ọ", "o");
|
||||
translitChars.put("ắ", "a");
|
||||
translitChars.put("ƒ", "f");
|
||||
translitChars.put("ǣ", "ae");
|
||||
translitChars.put("ꝡ", "vy");
|
||||
translitChars.put("ff", "ff");
|
||||
translitChars.put("ᶉ", "r");
|
||||
translitChars.put("ô", "o");
|
||||
translitChars.put("ǿ", "o");
|
||||
translitChars.put("ṳ", "u");
|
||||
translitChars.put("ȥ", "z");
|
||||
translitChars.put("ḟ", "f");
|
||||
translitChars.put("ḓ", "d");
|
||||
translitChars.put("ȇ", "e");
|
||||
translitChars.put("ȕ", "u");
|
||||
translitChars.put("п", "p");
|
||||
translitChars.put("ȵ", "n");
|
||||
translitChars.put("ʠ", "q");
|
||||
translitChars.put("ấ", "a");
|
||||
translitChars.put("ǩ", "k");
|
||||
translitChars.put("ĩ", "i");
|
||||
translitChars.put("ṵ", "u");
|
||||
translitChars.put("ŧ", "t");
|
||||
translitChars.put("ɾ", "r");
|
||||
translitChars.put("ƙ", "k");
|
||||
translitChars.put("ṫ", "t");
|
||||
translitChars.put("ꝗ", "q");
|
||||
translitChars.put("ậ", "a");
|
||||
translitChars.put("н", "n");
|
||||
translitChars.put("ʄ", "j");
|
||||
translitChars.put("ƚ", "l");
|
||||
translitChars.put("ᶂ", "f");
|
||||
translitChars.put("д", "d");
|
||||
translitChars.put("ᵴ", "s");
|
||||
translitChars.put("ꞃ", "r");
|
||||
translitChars.put("ᶌ", "v");
|
||||
translitChars.put("ɵ", "o");
|
||||
translitChars.put("ḉ", "c");
|
||||
translitChars.put("ᵤ", "u");
|
||||
translitChars.put("ẑ", "z");
|
||||
translitChars.put("ṹ", "u");
|
||||
translitChars.put("ň", "n");
|
||||
translitChars.put("ʍ", "w");
|
||||
translitChars.put("ầ", "a");
|
||||
translitChars.put("lj", "lj");
|
||||
translitChars.put("ɓ", "b");
|
||||
translitChars.put("ɼ", "r");
|
||||
translitChars.put("ò", "o");
|
||||
translitChars.put("ẘ", "w");
|
||||
translitChars.put("ɗ", "d");
|
||||
translitChars.put("ꜽ", "ay");
|
||||
translitChars.put("ư", "u");
|
||||
translitChars.put("ᶀ", "b");
|
||||
translitChars.put("ǜ", "u");
|
||||
translitChars.put("ẹ", "e");
|
||||
translitChars.put("ǡ", "a");
|
||||
translitChars.put("ɥ", "h");
|
||||
translitChars.put("ṏ", "o");
|
||||
translitChars.put("ǔ", "u");
|
||||
translitChars.put("ʎ", "y");
|
||||
translitChars.put("ȱ", "o");
|
||||
translitChars.put("ệ", "e");
|
||||
translitChars.put("ế", "e");
|
||||
translitChars.put("ĭ", "i");
|
||||
translitChars.put("ⱸ", "e");
|
||||
translitChars.put("ṯ", "t");
|
||||
translitChars.put("ᶑ", "d");
|
||||
translitChars.put("ḧ", "h");
|
||||
translitChars.put("ṥ", "s");
|
||||
translitChars.put("ë", "e");
|
||||
translitChars.put("ᴍ", "m");
|
||||
translitChars.put("ö", "o");
|
||||
translitChars.put("é", "e");
|
||||
translitChars.put("ı", "i");
|
||||
translitChars.put("ď", "d");
|
||||
translitChars.put("ᵯ", "m");
|
||||
translitChars.put("ỵ", "y");
|
||||
translitChars.put("я", "ya");
|
||||
translitChars.put("ŵ", "w");
|
||||
translitChars.put("ề", "e");
|
||||
translitChars.put("ứ", "u");
|
||||
translitChars.put("ƶ", "z");
|
||||
translitChars.put("ĵ", "j");
|
||||
translitChars.put("ḍ", "d");
|
||||
translitChars.put("ŭ", "u");
|
||||
translitChars.put("ʝ", "j");
|
||||
translitChars.put("ж", "zh");
|
||||
translitChars.put("ê", "e");
|
||||
translitChars.put("ǚ", "u");
|
||||
translitChars.put("ġ", "g");
|
||||
translitChars.put("ṙ", "r");
|
||||
translitChars.put("ƞ", "n");
|
||||
translitChars.put("ъ", "");
|
||||
translitChars.put("ḗ", "e");
|
||||
translitChars.put("ẝ", "s");
|
||||
translitChars.put("ᶁ", "d");
|
||||
translitChars.put("ķ", "k");
|
||||
translitChars.put("ᴂ", "ae");
|
||||
translitChars.put("ɘ", "e");
|
||||
translitChars.put("ợ", "o");
|
||||
translitChars.put("ḿ", "m");
|
||||
translitChars.put("ꜰ", "f");
|
||||
translitChars.put("а", "a");
|
||||
translitChars.put("ẵ", "a");
|
||||
translitChars.put("ꝏ", "oo");
|
||||
translitChars.put("ᶆ", "m");
|
||||
translitChars.put("ᵽ", "p");
|
||||
translitChars.put("ц", "ts");
|
||||
translitChars.put("ữ", "u");
|
||||
translitChars.put("ⱪ", "k");
|
||||
translitChars.put("ḥ", "h");
|
||||
translitChars.put("ţ", "t");
|
||||
translitChars.put("ᵱ", "p");
|
||||
translitChars.put("ṁ", "m");
|
||||
translitChars.put("á", "a");
|
||||
translitChars.put("ᴎ", "n");
|
||||
translitChars.put("ꝟ", "v");
|
||||
translitChars.put("è", "e");
|
||||
translitChars.put("ᶎ", "z");
|
||||
translitChars.put("ꝺ", "d");
|
||||
translitChars.put("ᶈ", "p");
|
||||
translitChars.put("м", "m");
|
||||
translitChars.put("ɫ", "l");
|
||||
translitChars.put("ᴢ", "z");
|
||||
translitChars.put("ɱ", "m");
|
||||
translitChars.put("ṝ", "r");
|
||||
translitChars.put("ṽ", "v");
|
||||
translitChars.put("ũ", "u");
|
||||
translitChars.put("ß", "ss");
|
||||
translitChars.put("т", "t");
|
||||
translitChars.put("ĥ", "h");
|
||||
translitChars.put("ᵵ", "t");
|
||||
translitChars.put("ʐ", "z");
|
||||
translitChars.put("ṟ", "r");
|
||||
translitChars.put("ɲ", "n");
|
||||
translitChars.put("à", "a");
|
||||
translitChars.put("ẙ", "y");
|
||||
translitChars.put("ỳ", "y");
|
||||
translitChars.put("ᴔ", "oe");
|
||||
translitChars.put("ы", "i");
|
||||
translitChars.put("ₓ", "x");
|
||||
translitChars.put("ȗ", "u");
|
||||
translitChars.put("ⱼ", "j");
|
||||
translitChars.put("ẫ", "a");
|
||||
translitChars.put("ʑ", "z");
|
||||
translitChars.put("ẛ", "s");
|
||||
translitChars.put("ḭ", "i");
|
||||
translitChars.put("ꜵ", "ao");
|
||||
translitChars.put("ɀ", "z");
|
||||
translitChars.put("ÿ", "y");
|
||||
translitChars.put("ǝ", "e");
|
||||
translitChars.put("ǭ", "o");
|
||||
translitChars.put("ᴅ", "d");
|
||||
translitChars.put("ᶅ", "l");
|
||||
translitChars.put("ù", "u");
|
||||
translitChars.put("ạ", "a");
|
||||
translitChars.put("ḅ", "b");
|
||||
translitChars.put("ụ", "u");
|
||||
translitChars.put("к", "k");
|
||||
translitChars.put("ằ", "a");
|
||||
translitChars.put("ᴛ", "t");
|
||||
translitChars.put("ƴ", "y");
|
||||
translitChars.put("ⱦ", "t");
|
||||
translitChars.put("з", "z");
|
||||
translitChars.put("ⱡ", "l");
|
||||
translitChars.put("ȷ", "j");
|
||||
translitChars.put("ᵶ", "z");
|
||||
translitChars.put("ḫ", "h");
|
||||
translitChars.put("ⱳ", "w");
|
||||
translitChars.put("ḵ", "k");
|
||||
translitChars.put("ờ", "o");
|
||||
translitChars.put("î", "i");
|
||||
translitChars.put("ģ", "g");
|
||||
translitChars.put("ȅ", "e");
|
||||
translitChars.put("ȧ", "a");
|
||||
translitChars.put("ẳ", "a");
|
||||
translitChars.put("щ", "sch");
|
||||
translitChars.put("ɋ", "q");
|
||||
translitChars.put("ṭ", "t");
|
||||
translitChars.put("ꝸ", "um");
|
||||
translitChars.put("ᴄ", "c");
|
||||
translitChars.put("ẍ", "x");
|
||||
translitChars.put("ủ", "u");
|
||||
translitChars.put("ỉ", "i");
|
||||
translitChars.put("ᴚ", "r");
|
||||
translitChars.put("ś", "s");
|
||||
translitChars.put("ꝋ", "o");
|
||||
translitChars.put("ỹ", "y");
|
||||
translitChars.put("ṡ", "s");
|
||||
translitChars.put("nj", "nj");
|
||||
translitChars.put("ȁ", "a");
|
||||
translitChars.put("ẗ", "t");
|
||||
translitChars.put("ĺ", "l");
|
||||
translitChars.put("ž", "z");
|
||||
translitChars.put("ᵺ", "th");
|
||||
translitChars.put("ƌ", "d");
|
||||
translitChars.put("ș", "s");
|
||||
translitChars.put("š", "s");
|
||||
translitChars.put("ᶙ", "u");
|
||||
translitChars.put("ẽ", "e");
|
||||
translitChars.put("ẜ", "s");
|
||||
translitChars.put("ɇ", "e");
|
||||
translitChars.put("ṷ", "u");
|
||||
translitChars.put("ố", "o");
|
||||
translitChars.put("ȿ", "s");
|
||||
translitChars.put("ᴠ", "v");
|
||||
translitChars.put("ꝭ", "is");
|
||||
translitChars.put("ᴏ", "o");
|
||||
translitChars.put("ɛ", "e");
|
||||
translitChars.put("ǻ", "a");
|
||||
translitChars.put("ffl", "ffl");
|
||||
translitChars.put("ⱺ", "o");
|
||||
translitChars.put("ȋ", "i");
|
||||
translitChars.put("ᵫ", "ue");
|
||||
translitChars.put("ȡ", "d");
|
||||
translitChars.put("ⱬ", "z");
|
||||
translitChars.put("ẁ", "w");
|
||||
translitChars.put("ᶏ", "a");
|
||||
translitChars.put("ꞇ", "t");
|
||||
translitChars.put("ğ", "g");
|
||||
translitChars.put("ɳ", "n");
|
||||
translitChars.put("ʛ", "g");
|
||||
translitChars.put("ᴜ", "u");
|
||||
translitChars.put("ф", "f");
|
||||
translitChars.put("ẩ", "a");
|
||||
translitChars.put("ṅ", "n");
|
||||
translitChars.put("ɨ", "i");
|
||||
translitChars.put("ᴙ", "r");
|
||||
translitChars.put("ǎ", "a");
|
||||
translitChars.put("ſ", "s");
|
||||
translitChars.put("у", "u");
|
||||
translitChars.put("ȫ", "o");
|
||||
translitChars.put("ɿ", "r");
|
||||
translitChars.put("ƭ", "t");
|
||||
translitChars.put("ḯ", "i");
|
||||
translitChars.put("ǽ", "ae");
|
||||
translitChars.put("ⱱ", "v");
|
||||
translitChars.put("ɶ", "oe");
|
||||
translitChars.put("ṃ", "m");
|
||||
translitChars.put("ż", "z");
|
||||
translitChars.put("ĕ", "e");
|
||||
translitChars.put("ꜻ", "av");
|
||||
translitChars.put("ở", "o");
|
||||
translitChars.put("ễ", "e");
|
||||
translitChars.put("ɬ", "l");
|
||||
translitChars.put("ị", "i");
|
||||
translitChars.put("ᵭ", "d");
|
||||
translitChars.put("st", "st");
|
||||
translitChars.put("ḷ", "l");
|
||||
translitChars.put("ŕ", "r");
|
||||
translitChars.put("ᴕ", "ou");
|
||||
translitChars.put("ʈ", "t");
|
||||
translitChars.put("ā", "a");
|
||||
translitChars.put("э", "e");
|
||||
translitChars.put("ḙ", "e");
|
||||
translitChars.put("ᴑ", "o");
|
||||
translitChars.put("ç", "c");
|
||||
translitChars.put("ᶊ", "s");
|
||||
translitChars.put("ặ", "a");
|
||||
translitChars.put("ų", "u");
|
||||
translitChars.put("ả", "a");
|
||||
translitChars.put("ǥ", "g");
|
||||
translitChars.put("р", "r");
|
||||
translitChars.put("ꝁ", "k");
|
||||
translitChars.put("ẕ", "z");
|
||||
translitChars.put("ŝ", "s");
|
||||
translitChars.put("ḕ", "e");
|
||||
translitChars.put("ɠ", "g");
|
||||
translitChars.put("ꝉ", "l");
|
||||
translitChars.put("ꝼ", "f");
|
||||
translitChars.put("ᶍ", "x");
|
||||
translitChars.put("х", "h");
|
||||
translitChars.put("ǒ", "o");
|
||||
translitChars.put("ę", "e");
|
||||
translitChars.put("ổ", "o");
|
||||
translitChars.put("ƫ", "t");
|
||||
translitChars.put("ǫ", "o");
|
||||
translitChars.put("i̇", "i");
|
||||
translitChars.put("ṇ", "n");
|
||||
translitChars.put("ć", "c");
|
||||
translitChars.put("ᵷ", "g");
|
||||
translitChars.put("ẅ", "w");
|
||||
translitChars.put("ḑ", "d");
|
||||
translitChars.put("ḹ", "l");
|
||||
translitChars.put("ч", "ch");
|
||||
translitChars.put("œ", "oe");
|
||||
translitChars.put("ᵳ", "r");
|
||||
translitChars.put("ļ", "l");
|
||||
translitChars.put("ȑ", "r");
|
||||
translitChars.put("ȭ", "o");
|
||||
translitChars.put("ᵰ", "n");
|
||||
translitChars.put("ᴁ", "ae");
|
||||
translitChars.put("ŀ", "l");
|
||||
translitChars.put("ä", "a");
|
||||
translitChars.put("ƥ", "p");
|
||||
translitChars.put("ỏ", "o");
|
||||
translitChars.put("į", "i");
|
||||
translitChars.put("ȓ", "r");
|
||||
translitChars.put("dž", "dz");
|
||||
translitChars.put("ḡ", "g");
|
||||
translitChars.put("ṻ", "u");
|
||||
translitChars.put("ō", "o");
|
||||
translitChars.put("ľ", "l");
|
||||
translitChars.put("ẃ", "w");
|
||||
translitChars.put("ț", "t");
|
||||
translitChars.put("ń", "n");
|
||||
translitChars.put("ɍ", "r");
|
||||
translitChars.put("ȃ", "a");
|
||||
translitChars.put("ü", "u");
|
||||
translitChars.put("ꞁ", "l");
|
||||
translitChars.put("ᴐ", "o");
|
||||
translitChars.put("ớ", "o");
|
||||
translitChars.put("ᴃ", "b");
|
||||
translitChars.put("ɹ", "r");
|
||||
translitChars.put("ᵲ", "r");
|
||||
translitChars.put("ʏ", "y");
|
||||
translitChars.put("ᵮ", "f");
|
||||
translitChars.put("ⱨ", "h");
|
||||
translitChars.put("ŏ", "o");
|
||||
translitChars.put("ú", "u");
|
||||
translitChars.put("ṛ", "r");
|
||||
translitChars.put("ʮ", "h");
|
||||
translitChars.put("ó", "o");
|
||||
translitChars.put("ů", "u");
|
||||
translitChars.put("ỡ", "o");
|
||||
translitChars.put("ṕ", "p");
|
||||
translitChars.put("ᶖ", "i");
|
||||
translitChars.put("ự", "u");
|
||||
translitChars.put("ã", "a");
|
||||
translitChars.put("ᵢ", "i");
|
||||
translitChars.put("ṱ", "t");
|
||||
translitChars.put("ể", "e");
|
||||
translitChars.put("ử", "u");
|
||||
translitChars.put("í", "i");
|
||||
translitChars.put("ɔ", "o");
|
||||
translitChars.put("с", "s");
|
||||
translitChars.put("й", "i");
|
||||
translitChars.put("ɺ", "r");
|
||||
translitChars.put("ɢ", "g");
|
||||
translitChars.put("ř", "r");
|
||||
translitChars.put("ẖ", "h");
|
||||
translitChars.put("ű", "u");
|
||||
translitChars.put("ȍ", "o");
|
||||
translitChars.put("ш", "sh");
|
||||
translitChars.put("ḻ", "l");
|
||||
translitChars.put("ḣ", "h");
|
||||
translitChars.put("ȶ", "t");
|
||||
translitChars.put("ņ", "n");
|
||||
translitChars.put("ᶒ", "e");
|
||||
translitChars.put("ì", "i");
|
||||
translitChars.put("ẉ", "w");
|
||||
translitChars.put("б", "b");
|
||||
translitChars.put("ē", "e");
|
||||
translitChars.put("ᴇ", "e");
|
||||
translitChars.put("ł", "l");
|
||||
translitChars.put("ộ", "o");
|
||||
translitChars.put("ɭ", "l");
|
||||
translitChars.put("ẏ", "y");
|
||||
translitChars.put("ᴊ", "j");
|
||||
translitChars.put("ḱ", "k");
|
||||
translitChars.put("ṿ", "v");
|
||||
translitChars.put("ȩ", "e");
|
||||
translitChars.put("â", "a");
|
||||
translitChars.put("ş", "s");
|
||||
translitChars.put("ŗ", "r");
|
||||
translitChars.put("ʋ", "v");
|
||||
translitChars.put("ₐ", "a");
|
||||
translitChars.put("ↄ", "c");
|
||||
translitChars.put("ᶓ", "e");
|
||||
translitChars.put("ɰ", "m");
|
||||
translitChars.put("е", "e");
|
||||
translitChars.put("ᴡ", "w");
|
||||
translitChars.put("ȏ", "o");
|
||||
translitChars.put("č", "c");
|
||||
translitChars.put("ǵ", "g");
|
||||
translitChars.put("ĉ", "c");
|
||||
translitChars.put("ю", "yu");
|
||||
translitChars.put("ᶗ", "o");
|
||||
translitChars.put("ꝃ", "k");
|
||||
translitChars.put("ꝙ", "q");
|
||||
translitChars.put("г", "g");
|
||||
translitChars.put("ṑ", "o");
|
||||
translitChars.put("ꜱ", "s");
|
||||
translitChars.put("ṓ", "o");
|
||||
translitChars.put("ȟ", "h");
|
||||
translitChars.put("ő", "o");
|
||||
translitChars.put("ꜩ", "tz");
|
||||
translitChars.put("ẻ", "e");
|
||||
translitChars.put("о", "o");
|
||||
}
|
||||
StringBuilder dst = new StringBuilder(src.length());
|
||||
int len = src.length();
|
||||
for (int a = 0; a < len; a++) {
|
||||
String ch = src.substring(a, a + 1);
|
||||
String tch = translitChars.get(ch);
|
||||
if (tch != null) {
|
||||
dst.append(tch);
|
||||
} else {
|
||||
dst.append(ch);
|
||||
}
|
||||
}
|
||||
return dst.toString();
|
||||
}
|
||||
|
||||
abstract public static class PluralRules {
|
||||
abstract int quantityForNumber(int n);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 1.3.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
@@ -51,7 +66,6 @@ import android.telephony.PhoneStateListener;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import com.b44t.messenger.audioinfo.AudioInfo;
|
||||
import com.b44t.messenger.query.SharedMediaQuery;
|
||||
import com.b44t.messenger.video.InputSurface;
|
||||
import com.b44t.messenger.video.MP4Builder;
|
||||
import com.b44t.messenger.video.Mp4Movie;
|
||||
@@ -274,8 +288,8 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
||||
private ArrayList<DownloadObject> videoDownloadQueue = new ArrayList<>();
|
||||
private HashMap<String, DownloadObject> downloadQueueKeys = new HashMap<>();
|
||||
|
||||
private boolean saveToGallery = true;
|
||||
private boolean autoplayGifs = true;
|
||||
private final boolean saveToGallery = false;
|
||||
private final boolean autoplayGifs = true;
|
||||
private boolean raiseToSpeak = true;
|
||||
private boolean directShare = true;
|
||||
private boolean shuffleMusic;
|
||||
@@ -504,11 +518,6 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
||||
|
||||
private ExternalObserver externalObserver = null;
|
||||
private InternalObserver internalObserver = null;
|
||||
private long lastSecretChatEnterTime = 0;
|
||||
private long lastSecretChatLeaveTime = 0;
|
||||
private long lastMediaCheckTime = 0;
|
||||
private TLRPC.EncryptedChat lastSecretChat = null;
|
||||
private ArrayList<Long> lastSecretChatVisibleMessages = null;
|
||||
private int startObserverToken = 0;
|
||||
private StopMediaObserverRunnable stopMediaObserverRunnable = null;
|
||||
|
||||
@@ -604,8 +613,8 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
||||
mobileDataDownloadMask = preferences.getInt("mobileDataDownloadMask", AUTODOWNLOAD_MASK_PHOTO | AUTODOWNLOAD_MASK_AUDIO | AUTODOWNLOAD_MASK_MUSIC | AUTODOWNLOAD_MASK_GIF);
|
||||
wifiDownloadMask = preferences.getInt("wifiDownloadMask", AUTODOWNLOAD_MASK_PHOTO | AUTODOWNLOAD_MASK_AUDIO | AUTODOWNLOAD_MASK_MUSIC | AUTODOWNLOAD_MASK_GIF);
|
||||
roamingDownloadMask = preferences.getInt("roamingDownloadMask", 0);
|
||||
saveToGallery = preferences.getBoolean("save_gallery", false);
|
||||
autoplayGifs = preferences.getBoolean("autoplay_gif", true);
|
||||
//saveToGallery = preferences.getBoolean("save_gallery", false);
|
||||
//autoplayGifs = preferences.getBoolean("autoplay_gif", true);
|
||||
raiseToSpeak = preferences.getBoolean("raise_to_speak", true);
|
||||
directShare = preferences.getBoolean("direct_share", true);
|
||||
shuffleMusic = preferences.getBoolean("shuffleMusic", false);
|
||||
@@ -620,7 +629,6 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
||||
NotificationCenter.getInstance().addObserver(MediaController.this, NotificationCenter.FileDidLoaded);
|
||||
NotificationCenter.getInstance().addObserver(MediaController.this, NotificationCenter.FileLoadProgressChanged);
|
||||
NotificationCenter.getInstance().addObserver(MediaController.this, NotificationCenter.FileUploadProgressChanged);
|
||||
NotificationCenter.getInstance().addObserver(MediaController.this, NotificationCenter.removeAllMessagesFromDialog);
|
||||
NotificationCenter.getInstance().addObserver(MediaController.this, NotificationCenter.musicDidLoaded);
|
||||
}
|
||||
});
|
||||
@@ -1359,11 +1367,6 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (id == NotificationCenter.removeAllMessagesFromDialog) {
|
||||
long did = (Long) args[0];
|
||||
if (playingMessageObject != null && playingMessageObject.getDialogId() == did) {
|
||||
cleanupPlayer(false, true);
|
||||
}
|
||||
} else if (id == NotificationCenter.musicDidLoaded) {
|
||||
long did = (Long) args[0];
|
||||
if (playingMessageObject != null && playingMessageObject.isMusic() && playingMessageObject.getDialogId() == did) {
|
||||
@@ -1995,7 +1998,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
||||
currentPlaylistNum = 0;
|
||||
}
|
||||
if (loadMusic) {
|
||||
SharedMediaQuery.loadMusic(current.getDialogId(), playlist.get(0).getId());
|
||||
//SharedMediaQuery.loadMusic(current.getDialogId(), playlist.get(0).getId());
|
||||
}
|
||||
}
|
||||
return playAudio(current);
|
||||
@@ -2512,7 +2515,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
||||
try {
|
||||
Vibrator v = (Vibrator) ApplicationLoader.applicationContext.getSystemService(Context.VIBRATOR_SERVICE);
|
||||
v.vibrate(50);
|
||||
//NotificationsController.getInstance().playRecordSound();
|
||||
//NotificationsController.getInstance().playRecordSound(); -- was also disabled in Telegram; playing a sound while recording may result in a feedback
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
@@ -2973,6 +2976,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
public void toggleSaveToGallery() {
|
||||
saveToGallery = !saveToGallery;
|
||||
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
|
||||
@@ -2989,6 +2993,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
||||
editor.putBoolean("autoplay_gif", autoplayGifs);
|
||||
editor.commit();
|
||||
}
|
||||
*/
|
||||
|
||||
public void toogleRaiseToSpeak() {
|
||||
raiseToSpeak = !raiseToSpeak;
|
||||
@@ -3006,7 +3011,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public void checkSaveToGalleryFiles() {
|
||||
public void checkSaveToGalleryFiles() { // not sure, but it seems as if these paths are not needed
|
||||
try {
|
||||
File messengerPath = new File(Environment.getExternalStorageDirectory(), "Delta Chat");
|
||||
File imagePath = new File(messengerPath, "Delta Chat Images");
|
||||
@@ -3034,9 +3039,11 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public boolean canSaveToGallery() {
|
||||
return saveToGallery;
|
||||
}
|
||||
*/
|
||||
|
||||
public boolean canAutoplayGifs() {
|
||||
return autoplayGifs;
|
||||
|
||||
@@ -1,31 +1,37 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Typeface;
|
||||
import android.text.Layout;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.StaticLayout;
|
||||
import android.text.TextPaint;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.URLSpan;
|
||||
import android.text.util.Linkify;
|
||||
|
||||
import com.b44t.ui.ActionBar.Theme;
|
||||
import com.b44t.ui.Components.TypefaceSpan;
|
||||
import com.b44t.ui.Components.URLSpanNoUnderline;
|
||||
import com.b44t.ui.Components.URLSpanNoUnderlineBold;
|
||||
import com.b44t.ui.Components.URLSpanReplacement;
|
||||
import com.b44t.ui.Components.URLSpanUserMention;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.AbstractMap;
|
||||
@@ -43,14 +49,11 @@ public class MessageObject {
|
||||
|
||||
public TLRPC.Message messageOwner;
|
||||
public CharSequence messageText;
|
||||
public CharSequence linkDescription;
|
||||
public CharSequence caption;
|
||||
public MessageObject replyMessageObject;
|
||||
public int type = 1000;
|
||||
public int contentType;
|
||||
public int type = 1000; // 13: sticker
|
||||
public int contentType; // one of ChatActivity.ROWTYPE_MESSAGE_CELL, .ROWTYPE_ACTION_CELL or .ROWTYPE_UNREAD_CELL
|
||||
public String dateKey;
|
||||
public String monthKey;
|
||||
public boolean deleted;
|
||||
public float audioProgress;
|
||||
public int audioProgressSec;
|
||||
public ArrayList<TLRPC.PhotoSize> photoThumbs;
|
||||
@@ -110,7 +113,7 @@ public class MessageObject {
|
||||
}
|
||||
}
|
||||
|
||||
if (message instanceof TLRPC.TL_messageService) {
|
||||
/*if (message instanceof TLRPC.TL_messageService) {
|
||||
if (message.action != null) {
|
||||
if (message.action instanceof TLRPC.TL_messageActionChatCreate) {
|
||||
if (isOut()) {
|
||||
@@ -203,7 +206,7 @@ public class MessageObject {
|
||||
messageText = LocaleController.getString("HistoryCleared", R.string.HistoryCleared);
|
||||
}
|
||||
}
|
||||
} else if (!isMediaEmpty()) {
|
||||
} else*/ if (!isMediaEmpty()) {
|
||||
if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
|
||||
messageText = LocaleController.getString("AttachPhoto", R.string.AttachPhoto);
|
||||
} else if (isVideo()) {
|
||||
@@ -253,7 +256,6 @@ public class MessageObject {
|
||||
int dateYear = rightNow.get(Calendar.YEAR);
|
||||
int dateMonth = rightNow.get(Calendar.MONTH);
|
||||
dateKey = String.format("%d_%02d_%02d", dateYear, dateMonth, dateDay);
|
||||
monthKey = String.format("%d_%02d", dateYear, dateMonth);
|
||||
|
||||
if (messageOwner.message != null && messageOwner.id < 0 && messageOwner.message.length() > 6 && isVideo()) {
|
||||
videoEditedInfo = new VideoEditedInfo();
|
||||
@@ -317,29 +319,28 @@ public class MessageObject {
|
||||
type = 9;
|
||||
}
|
||||
}
|
||||
} else if (messageOwner instanceof TLRPC.TL_messageService) {
|
||||
/*if (messageOwner.action instanceof TLRPC.TL_messageActionLoginUnknownLocation) {
|
||||
} /*else if (messageOwner instanceof TLRPC.TL_messageService) {
|
||||
if (messageOwner.action instanceof TLRPC.TL_messageActionLoginUnknownLocation) {
|
||||
type = 0;
|
||||
} else */
|
||||
if (messageOwner.action instanceof TLRPC.TL_messageActionChatEditPhoto || messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
|
||||
contentType = 1;
|
||||
} else if (messageOwner.action instanceof TLRPC.TL_messageActionChatEditPhoto || messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
|
||||
contentType = ChatActivity.ROWTYPE_ACTION_CELL;
|
||||
type = 11;
|
||||
/*} else if (messageOwner.action instanceof TLRPC.TL_messageEncryptedAction) {
|
||||
} else if (messageOwner.action instanceof TLRPC.TL_messageEncryptedAction) {
|
||||
if (messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages || messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) {
|
||||
contentType = 1;
|
||||
contentType = ChatActivity.ROWTYPE_ACTION_CELL;
|
||||
type = 10;
|
||||
} else {
|
||||
contentType = -1;
|
||||
type = -1;
|
||||
}*/
|
||||
}
|
||||
} else if (messageOwner.action instanceof TLRPC.TL_messageActionHistoryClear) {
|
||||
contentType = -1;
|
||||
type = -1;
|
||||
} else {
|
||||
contentType = 1;
|
||||
contentType = ChatActivity.ROWTYPE_ACTION_CELL;
|
||||
type = 10;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
if (oldType != 1000 && oldType != type) {
|
||||
generateThumbs(false);
|
||||
}
|
||||
@@ -373,7 +374,7 @@ public class MessageObject {
|
||||
}
|
||||
|
||||
public void generateThumbs(boolean update) {
|
||||
if (messageOwner instanceof TLRPC.TL_messageService) {
|
||||
/*if (messageOwner instanceof TLRPC.TL_messageService) {
|
||||
if (messageOwner.action instanceof TLRPC.TL_messageActionChatEditPhoto) {
|
||||
if (!update) {
|
||||
photoThumbs = new ArrayList<>(messageOwner.action.photo.sizes);
|
||||
@@ -393,7 +394,7 @@ public class MessageObject {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (messageOwner.media != null && !(messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) {
|
||||
} else*/ if (messageOwner.media != null && !(messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) {
|
||||
if (messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) {
|
||||
if (!update || photoThumbs != null && photoThumbs.size() != messageOwner.media.photo.sizes.size()) {
|
||||
photoThumbs = new ArrayList<>(messageOwner.media.photo.sizes);
|
||||
@@ -424,7 +425,7 @@ public class MessageObject {
|
||||
photoObject.h = messageOwner.media.document.thumb.h;
|
||||
}
|
||||
}
|
||||
} else if (messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
} /* else if (messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
if (messageOwner.media.webpage.photo != null) {
|
||||
if (!update || photoThumbs == null) {
|
||||
photoThumbs = new ArrayList<>(messageOwner.media.webpage.photo.sizes);
|
||||
@@ -454,10 +455,11 @@ public class MessageObject {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public CharSequence replaceWithLink(CharSequence source, String param, ArrayList<Integer> uids, AbstractMap<Integer, TLRPC.User> usersDict) {
|
||||
int start = TextUtils.indexOf(source, param);
|
||||
if (start >= 0) {
|
||||
@@ -506,6 +508,7 @@ public class MessageObject {
|
||||
}
|
||||
return source;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
public String getExtension() {
|
||||
@@ -537,9 +540,9 @@ public class MessageObject {
|
||||
return FileLoader.getAttachFileName(sizeFull);
|
||||
}
|
||||
}
|
||||
} else if (messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
} /*else if (messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
return FileLoader.getAttachFileName(messageOwner.media.webpage.document);
|
||||
}
|
||||
} */
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -617,7 +620,7 @@ public class MessageObject {
|
||||
}
|
||||
|
||||
public void generateLinkDescription() {
|
||||
if (linkDescription != null) {
|
||||
/*if (linkDescription != null) {
|
||||
return;
|
||||
}
|
||||
if (messageOwner.media instanceof TLRPC.TL_messageMediaWebPage && messageOwner.media.webpage instanceof TLRPC.TL_webPage && messageOwner.media.webpage.description != null) {
|
||||
@@ -630,7 +633,7 @@ public class MessageObject {
|
||||
}
|
||||
}
|
||||
linkDescription = Emoji.replaceEmoji(linkDescription, textPaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
public void generateCaption() {
|
||||
@@ -704,25 +707,10 @@ public class MessageObject {
|
||||
generateLinkDescription();
|
||||
textLayoutBlocks = new ArrayList<>();
|
||||
|
||||
boolean hasEntities;
|
||||
if (messageOwner.send_state != MESSAGE_SEND_STATE_SENT) {
|
||||
hasEntities = false;
|
||||
for (int a = 0; a < messageOwner.entities.size(); a++) {
|
||||
if (!(messageOwner.entities.get(a) instanceof TLRPC.TL_inputMessageEntityMentionName)) {
|
||||
hasEntities = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
hasEntities = !messageOwner.entities.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
final boolean useManualParse = true; // false only add links to phone numbers; was used in Telegram for incoming messages that were already parsed (?)
|
||||
|
||||
if (useManualParse) {
|
||||
/*final boolean useManualParse = true; // false only add links to phone numbers; was used in Telegram for incoming messages that were already parsed (?)
|
||||
if (useManualParse) {*/
|
||||
addLinks(messageText);
|
||||
} else {
|
||||
/*} else {
|
||||
if (messageText instanceof Spannable && messageText.length() < 200) {
|
||||
try {
|
||||
Linkify.addLinks((Spannable) messageText, Linkify.PHONE_NUMBERS);
|
||||
@@ -730,14 +718,14 @@ public class MessageObject {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if (messageText instanceof Spannable) {
|
||||
/*if (messageText instanceof Spannable) {
|
||||
Spannable spannable = (Spannable) messageText;
|
||||
int count = messageOwner.entities.size();
|
||||
int count = messageOwner.entities_.size();
|
||||
URLSpan[] spans = spannable.getSpans(0, messageText.length(), URLSpan.class);
|
||||
for (int a = 0; a < count; a++) {
|
||||
TLRPC.MessageEntity entity = messageOwner.entities.get(a);
|
||||
TLRPC.MessageEntity entity = messageOwner.entities_.get(a);
|
||||
if (entity.length <= 0 || entity.offset < 0 || entity.offset >= messageOwner.message.length()) {
|
||||
continue;
|
||||
} else if (entity.offset + entity.length > messageOwner.message.length()) {
|
||||
@@ -783,7 +771,7 @@ public class MessageObject {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
int maxWidth;
|
||||
if (AndroidUtilities.isTablet()) {
|
||||
@@ -799,9 +787,9 @@ public class MessageObject {
|
||||
maxWidth = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) - AndroidUtilities.dp(80);
|
||||
}
|
||||
}
|
||||
if (fromUser != null && fromUser.bot || (isMegagroup() || messageOwner.fwd_from != null && messageOwner.fwd_from.channel_id != 0) && !isOut()) {
|
||||
/*if ( (messageOwner.fwd_from != null && messageOwner.fwd_from.channel_id != 0) && !isOut()) {
|
||||
maxWidth -= AndroidUtilities.dp(20);
|
||||
}
|
||||
}*/
|
||||
|
||||
StaticLayout textLayout;
|
||||
|
||||
@@ -993,14 +981,6 @@ public class MessageObject {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isMegagroup() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isMegagroup(TLRPC.Message message) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isOut(TLRPC.Message message) {
|
||||
return message.out;
|
||||
}
|
||||
@@ -1101,9 +1081,9 @@ public class MessageObject {
|
||||
}
|
||||
|
||||
public TLRPC.Document getDocument() {
|
||||
if (messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
/*if (messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
return messageOwner.media.webpage.document;
|
||||
}
|
||||
}*/
|
||||
return messageOwner.media != null ? messageOwner.media.document : null;
|
||||
}
|
||||
|
||||
@@ -1112,23 +1092,23 @@ public class MessageObject {
|
||||
}
|
||||
|
||||
public static boolean isMusicMessage(TLRPC.Message message) {
|
||||
if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
/*if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
return isMusicDocument(message.media.webpage.document);
|
||||
}
|
||||
}*/
|
||||
return message.media != null && message.media.document != null && isMusicDocument(message.media.document);
|
||||
}
|
||||
|
||||
public static boolean isVoiceMessage(TLRPC.Message message) {
|
||||
if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
/*if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
return isVoiceDocument(message.media.webpage.document);
|
||||
}
|
||||
}*/
|
||||
return message.media != null && message.media.document != null && isVoiceDocument(message.media.document);
|
||||
}
|
||||
|
||||
public static boolean isVideoMessage(TLRPC.Message message) {
|
||||
if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
/*if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
return isVideoDocument(message.media.webpage.document);
|
||||
}
|
||||
}*/
|
||||
return message.media != null && message.media.document != null && isVideoDocument(message.media.document);
|
||||
}
|
||||
|
||||
@@ -1157,9 +1137,16 @@ public class MessageObject {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isSelectable() {
|
||||
if (type == 6 || type == 10 || type == 11) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getApproximateHeight() {
|
||||
if (type == 0) {
|
||||
int height = textHeight + (messageOwner.media instanceof TLRPC.TL_messageMediaWebPage && messageOwner.media.webpage instanceof TLRPC.TL_webPage ? AndroidUtilities.dp(100) : 0);
|
||||
int height = textHeight /*+ (messageOwner.media instanceof TLRPC.TL_messageMediaWebPage && messageOwner.media.webpage instanceof TLRPC.TL_webPage ? AndroidUtilities.dp(100) : 0)*/;
|
||||
if (isReply()) {
|
||||
height += AndroidUtilities.dp(42);
|
||||
}
|
||||
@@ -1283,7 +1270,7 @@ public class MessageObject {
|
||||
}
|
||||
|
||||
public boolean isWebpageDocument() {
|
||||
return messageOwner.media instanceof TLRPC.TL_messageMediaWebPage && messageOwner.media.webpage.document != null && !isGifDocument(messageOwner.media.webpage.document);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isNewGif() {
|
||||
@@ -1343,24 +1330,14 @@ public class MessageObject {
|
||||
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
|
||||
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
|
||||
if (attribute.voice) {
|
||||
if (isOutOwner() || messageOwner.fwd_from != null && messageOwner.fwd_from.from_id == UserConfig.getClientUserId()) {
|
||||
if (isOutOwner() ) {
|
||||
return LocaleController.getString("FromSelf", R.string.FromSelf);
|
||||
}
|
||||
TLRPC.User user = null;
|
||||
TLRPC.Chat chat = null;
|
||||
if (messageOwner.fwd_from != null && messageOwner.fwd_from.channel_id != 0) {
|
||||
chat = MessagesController.getInstance().getChat(messageOwner.fwd_from.channel_id);
|
||||
} else if (messageOwner.fwd_from != null && messageOwner.fwd_from.from_id != 0) {
|
||||
user = MessagesController.getInstance().getUser(messageOwner.fwd_from.from_id);
|
||||
} else if (messageOwner.from_id < 0) {
|
||||
chat = MessagesController.getInstance().getChat(-messageOwner.from_id);
|
||||
else if (messageOwner.fwd_from != null ) {
|
||||
return messageOwner.fwd_from.m_name;
|
||||
} else {
|
||||
user = MessagesController.getInstance().getUser(messageOwner.from_id);
|
||||
}
|
||||
if (user != null) {
|
||||
TLRPC.User user = MessagesController.getInstance().getUser(messageOwner.from_id);
|
||||
return UserObject.getUserName(user);
|
||||
} else if (chat != null) {
|
||||
return chat.title;
|
||||
}
|
||||
}
|
||||
String performer = attribute.performer;
|
||||
@@ -1394,17 +1371,12 @@ public class MessageObject {
|
||||
}
|
||||
|
||||
public static boolean isMediaEmpty(TLRPC.Message message) {
|
||||
return message == null || message.media == null || message.media instanceof TLRPC.TL_messageMediaEmpty || message.media instanceof TLRPC.TL_messageMediaWebPage;
|
||||
return message == null || message.media == null || message.media instanceof TLRPC.TL_messageMediaEmpty;
|
||||
}
|
||||
|
||||
public String getForwardedName() {
|
||||
if (messageOwner.fwd_from != null) {
|
||||
if (messageOwner.fwd_from.from_id != 0) {
|
||||
TLRPC.User user = MessagesController.getInstance().getUser(messageOwner.fwd_from.from_id);
|
||||
if (user != null) {
|
||||
return UserObject.getUserName(user);
|
||||
}
|
||||
}
|
||||
return messageOwner.fwd_from.m_name;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,67 +1,52 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.b44t.messenger.query.DraftQuery;
|
||||
import com.b44t.messenger.query.MessagesQuery;
|
||||
import com.b44t.messenger.query.SearchQuery;
|
||||
import com.b44t.ui.ActionBar.BaseFragment;
|
||||
import com.b44t.ui.ChatActivity;
|
||||
import com.b44t.ui.ProfileActivity;
|
||||
import com.b44t.ui.SettingsActivity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
public class MessagesController implements NotificationCenter.NotificationCenterDelegate {
|
||||
|
||||
private ConcurrentHashMap<Integer, TLRPC.Chat> chats = new ConcurrentHashMap<>(100, 1.0f, 2);
|
||||
private ConcurrentHashMap<Integer, TLRPC.EncryptedChat> encryptedChats = new ConcurrentHashMap<>(10, 1.0f, 2);
|
||||
private ConcurrentHashMap<Integer, TLRPC.User> users = new ConcurrentHashMap<>(100, 1.0f, 2);
|
||||
private ConcurrentHashMap<String, TLRPC.User> usersByUsernames = new ConcurrentHashMap<>(100, 1.0f, 2);
|
||||
|
||||
public ArrayList<TLRPC.TL_dialog> dialogs = new ArrayList<>();
|
||||
public ArrayList<TLRPC.TL_dialog> dialogsServerOnly = new ArrayList<>();
|
||||
public ArrayList<TLRPC.TL_dialog> dialogsGroupsOnly = new ArrayList<>();
|
||||
public int nextDialogsCacheOffset;
|
||||
public ConcurrentHashMap<Long, TLRPC.TL_dialog> dialogs_dict = new ConcurrentHashMap<>(100, 1.0f, 2);
|
||||
public HashMap<Long, MessageObject> dialogMessage = new HashMap<>();
|
||||
public HashMap<Long, MessageObject> dialogMessagesByRandomIds = new HashMap<>();
|
||||
public HashMap<Integer, MessageObject> dialogMessagesByIds = new HashMap<>();
|
||||
public HashMap<Long, CharSequence> printingStrings = new HashMap<>();
|
||||
public ConcurrentHashMap<Integer, Integer> onlinePrivacy = new ConcurrentHashMap<>(20, 1.0f, 2);
|
||||
|
||||
private ArrayList<Long> createdDialogIds = new ArrayList<>();
|
||||
|
||||
private ArrayList<Integer> loadedFullUsers = new ArrayList<>();
|
||||
private ArrayList<Integer> loadedFullChats = new ArrayList<>();
|
||||
|
||||
private HashMap<String, ArrayList<MessageObject>> reloadingWebpages = new HashMap<>();
|
||||
|
||||
public boolean loadingDialogs = false;
|
||||
public boolean dialogsEndReached = false;
|
||||
|
||||
public int secretWebpagePreview = 2;
|
||||
|
||||
private String uploadingAvatar = null;
|
||||
|
||||
public boolean enableJoined = true;
|
||||
public int fontSize = AndroidUtilities.dp(16);
|
||||
public int ratingDecay;
|
||||
|
||||
@@ -72,32 +57,13 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
public static final int UPDATE_MASK_CHAT_NAME = 16;
|
||||
public static final int UPDATE_MASK_CHAT_MEMBERS = 32;
|
||||
public static final int UPDATE_MASK_USER_PRINT = 64;
|
||||
public static final int UPDATE_MASK_USER_PHONE = 128;
|
||||
public static final int UPDATE_MASK_READ_DIALOG_MESSAGE = 256;
|
||||
public static final int UPDATE_MASK_SELECT_DIALOG = 512;
|
||||
public static final int UPDATE_MASK_NEW_MESSAGE = 2048;
|
||||
public static final int UPDATE_MASK_SEND_STATE = 4096;
|
||||
public static final int UPDATE_MASK_CHANNEL = 8192;
|
||||
public static final int UPDATE_MASK_CHAT_ADMINS = 16384;
|
||||
|
||||
private static volatile MessagesController Instance = null;
|
||||
|
||||
private final Comparator<TLRPC.TL_dialog> dialogComparator = new Comparator<TLRPC.TL_dialog>() {
|
||||
@Override
|
||||
public int compare(TLRPC.TL_dialog dialog1, TLRPC.TL_dialog dialog2) {
|
||||
TLRPC.DraftMessage draftMessage = DraftQuery.getDraft(dialog1.id);
|
||||
int date1 = draftMessage != null && draftMessage.date >= dialog1.last_message_date ? draftMessage.date : dialog1.last_message_date;
|
||||
draftMessage = DraftQuery.getDraft(dialog2.id);
|
||||
int date2 = draftMessage != null && draftMessage.date >= dialog2.last_message_date ? draftMessage.date : dialog2.last_message_date;
|
||||
if (date1 < date2) {
|
||||
return 1;
|
||||
} else if (date1 > date2) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
public static MessagesController getInstance() {
|
||||
MessagesController localInstance = Instance;
|
||||
if (localInstance == null) {
|
||||
@@ -113,21 +79,19 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
|
||||
public MessagesController() {
|
||||
ImageLoader.getInstance();
|
||||
//MessagesStorage.getInstance();
|
||||
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidUpload);
|
||||
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidFailUpload);
|
||||
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidLoaded);
|
||||
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidFailedLoad);
|
||||
NotificationCenter.getInstance().addObserver(this, NotificationCenter.messageReceivedByServer);
|
||||
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
|
||||
enableJoined = preferences.getBoolean("EnableContactJoined", true);
|
||||
|
||||
preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
|
||||
secretWebpagePreview = preferences.getInt("secretWebpage2", 2);
|
||||
ratingDecay = preferences.getInt("ratingDecay", 2419200);
|
||||
fontSize = preferences.getInt("fons_size", AndroidUtilities.isTablet() ? 18 : 16);
|
||||
fontSize = preferences.getInt("msg_font_size", SettingsActivity.defMsgFontSize());
|
||||
}
|
||||
|
||||
/*
|
||||
public static TLRPC.InputUser getInputUser(TLRPC.User user) {
|
||||
if (user == null) {
|
||||
return new TLRPC.TL_inputUserEmpty();
|
||||
@@ -138,7 +102,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
} else {
|
||||
inputUser = new TLRPC.TL_inputUser();
|
||||
inputUser.user_id = user.id;
|
||||
inputUser.access_hash = user.access_hash;
|
||||
}
|
||||
return inputUser;
|
||||
}
|
||||
@@ -147,36 +110,23 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
TLRPC.User user = getInstance().getUser(user_id);
|
||||
return getInputUser(user);
|
||||
}
|
||||
*/
|
||||
|
||||
public static TLRPC.InputPeer getInputPeer(int id) {
|
||||
TLRPC.InputPeer inputPeer;
|
||||
/*if (id < 0) {
|
||||
TLRPC.Chat chat = getInstance().getChat(-id);
|
||||
if (ChatObject.isChannel(chat)) {
|
||||
inputPeer = new TLRPC.TL_inputPeerChannel();
|
||||
inputPeer.channel_id = -id;
|
||||
inputPeer.access_hash = chat.access_hash;
|
||||
} else {
|
||||
inputPeer = new TLRPC.TL_inputPeerChat();
|
||||
inputPeer.chat_id = -id;
|
||||
}
|
||||
} else */ {
|
||||
TLRPC.User user = getInstance().getUser(id);
|
||||
{
|
||||
inputPeer = new TLRPC.TL_inputPeerUser();
|
||||
inputPeer.user_id = id;
|
||||
if (user != null) {
|
||||
inputPeer.access_hash = user.access_hash;
|
||||
}
|
||||
}
|
||||
return inputPeer;
|
||||
}
|
||||
|
||||
public static TLRPC.Peer getPeer(int id) {
|
||||
TLRPC.Peer inputPeer;
|
||||
if (id < 0) {
|
||||
/*if (id < 0) {
|
||||
inputPeer = new TLRPC.TL_peerChat();
|
||||
inputPeer.chat_id = -id;
|
||||
} else {
|
||||
} else*/ {
|
||||
inputPeer = new TLRPC.TL_peerUser();
|
||||
inputPeer.user_id = id;
|
||||
}
|
||||
@@ -243,117 +193,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
if (uploadingAvatar != null && uploadingAvatar.equals(location)) {
|
||||
uploadingAvatar = null;
|
||||
}
|
||||
} else if (id == NotificationCenter.messageReceivedByServer) {
|
||||
Integer msgId = (Integer) args[0];
|
||||
Integer newMsgId = (Integer) args[1];
|
||||
Long did = (Long) args[3];
|
||||
MessageObject obj = dialogMessage.get(did);
|
||||
if (obj != null && obj.getId() == msgId) {
|
||||
obj.messageOwner.id = newMsgId;
|
||||
obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENT;
|
||||
TLRPC.TL_dialog dialog = dialogs_dict.get(did);
|
||||
if (dialog != null) {
|
||||
if (dialog.top_message == msgId) {
|
||||
dialog.top_message = newMsgId;
|
||||
}
|
||||
}
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
|
||||
}
|
||||
obj = dialogMessagesByIds.remove(msgId);
|
||||
if (obj != null) {
|
||||
dialogMessagesByIds.put(newMsgId, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public void cleanup() {
|
||||
ContactsController.getInstance().cleanup();
|
||||
MediaController.getInstance().cleanup();
|
||||
NotificationsController.getInstance().cleanup();
|
||||
SendMessagesHelper.getInstance().cleanup();
|
||||
//SecretChatHelper.getInstance().cleanup();
|
||||
StickersQuery.cleanup();
|
||||
SearchQuery.cleanup();
|
||||
DraftQuery.cleanup();
|
||||
|
||||
reloadingWebpages.clear();
|
||||
reloadingWebpagesPending.clear();
|
||||
dialogs_dict.clear();
|
||||
dialogs_read_inbox_max.clear();
|
||||
dialogs_read_outbox_max.clear();
|
||||
dialogs.clear();
|
||||
channelViewsToSend.clear();
|
||||
channelViewsToReload.clear();
|
||||
dialogsServerOnly.clear();
|
||||
dialogsGroupsOnly.clear();
|
||||
dialogMessagesByIds.clear();
|
||||
dialogMessagesByRandomIds.clear();
|
||||
users.clear();
|
||||
usersByUsernames.clear();
|
||||
chats.clear();
|
||||
dialogMessage.clear();
|
||||
printingUsers.clear();
|
||||
printingStrings.clear();
|
||||
printingStringsTypes.clear();
|
||||
onlinePrivacy.clear();
|
||||
loadingPeerSettings.clear();
|
||||
lastPrintingStringCount = 0;
|
||||
nextDialogsCacheOffset = 0;
|
||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
gettingUnknownChannels.clear();
|
||||
createdDialogIds.clear();
|
||||
gettingDifference = false;
|
||||
}
|
||||
});
|
||||
blockedUsers.clear();
|
||||
sendingTypings.clear();
|
||||
loadingFullUsers.clear();
|
||||
loadedFullUsers.clear();
|
||||
reloadingMessages.clear();
|
||||
loadingFullChats.clear();
|
||||
loadingFullParticipants.clear();
|
||||
loadedFullParticipants.clear();
|
||||
loadedFullChats.clear();
|
||||
|
||||
currentDeletingTaskTime = 0;
|
||||
currentDeletingTaskMids = null;
|
||||
gettingNewDeleteTask = false;
|
||||
loadingDialogs = false;
|
||||
dialogsEndReached = false;
|
||||
loadingBlockedUsers = false;
|
||||
firstGettingTask = false;
|
||||
updatingState = false;
|
||||
offlineSent = false;
|
||||
registeringForPush = false;
|
||||
uploadingAvatar = null;
|
||||
statusRequest = 0;
|
||||
statusSettingState = 0;
|
||||
|
||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//ConnectionsManager.getInstance().setIsUpdating(false);
|
||||
updatesQueueChannels.clear();
|
||||
updatesStartWaitTimeChannels.clear();
|
||||
gettingDifferenceChannels.clear();
|
||||
channelsPts.clear();
|
||||
shortPollChannels.clear();
|
||||
needShortPollChannels.clear();
|
||||
}
|
||||
});
|
||||
|
||||
if (currentDeleteTaskRunnable != null) {
|
||||
Utilities.stageQueue.cancelRunnable(currentDeleteTaskRunnable);
|
||||
currentDeleteTaskRunnable = null;
|
||||
}
|
||||
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
|
||||
}
|
||||
*/
|
||||
|
||||
public TLRPC.User getUser(Integer id) {
|
||||
// EDIT BY MR - additional information should be loaded as needed by the caller
|
||||
TLRPC.User u = new TLRPC.User();
|
||||
@@ -361,270 +203,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
return u;
|
||||
}
|
||||
|
||||
public TLRPC.User getUser(String username) {
|
||||
if (username == null || username.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
return usersByUsernames.get(username.toLowerCase());
|
||||
}
|
||||
|
||||
public ConcurrentHashMap<Integer, TLRPC.User> getUsers() {
|
||||
return users;
|
||||
}
|
||||
|
||||
public TLRPC.Chat getChat(Integer id) {
|
||||
return chats.get(id);
|
||||
return null;
|
||||
}
|
||||
|
||||
public TLRPC.EncryptedChat getEncryptedChat(Integer id) {
|
||||
return encryptedChats.get(id);
|
||||
}
|
||||
|
||||
public void setLastCreatedDialogId(final long dialog_id, final boolean set) {
|
||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (set) {
|
||||
createdDialogIds.add(dialog_id);
|
||||
} else {
|
||||
createdDialogIds.remove(dialog_id);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean putUser(TLRPC.User user, boolean fromCache) {
|
||||
if (user == null) {
|
||||
return false;
|
||||
}
|
||||
fromCache = fromCache && user.id / 1000 != 333 && user.id != 777000;
|
||||
TLRPC.User oldUser = users.get(user.id);
|
||||
if (oldUser != null && oldUser.username != null && oldUser.username.length() > 0) {
|
||||
usersByUsernames.remove(oldUser.username);
|
||||
}
|
||||
if (user.username != null && user.username.length() > 0) {
|
||||
usersByUsernames.put(user.username.toLowerCase(), user);
|
||||
}
|
||||
if (user.min) {
|
||||
if (oldUser != null) {
|
||||
if (!fromCache) {
|
||||
if (user.username != null) {
|
||||
oldUser.username = user.username;
|
||||
oldUser.flags |= 8;
|
||||
} else {
|
||||
oldUser.username = null;
|
||||
oldUser.flags = oldUser.flags &~ 8;
|
||||
}
|
||||
if (user.photo != null) {
|
||||
oldUser.photo = user.photo;
|
||||
oldUser.flags |= 32;
|
||||
} else {
|
||||
oldUser.photo = null;
|
||||
oldUser.flags = oldUser.flags &~ 32;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
users.put(user.id, user);
|
||||
}
|
||||
} else {
|
||||
if (!fromCache) {
|
||||
users.put(user.id, user);
|
||||
if (user.id == UserConfig.getClientUserId()) {
|
||||
UserConfig.setCurrentUser(user);
|
||||
UserConfig.saveConfig(true);
|
||||
}
|
||||
if (oldUser != null && user.status != null && oldUser.status != null && user.status.expires != oldUser.status.expires) {
|
||||
return true;
|
||||
}
|
||||
} else if (oldUser == null) {
|
||||
users.put(user.id, user);
|
||||
} else if (oldUser.min) {
|
||||
user.min = false;
|
||||
if (oldUser.username != null) {
|
||||
user.username = oldUser.username;
|
||||
user.flags |= 8;
|
||||
} else {
|
||||
user.username = null;
|
||||
user.flags = user.flags &~ 8;
|
||||
}
|
||||
if (oldUser.photo != null) {
|
||||
user.photo = oldUser.photo;
|
||||
user.flags |= 32;
|
||||
} else {
|
||||
user.photo = null;
|
||||
user.flags = user.flags &~ 32;
|
||||
}
|
||||
users.put(user.id, user);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void putUsers(ArrayList<TLRPC.User> users, boolean fromCache) {
|
||||
if (users == null || users.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
boolean updateStatus = false;
|
||||
int count = users.size();
|
||||
for (int a = 0; a < count; a++) {
|
||||
TLRPC.User user = users.get(a);
|
||||
if (putUser(user, fromCache)) {
|
||||
updateStatus = true;
|
||||
}
|
||||
}
|
||||
if (updateStatus) {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_STATUS);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public void putChat(TLRPC.Chat chat, boolean fromCache) {
|
||||
if (chat == null) {
|
||||
return;
|
||||
}
|
||||
TLRPC.Chat oldChat = chats.get(chat.id);
|
||||
|
||||
if (chat.min) {
|
||||
if (oldChat != null) {
|
||||
if (!fromCache) {
|
||||
oldChat.title = chat.title;
|
||||
oldChat.photo = chat.photo;
|
||||
//oldChat.broadcast = chat.broadcast;
|
||||
oldChat.verified = chat.verified;
|
||||
//oldChat.megagroup = chat.megagroup;
|
||||
oldChat.democracy = chat.democracy;
|
||||
if (chat.username != null) {
|
||||
oldChat.username = chat.username;
|
||||
oldChat.flags |= 64;
|
||||
} else {
|
||||
oldChat.username = null;
|
||||
oldChat.flags = oldChat.flags &~ 64;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
chats.put(chat.id, chat);
|
||||
}
|
||||
} else {
|
||||
if (!fromCache) {
|
||||
if (oldChat != null && chat.version != oldChat.version) {
|
||||
loadedFullChats.remove((Integer) chat.id);
|
||||
}
|
||||
chats.put(chat.id, chat);
|
||||
} else if (oldChat == null) {
|
||||
chats.put(chat.id, chat);
|
||||
} else if (oldChat.min) {
|
||||
chat.min = false;
|
||||
chat.title = oldChat.title;
|
||||
chat.photo = oldChat.photo;
|
||||
//chat.broadcast = oldChat.broadcast;
|
||||
chat.verified = oldChat.verified;
|
||||
//chat.megagroup = oldChat.megagroup;
|
||||
chat.democracy = oldChat.democracy;
|
||||
if (oldChat.username != null) {
|
||||
chat.username = oldChat.username;
|
||||
chat.flags |= 64;
|
||||
} else {
|
||||
chat.username = null;
|
||||
chat.flags = chat.flags &~ 64;
|
||||
}
|
||||
chats.put(chat.id, chat);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
public void putChats(ArrayList<TLRPC.Chat> chats, boolean fromCache) {
|
||||
if (chats == null || chats.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int count = chats.size();
|
||||
for (int a = 0; a < count; a++) {
|
||||
TLRPC.Chat chat = chats.get(a);
|
||||
putChat(chat, fromCache);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
protected void clearFullUsers() {
|
||||
loadedFullUsers.clear();
|
||||
loadedFullChats.clear();
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
public void loadDialogPhotos(final int did, final int offset, final int count, final long max_id, final boolean fromCache, final int classGuid) {
|
||||
if (fromCache) {
|
||||
MessagesStorage.getInstance().getDialogPhotos(did, offset, count, max_id, classGuid);
|
||||
} else {
|
||||
if (did > 0) {
|
||||
TLRPC.User user = getUser(did);
|
||||
if (user == null) {
|
||||
return;
|
||||
}
|
||||
TLRPC.TL_photos_getUserPhotos req = new TLRPC.TL_photos_getUserPhotos();
|
||||
req.limit = count;
|
||||
req.offset = offset;
|
||||
req.max_id = (int) max_id;
|
||||
req.user_id = getInputUser(user);
|
||||
int reqId = ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, TLRPC.TL_error error) {
|
||||
if (error == null) {
|
||||
TLRPC.photos_Photos res = (TLRPC.photos_Photos) response;
|
||||
processLoadedUserPhotos(res, did, offset, count, max_id, false, classGuid);
|
||||
}
|
||||
}
|
||||
});
|
||||
ConnectionsManager.getInstance().bindRequestToGuid(reqId, classGuid);
|
||||
} else if (did < 0) {
|
||||
TLRPC.TL_messages_search req = new TLRPC.TL_messages_search();
|
||||
req.filter = new TLRPC.TL_inputMessagesFilterChatPhotos();
|
||||
req.limit = count;
|
||||
req.offset = offset;
|
||||
req.max_id = (int) max_id;
|
||||
req.q = "";
|
||||
req.peer = MessagesController.getInputPeer(did);
|
||||
int reqId = ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, TLRPC.TL_error error) {
|
||||
if (error == null) {
|
||||
TLRPC.messages_Messages messages = (TLRPC.messages_Messages) response;
|
||||
TLRPC.TL_photos_photos res = new TLRPC.TL_photos_photos();
|
||||
res.count = messages.count;
|
||||
res.users.addAll(messages.users);
|
||||
for (int a = 0; a < messages.messages.size(); a++) {
|
||||
TLRPC.Message message = messages.messages.get(a);
|
||||
if (message.action == null || message.action.photo == null) {
|
||||
continue;
|
||||
}
|
||||
res.photos.add(message.action.photo);
|
||||
}
|
||||
processLoadedUserPhotos(res, did, offset, count, max_id, false, classGuid);
|
||||
}
|
||||
}
|
||||
});
|
||||
ConnectionsManager.getInstance().bindRequestToGuid(reqId, classGuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public void deleteMessages(ArrayList<Integer> messages, ArrayList<Long> randoms, TLRPC.EncryptedChat encryptedChat, final int channelId) {
|
||||
|
||||
}
|
||||
|
||||
public void deleteDialog(final long did, final int onlyHistory) {
|
||||
deleteDialog(did, true, onlyHistory, 0);
|
||||
}
|
||||
|
||||
private void deleteDialog(final long did, final boolean first, final int onlyHistory, final int max_id) {
|
||||
public void deleteMessages(ArrayList<Integer> messages, ArrayList<Long> randoms, Object encryptedChat, final int channelId) {
|
||||
|
||||
}
|
||||
|
||||
@@ -652,142 +235,15 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
return searchImage;
|
||||
}
|
||||
|
||||
public void loadChatInfo(final int chat_id, Semaphore semaphore, boolean force) {
|
||||
//MessagesStorage.getInstance().loadChatInfo(chat_id, semaphore, force, false);
|
||||
}
|
||||
|
||||
public void cancelTyping(int action, long dialog_id) {
|
||||
}
|
||||
|
||||
public void sendTyping(final long dialog_id, final int action, int classGuid) {
|
||||
}
|
||||
|
||||
public void loadMessages(final long dialog_id, final int count, final int max_id, boolean fromCache, int midDate, final int classGuid, final int load_type, final int last_message_id, final boolean isChannel, final int loadIndex) {
|
||||
loadMessages(dialog_id, count, max_id, fromCache, midDate, classGuid, load_type, last_message_id, isChannel, loadIndex, 0, 0, 0, false);
|
||||
}
|
||||
|
||||
public void loadMessages(final long dialog_id, final int count, final int max_id, boolean fromCache, int midDate, final int classGuid, final int load_type, final int last_message_id, final boolean isChannel, final int loadIndex, final int first_unread, final int unread_count, final int last_date, final boolean queryFromServer) {
|
||||
|
||||
}
|
||||
|
||||
public void reloadWebPages(final long dialog_id, HashMap<String, ArrayList<MessageObject>> webpagesToReload) {
|
||||
for (HashMap.Entry<String, ArrayList<MessageObject>> entry : webpagesToReload.entrySet()) {
|
||||
final String url = entry.getKey();
|
||||
final ArrayList<MessageObject> messages = entry.getValue();
|
||||
ArrayList<MessageObject> arrayList = reloadingWebpages.get(url);
|
||||
if (arrayList == null) {
|
||||
arrayList = new ArrayList<>();
|
||||
reloadingWebpages.put(url, arrayList);
|
||||
}
|
||||
arrayList.addAll(messages);
|
||||
/*TLRPC.TL_messages_getWebPagePreview req = new TLRPC.TL_messages_getWebPagePreview();
|
||||
req.message = url;
|
||||
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(final TLObject response, final TLRPC.TL_error error) {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ArrayList<MessageObject> arrayList = reloadingWebpages.remove(url);
|
||||
if (arrayList == null) {
|
||||
return;
|
||||
}
|
||||
TLRPC.TL_messages_messages messagesRes = new TLRPC.TL_messages_messages();
|
||||
if (!(response instanceof TLRPC.TL_messageMediaWebPage)) {
|
||||
for (int a = 0; a < arrayList.size(); a++) {
|
||||
arrayList.get(a).messageOwner.media.webpage = new TLRPC.TL_webPageEmpty();
|
||||
messagesRes.messages.add(arrayList.get(a).messageOwner);
|
||||
}
|
||||
} else {
|
||||
TLRPC.TL_messageMediaWebPage media = (TLRPC.TL_messageMediaWebPage) response;
|
||||
if (media.webpage instanceof TLRPC.TL_webPage || media.webpage instanceof TLRPC.TL_webPageEmpty) {
|
||||
for (int a = 0; a < arrayList.size(); a++) {
|
||||
arrayList.get(a).messageOwner.media.webpage = media.webpage;
|
||||
if (a == 0) {
|
||||
ImageLoader.saveMessageThumbs(arrayList.get(a).messageOwner);
|
||||
}
|
||||
messagesRes.messages.add(arrayList.get(a).messageOwner);
|
||||
}
|
||||
} else {
|
||||
reloadingWebpagesPending.put(media.webpage.id, arrayList);
|
||||
}
|
||||
}
|
||||
if (!messagesRes.messages.isEmpty()) {
|
||||
//MessagesStorage.getInstance().putMessages(messagesRes, dialog_id, -2, 0, false);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.replaceMessagesObjects, dialog_id, arrayList);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});*/
|
||||
}
|
||||
}
|
||||
|
||||
public void loadDialogs(final int offset, final int count, boolean fromCache) {
|
||||
if (loadingDialogs) {
|
||||
return;
|
||||
}
|
||||
loadingDialogs = true;
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
|
||||
FileLog.e("messenger", "load cacheOffset = " + offset + " count = " + count + " cache = " + fromCache);
|
||||
if (fromCache) {
|
||||
//MessagesStorage.getInstance().getDialogs(offset == 0 ? 0 : nextDialogsCacheOffset, count);
|
||||
} else {
|
||||
/*
|
||||
TLRPC.TL_messages_getDialogs req = new TLRPC.TL_messages_getDialogs();
|
||||
req.limit = count;
|
||||
boolean found = false;
|
||||
for (int a = dialogs.size() - 1; a >= 0; a--) {
|
||||
TLRPC.TL_dialog dialog = dialogs.get(a);
|
||||
int lower_id = (int) dialog.id;
|
||||
int high_id = (int) (dialog.id >> 32);
|
||||
if (lower_id != 0 && high_id != 1 && dialog.top_message > 0) {
|
||||
MessageObject message = dialogMessage.get(dialog.id);
|
||||
if (message != null && message.getId() > 0) {
|
||||
req.offset_date = message.messageOwner.date;
|
||||
req.offset_id = message.messageOwner.id;
|
||||
int id;
|
||||
if (message.messageOwner.to_id.channel_id != 0) {
|
||||
id = -message.messageOwner.to_id.channel_id;
|
||||
} else if (message.messageOwner.to_id.chat_id != 0) {
|
||||
id = -message.messageOwner.to_id.chat_id;
|
||||
} else {
|
||||
id = message.messageOwner.to_id.user_id;
|
||||
}
|
||||
req.offset_peer = getInputPeer(id);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
req.offset_peer = new TLRPC.TL_inputPeerEmpty();
|
||||
}
|
||||
*/
|
||||
/*ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, TLRPC.TL_error error) {
|
||||
if (error == null) {
|
||||
//final TLRPC.messages_Dialogs dialogsRes = (TLRPC.messages_Dialogs) response;
|
||||
//processLoadedDialogs(dialogsRes, null, 0, count, 0, false, false);
|
||||
}
|
||||
}
|
||||
});*/
|
||||
}
|
||||
}
|
||||
|
||||
public void markMessageContentAsRead(final MessageObject messageObject) {
|
||||
}
|
||||
|
||||
public void markMessageAsRead(final long dialog_id, final long random_id, int ttl) {
|
||||
if (random_id == 0 || dialog_id == 0 || ttl <= 0 && ttl != Integer.MIN_VALUE) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void markDialogAsRead(final long dialog_id, final int max_id, final int max_positive_id, final int max_date, final boolean was, final boolean popup) {
|
||||
}
|
||||
|
||||
public void addUserToChat(final int chat_id, final TLRPC.User user, final TLRPC.ChatFull info, int count_fwd, String botHash, final BaseFragment fragment) {
|
||||
}
|
||||
|
||||
@@ -842,7 +298,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
searchImage.date = date;
|
||||
searchImage.id = "" + searchImage.document.id;
|
||||
arrayList.add(searchImage);
|
||||
//MessagesStorage.getInstance().putWebRecent(arrayList);
|
||||
}
|
||||
|
||||
protected void updateInterfaceWithMessages(final long uid, final ArrayList<MessageObject> messages, boolean isBroadcast) {
|
||||
@@ -850,26 +305,19 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isEncryptedChat = ((int) uid) == 0;
|
||||
final boolean isEncryptedChat = false;
|
||||
MessageObject lastMessage = null;
|
||||
int channelId = 0;
|
||||
boolean updateRating = false;
|
||||
for (int a = 0; a < messages.size(); a++) {
|
||||
MessageObject message = messages.get(a);
|
||||
if (lastMessage == null || (!isEncryptedChat && message.getId() > lastMessage.getId() || (isEncryptedChat || message.getId() < 0 && lastMessage.getId() < 0) && message.getId() < lastMessage.getId()) || message.messageOwner.date > lastMessage.messageOwner.date) {
|
||||
lastMessage = message;
|
||||
if (message.messageOwner.to_id.channel_id != 0) {
|
||||
channelId = message.messageOwner.to_id.channel_id;
|
||||
}
|
||||
}
|
||||
if (message.isOut() && message.isNewGif() && !message.isSending() && !message.isForwarded()) {
|
||||
addNewGifToRecent(message.messageOwner.media.document, message.messageOwner.date);
|
||||
}
|
||||
if (message.isOut() && message.isSent()) {
|
||||
updateRating = true;
|
||||
}
|
||||
}
|
||||
MessagesQuery.loadReplyMessagesForMessages(messages, uid);
|
||||
//MessagesQuery.loadReplyMessagesForMessages(messages, uid);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.didReceivedNewMessages, uid, messages);
|
||||
|
||||
if (lastMessage == null) {
|
||||
@@ -877,12 +325,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
}
|
||||
TLRPC.TL_dialog dialog = dialogs_dict.get(uid);
|
||||
|
||||
boolean changed = false;
|
||||
|
||||
if (dialog == null) {
|
||||
if (!isBroadcast) {
|
||||
TLRPC.Chat chat = getChat(channelId);
|
||||
if (channelId != 0 && chat == null || chat != null && chat.left) {
|
||||
if (channelId != 0 && chat == null || chat != null && false/*chat.left*/) {
|
||||
return;
|
||||
}
|
||||
dialog = new TLRPC.TL_dialog();
|
||||
@@ -901,7 +347,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
}
|
||||
}
|
||||
nextDialogsCacheOffset++;
|
||||
changed = true;
|
||||
}
|
||||
} else {
|
||||
if ((dialog.top_message > 0 && lastMessage.getId() > 0 && lastMessage.getId() > dialog.top_message) ||
|
||||
@@ -914,7 +359,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
dialog.top_message = lastMessage.getId();
|
||||
if (!isBroadcast) {
|
||||
dialog.last_message_date = lastMessage.messageOwner.date;
|
||||
changed = true;
|
||||
}
|
||||
dialogMessage.put(uid, lastMessage);
|
||||
if (lastMessage.messageOwner.to_id.channel_id == 0) {
|
||||
@@ -925,173 +369,5 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
sortDialogs(null);
|
||||
}
|
||||
|
||||
if (updateRating) {
|
||||
SearchQuery.increasePeerRaiting(uid);
|
||||
}
|
||||
}
|
||||
|
||||
public void sortDialogs(HashMap<Integer, TLRPC.Chat> chatsDict) {
|
||||
dialogsServerOnly.clear();
|
||||
dialogsGroupsOnly.clear();
|
||||
Collections.sort(dialogs, dialogComparator);
|
||||
for (int a = 0; a < dialogs.size(); a++) {
|
||||
TLRPC.TL_dialog d = dialogs.get(a);
|
||||
int high_id = (int) (d.id >> 32);
|
||||
int lower_id = (int) d.id;
|
||||
if (lower_id != 0 && high_id != 1) {
|
||||
dialogsServerOnly.add(d);
|
||||
/*if (DialogObject.isChannel(d)) {
|
||||
TLRPC.Chat chat = getChat(-lower_id);
|
||||
if (chat != null && (chat.megagroup && chat.editor || chat.creator)) {
|
||||
dialogsGroupsOnly.add(d);
|
||||
}
|
||||
} else*/ if (lower_id < 0) {
|
||||
/*if (chatsDict != null) {
|
||||
TLRPC.Chat chat = chatsDict.get(-lower_id);
|
||||
if (chat != null && chat.migrated_to != null) {
|
||||
dialogs.remove(a);
|
||||
a--;
|
||||
continue;
|
||||
}
|
||||
}*/
|
||||
dialogsGroupsOnly.add(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getRestrictionReason(String reason) {
|
||||
if (reason == null || reason.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
int index = reason.indexOf(": ");
|
||||
if (index > 0) {
|
||||
String type = reason.substring(0, index);
|
||||
if (type.contains("-all") || type.contains("-android")) {
|
||||
return reason.substring(index + 2);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void showCantOpenAlert(BaseFragment fragment, String reason) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(fragment.getParentActivity());
|
||||
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null);
|
||||
builder.setMessage(reason);
|
||||
fragment.showDialog(builder.create());
|
||||
}
|
||||
|
||||
public static boolean checkCanOpenChat(Bundle bundle, BaseFragment fragment) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void openChatOrProfileWith(TLRPC.User user, TLRPC.Chat chat, BaseFragment fragment, int type) {
|
||||
if (user == null && chat == null || fragment == null) {
|
||||
return;
|
||||
}
|
||||
String reason = null;
|
||||
boolean closeLast = false;
|
||||
if (chat != null) {
|
||||
reason = getRestrictionReason(chat.restriction_reason);
|
||||
} else if (user != null) {
|
||||
reason = getRestrictionReason(user.restriction_reason);
|
||||
if (user.bot) {
|
||||
type = 1;
|
||||
closeLast = true;
|
||||
}
|
||||
}
|
||||
if (reason != null) {
|
||||
showCantOpenAlert(fragment, reason);
|
||||
} else {
|
||||
Bundle args = new Bundle();
|
||||
if (chat != null) {
|
||||
args.putInt("chat_id", chat.id);
|
||||
} else {
|
||||
args.putInt("user_id", user.id);
|
||||
}
|
||||
if (type == 0) {
|
||||
fragment.presentFragment(new ProfileActivity(args));
|
||||
} else {
|
||||
fragment.presentFragment(new ChatActivity(args), closeLast);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void openByUserName(String username, final BaseFragment fragment, final int type) {
|
||||
if (username == null || fragment == null) {
|
||||
return;
|
||||
}
|
||||
TLRPC.User user = getInstance().getUser(username);
|
||||
if (user != null) {
|
||||
openChatOrProfileWith(user, null, fragment, type);
|
||||
} else {
|
||||
if (fragment.getParentActivity() == null) {
|
||||
return;
|
||||
}
|
||||
final ProgressDialog progressDialog = new ProgressDialog(fragment.getParentActivity());
|
||||
progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading));
|
||||
progressDialog.setCanceledOnTouchOutside(false);
|
||||
progressDialog.setCancelable(false);
|
||||
|
||||
/*TLRPC.TL_contacts_resolveUsername req = new TLRPC.TL_contacts_resolveUsername();
|
||||
req.username = username;*/
|
||||
final int reqId = 0; /*ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(final TLObject response, final TLRPC.TL_error error) {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
progressDialog.dismiss();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
fragment.setVisibleDialog(null);
|
||||
if (error == null) {
|
||||
TLRPC.TL_contacts_resolvedPeer res = (TLRPC.TL_contacts_resolvedPeer) response;
|
||||
getInstance().putUsers(res.users, false);
|
||||
getInstance().putChats(res.chats, false);
|
||||
//MessagesStorage.getInstance().putUsersAndChats(res.users, res.chats, false, true);
|
||||
if (!res.chats.isEmpty()) {
|
||||
openChatOrProfileWith(null, res.chats.get(0), fragment, 1);
|
||||
} else if (!res.users.isEmpty()) {
|
||||
openChatOrProfileWith(res.users.get(0), null, fragment, type);
|
||||
}
|
||||
} else {
|
||||
if (fragment != null && fragment.getParentActivity() != null) {
|
||||
try {
|
||||
Toast.makeText(fragment.getParentActivity(), LocaleController.getString("NoUsernameFound", R.string.NoUsernameFound), Toast.LENGTH_SHORT).show();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
*/
|
||||
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, LocaleController.getString("Cancel", R.string.Cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
ConnectionsManager.getInstance().cancelRequest(reqId, true);
|
||||
try {
|
||||
dialog.dismiss();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
if (fragment != null) {
|
||||
fragment.setVisibleDialog(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
fragment.setVisibleDialog(progressDialog);
|
||||
progressDialog.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Messenger Android Frontend
|
||||
* Copyright (C) 2016 Björn Petersen Software Design and Development
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
@@ -20,13 +20,14 @@
|
||||
*******************************************************************************
|
||||
*
|
||||
* File: MrChat.java
|
||||
* Authors: Björn Petersen
|
||||
* Purpose: Wrap around mrchat_t
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
public class MrChat {
|
||||
|
||||
public final static int MR_CHAT_UNDEFINED = 0;
|
||||
@@ -44,20 +45,13 @@ public class MrChat {
|
||||
MrChatUnref(m_hChat);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return MrChatGetId(m_hChat);
|
||||
}
|
||||
public int getType() {
|
||||
return MrChatGetType(m_hChat);
|
||||
}
|
||||
public native int getId();
|
||||
public native int getType();
|
||||
public native String getName();
|
||||
public native String getSubtitle();
|
||||
|
||||
public String getName() {
|
||||
return MrChatGetName(m_hChat);
|
||||
}
|
||||
|
||||
public String getSubtitle() {
|
||||
return MrChatGetSubtitle(m_hChat);
|
||||
}
|
||||
public static int MR_CHAT_PARAM_UNPROMOTED = 'U';
|
||||
public native int getParamInt(int key, int def);
|
||||
|
||||
public String getDraft() {
|
||||
return MrChatGetDraft(m_hChat);
|
||||
@@ -90,19 +84,14 @@ public class MrChat {
|
||||
return MrChatSendMedia(m_hChat, type, file, mime, w, h, time_ms);
|
||||
}
|
||||
|
||||
private long m_hChat;
|
||||
private long m_hChat; // must not be renamed as referenced by JNI under the name "m_hChat"
|
||||
private native static void MrChatUnref (long hChat);
|
||||
private native static int MrChatGetId (long hChat);
|
||||
private native static int MrChatGetType (long hChat);
|
||||
private native static String MrChatGetName (long hChat);
|
||||
private native static String MrChatGetSubtitle (long hChat);
|
||||
private native static String MrChatGetDraft (long hChat); // returns null for "no draft"
|
||||
private native static long MrChatGetDraftTimestamp (long hChat); // returns 0 for "no draft"
|
||||
private native static int MrChatGetDraftReplyToMsgId (long hChat); // returns 0 for "no draft"
|
||||
private native static int MrChatSetDraft (long hChat, String draft/*NULL=delete*/, long replyToMsgId);
|
||||
private native static int MrChatGetUnseenCount (long hChat);
|
||||
private native static int MrChatGetTotalMsgCount (long hChat);
|
||||
private native static long MrChatGetSummary (long hChat); // returns hPoortext
|
||||
private native static int MrChatSendText (long hChat, String text); // returns message id
|
||||
private native static int MrChatSendMedia (long hChat, int type, String file, String mime, int w, int h, int time_ms);
|
||||
|
||||
@@ -128,7 +117,51 @@ public class MrChat {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public long GetCPtr() {
|
||||
public long getCPtr() {
|
||||
return m_hChat;
|
||||
}
|
||||
|
||||
public TLRPC.DraftMessage getDraftMessageObj() {
|
||||
if( getId() == 0 ) {
|
||||
return null;
|
||||
}
|
||||
TLRPC.DraftMessage ret = new TLRPC.DraftMessage();
|
||||
ret.message = getDraft();
|
||||
if( ret.message==null || ret.message.isEmpty() ) {
|
||||
return null;
|
||||
}
|
||||
ret.date = (int)getDraftTimestamp();
|
||||
ret.reply_to_msg_id = getDraftReplyToMsgId();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void saveDraft(CharSequence message, TLRPC.Message replyToMessage) {
|
||||
if( message == null || TextUtils.isEmpty(message) ) {
|
||||
setDraft(null, 0);
|
||||
}
|
||||
else {
|
||||
setDraft(message.toString(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void cleanDraft()
|
||||
{
|
||||
setDraft(null, 0);
|
||||
}
|
||||
|
||||
public String getNameNAddr()
|
||||
{
|
||||
// returns name of group chats or name+e-mail-address for normal chats
|
||||
String name = "ErrGrpNameNAddr";
|
||||
if( getType()==MR_CHAT_GROUP ) {
|
||||
name = getName();
|
||||
}
|
||||
else {
|
||||
int contacts[] = MrMailbox.getChatContacts(getId());
|
||||
if( contacts.length==1 ) {
|
||||
name = MrMailbox.getContact(contacts[0]).getNameNAddr();
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Messenger Android Frontend
|
||||
* Copyright (C) 2016 Björn Petersen Software Design and Development
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
@@ -20,7 +20,6 @@
|
||||
*******************************************************************************
|
||||
*
|
||||
* File: MrChatlist.java
|
||||
* Authors: Björn Petersen
|
||||
* Purpose: Wrap around mrchatlist_t
|
||||
*
|
||||
******************************************************************************/
|
||||
@@ -48,7 +47,7 @@ public class MrChatlist {
|
||||
}
|
||||
|
||||
public MrPoortext getSummaryByIndex(int index, MrChat chat) {
|
||||
return new MrPoortext(MrChatlistGetSummaryByIndex(m_hChatlist, index, chat.GetCPtr()));
|
||||
return new MrPoortext(MrChatlistGetSummaryByIndex(m_hChatlist, index, chat.getCPtr()));
|
||||
}
|
||||
|
||||
private long m_hChatlist;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Messenger Android Frontend
|
||||
* Copyright (C) 2016 Björn Petersen Software Design and Development
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
@@ -20,7 +20,6 @@
|
||||
*******************************************************************************
|
||||
*
|
||||
* File: MrContact.java
|
||||
* Authors: Björn Petersen
|
||||
* Purpose: Wrap around mrcontact_t
|
||||
*
|
||||
******************************************************************************/
|
||||
@@ -32,6 +31,7 @@ package com.b44t.messenger;
|
||||
public class MrContact {
|
||||
|
||||
public final static int MR_CONTACT_ID_SELF = 1;
|
||||
public final static int MR_CONTACT_ID_LAST_SPECIAL = 9;
|
||||
|
||||
public MrContact(long hContact) {
|
||||
m_hContact = hContact;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Messenger Android Frontend
|
||||
* Copyright (C) 2016 Björn Petersen Software Design and Development
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
@@ -20,7 +20,6 @@
|
||||
*******************************************************************************
|
||||
*
|
||||
* File: MrMailbox.java
|
||||
* Authors: Björn Petersen
|
||||
* Purpose: Wrap around mrmailbox_t
|
||||
*
|
||||
******************************************************************************/
|
||||
@@ -35,13 +34,9 @@ public class MrMailbox {
|
||||
m_hMailbox = MrMailboxNew();
|
||||
}
|
||||
|
||||
public static int open(String dbfile, String blobdir) {
|
||||
return MrMailboxOpen(m_hMailbox, dbfile, blobdir);
|
||||
}
|
||||
|
||||
public static void close() {
|
||||
MrMailboxClose(m_hMailbox);
|
||||
}
|
||||
public native static int open(String dbfile);
|
||||
public native static void close();
|
||||
public native static String getBlobdir();
|
||||
|
||||
public static int configure() {
|
||||
return MrMailboxConfigure(m_hMailbox);
|
||||
@@ -63,6 +58,8 @@ public class MrMailbox {
|
||||
return MrMailboxFetch(m_hMailbox);
|
||||
}
|
||||
|
||||
public native static String getErrorDescr();
|
||||
|
||||
public static int setConfig(String key, String value) {
|
||||
return MrMailboxSetConfig(m_hMailbox, key, value);
|
||||
}
|
||||
@@ -75,18 +72,11 @@ public class MrMailbox {
|
||||
return MrMailboxGetConfigInt(m_hMailbox, key, def);
|
||||
}
|
||||
|
||||
public static String getInfo() {
|
||||
return MrMailboxGetInfo(m_hMailbox);
|
||||
}
|
||||
public native static String getInfo();
|
||||
public native static String cmdline(String cmd);
|
||||
|
||||
public static String execute(String cmd) {
|
||||
return MrMailboxExecute(m_hMailbox, cmd);
|
||||
}
|
||||
|
||||
private static long m_hMailbox = 0;
|
||||
private static long m_hMailbox = 0; // do not rename this, is used in C-part
|
||||
private native static long MrMailboxNew (); // returns hMailbox which must be unref'd after usage (Names as mrmailbox_new don't work due to the additional underscore)
|
||||
private native static int MrMailboxOpen (long hMailbox, String dbfile, String blobdir);
|
||||
private native static void MrMailboxClose (long hMailbox);
|
||||
private native static int MrMailboxConfigure (long hMailbox);
|
||||
private native static int MrMailboxIsConfigured (long hMailbox);
|
||||
private native static int MrMailboxConnect (long hMailbox);
|
||||
@@ -95,18 +85,11 @@ public class MrMailbox {
|
||||
private native static int MrMailboxSetConfig (long hMailbox, String key, String value); // value may be NULL
|
||||
private native static String MrMailboxGetConfig (long hMailbox, String key, String def); // def may be NULL, returns empty string as NULL
|
||||
private native static int MrMailboxGetConfigInt (long hMailbox, String key, int def); // def may be NULL, returns empty string as NULL
|
||||
private native static String MrMailboxGetInfo (long hMailbox);
|
||||
private native static String MrMailboxExecute (long hMailbox, String cmd);
|
||||
|
||||
|
||||
// contacts
|
||||
public static int[] getKnownContacts(String query) {
|
||||
return MrMailboxGetKnownContacts(m_hMailbox, query);
|
||||
}
|
||||
|
||||
public static int[] getBlockedContacts() {
|
||||
return MrMailboxGetBlockedContacts(m_hMailbox);
|
||||
}
|
||||
public native static int[] getKnownContacts(String query);
|
||||
public native static int getBlockedCount();
|
||||
public native static int[] getBlockedContacts();
|
||||
|
||||
public static MrContact getContact(int contact_id) {
|
||||
return new MrContact(MrMailboxGetContact(m_hMailbox, contact_id));
|
||||
@@ -128,8 +111,6 @@ public class MrMailbox {
|
||||
return MrMailboxAddAddressBook(m_hMailbox, adrbook);
|
||||
}
|
||||
|
||||
private native static int[] MrMailboxGetKnownContacts (long hMailbox, String query);
|
||||
private native static int[] MrMailboxGetBlockedContacts(long hMailbox);
|
||||
private native static long MrMailboxGetContact (long hMailbox, int id);// returns hContact which must be unref'd after usage
|
||||
private native static int MrMailboxCreateContact (long hMailbox, String name, String addr);
|
||||
private native static int MrMailboxBlockContact (long hMailbox, int id, int block);
|
||||
@@ -138,17 +119,16 @@ public class MrMailbox {
|
||||
|
||||
|
||||
// chats
|
||||
public static MrChatlist getChatlist() {
|
||||
return new MrChatlist(MrMailboxGetChatlist(m_hMailbox));
|
||||
public static MrChatlist getChatlist(String query) {
|
||||
return new MrChatlist(MrMailboxGetChatlist(m_hMailbox, query));
|
||||
}
|
||||
|
||||
public static MrChat getChat(int contact_id) {
|
||||
return new MrChat(MrMailboxGetChat(m_hMailbox, contact_id));
|
||||
public static MrChat getChat(int chat_id) {
|
||||
return new MrChat(MrMailboxGetChat(m_hMailbox, chat_id));
|
||||
}
|
||||
|
||||
public static int markseenChat(int id) {
|
||||
return MrMailboxMarkseenChat(m_hMailbox, id);
|
||||
}
|
||||
public native static int markseenMsg (int msg_id);
|
||||
public native static int markseenChat (int chat_id);
|
||||
|
||||
public static int getChatIdByContactId (int contact_id) {
|
||||
return MrMailboxGetChatIdByContactId(m_hMailbox, contact_id);
|
||||
@@ -158,31 +138,30 @@ public class MrMailbox {
|
||||
return MrMailboxCreateChatByContactId(m_hMailbox, contact_id);
|
||||
}
|
||||
|
||||
public static int[] getChatMsgs(int chat_id) {
|
||||
return MrMailboxGetChatMsgs(m_hMailbox, chat_id);
|
||||
}
|
||||
public native static int createGroupChat (String name);
|
||||
public native static int addContactToChat (int chat_id, int contact_id);
|
||||
public native static int removeContactFromChat (int chat_id, int contact_id);
|
||||
public native static int setChatName (int chat_id, String name);
|
||||
|
||||
public final static int MR_GCM_ADDDAYMARKER = 0x01;
|
||||
public native static int[] getChatMsgs(int chat_id, int flags, int marker1before);
|
||||
|
||||
public native static int[] searchMsgs(int chat_id, String query);
|
||||
|
||||
public native static int[] getUnseenMsgs();
|
||||
|
||||
public static int[] getChatMedia(int chat_id, int msg_type, int or_msg_type) {
|
||||
return MrMailboxGetChatMedia(m_hMailbox, chat_id, msg_type, or_msg_type);
|
||||
}
|
||||
|
||||
public static int[] getChatContacts(int chat_id) {
|
||||
return MrMailboxGetChatContacts(m_hMailbox, chat_id);
|
||||
}
|
||||
public native static int[] getChatContacts(int chat_id);
|
||||
public native static int deleteChat(int chat_id);
|
||||
|
||||
public static int deleteChat(int chat_id) {
|
||||
return MrMailboxDeleteChat(m_hMailbox, chat_id);
|
||||
}
|
||||
|
||||
private native static long MrMailboxGetChatlist (long hMailbox); // returns hChatlist which must be unref'd after usage
|
||||
private native static long MrMailboxGetChatlist (long hMailbox, String query); // returns hChatlist which must be unref'd after usage
|
||||
private native static long MrMailboxGetChat (long hMailbox, int chat_id); // return hChat which must be unref'd after usage
|
||||
private native static int MrMailboxMarkseenChat (long hMailbox, int id);
|
||||
private native static int MrMailboxGetChatIdByContactId (long hMailbox, int contact_id);
|
||||
private native static int MrMailboxCreateChatByContactId(long hMailbox, int contact_id); // returns chat_id
|
||||
private native static int[] MrMailboxGetChatMsgs (long hMailbox, int chat_id);
|
||||
private native static int[] MrMailboxGetChatMedia (long hMailbox, int chat_id, int msg_type, int or_msg_type);
|
||||
private native static int[] MrMailboxGetChatContacts (long hMailbox, int chat_id);
|
||||
private native static int MrMailboxDeleteChat (long hMailbox, int chat_id);
|
||||
|
||||
|
||||
// msgs
|
||||
@@ -194,16 +173,14 @@ public class MrMailbox {
|
||||
return MrMailboxGetMsgInfo(m_hMailbox, id);
|
||||
}
|
||||
|
||||
public static void deleteMsg(int id) {
|
||||
MrMailboxDeleteMsg(m_hMailbox, id);
|
||||
}
|
||||
public native static void deleteMsg(int id);
|
||||
public native static void forwardMsgs(int msg_ids[], int chat_ids);
|
||||
|
||||
private native static long MrMailboxGetMsg (long hMailbox, int id); // return hMsg which must be unref'd after usage
|
||||
private native static String MrMailboxGetMsgInfo (long hMailbox, int id);
|
||||
private native static void MrMailboxDeleteMsg (long hMailbox, int id);
|
||||
|
||||
// static
|
||||
public native static void MrStockAddStr (int id, String str);
|
||||
private native static void MrStockAddStr (int id, String str);
|
||||
public native static String MrGetVersionStr ();
|
||||
public native static String CPtr2String (long hString); // get strings eg. from data1 from the callback
|
||||
|
||||
@@ -211,11 +188,17 @@ public class MrMailbox {
|
||||
/* receive events
|
||||
**********************************************************************************************/
|
||||
|
||||
public final static int MR_EVENT_MSGS_UPDATED = 2000;
|
||||
public final static int MR_EVENT_MSGS_CHANGED = 2000;
|
||||
public final static int MR_EVENT_INCOMING_MSG = 2005;
|
||||
public final static int MR_EVENT_MSG_DELIVERED = 2010;
|
||||
public final static int MR_EVENT_MSG_READ = 2015;
|
||||
public final static int MR_EVENT_CHAT_MODIFIED = 2020;
|
||||
public final static int MR_EVENT_CONTACTS_CHANGED = 2030;
|
||||
public final static int MR_EVENT_MSG_DELIVERED = 3000;
|
||||
public final static int MR_EVENT_MSG_READ = 3010;
|
||||
public final static int MR_EVENT_CONNECTION_STATE_CHANGED = 3020;
|
||||
public final static int MR_EVENT_CONNECTION_STATE_CHANGED = 2040;
|
||||
public final static int MR_EVENT_REPORT = 2050;
|
||||
|
||||
public final static int MR_REPORT_ERR_SELF_NOT_IN_GROUP = 1;
|
||||
|
||||
public static long MrCallback(final int event, final long data1, final long data2) // this function is called from within the C-wrapper
|
||||
{
|
||||
switch(event) {
|
||||
@@ -228,12 +211,16 @@ public class MrMailbox {
|
||||
});
|
||||
return 0;
|
||||
|
||||
case MR_EVENT_MSGS_UPDATED:
|
||||
case MR_EVENT_MSGS_CHANGED:
|
||||
case MR_EVENT_INCOMING_MSG:
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
reloadMainChatlist();
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload, event, (int)data1, (int)data2);
|
||||
if( event == MR_EVENT_INCOMING_MSG ) {
|
||||
NotificationsController.getInstance().processNewMessages((int)data1, (int)data2);
|
||||
}
|
||||
}
|
||||
});
|
||||
return 0;
|
||||
@@ -261,6 +248,29 @@ public class MrMailbox {
|
||||
}
|
||||
});
|
||||
return 0;
|
||||
|
||||
case MR_EVENT_CHAT_MODIFIED:
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
reloadMainChatlist();
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces,
|
||||
MessagesController.UPDATE_MASK_NAME|MessagesController.UPDATE_MASK_CHAT_NAME|
|
||||
MessagesController.UPDATE_MASK_CHAT_MEMBERS|MessagesController.UPDATE_MASK_AVATAR);
|
||||
}
|
||||
});
|
||||
return 0;
|
||||
|
||||
case MR_EVENT_REPORT:
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(data1==MR_REPORT_ERR_SELF_NOT_IN_GROUP) {
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.errSelfNotInGroup);
|
||||
}
|
||||
}
|
||||
});
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -273,6 +283,54 @@ public class MrMailbox {
|
||||
public native static int getCurrentTime ();
|
||||
public static void reloadMainChatlist()
|
||||
{
|
||||
m_currChatlist = getChatlist();
|
||||
m_currChatlist = getChatlist(null);
|
||||
}
|
||||
|
||||
public final static int MEDIA_PHOTOVIDEO = 0;
|
||||
public static void getMediaCount(final long uid, final int type, final int classGuid, boolean fromCache) {
|
||||
Utilities.globalQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int[] media = new int[0];
|
||||
if( type == MEDIA_PHOTOVIDEO ) {
|
||||
media = MrMailbox.getChatMedia((int)uid, MrMsg.MR_MSG_IMAGE, MrMsg.MR_MSG_VIDEO);
|
||||
}
|
||||
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.mediaCountDidLoaded,
|
||||
uid, media.length, false /*not from cache*/, type, media);
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void initStockStrings()
|
||||
{
|
||||
MrStockAddStr(1, LocaleController.getString("NoMessages", R.string.NoMessages));
|
||||
MrStockAddStr(2, LocaleController.getString("FromSelf", R.string.FromSelf));
|
||||
MrStockAddStr(3, LocaleController.getString("Draft", R.string.Draft));
|
||||
MrStockAddStr(4, LocaleController.getString("MemberSg", R.string.MemberSg));
|
||||
MrStockAddStr(5, LocaleController.getString("MemberPl", R.string.MemberPl));
|
||||
MrStockAddStr(6, LocaleController.getString("ContactSg", R.string.ContactSg));
|
||||
MrStockAddStr(7, LocaleController.getString("ContactPl", R.string.ContactPl));
|
||||
MrStockAddStr(8, LocaleController.getString("Deaddrop", R.string.Deaddrop));
|
||||
MrStockAddStr(9, LocaleController.getString("AttachPhoto", R.string.AttachPhoto));
|
||||
MrStockAddStr(10, LocaleController.getString("AttachVideo", R.string.AttachVideo));
|
||||
MrStockAddStr(11, LocaleController.getString("AttachAudio", R.string.AttachAudio));
|
||||
MrStockAddStr(12, LocaleController.getString("AttachDocument", R.string.AttachDocument));
|
||||
MrStockAddStr(13, LocaleController.getString("DefaultStatusText", R.string.DefaultStatusText));
|
||||
MrStockAddStr(14, LocaleController.getString("MsgNewGroupDraft", R.string.MsgNewGroupDraft));
|
||||
MrStockAddStr(15, LocaleController.getString("MsgGroupNameChanged", R.string.MsgGroupNameChanged));
|
||||
MrStockAddStr(16, LocaleController.getString("MsgGroupImageChanged", R.string.MsgGroupImageChanged));
|
||||
MrStockAddStr(17, LocaleController.getString("MsgMemberAddedToGroup", R.string.MsgMemberAddedToGroup));
|
||||
MrStockAddStr(18, LocaleController.getString("MsgMemberRemovedFromToGroup", R.string.MsgMemberRemovedFromToGroup));
|
||||
MrStockAddStr(19, LocaleController.getString("MsgGroupLeft", R.string.MsgGroupLeft));
|
||||
}
|
||||
|
||||
public static String getInviteText() {
|
||||
String url = "https://getdelta.org";
|
||||
String email = getConfig("addr", "");
|
||||
String text = LocaleController.formatString("InviteText", R.string.InviteText, url, email);
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Messenger Android Frontend
|
||||
* Copyright (C) 2016 Björn Petersen Software Design and Development
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
@@ -20,7 +20,6 @@
|
||||
*******************************************************************************
|
||||
*
|
||||
* File: MrMsg.java
|
||||
* Authors: Björn Petersen
|
||||
* Purpose: Wrap around mrmsg_t
|
||||
*
|
||||
******************************************************************************/
|
||||
@@ -28,8 +27,12 @@
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class MrMsg {
|
||||
|
||||
private static final String TAG = "MrMsg";
|
||||
|
||||
public final static int MR_MSG_UNDEFINED = 0;
|
||||
public final static int MR_MSG_TEXT = 10;
|
||||
public final static int MR_MSG_IMAGE = 20;
|
||||
@@ -46,6 +49,9 @@ public class MrMsg {
|
||||
public final static int MR_OUT_DELIVERED = 26;
|
||||
public final static int MR_OUT_READ = 28;
|
||||
|
||||
public final static int MR_MSG_ID_MARKER1 = 1;
|
||||
public final static int MR_MSG_ID_DAYMARKER = 9;
|
||||
|
||||
public MrMsg(long hMsg) {
|
||||
m_hMsg = hMsg;
|
||||
}
|
||||
@@ -91,7 +97,12 @@ public class MrMsg {
|
||||
return MrMsgGetParamInt(m_hMsg, key, def);
|
||||
}
|
||||
|
||||
private long m_hMsg;
|
||||
public native int getBytes();
|
||||
public MrPoortext getSummary(MrChat chat) { return new MrPoortext(getSummaryCPtr(chat.getCPtr())); }
|
||||
private native long getSummaryCPtr(long hChat);
|
||||
public native String getSummarytext(int approx_characters);
|
||||
|
||||
private long m_hMsg; // must not be renamed as referenced by JNI under the name "m_hMsg"
|
||||
private native static void MrMsgUnref (long hMsg);
|
||||
private native static int MrMsgGetId (long hMsg);
|
||||
private native static String MrMsgGetText (long hMsg);
|
||||
@@ -147,11 +158,21 @@ public class MrMsg {
|
||||
TLRPC.TL_photoSize photoSize = new TLRPC.TL_photoSize();
|
||||
photoSize.w = getParamInt('w', 800);
|
||||
photoSize.h = getParamInt('h', 800);
|
||||
photoSize.size = 0;
|
||||
photoSize.size = 0; // not sure what to use here, maybe `getBytes();`?
|
||||
photoSize.location = new TLRPC.TL_fileLocation();
|
||||
photoSize.location.mr_path = path;
|
||||
photoSize.location.local_id = -ret.id; // this forces the document to be searched in the cache dir
|
||||
photoSize.type = "x";
|
||||
if (photoSize.w <= 100 && photoSize.h <= 100) {
|
||||
photoSize.type = "s";
|
||||
} else if (photoSize.w <= 320 && photoSize.h <= 320) {
|
||||
photoSize.type = "m";
|
||||
} else if (photoSize.w <= 800 && photoSize.h <= 800) {
|
||||
photoSize.type = "x";
|
||||
} else if (photoSize.w <= 1280 && photoSize.h <= 1280) {
|
||||
photoSize.type = "y";
|
||||
} else {
|
||||
photoSize.type = "w";
|
||||
}
|
||||
photo = new TLRPC.TL_photo();
|
||||
photo.sizes.add(photoSize);
|
||||
} catch (Exception e) {
|
||||
@@ -200,6 +221,15 @@ public class MrMsg {
|
||||
ret.message = String.format("<unsupported message type #%d for id #%d>", type, ret.id);
|
||||
}
|
||||
|
||||
if( !getParam('a', "").equals("") ) {
|
||||
ret.flags |= TLRPC.MESSAGE_FLAG_FWD;
|
||||
ret.fwd_from = new TLRPC.TL_messageFwdHeader();
|
||||
ret.fwd_from.m_name = getParam('A', "");
|
||||
if( ret.fwd_from.m_name.isEmpty() ) {
|
||||
ret.fwd_from.m_name = getParam('a', "");
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Messenger Android Frontend
|
||||
* Copyright (C) 2016 Björn Petersen Software Design and Development
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
@@ -20,7 +20,6 @@
|
||||
*******************************************************************************
|
||||
*
|
||||
* File: MrPoortext.java
|
||||
* Authors: Björn Petersen
|
||||
* Purpose: Wrap around mrpoortext_t
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 1.3.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
@@ -113,7 +128,7 @@ public class NativeLoader {
|
||||
return;
|
||||
}
|
||||
|
||||
String crashDir = context.getCacheDir().getAbsolutePath();
|
||||
//String crashDir = context.getCacheDir().getAbsolutePath();
|
||||
|
||||
try {
|
||||
String folder;
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
@@ -23,47 +38,28 @@ public class NotificationCenter {
|
||||
public static final int closeChats = totalEvents++;
|
||||
public static final int messagesDeleted = totalEvents++;
|
||||
public static final int messagesSentOrRead = totalEvents++;
|
||||
public static final int messagesDidLoaded = totalEvents++;
|
||||
public static final int messageReceivedByAck = totalEvents++;
|
||||
public static final int messageReceivedByServer = totalEvents++;
|
||||
public static final int messageSendError = totalEvents++;
|
||||
public static final int contactsDidLoaded = totalEvents++;
|
||||
public static final int chatDidCreated = totalEvents++;
|
||||
public static final int chatDidFailCreate = totalEvents++;
|
||||
public static final int mediaDidLoaded = totalEvents++;
|
||||
public static final int mediaCountDidLoaded = totalEvents++;
|
||||
public static final int dialogPhotosLoaded = totalEvents++;
|
||||
public static final int removeAllMessagesFromDialog = totalEvents++;
|
||||
public static final int notificationsSettingsUpdated = totalEvents++;
|
||||
public static final int pushMessagesUpdated = totalEvents++;
|
||||
public static final int blockedUsersDidLoaded = totalEvents++;
|
||||
public static final int openedChatChanged = totalEvents++;
|
||||
public static final int stopEncodingService = totalEvents++;
|
||||
public static final int didCreatedNewDeleteTask = totalEvents++;
|
||||
public static final int mainUserInfoChanged = totalEvents++;
|
||||
public static final int updateMessageMedia = totalEvents++;
|
||||
public static final int recentImagesDidLoaded = totalEvents++;
|
||||
public static final int replaceMessagesObjects = totalEvents++;
|
||||
public static final int didSetPasscode = totalEvents++;
|
||||
//public static final int screenStateChanged = totalEvents++; -- currently not used, but this may get handy
|
||||
public static final int didLoadedReplyMessages = totalEvents++;
|
||||
public static final int didReceivedWebpages = totalEvents++;
|
||||
public static final int didReceivedWebpagesInUpdates = totalEvents++;
|
||||
public static final int stickersDidLoaded = totalEvents++;
|
||||
public static final int didReplacedPhotoInMemCache = totalEvents++;
|
||||
public static final int messagesReadContent = totalEvents++;
|
||||
public static final int userInfoDidLoaded = totalEvents++;
|
||||
public static final int chatSearchResultsAvailable = totalEvents++;
|
||||
public static final int musicDidLoaded = totalEvents++;
|
||||
public static final int needShowAlert = totalEvents++;
|
||||
public static final int didUpdatedMessagesViews = totalEvents++;
|
||||
public static final int needReloadRecentDialogsSearch = totalEvents++;
|
||||
public static final int locationPermissionGranted = totalEvents++;
|
||||
public static final int peerSettingsDidLoaded = totalEvents++;
|
||||
public static final int wasUnableToFindCurrentLocation = totalEvents++;
|
||||
public static final int reloadHints = totalEvents++;
|
||||
public static final int reloadInlineHints = totalEvents++;
|
||||
public static final int newDraftReceived = totalEvents++;
|
||||
|
||||
public static final int httpFileDidLoaded = totalEvents++;
|
||||
public static final int httpFileDidFailedLoad = totalEvents++;
|
||||
@@ -73,10 +69,7 @@ public class NotificationCenter {
|
||||
public static final int wallpapersDidLoaded = totalEvents++;
|
||||
public static final int closeOtherAppActivities = totalEvents++;
|
||||
public static final int didUpdatedConnectionState = totalEvents++;
|
||||
public static final int didReceiveSmsCode = totalEvents++;
|
||||
public static final int didReceiveCall = totalEvents++;
|
||||
public static final int emojiDidLoaded = totalEvents++;
|
||||
public static final int appDidLogout = totalEvents++;
|
||||
|
||||
public static final int FileDidUpload = totalEvents++;
|
||||
public static final int FileDidFailUpload = totalEvents++;
|
||||
@@ -101,6 +94,8 @@ public class NotificationCenter {
|
||||
public static final int audioDidStarted = totalEvents++;
|
||||
public static final int audioRouteChanged = totalEvents++;
|
||||
|
||||
public static final int errSelfNotInGroup = totalEvents++;
|
||||
|
||||
private SparseArray<ArrayList<Object>> observers = new SparseArray<>();
|
||||
private SparseArray<ArrayList<Object>> removeAfterBroadcast = new SparseArray<>();
|
||||
private SparseArray<ArrayList<Object>> addAfterBroadcast = new SparseArray<>();
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 1.3.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 1.3.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
@@ -19,7 +34,6 @@ import android.webkit.MimeTypeMap;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.b44t.messenger.audioinfo.AudioInfo;
|
||||
import com.b44t.messenger.query.DraftQuery;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
@@ -544,63 +558,23 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||
if (document == null) {
|
||||
return;
|
||||
}
|
||||
if ((int) peer == 0) {
|
||||
int high_id = (int) (peer >> 32);
|
||||
TLRPC.EncryptedChat encryptedChat = MessagesController.getInstance().getEncryptedChat(high_id);
|
||||
if (encryptedChat == null) {
|
||||
return;
|
||||
}
|
||||
if (document.thumb instanceof TLRPC.TL_photoSize) {
|
||||
File file = FileLoader.getPathToAttach(document.thumb, true);
|
||||
if (file.exists()) {
|
||||
try {
|
||||
int len = (int) file.length();
|
||||
byte[] arr = new byte[(int) file.length()];
|
||||
RandomAccessFile reader = new RandomAccessFile(file, "r");
|
||||
reader.readFully(arr);
|
||||
TLRPC.TL_document newDocument = new TLRPC.TL_document();
|
||||
newDocument.thumb = new TLRPC.TL_photoCachedSize();
|
||||
newDocument.thumb.location = document.thumb.location;
|
||||
newDocument.thumb.size = document.thumb.size;
|
||||
newDocument.thumb.w = document.thumb.w;
|
||||
newDocument.thumb.h = document.thumb.h;
|
||||
newDocument.thumb.type = document.thumb.type;
|
||||
newDocument.thumb.bytes = arr;
|
||||
|
||||
newDocument.id = document.id;
|
||||
newDocument.access_hash = document.access_hash;
|
||||
newDocument.date = document.date;
|
||||
newDocument.mime_type = document.mime_type;
|
||||
newDocument.size = document.size;
|
||||
newDocument.dc_id = document.dc_id;
|
||||
newDocument.attributes = document.attributes;
|
||||
if (newDocument.mime_type == null) {
|
||||
newDocument.mime_type = "";
|
||||
}
|
||||
document = newDocument;
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SendMessagesHelper.getInstance().sendMessageDocument((TLRPC.TL_document) document, null, null, peer, replyingMessageObject, null);
|
||||
}
|
||||
|
||||
public void sendMessageContact(TLRPC.User user, long peer, MessageObject reply_to_msg, HashMap<String, String> params) {
|
||||
sendMessage__(null, null, null, null, user, null, peer, null, reply_to_msg, null, null, params);
|
||||
sendMessage__(null, null, null, null, user, null, peer, null, reply_to_msg, params);
|
||||
}
|
||||
|
||||
public void sendMessageDocument(TLRPC.TL_document document, VideoEditedInfo videoEditedInfo, String path, long peer, MessageObject reply_to_msg, HashMap<String, String> params) {
|
||||
sendMessage__(null, null, null, videoEditedInfo, null, document, peer, path, reply_to_msg, null, null, params);
|
||||
sendMessage__(null, null, null, videoEditedInfo, null, document, peer, path, reply_to_msg, params);
|
||||
}
|
||||
|
||||
public void sendMessageText(String message, long peer, MessageObject reply_to_msg, TLRPC.WebPage webPage, boolean searchLinks, ArrayList<TLRPC.MessageEntity> entities, HashMap<String, String> params) {
|
||||
sendMessage__(message, null, null, null, null, null, peer, null, reply_to_msg, webPage, entities, params);
|
||||
public void sendMessageText(String message, long peer, MessageObject reply_to_msg, HashMap<String, String> params) {
|
||||
sendMessage__(message, null, null, null, null, null, peer, null, reply_to_msg, params);
|
||||
}
|
||||
|
||||
public void sendMessagePhoto(TLRPC.TL_photo photo, String path, long peer, MessageObject reply_to_msg, HashMap<String, String> params) {
|
||||
sendMessage__(null, null, photo, null, null, null, peer, path, reply_to_msg, null, null, params);
|
||||
sendMessage__(null, null, photo, null, null, null, peer, path, reply_to_msg, params);
|
||||
}
|
||||
|
||||
private void sendMessage__(String message,
|
||||
@@ -612,8 +586,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||
long peer,
|
||||
String path,
|
||||
MessageObject reply_to_msg,
|
||||
TLRPC.WebPage webPage,
|
||||
ArrayList<TLRPC.MessageEntity> entities,
|
||||
HashMap<String, String> params) {
|
||||
if (peer == 0) { // peer == dialog id
|
||||
return;
|
||||
@@ -653,15 +625,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||
{
|
||||
if (message != null) {
|
||||
newMsg = new TLRPC.TL_message();
|
||||
if (entities != null && !entities.isEmpty()) {
|
||||
newMsg.entities = entities;
|
||||
}
|
||||
if (webPage == null) {
|
||||
newMsg.media = new TLRPC.TL_messageMediaEmpty();
|
||||
} else {
|
||||
newMsg.media = new TLRPC.TL_messageMediaWebPage();
|
||||
newMsg.media.webpage = webPage;
|
||||
}
|
||||
newMsg.media = new TLRPC.TL_messageMediaEmpty();
|
||||
if (params != null && params.containsKey("query_id")) {
|
||||
type = 9;
|
||||
} else {
|
||||
@@ -799,7 +763,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||
if (type == 0 /*|| type == 9 && message != null && encryptedChat != null*/ )
|
||||
{
|
||||
newMsg.id = mrChat.sendText(newMsg.message);
|
||||
DraftQuery.cleanDraft(peer, false);
|
||||
mrChat.cleanDraft();
|
||||
|
||||
MrMailbox.reloadMainChatlist();
|
||||
}
|
||||
@@ -1072,6 +1036,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||
*/
|
||||
}
|
||||
|
||||
if( newMsg.id!=0 ) {
|
||||
NotificationsController.getInstance().playOutChatSound();
|
||||
}
|
||||
|
||||
// finally update the interface, this results u.a. in an didReceivedNewMessages event which requires newMsg.id to be set
|
||||
MessagesController.getInstance().updateInterfaceWithMessages(peer, objArr);
|
||||
@@ -1646,7 +1613,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||
//int count = (int) Math.ceil(textFinal.length() / 4096.0f);
|
||||
//for (int a = 0; a < count; a++) {
|
||||
// String mess = textFinal.substring(a * 4096, Math.min((a + 1) * 4096, textFinal.length()));
|
||||
SendMessagesHelper.getInstance().sendMessageText(textFinal, dialog_id, null, null, true, null, null);
|
||||
SendMessagesHelper.getInstance().sendMessageText(textFinal, dialog_id, null, null);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
@@ -17,14 +32,11 @@ public class TLRPC {
|
||||
public static final int MESSAGE_FLAG_REPLY = 0x00000008;
|
||||
public static final int MESSAGE_FLAG_HAS_FROM_ID = 0x00000100;
|
||||
public static final int MESSAGE_FLAG_HAS_MEDIA = 0x00000200;
|
||||
public static final int MESSAGE_FLAG_EDITED = 0x00008000;
|
||||
|
||||
public static class DraftMessage extends TLObject {
|
||||
public int flags;
|
||||
public boolean no_webpage;
|
||||
public int reply_to_msg_id;
|
||||
public String message;
|
||||
public ArrayList<MessageEntity> entities = new ArrayList<>();
|
||||
public int date;
|
||||
}
|
||||
|
||||
@@ -80,15 +92,12 @@ public class TLRPC {
|
||||
public static class Peer extends TLObject {
|
||||
public final int channel_id = 0;
|
||||
public int user_id;
|
||||
public int chat_id;
|
||||
public final int chat_id = 0;
|
||||
}
|
||||
|
||||
public static class TL_peerUser extends Peer {
|
||||
}
|
||||
|
||||
public static class TL_peerChat extends Peer {
|
||||
}
|
||||
|
||||
public static class GeoPoint extends TLObject {
|
||||
public double _long;
|
||||
public double lat;
|
||||
@@ -97,15 +106,6 @@ public class TLRPC {
|
||||
public static class TL_geoPoint extends GeoPoint {
|
||||
}
|
||||
|
||||
public static class SendMessageAction extends TLObject {
|
||||
public int progress;
|
||||
}
|
||||
|
||||
public static class PrivacyRule extends TLObject {
|
||||
public ArrayList<Integer> users = new ArrayList<>();
|
||||
|
||||
}
|
||||
|
||||
public static class TL_messageMediaEmpty extends MessageMedia {
|
||||
}
|
||||
|
||||
@@ -124,27 +124,6 @@ public class TLRPC {
|
||||
public static class TL_messageMediaGeo extends MessageMedia {
|
||||
}
|
||||
|
||||
public static class TL_messageMediaWebPage extends MessageMedia {
|
||||
}
|
||||
|
||||
public static class BotInlineResult extends TLObject {
|
||||
public int flags;
|
||||
public String id;
|
||||
public String type;
|
||||
public String title;
|
||||
public String description;
|
||||
public String url;
|
||||
public String thumb_url;
|
||||
public String content_url;
|
||||
public String content_type;
|
||||
public int w;
|
||||
public int h;
|
||||
public int duration;
|
||||
public Photo photo;
|
||||
public Document document;
|
||||
}
|
||||
|
||||
|
||||
public static class PeerNotifySettings extends TLObject {
|
||||
public int flags;
|
||||
public boolean silent;
|
||||
@@ -157,7 +136,6 @@ public class TLRPC {
|
||||
|
||||
public static class TL_messages_stickerSet extends TLObject {
|
||||
public StickerSet set;
|
||||
public ArrayList<TL_stickerPack> packs = new ArrayList<>();
|
||||
public ArrayList<Document> documents = new ArrayList<>();
|
||||
}
|
||||
|
||||
@@ -185,54 +163,22 @@ public class TLRPC {
|
||||
public int flags;
|
||||
public int id;
|
||||
public String about;
|
||||
public int pinned_msg_id;
|
||||
public ChatParticipants participants;
|
||||
}
|
||||
|
||||
public static class TL_topPeerCategoryPeers extends TLObject {
|
||||
public TopPeerCategory category;
|
||||
public int count;
|
||||
}
|
||||
|
||||
public static class InputUser extends TLObject {
|
||||
public int user_id;
|
||||
public long access_hash;
|
||||
}
|
||||
|
||||
public static class TL_inputUserEmpty extends InputUser {
|
||||
}
|
||||
|
||||
public static class TL_inputUserSelf extends InputUser {
|
||||
}
|
||||
|
||||
public static class TL_inputUser extends InputUser {
|
||||
}
|
||||
|
||||
public static class WebPage extends TLObject {
|
||||
public int flags;
|
||||
public long id;
|
||||
public String url;
|
||||
public String display_url;
|
||||
public String type;
|
||||
public String site_name;
|
||||
public String title;
|
||||
public String description;
|
||||
public Photo photo;
|
||||
public String embed_url;
|
||||
public int embed_width;
|
||||
public int embed_height;
|
||||
public int duration;
|
||||
public String author;
|
||||
public int date;
|
||||
public Document document;
|
||||
}
|
||||
|
||||
public static class TL_webPageEmpty extends WebPage {
|
||||
}
|
||||
|
||||
public static class TL_webPage extends WebPage {
|
||||
}
|
||||
|
||||
public static class InputFileLocation extends TLObject {
|
||||
public long id;
|
||||
public long access_hash;
|
||||
@@ -252,62 +198,17 @@ public class TLRPC {
|
||||
public String first_name;
|
||||
public String last_name;
|
||||
public String username;
|
||||
public long access_hash;
|
||||
public String phone;
|
||||
public UserProfilePhoto photo;
|
||||
public UserStatus status;
|
||||
public int flags;
|
||||
public boolean self;
|
||||
public boolean contact;
|
||||
public boolean mutual_contact;
|
||||
public boolean deleted;
|
||||
public final boolean bot = false;
|
||||
public boolean verified;
|
||||
public boolean min;
|
||||
public String restriction_reason;
|
||||
}
|
||||
|
||||
public static class TL_userContact_old2 extends User {
|
||||
}
|
||||
|
||||
public static class MessageAction extends TLObject {
|
||||
public String title;
|
||||
public String address;
|
||||
public ArrayList<Integer> users = new ArrayList<>();
|
||||
public final int channel_id = 0;
|
||||
public Photo photo;
|
||||
public int chat_id;
|
||||
public int user_id;
|
||||
public UserProfilePhoto newUserPhoto;
|
||||
}
|
||||
|
||||
public static class TL_messageActionChatCreate extends MessageAction {
|
||||
}
|
||||
|
||||
public static class TL_messageActionHistoryClear extends MessageAction {
|
||||
}
|
||||
|
||||
public static class TL_messageActionChatEditPhoto extends MessageAction {
|
||||
}
|
||||
|
||||
public static class TL_messageActionChatAddUser extends MessageAction {
|
||||
}
|
||||
|
||||
public static class TL_messageActionChatDeleteUser extends MessageAction {
|
||||
}
|
||||
|
||||
public static class TL_messageActionUserUpdatedPhoto extends MessageAction {
|
||||
}
|
||||
|
||||
public static class TL_messageActionChatDeletePhoto extends MessageAction {
|
||||
}
|
||||
|
||||
public static class TL_messageActionChatEditTitle extends MessageAction {
|
||||
}
|
||||
|
||||
public static class TL_messageActionEmpty extends MessageAction {
|
||||
}
|
||||
|
||||
public static class Video extends TLObject {
|
||||
public long id;
|
||||
public int user_id;
|
||||
@@ -324,9 +225,6 @@ public class TLRPC {
|
||||
public byte[] iv;
|
||||
}
|
||||
|
||||
public static class TopPeerCategory extends TLObject {
|
||||
}
|
||||
|
||||
public static class InputDocument extends TLObject {
|
||||
public long id;
|
||||
public long access_hash;
|
||||
@@ -404,65 +302,12 @@ public class TLRPC {
|
||||
|
||||
public static class InputStickerSet extends TLObject {
|
||||
public long id;
|
||||
public long access_hash;
|
||||
public String short_name;
|
||||
}
|
||||
|
||||
public static class TL_inputStickerSetEmpty extends InputStickerSet {
|
||||
}
|
||||
|
||||
public static class TL_inputStickerSetID extends InputStickerSet {
|
||||
}
|
||||
|
||||
public static class TL_inputStickerSetShortName extends InputStickerSet {
|
||||
}
|
||||
|
||||
public static class UserStatus extends TLObject {
|
||||
public int expires;
|
||||
}
|
||||
|
||||
public static class TL_userStatusLastWeek extends UserStatus {
|
||||
}
|
||||
|
||||
public static class TL_userStatusLastMonth extends UserStatus {
|
||||
}
|
||||
|
||||
public static class TL_userStatusRecently extends UserStatus {
|
||||
}
|
||||
|
||||
public static class Update extends TLObject {
|
||||
public int chat_id;
|
||||
public int user_id;
|
||||
public int date;
|
||||
public int version;
|
||||
public DraftMessage draft;
|
||||
public int pts;
|
||||
public byte[] data;
|
||||
public int flags;
|
||||
public String query;
|
||||
public String offset;
|
||||
public int channel_id;
|
||||
public SendMessageAction action;
|
||||
public boolean blocked;
|
||||
public String location;
|
||||
public boolean enabled;
|
||||
public ArrayList<PrivacyRule> rules = new ArrayList<>();
|
||||
public UserStatus status;
|
||||
public int views;
|
||||
public String type;
|
||||
public MessageMedia media;
|
||||
public String first_name;
|
||||
public String last_name;
|
||||
public String username;
|
||||
public ArrayList<Integer> messages = new ArrayList<>();
|
||||
public String phone;
|
||||
public WebPage webpage;
|
||||
public EncryptedChat chat;
|
||||
public ArrayList<Long> order = new ArrayList<>();
|
||||
public UserProfilePhoto photo;
|
||||
public boolean previous;
|
||||
}
|
||||
|
||||
public static class InputEncryptedFile extends TLObject {
|
||||
public long id;
|
||||
public int parts;
|
||||
@@ -473,48 +318,6 @@ public class TLRPC {
|
||||
public FileLocation photo_big;
|
||||
}
|
||||
|
||||
public static class MessageEntity extends TLObject {
|
||||
public int offset;
|
||||
public int length;
|
||||
public String url;
|
||||
public String language;
|
||||
}
|
||||
|
||||
public static class TL_messageEntityTextUrl extends MessageEntity {
|
||||
}
|
||||
|
||||
public static class TL_messageEntityEmail extends MessageEntity {
|
||||
}
|
||||
|
||||
public static class TL_messageEntityPre extends MessageEntity {
|
||||
}
|
||||
|
||||
public static class TL_messageEntityUrl extends MessageEntity {
|
||||
}
|
||||
|
||||
public static class TL_messageEntityItalic extends MessageEntity {
|
||||
}
|
||||
|
||||
public static class TL_messageEntityMention extends MessageEntity {
|
||||
}
|
||||
|
||||
public static class TL_messageEntityMentionName extends MessageEntity {
|
||||
public int user_id;
|
||||
}
|
||||
|
||||
public static class TL_inputMessageEntityMentionName extends MessageEntity {
|
||||
public InputUser user_id;
|
||||
}
|
||||
|
||||
public static class TL_messageEntityBold extends MessageEntity {
|
||||
}
|
||||
|
||||
public static class TL_messageEntityHashtag extends MessageEntity {
|
||||
}
|
||||
|
||||
public static class TL_messageEntityCode extends MessageEntity {
|
||||
}
|
||||
|
||||
public static class Photo extends TLObject {
|
||||
public long id;
|
||||
public long access_hash;
|
||||
@@ -530,49 +333,23 @@ public class TLRPC {
|
||||
public static class TL_photoEmpty extends Photo {
|
||||
}
|
||||
|
||||
public static class TL_contact extends TLObject {
|
||||
public int user_id;
|
||||
public boolean mutual;
|
||||
}
|
||||
|
||||
public static class ChatParticipants extends TLObject {
|
||||
public int flags;
|
||||
public int chat_id;
|
||||
public ArrayList<ChatParticipant> participants = new ArrayList<>();
|
||||
public int version;
|
||||
}
|
||||
|
||||
public static class ChatParticipant extends TLObject {
|
||||
public int user_id;
|
||||
public int date;
|
||||
}
|
||||
|
||||
public static class Chat extends TLObject {
|
||||
public int flags;
|
||||
public boolean creator;
|
||||
public boolean kicked;
|
||||
public boolean deactivated;
|
||||
public int id;
|
||||
public String title;
|
||||
public final ChatPhoto photo = null;
|
||||
public int date;
|
||||
public int version;
|
||||
public boolean editor;
|
||||
public final boolean broadcast = false;
|
||||
public boolean verified;
|
||||
public final boolean megagroup = false;
|
||||
public boolean left;
|
||||
public String username;
|
||||
public boolean restricted;
|
||||
public boolean signatures;
|
||||
public String restriction_reason;
|
||||
public boolean min;
|
||||
public String address;
|
||||
}
|
||||
|
||||
public static class StickerSet extends TLObject {
|
||||
public long id;
|
||||
public long access_hash;
|
||||
public String title;
|
||||
public int flags;
|
||||
public boolean installed;
|
||||
@@ -582,33 +359,8 @@ public class TLRPC {
|
||||
public int hash;
|
||||
}
|
||||
|
||||
public static class MessagesFilter extends TLObject {
|
||||
}
|
||||
|
||||
public static class TL_inputMessagesFilterDocument extends MessagesFilter {
|
||||
}
|
||||
|
||||
public static class TL_inputMessagesFilterMusic extends MessagesFilter {
|
||||
}
|
||||
|
||||
public static class TL_inputMessagesFilterUrl extends MessagesFilter {
|
||||
}
|
||||
|
||||
public static class TL_inputMessagesFilterVoice extends MessagesFilter {
|
||||
}
|
||||
|
||||
public static class TL_inputMessagesFilterEmpty extends MessagesFilter {
|
||||
}
|
||||
|
||||
public static class TL_inputMessagesFilterPhotoVideo extends MessagesFilter {
|
||||
}
|
||||
|
||||
public static class TL_messageFwdHeader extends TLObject {
|
||||
public int flags;
|
||||
public int from_id;
|
||||
public int date;
|
||||
public int channel_id;
|
||||
public int channel_post;
|
||||
public String m_name;
|
||||
}
|
||||
|
||||
public static class FileLocation extends TLObject {
|
||||
@@ -627,7 +379,7 @@ public class TLRPC {
|
||||
}
|
||||
|
||||
public static class PhotoSize extends TLObject {
|
||||
public String type;
|
||||
public String type; // s, m, x, y, w for small, medium, ... widest
|
||||
public FileLocation location;
|
||||
public int w;
|
||||
public int h;
|
||||
@@ -651,26 +403,6 @@ public class TLRPC {
|
||||
public String name;
|
||||
}
|
||||
|
||||
public static class Updates extends TLObject {
|
||||
public ArrayList<Update> updates = new ArrayList<>();
|
||||
public ArrayList<User> users = new ArrayList<>();
|
||||
public ArrayList<Chat> chats = new ArrayList<>();
|
||||
public int date;
|
||||
public int seq;
|
||||
public int flags;
|
||||
public boolean out;
|
||||
public boolean mentioned;
|
||||
public boolean silent;
|
||||
public int id;
|
||||
public int user_id;
|
||||
public String message;
|
||||
public int pts;
|
||||
public MessageMedia media;
|
||||
public Update update;
|
||||
public int from_id;
|
||||
public int chat_id;
|
||||
}
|
||||
|
||||
public static class WallPaper extends TLObject {
|
||||
public int id;
|
||||
public String title;
|
||||
@@ -685,10 +417,6 @@ public class TLRPC {
|
||||
public static class TL_wallPaperSolid extends WallPaper {
|
||||
}
|
||||
|
||||
public static class TL_stickerPack extends TLObject {
|
||||
public ArrayList<Long> documents = new ArrayList<>();
|
||||
}
|
||||
|
||||
public static class InputPhoto extends TLObject {
|
||||
public long id;
|
||||
public long access_hash;
|
||||
@@ -699,7 +427,6 @@ public class TLRPC {
|
||||
|
||||
public static class InputPeer extends TLObject {
|
||||
public int user_id;
|
||||
public long access_hash;
|
||||
public int chat_id;
|
||||
public int channel_id;
|
||||
}
|
||||
@@ -707,31 +434,6 @@ public class TLRPC {
|
||||
public static class TL_inputPeerUser extends InputPeer {
|
||||
}
|
||||
|
||||
public static class TL_inputPeerEmpty extends InputPeer {
|
||||
}
|
||||
|
||||
public static class TL_topPeer extends TLObject {
|
||||
public Peer peer;
|
||||
}
|
||||
|
||||
public static class TL_messages_search extends TLObject {
|
||||
public int flags;
|
||||
public InputPeer peer;
|
||||
public String q;
|
||||
public MessagesFilter filter;
|
||||
public int offset;
|
||||
public int max_id;
|
||||
public int limit;
|
||||
}
|
||||
|
||||
public static class TL_messages_searchGlobal extends TLObject {
|
||||
public String q;
|
||||
public int offset_date;
|
||||
public InputPeer offset_peer;
|
||||
public int offset_id;
|
||||
public int limit;
|
||||
}
|
||||
|
||||
public static class MessageMedia extends TLObject {
|
||||
public byte[] bytes;
|
||||
public Photo photo;
|
||||
@@ -749,47 +451,28 @@ public class TLRPC {
|
||||
public WebPage webpage;
|
||||
}
|
||||
|
||||
public static class EncryptedChat extends TLObject {
|
||||
public int id;
|
||||
public int date;
|
||||
public byte[] nonce;
|
||||
public byte[] auth_key; //custom
|
||||
public int user_id; //custom
|
||||
public int ttl; //custom
|
||||
public int layer; //custom
|
||||
public byte[] key_hash; //custom
|
||||
}
|
||||
|
||||
public static class Message extends TLObject {
|
||||
public int id;
|
||||
public int from_id;
|
||||
public Peer to_id;
|
||||
public int date;
|
||||
public MessageAction action;
|
||||
public int reply_to_msg_id;
|
||||
public long reply_to_random_id;
|
||||
public String message;
|
||||
public MessageMedia media;
|
||||
public int flags;
|
||||
public boolean mentioned;
|
||||
public boolean media_unread;
|
||||
public boolean out;
|
||||
public boolean unread;
|
||||
public ArrayList<MessageEntity> entities = new ArrayList<>();
|
||||
public String via_bot_name;
|
||||
public int views;
|
||||
public int edit_date;
|
||||
public boolean silent;
|
||||
public boolean post;
|
||||
public TL_messageFwdHeader fwd_from;
|
||||
public int via_bot_id;
|
||||
public int send_state = 0; //custom
|
||||
public String attachPath = ""; //custom
|
||||
public HashMap<String, String> params; //custom
|
||||
public long random_id; //custom
|
||||
public long dialog_id; //custom
|
||||
public int ttl; //custom
|
||||
public int destroyTime; //custom
|
||||
public int layer; //custom
|
||||
public TLRPC.Message replyMessage; //custom
|
||||
public boolean created_by_mr;
|
||||
@@ -801,9 +484,6 @@ public class TLRPC {
|
||||
public static class TL_message extends Message {
|
||||
}
|
||||
|
||||
public static class TL_messageService extends Message {
|
||||
}
|
||||
|
||||
public static class TL_dialog extends TLObject {
|
||||
final public int flags = 0;
|
||||
public Peer peer;
|
||||
@@ -816,8 +496,6 @@ public class TLRPC {
|
||||
public long id; //custom
|
||||
}
|
||||
|
||||
public static class TL_chatEmpty extends Chat {
|
||||
}
|
||||
public static class Vector extends TLObject {
|
||||
public ArrayList<Object> objects = new ArrayList<>();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,39 +1,35 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
public class UserObject {
|
||||
|
||||
public static boolean isDeleted(TLRPC.User user) {
|
||||
return user == null || user.deleted;
|
||||
}
|
||||
|
||||
public static boolean isUserSelf(TLRPC.User user) {
|
||||
return user.self;
|
||||
}
|
||||
|
||||
public static String getUserName(TLRPC.User user) {
|
||||
if (user == null || isDeleted(user)) {
|
||||
return "ErrName";
|
||||
}
|
||||
String name = ContactsController.formatName(user.first_name, user.last_name);
|
||||
return name.length() != 0 || user.phone == null || user.phone.length() == 0 ? name : ""/*PhoneFormat.getInstance().format("+" + user.phone)*/;
|
||||
}
|
||||
|
||||
public static String getFirstName(TLRPC.User user) {
|
||||
if (user == null || isDeleted(user)) {
|
||||
return "DELETED";
|
||||
}
|
||||
String name = user.first_name;
|
||||
if (name == null || name.length() == 0) {
|
||||
name = user.last_name;
|
||||
}
|
||||
return name != null && name.length() > 0 ? name : "ErrFirstName";
|
||||
return "ErrName"; // use MrContact.getName() instead
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger;
|
||||
|
||||
@@ -32,7 +47,8 @@ public class WearReplyReceiver extends BroadcastReceiver {
|
||||
if (dialog_id == 0 || max_id == 0) {
|
||||
return;
|
||||
}
|
||||
SendMessagesHelper.getInstance().sendMessageText(text.toString(), dialog_id, null, null, true, null, null);
|
||||
MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, true, false);
|
||||
SendMessagesHelper.getInstance().sendMessageText(text.toString(), dialog_id, null, null);
|
||||
MrMailbox.markseenChat((int)dialog_id);
|
||||
NotificationsController.getInstance().removeSeenMessages();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger.browser;
|
||||
|
||||
|
||||
@@ -1,208 +0,0 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
|
||||
package com.b44t.messenger.query;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.b44t.messenger.MrChat;
|
||||
import com.b44t.messenger.MrMailbox;
|
||||
import com.b44t.messenger.TLRPC;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public class DraftQuery {
|
||||
|
||||
/* EDIT BY MR
|
||||
private static HashMap<Long, TLRPC.DraftMessage> drafts = new HashMap<>();
|
||||
private static HashMap<Long, TLRPC.Message> draftMessages = new HashMap<>();
|
||||
private static boolean inTransaction;
|
||||
private static SharedPreferences preferences;
|
||||
private static boolean loadingDrafts;
|
||||
|
||||
static {
|
||||
preferences = ApplicationLoader.applicationContext.getSharedPreferences("drafts", Activity.MODE_PRIVATE);
|
||||
Map<String, ?> values = preferences.getAll();
|
||||
for (Map.Entry<String, ?> entry : values.entrySet()) {
|
||||
try {
|
||||
String key = entry.getKey();
|
||||
long did = Utilities.parseLong(key);
|
||||
byte[] bytes = Utilities.hexToBytes((String) entry.getValue());
|
||||
SerializedData serializedData = new SerializedData(bytes);
|
||||
if (key.startsWith("r_")) {
|
||||
TLRPC.Message message = TLRPC.Message.TLdeserialize(serializedData, serializedData.readInt32(true), true);
|
||||
if (message != null) {
|
||||
draftMessages.put(did, message);
|
||||
}
|
||||
} else {
|
||||
TLRPC.DraftMessage draftMessage = TLRPC.DraftMessage.TLdeserialize(serializedData, serializedData.readInt32(true), true);
|
||||
if (draftMessage != null) {
|
||||
drafts.put(did, draftMessage);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
//igonre
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public static void cleanup() {
|
||||
/* EDIT BY MR
|
||||
drafts.clear();
|
||||
draftMessages.clear();
|
||||
preferences.edit().clear().commit();
|
||||
*/
|
||||
}
|
||||
|
||||
public static TLRPC.DraftMessage getDraft(long did) { // returns null for "no draft"
|
||||
MrChat mrChat = MrMailbox.getChat((int)did);
|
||||
if( mrChat.getId() == 0 ) {
|
||||
return null;
|
||||
}
|
||||
TLRPC.DraftMessage ret = new TLRPC.DraftMessage();
|
||||
ret.message = mrChat.getDraft();
|
||||
ret.date = (int)mrChat.getDraftTimestamp();
|
||||
ret.reply_to_msg_id = mrChat.getDraftReplyToMsgId();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static TLRPC.Message getDraftMessage(long did) { // returns null for "no draft"
|
||||
MrChat mrChat = MrMailbox.getChat((int)did);
|
||||
if( mrChat.getId() == 0 ) {
|
||||
return null;
|
||||
}
|
||||
TLRPC.Message ret = new TLRPC.Message();
|
||||
ret.message = mrChat.getDraft();
|
||||
ret.date = (int)mrChat.getDraftTimestamp();
|
||||
ret.reply_to_msg_id = mrChat.getDraftReplyToMsgId();
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static void saveDraft__(long did, String message, long replyToMessageId) // message may be null
|
||||
{
|
||||
MrChat mrChat = MrMailbox.getChat((int)did);
|
||||
mrChat.setDraft(message, replyToMessageId);
|
||||
}
|
||||
|
||||
public static void saveDraft(long did, CharSequence message, ArrayList<TLRPC.MessageEntity> entities, TLRPC.Message replyToMessage, boolean noWebpage) {
|
||||
saveDraft(did, message, entities, replyToMessage, noWebpage, false);
|
||||
}
|
||||
|
||||
public static void saveDraft(long did, CharSequence message, ArrayList<TLRPC.MessageEntity> entities, TLRPC.Message replyToMessage, boolean noWebpage, boolean clean) {
|
||||
if( message == null || TextUtils.isEmpty(message) ) {
|
||||
saveDraft__(did, null, 0);
|
||||
}
|
||||
else {
|
||||
saveDraft__(did, message.toString(), 0);
|
||||
|
||||
}
|
||||
/* EDIT BY MR
|
||||
TLRPC.DraftMessage draftMessage;
|
||||
if (!TextUtils.isEmpty(message) || replyToMessage != null) {
|
||||
draftMessage = new TLRPC.TL_draftMessage();
|
||||
} else {
|
||||
draftMessage = new TLRPC.TL_draftMessageEmpty();
|
||||
}
|
||||
draftMessage.date = (int) (System.currentTimeMillis() / 1000);
|
||||
draftMessage.message = message == null ? "" : message.toString();
|
||||
draftMessage.no_webpage = noWebpage;
|
||||
if (replyToMessage != null) {
|
||||
draftMessage.reply_to_msg_id = replyToMessage.id;
|
||||
draftMessage.flags |= 1;
|
||||
}
|
||||
if (entities != null && !entities.isEmpty()) {
|
||||
draftMessage.entities = entities;
|
||||
draftMessage.flags |= 8;
|
||||
}
|
||||
|
||||
TLRPC.DraftMessage currentDraft = drafts.get(did);
|
||||
if (!clean) {
|
||||
if (currentDraft != null && currentDraft.message.equals(draftMessage.message) && currentDraft.reply_to_msg_id == draftMessage.reply_to_msg_id && currentDraft.no_webpage == draftMessage.no_webpage ||
|
||||
currentDraft == null && TextUtils.isEmpty(draftMessage.message) && draftMessage.reply_to_msg_id == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
saveDraft(did, draftMessage, replyToMessage, false);
|
||||
int lower_id = (int) did;
|
||||
if (lower_id != 0) {
|
||||
TLRPC.TL_messages_saveDraft req = new TLRPC.TL_messages_saveDraft();
|
||||
req.peer = MessagesController.getInputPeer(lower_id);
|
||||
if (req.peer == null) {
|
||||
return;
|
||||
}
|
||||
req.message = draftMessage.message;
|
||||
req.no_webpage = draftMessage.no_webpage;
|
||||
req.reply_to_msg_id = draftMessage.reply_to_msg_id;
|
||||
req.entities = draftMessage.entities;
|
||||
req.flags = draftMessage.flags;
|
||||
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, TLRPC.TL_error error) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
MessagesController.getInstance().sortDialogs(null);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
|
||||
*/
|
||||
}
|
||||
|
||||
/* EDIT BY MR
|
||||
private static void saveDraftReplyMessage(final long did, final TLRPC.Message message) {
|
||||
if (message == null) {
|
||||
return;
|
||||
}
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
TLRPC.DraftMessage draftMessage = drafts.get(did);
|
||||
if (draftMessage != null && draftMessage.reply_to_msg_id == message.id) {
|
||||
draftMessages.put(did, message);
|
||||
SerializedData serializedData = new SerializedData(message.getObjectSize());
|
||||
message.serializeToStream(serializedData);
|
||||
preferences.edit().putString("r_" + did, Utilities.bytesToHex(serializedData.toByteArray())).commit();
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.newDraftReceived, did);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
public static void cleanDraft(long did, boolean replyOnly) {
|
||||
saveDraft__(did, null, 0);
|
||||
/* EDIT BY MR
|
||||
TLRPC.DraftMessage draftMessage = drafts.get(did);
|
||||
if (draftMessage == null) {
|
||||
return;
|
||||
}
|
||||
if (!replyOnly) {
|
||||
drafts.remove(did);
|
||||
draftMessages.remove(did);
|
||||
preferences.edit().remove("" + did).remove("r_" + did).commit();
|
||||
MessagesController.getInstance().sortDialogs(null);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
|
||||
} else if (draftMessage.reply_to_msg_id != 0) {
|
||||
draftMessage.reply_to_msg_id = 0;
|
||||
draftMessage.flags &= ~1;
|
||||
saveDraft(did, draftMessage.message, draftMessage.entities, null, draftMessage.no_webpage, true);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/* EDIT BY MR
|
||||
public static void beginTransaction() {
|
||||
inTransaction = true;
|
||||
}
|
||||
|
||||
public static void endTransaction() {
|
||||
inTransaction = false;
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -1,445 +0,0 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
|
||||
package com.b44t.messenger.query;
|
||||
|
||||
import android.text.Spannable;
|
||||
import com.b44t.messenger.MessageObject;
|
||||
import com.b44t.messenger.MessagesController;
|
||||
import com.b44t.messenger.Utilities;
|
||||
import com.b44t.messenger.TLRPC;
|
||||
import com.b44t.ui.Components.URLSpanUserMention;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class MessagesQuery {
|
||||
|
||||
public static MessageObject loadPinnedMessage(final int channelId, final int mid, boolean useQueue) {
|
||||
if (useQueue) {
|
||||
/*
|
||||
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
loadPinnedMessageInternal(channelId, mid, false);
|
||||
}
|
||||
});
|
||||
*/
|
||||
} else {
|
||||
return loadPinnedMessageInternal(channelId, mid, true);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static MessageObject loadPinnedMessageInternal(final int channelId, final int mid, boolean returnValue) {
|
||||
/*
|
||||
try {
|
||||
long messageId = ((long) mid) | ((long) channelId) << 32;
|
||||
|
||||
TLRPC.Message result = null;
|
||||
final ArrayList<TLRPC.User> users = new ArrayList<>();
|
||||
final ArrayList<TLRPC.Chat> chats = new ArrayList<>();
|
||||
ArrayList<Integer> usersToLoad = new ArrayList<>();
|
||||
ArrayList<Integer> chatsToLoad = new ArrayList<>();
|
||||
|
||||
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, mid, date FROM messages WHERE mid = %d", messageId));
|
||||
if (cursor.next()) {
|
||||
NativeByteBuffer data = cursor.byteBufferValue(0);
|
||||
if (data != null) {
|
||||
result = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
|
||||
data.reuse();
|
||||
result.id = cursor.intValue(1);
|
||||
result.date = cursor.intValue(2);
|
||||
result.dialog_id = -channelId;
|
||||
MessagesStorage.addUsersAndChatsFromMessage(result, usersToLoad, chatsToLoad);
|
||||
}
|
||||
}
|
||||
cursor.dispose();
|
||||
|
||||
if (result == null) {
|
||||
cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data FROM chat_pinned WHERE uid = %d", channelId));
|
||||
if (cursor.next()) {
|
||||
NativeByteBuffer data = cursor.byteBufferValue(0);
|
||||
if (data != null) {
|
||||
result = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
|
||||
data.reuse();
|
||||
if (result.id != mid) {
|
||||
result = null;
|
||||
} else {
|
||||
result.dialog_id = -channelId;
|
||||
MessagesStorage.addUsersAndChatsFromMessage(result, usersToLoad, chatsToLoad);
|
||||
}
|
||||
}
|
||||
}
|
||||
cursor.dispose();
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
final TLRPC.TL_channels_getMessages req = new TLRPC.TL_channels_getMessages();
|
||||
req.channel = MessagesController.getInputChannel(channelId);
|
||||
req.id.add(mid);
|
||||
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, TLRPC.TL_error error) {
|
||||
boolean ok = false;
|
||||
if (error == null) {
|
||||
TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response;
|
||||
if (!messagesRes.messages.isEmpty()) {
|
||||
ImageLoader.saveMessagesThumbs(messagesRes.messages);
|
||||
broadcastPinnedMessage(messagesRes.messages.get(0), messagesRes.users, messagesRes.chats, false, false);
|
||||
//MessagesStorage.getInstance().putUsersAndChats(messagesRes.users, messagesRes.chats, true, true);
|
||||
savePinnedMessage(messagesRes.messages.get(0));
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
MessagesStorage.getInstance().updateChannelPinnedMessage(channelId, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (returnValue) {
|
||||
return broadcastPinnedMessage(result, users, chats, true, returnValue);
|
||||
} else {
|
||||
if (!usersToLoad.isEmpty()) {
|
||||
//MessagesStorage.getInstance().getUsersInternal(TextUtils.join(",", usersToLoad), users);
|
||||
}
|
||||
if (!chatsToLoad.isEmpty()) {
|
||||
//MessagesStorage.getInstance().getChatsInternal(TextUtils.join(",", chatsToLoad), chats);
|
||||
}
|
||||
broadcastPinnedMessage(result, users, chats, true, false);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
private static MessageObject broadcastPinnedMessage(final TLRPC.Message result, final ArrayList<TLRPC.User> users, final ArrayList<TLRPC.Chat> chats, final boolean isCache, boolean returnValue) {
|
||||
final HashMap<Integer, TLRPC.User> usersDict = new HashMap<>();
|
||||
for (int a = 0; a < users.size(); a++) {
|
||||
TLRPC.User user = users.get(a);
|
||||
usersDict.put(user.id, user);
|
||||
}
|
||||
final HashMap<Integer, TLRPC.Chat> chatsDict = new HashMap<>();
|
||||
for (int a = 0; a < chats.size(); a++) {
|
||||
TLRPC.Chat chat = chats.get(a);
|
||||
chatsDict.put(chat.id, chat);
|
||||
}
|
||||
if (returnValue) {
|
||||
return new MessageObject(result, usersDict, chatsDict, false);
|
||||
} else {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
MessagesController.getInstance().putUsers(users, isCache);
|
||||
MessagesController.getInstance().putChats(chats, isCache);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.didLoadedPinnedMessage, new MessageObject(result, usersDict, chatsDict, false));
|
||||
}
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
*/
|
||||
|
||||
public static void loadReplyMessagesForMessages(final ArrayList<MessageObject> messages, final long dialogId) {
|
||||
if ((int) dialogId == 0) {
|
||||
final ArrayList<Long> replyMessages = new ArrayList<>();
|
||||
final HashMap<Long, ArrayList<MessageObject>> replyMessageRandomOwners = new HashMap<>();
|
||||
final StringBuilder stringBuilder = new StringBuilder();
|
||||
for (int a = 0; a < messages.size(); a++) {
|
||||
MessageObject messageObject = messages.get(a);
|
||||
if (messageObject.isReply() && messageObject.replyMessageObject == null) {
|
||||
Long id = messageObject.messageOwner.reply_to_random_id;
|
||||
if (stringBuilder.length() > 0) {
|
||||
stringBuilder.append(',');
|
||||
}
|
||||
stringBuilder.append(id);
|
||||
ArrayList<MessageObject> messageObjects = replyMessageRandomOwners.get(id);
|
||||
if (messageObjects == null) {
|
||||
messageObjects = new ArrayList<>();
|
||||
replyMessageRandomOwners.put(id, messageObjects);
|
||||
}
|
||||
messageObjects.add(messageObject);
|
||||
if (!replyMessages.contains(id)) {
|
||||
replyMessages.add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (replyMessages.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid, m.date, r.random_id FROM randoms as r INNER JOIN messages as m ON r.mid = m.mid WHERE r.random_id IN(%s)", TextUtils.join(",", replyMessages)));
|
||||
while (cursor.next()) {
|
||||
NativeByteBuffer data = cursor.byteBufferValue(0);
|
||||
if (data != null) {
|
||||
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
|
||||
data.reuse();
|
||||
message.id = cursor.intValue(1);
|
||||
message.date = cursor.intValue(2);
|
||||
message.dialog_id = dialogId;
|
||||
|
||||
ArrayList<MessageObject> arrayList = replyMessageRandomOwners.remove(cursor.longValue(3));
|
||||
if (arrayList != null) {
|
||||
MessageObject messageObject = new MessageObject(message, null, null, false);
|
||||
for (int b = 0; b < arrayList.size(); b++) {
|
||||
MessageObject object = arrayList.get(b);
|
||||
object.replyMessageObject = messageObject;
|
||||
object.messageOwner.reply_to_msg_id = messageObject.getId();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cursor.dispose();
|
||||
if (!replyMessageRandomOwners.isEmpty()) {
|
||||
for (HashMap.Entry<Long, ArrayList<MessageObject>> entry : replyMessageRandomOwners.entrySet()) {
|
||||
ArrayList<MessageObject> arrayList = entry.getValue();
|
||||
for (int a = 0; a < arrayList.size(); a++) {
|
||||
arrayList.get(a).messageOwner.reply_to_random_id = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.didLoadedReplyMessages, dialogId);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
} else {
|
||||
final ArrayList<Integer> replyMessages = new ArrayList<>();
|
||||
final HashMap<Integer, ArrayList<MessageObject>> replyMessageOwners = new HashMap<>();
|
||||
final StringBuilder stringBuilder = new StringBuilder();
|
||||
int channelId = 0;
|
||||
for (int a = 0; a < messages.size(); a++) {
|
||||
MessageObject messageObject = messages.get(a);
|
||||
if (messageObject.getId() > 0 && messageObject.isReply() && messageObject.replyMessageObject == null) {
|
||||
Integer id = messageObject.messageOwner.reply_to_msg_id;
|
||||
long messageId = id;
|
||||
if (messageObject.messageOwner.to_id.channel_id != 0) {
|
||||
messageId |= ((long) messageObject.messageOwner.to_id.channel_id) << 32;
|
||||
channelId = messageObject.messageOwner.to_id.channel_id;
|
||||
}
|
||||
if (stringBuilder.length() > 0) {
|
||||
stringBuilder.append(',');
|
||||
}
|
||||
stringBuilder.append(messageId);
|
||||
ArrayList<MessageObject> messageObjects = replyMessageOwners.get(id);
|
||||
if (messageObjects == null) {
|
||||
messageObjects = new ArrayList<>();
|
||||
replyMessageOwners.put(id, messageObjects);
|
||||
}
|
||||
messageObjects.add(messageObject);
|
||||
if (!replyMessages.contains(id)) {
|
||||
replyMessages.add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (replyMessages.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
final int channelIdFinal = channelId;
|
||||
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final ArrayList<TLRPC.Message> result = new ArrayList<>();
|
||||
final ArrayList<TLRPC.User> users = new ArrayList<>();
|
||||
final ArrayList<TLRPC.Chat> chats = new ArrayList<>();
|
||||
ArrayList<Integer> usersToLoad = new ArrayList<>();
|
||||
ArrayList<Integer> chatsToLoad = new ArrayList<>();
|
||||
|
||||
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, mid, date FROM messages WHERE mid IN(%s)", stringBuilder.toString()));
|
||||
while (cursor.next()) {
|
||||
NativeByteBuffer data = cursor.byteBufferValue(0);
|
||||
if (data != null) {
|
||||
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
|
||||
data.reuse();
|
||||
message.id = cursor.intValue(1);
|
||||
message.date = cursor.intValue(2);
|
||||
message.dialog_id = dialogId;
|
||||
MessagesStorage.addUsersAndChatsFromMessage(message, usersToLoad, chatsToLoad);
|
||||
result.add(message);
|
||||
replyMessages.remove((Integer) message.id);
|
||||
}
|
||||
}
|
||||
cursor.dispose();
|
||||
|
||||
if (!usersToLoad.isEmpty()) {
|
||||
//MessagesStorage.getInstance().getUsersInternal(TextUtils.join(",", usersToLoad), users);
|
||||
}
|
||||
if (!chatsToLoad.isEmpty()) {
|
||||
//MessagesStorage.getInstance().getChatsInternal(TextUtils.join(",", chatsToLoad), chats);
|
||||
}
|
||||
broadcastReplyMessages(result, replyMessageOwners, users, chats, dialogId, true);
|
||||
|
||||
if (!replyMessages.isEmpty()) {
|
||||
if (channelIdFinal != 0) {
|
||||
final TLRPC.TL_channels_getMessages req = new TLRPC.TL_channels_getMessages();
|
||||
req.channel = MessagesController.getInputChannel(channelIdFinal);
|
||||
req.id = replyMessages;
|
||||
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, TLRPC.TL_error error) {
|
||||
if (error == null) {
|
||||
TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response;
|
||||
ImageLoader.saveMessagesThumbs(messagesRes.messages);
|
||||
broadcastReplyMessages(messagesRes.messages, replyMessageOwners, messagesRes.users, messagesRes.chats, dialogId, false);
|
||||
//MessagesStorage.getInstance().putUsersAndChats(messagesRes.users, messagesRes.chats, true, true);
|
||||
saveReplyMessages(replyMessageOwners, messagesRes.messages);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
TLRPC.TL_messages_getMessages req = new TLRPC.TL_messages_getMessages();
|
||||
req.id = replyMessages;
|
||||
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, TLRPC.TL_error error) {
|
||||
if (error == null) {
|
||||
TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response;
|
||||
ImageLoader.saveMessagesThumbs(messagesRes.messages);
|
||||
broadcastReplyMessages(messagesRes.messages, replyMessageOwners, messagesRes.users, messagesRes.chats, dialogId, false);
|
||||
//MessagesStorage.getInstance().putUsersAndChats(messagesRes.users, messagesRes.chats, true, true);
|
||||
saveReplyMessages(replyMessageOwners, messagesRes.messages);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
private static void saveReplyMessages(final HashMap<Integer, ArrayList<MessageObject>> replyMessageOwners, final ArrayList<TLRPC.Message> result) {
|
||||
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
MessagesStorage.getInstance().getDatabase().beginTransaction();
|
||||
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("UPDATE messages SET replydata = ? WHERE mid = ?");
|
||||
for (int a = 0; a < result.size(); a++) {
|
||||
TLRPC.Message message = result.get(a);
|
||||
ArrayList<MessageObject> messageObjects = replyMessageOwners.get(message.id);
|
||||
if (messageObjects != null) {
|
||||
NativeByteBuffer data = new NativeByteBuffer(message.getObjectSize());
|
||||
message.serializeToStream(data);
|
||||
for (int b = 0; b < messageObjects.size(); b++) {
|
||||
MessageObject messageObject = messageObjects.get(b);
|
||||
state.requery();
|
||||
long messageId = messageObject.getId();
|
||||
if (messageObject.messageOwner.to_id.channel_id != 0) {
|
||||
messageId |= ((long) messageObject.messageOwner.to_id.channel_id) << 32;
|
||||
}
|
||||
state.bindByteBuffer(1, data);
|
||||
state.bindLong(2, messageId);
|
||||
state.step();
|
||||
}
|
||||
data.reuse();
|
||||
}
|
||||
}
|
||||
state.dispose();
|
||||
MessagesStorage.getInstance().getDatabase().commitTransaction();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
private static void broadcastReplyMessages(final ArrayList<TLRPC.Message> result, final HashMap<Integer, ArrayList<MessageObject>> replyMessageOwners, final ArrayList<TLRPC.User> users, final ArrayList<TLRPC.Chat> chats, final long dialog_id, final boolean isCache) {
|
||||
final HashMap<Integer, TLRPC.User> usersDict = new HashMap<>();
|
||||
for (int a = 0; a < users.size(); a++) {
|
||||
TLRPC.User user = users.get(a);
|
||||
usersDict.put(user.id, user);
|
||||
}
|
||||
final HashMap<Integer, TLRPC.Chat> chatsDict = new HashMap<>();
|
||||
for (int a = 0; a < chats.size(); a++) {
|
||||
TLRPC.Chat chat = chats.get(a);
|
||||
chatsDict.put(chat.id, chat);
|
||||
}
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
MessagesController.getInstance().putUsers(users, isCache);
|
||||
MessagesController.getInstance().putChats(chats, isCache);
|
||||
boolean changed = false;
|
||||
for (int a = 0; a < result.size(); a++) {
|
||||
TLRPC.Message message = result.get(a);
|
||||
ArrayList<MessageObject> arrayList = replyMessageOwners.get(message.id);
|
||||
if (arrayList != null) {
|
||||
MessageObject messageObject = new MessageObject(message, usersDict, chatsDict, false);
|
||||
for (int b = 0; b < arrayList.size(); b++) {
|
||||
MessageObject m = arrayList.get(b);
|
||||
m.replyMessageObject = messageObject;
|
||||
//if (m.messageOwner.action instanceof TLRPC.TL_messageActionPinMessage) {
|
||||
// m.generatePinMessageText(null, null);
|
||||
//}
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.didLoadedReplyMessages, dialog_id);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
public static ArrayList<TLRPC.MessageEntity> getEntities(CharSequence message) {
|
||||
if (message == null) {
|
||||
return null;
|
||||
}
|
||||
ArrayList<TLRPC.MessageEntity> entities = null;
|
||||
if (message instanceof Spannable) {
|
||||
Spannable spannable = (Spannable) message;
|
||||
URLSpanUserMention spans[] = spannable.getSpans(0, message.length(), URLSpanUserMention.class);
|
||||
if (spans != null && spans.length > 0) {
|
||||
entities = new ArrayList<>();
|
||||
for (int b = 0; b < spans.length; b++) {
|
||||
TLRPC.TL_inputMessageEntityMentionName entity = new TLRPC.TL_inputMessageEntityMentionName();
|
||||
entity.user_id = MessagesController.getInputUser(Utilities.parseInt(spans[b].getURL()));
|
||||
if (entity.user_id != null) {
|
||||
entity.offset = spannable.getSpanStart(spans[b]);
|
||||
entity.length = Math.min(spannable.getSpanEnd(spans[b]), message.length()) - entity.offset;
|
||||
if (message.charAt(entity.offset + entity.length - 1) == ' ') {
|
||||
entity.length--;
|
||||
}
|
||||
entities.add(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
}
|
||||
@@ -1,208 +0,0 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
|
||||
package com.b44t.messenger.query;
|
||||
|
||||
import com.b44t.messenger.MessageObject;
|
||||
import com.b44t.messenger.MessagesController;
|
||||
import com.b44t.messenger.NotificationCenter;
|
||||
import com.b44t.messenger.ConnectionsManager;
|
||||
import com.b44t.messenger.TLRPC;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class MessagesSearchQuery {
|
||||
|
||||
private static int reqId;
|
||||
private static int mergeReqId;
|
||||
private static long lastMergeDialogId;
|
||||
private static int lastReqId;
|
||||
private static int messagesSearchCount[] = new int[] {0, 0};
|
||||
private static boolean messagesSearchEndReached[] = new boolean[] {false, false};
|
||||
private static ArrayList<MessageObject> searchResultMessages = new ArrayList<>();
|
||||
private static String lastSearchQuery;
|
||||
private static int lastReturnedNum;
|
||||
|
||||
private static int getMask() {
|
||||
int mask = 0;
|
||||
if (lastReturnedNum < searchResultMessages.size() - 1 || !messagesSearchEndReached[0] || !messagesSearchEndReached[1]) {
|
||||
mask |= 1;
|
||||
}
|
||||
if (lastReturnedNum > 0) {
|
||||
mask |= 2;
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
public static void searchMessagesInChat(String query, final long dialog_id, final long mergeDialogId, final int guid, final int direction) {
|
||||
searchMessagesInChat(query, dialog_id, mergeDialogId, guid, direction, false);
|
||||
}
|
||||
|
||||
private static void searchMessagesInChat(String query, final long dialog_id, final long mergeDialogId, final int guid, final int direction, final boolean internal) {
|
||||
int max_id = 0;
|
||||
long queryWithDialog = dialog_id;
|
||||
boolean firstQuery = !internal;
|
||||
if (reqId != 0) {
|
||||
ConnectionsManager.getInstance().cancelRequest(reqId, true);
|
||||
reqId = 0;
|
||||
}
|
||||
if (mergeReqId != 0) {
|
||||
ConnectionsManager.getInstance().cancelRequest(mergeReqId, true);
|
||||
mergeReqId = 0;
|
||||
}
|
||||
if (query == null || query.length() == 0) {
|
||||
if (searchResultMessages.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (direction == 1) {
|
||||
lastReturnedNum++;
|
||||
if (lastReturnedNum < searchResultMessages.size()) {
|
||||
MessageObject messageObject = searchResultMessages.get(lastReturnedNum);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, messageObject.getId(), getMask(), messageObject.getDialogId(), lastReturnedNum, messagesSearchCount[0] + messagesSearchCount[1]);
|
||||
return;
|
||||
} else {
|
||||
if (messagesSearchEndReached[0] && mergeDialogId == 0 || messagesSearchEndReached[1]) {
|
||||
lastReturnedNum--;
|
||||
return;
|
||||
}
|
||||
firstQuery = false;
|
||||
query = lastSearchQuery;
|
||||
MessageObject messageObject = searchResultMessages.get(searchResultMessages.size() - 1);
|
||||
if (messageObject.getDialogId() == dialog_id && !messagesSearchEndReached[0]) {
|
||||
max_id = messageObject.getId();
|
||||
queryWithDialog = dialog_id;
|
||||
} else {
|
||||
if (messageObject.getDialogId() == mergeDialogId) {
|
||||
max_id = messageObject.getId();
|
||||
}
|
||||
queryWithDialog = mergeDialogId;
|
||||
messagesSearchEndReached[1] = false;
|
||||
}
|
||||
}
|
||||
} else if (direction == 2) {
|
||||
lastReturnedNum--;
|
||||
if (lastReturnedNum < 0) {
|
||||
lastReturnedNum = 0;
|
||||
return;
|
||||
}
|
||||
if (lastReturnedNum >= searchResultMessages.size()) {
|
||||
lastReturnedNum = searchResultMessages.size() - 1;
|
||||
}
|
||||
MessageObject messageObject = searchResultMessages.get(lastReturnedNum);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, messageObject.getId(), getMask(), messageObject.getDialogId(), lastReturnedNum, messagesSearchCount[0] + messagesSearchCount[1]);
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (messagesSearchEndReached[0] && !messagesSearchEndReached[1] && mergeDialogId != 0) {
|
||||
queryWithDialog = mergeDialogId;
|
||||
}
|
||||
if (queryWithDialog == dialog_id && firstQuery) {
|
||||
if (mergeDialogId != 0) {
|
||||
TLRPC.InputPeer inputPeer = MessagesController.getInputPeer((int) mergeDialogId);
|
||||
if (inputPeer == null) {
|
||||
return;
|
||||
}
|
||||
final TLRPC.TL_messages_search req = new TLRPC.TL_messages_search();
|
||||
req.peer = inputPeer;
|
||||
lastMergeDialogId = mergeDialogId;
|
||||
req.limit = 1;
|
||||
req.q = query;
|
||||
req.filter = new TLRPC.TL_inputMessagesFilterEmpty();
|
||||
mergeReqId = 0;/*ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(final TLObject response, final TLRPC.TL_error error) {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (lastMergeDialogId == mergeDialogId) {
|
||||
mergeReqId = 0;
|
||||
if (response != null) {
|
||||
TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
|
||||
messagesSearchEndReached[1] = res.messages.isEmpty();
|
||||
messagesSearchCount[1] = res instanceof TLRPC.TL_messages_messagesSlice ? res.count : res.messages.size();
|
||||
searchMessagesInChat(req.q, dialog_id, mergeDialogId, guid, direction, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}, ConnectionsManager.RequestFlagFailOnServerErrors);*/
|
||||
return;
|
||||
} else {
|
||||
lastMergeDialogId = 0;
|
||||
messagesSearchEndReached[1] = true;
|
||||
messagesSearchCount[1] = 0;
|
||||
}
|
||||
}
|
||||
final TLRPC.TL_messages_search req = new TLRPC.TL_messages_search();
|
||||
req.peer = MessagesController.getInputPeer((int) queryWithDialog);
|
||||
if (req.peer == null) {
|
||||
return;
|
||||
}
|
||||
req.limit = 21;
|
||||
req.q = query;
|
||||
req.max_id = max_id;
|
||||
req.filter = new TLRPC.TL_inputMessagesFilterEmpty();
|
||||
final int currentReqId = ++lastReqId;
|
||||
lastSearchQuery = query;
|
||||
final long queryWithDialogFinal = queryWithDialog;
|
||||
reqId = 0; /* ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(final TLObject response, final TLRPC.TL_error error) {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (currentReqId == lastReqId) {
|
||||
reqId = 0;
|
||||
if (response != null) {
|
||||
TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
|
||||
//MessagesStorage.getInstance().putUsersAndChats(res.users, res.chats, true, true);
|
||||
MessagesController.getInstance().putUsers(res.users, false);
|
||||
MessagesController.getInstance().putChats(res.chats, false);
|
||||
if (req.max_id == 0 && queryWithDialogFinal == dialog_id) {
|
||||
lastReturnedNum = 0;
|
||||
searchResultMessages.clear();
|
||||
messagesSearchCount[0] = 0;
|
||||
}
|
||||
boolean added = false;
|
||||
for (int a = 0; a < Math.min(res.messages.size(), 20); a++) {
|
||||
TLRPC.Message message = res.messages.get(a);
|
||||
added = true;
|
||||
searchResultMessages.add(new MessageObject(message, null, false));
|
||||
}
|
||||
messagesSearchEndReached[queryWithDialogFinal == dialog_id ? 0 : 1] = res.messages.size() != 21;
|
||||
messagesSearchCount[queryWithDialogFinal == dialog_id ? 0 : 1] = res instanceof TLRPC.TL_messages_messagesSlice ? res.count : res.messages.size();
|
||||
if (searchResultMessages.isEmpty()) {
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, 0, getMask(), (long) 0, 0, 0);
|
||||
} else {
|
||||
if (added) {
|
||||
if (lastReturnedNum >= searchResultMessages.size()) {
|
||||
lastReturnedNum = searchResultMessages.size() - 1;
|
||||
}
|
||||
MessageObject messageObject = searchResultMessages.get(lastReturnedNum);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, messageObject.getId(), getMask(), messageObject.getDialogId(), lastReturnedNum, messagesSearchCount[0] + messagesSearchCount[1]);
|
||||
}
|
||||
}
|
||||
if (queryWithDialogFinal == dialog_id && messagesSearchEndReached[0] && mergeDialogId != 0 && !messagesSearchEndReached[1]) {
|
||||
searchMessagesInChat(lastSearchQuery, dialog_id, mergeDialogId, guid, 0, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}, ConnectionsManager.RequestFlagFailOnServerErrors);*/
|
||||
}
|
||||
|
||||
public static String getLastSearchQuery() {
|
||||
return lastSearchQuery;
|
||||
}
|
||||
}
|
||||
@@ -1,327 +0,0 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
|
||||
package com.b44t.messenger.query;
|
||||
|
||||
import com.b44t.messenger.MessagesController;
|
||||
import com.b44t.messenger.NotificationCenter;
|
||||
import com.b44t.messenger.TLRPC;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class SearchQuery {
|
||||
|
||||
public static ArrayList<TLRPC.TL_topPeer> hints = new ArrayList<>();
|
||||
public static ArrayList<TLRPC.TL_topPeer> inlineBots = new ArrayList<>();
|
||||
private static HashMap<Integer, Integer> inlineDates = new HashMap<>();
|
||||
private static boolean loaded;
|
||||
private static boolean loading;
|
||||
|
||||
public static void cleanup() {
|
||||
loading = false;
|
||||
loaded = false;
|
||||
hints.clear();
|
||||
inlineBots.clear();
|
||||
inlineDates.clear();
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadHints);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadInlineHints);
|
||||
}
|
||||
|
||||
public static void loadHints(boolean cache) {
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
if (cache) {
|
||||
if (loaded) {
|
||||
return;
|
||||
}
|
||||
loading = true;
|
||||
/*
|
||||
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final ArrayList<TLRPC.TL_topPeer> hintsNew = new ArrayList<>();
|
||||
final ArrayList<TLRPC.TL_topPeer> inlineBotsNew = new ArrayList<>();
|
||||
final HashMap<Integer, Integer> inlineDatesNew = new HashMap<>();
|
||||
final ArrayList<TLRPC.User> users = new ArrayList<>();
|
||||
final ArrayList<TLRPC.Chat> chats = new ArrayList<>();
|
||||
try {
|
||||
ArrayList<Integer> usersToLoad = new ArrayList<>();
|
||||
ArrayList<Integer> chatsToLoad = new ArrayList<>();
|
||||
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT did, type, rating, date FROM chat_hints WHERE 1 ORDER BY rating DESC");
|
||||
while (cursor.next()) {
|
||||
int did = cursor.intValue(0);
|
||||
int type = cursor.intValue(1);
|
||||
TLRPC.TL_topPeer peer = new TLRPC.TL_topPeer();
|
||||
peer.rating = cursor.doubleValue(2);
|
||||
if (did > 0) {
|
||||
peer.peer = new TLRPC.TL_peerUser();
|
||||
peer.peer.user_id = did;
|
||||
usersToLoad.add(did);
|
||||
} else {
|
||||
peer.peer = new TLRPC.TL_peerChat();
|
||||
peer.peer.chat_id = -did;
|
||||
chatsToLoad.add(-did);
|
||||
}
|
||||
if (type == 0) {
|
||||
hintsNew.add(peer);
|
||||
} else if (type == 1) {
|
||||
inlineBotsNew.add(peer);
|
||||
inlineDatesNew.put(did, cursor.intValue(3));
|
||||
}
|
||||
}
|
||||
cursor.dispose();
|
||||
if (!usersToLoad.isEmpty()) {
|
||||
//MessagesStorage.getInstance().getUsersInternal(TextUtils.join(",", usersToLoad), users);
|
||||
}
|
||||
|
||||
if (!chatsToLoad.isEmpty()) {
|
||||
//MessagesStorage.getInstance().getChatsInternal(TextUtils.join(",", chatsToLoad), chats);
|
||||
}
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
MessagesController.getInstance().putUsers(users, true);
|
||||
MessagesController.getInstance().putChats(chats, true);
|
||||
loading = false;
|
||||
loaded = true;
|
||||
hints = hintsNew;
|
||||
inlineBots = inlineBotsNew;
|
||||
inlineDates = inlineDatesNew;
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadHints);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadInlineHints);
|
||||
if (Math.abs(UserConfig.lastHintsSyncTime - (int) (System.currentTimeMillis() / 1000)) >= 24 * 60 * 60) {
|
||||
loadHints(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
loaded = true;
|
||||
} else {
|
||||
loading = true;
|
||||
/*
|
||||
TLRPC.TL_contacts_getTopPeers req = new TLRPC.TL_contacts_getTopPeers();
|
||||
req.hash = 0;
|
||||
req.bots_pm = false;
|
||||
req.correspondents = true;
|
||||
req.groups = false;
|
||||
req.channels = false;
|
||||
req.bots_inline = true;
|
||||
req.offset = 0;
|
||||
req.limit = 20;
|
||||
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(final TLObject response, TLRPC.TL_error error) {
|
||||
if (response instanceof TLRPC.TL_contacts_topPeers) {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final TLRPC.TL_contacts_topPeers topPeers = (TLRPC.TL_contacts_topPeers) response;
|
||||
MessagesController.getInstance().putUsers(topPeers.users, false);
|
||||
MessagesController.getInstance().putChats(topPeers.chats, false);
|
||||
for (int a = 0; a < topPeers.categories.size(); a++) {
|
||||
TLRPC.TL_topPeerCategoryPeers category = topPeers.categories.get(a);
|
||||
if (category.category instanceof TLRPC.TL_topPeerCategoryBotsInline) {
|
||||
inlineBots = category.peers;
|
||||
} else {
|
||||
hints = category.peers;
|
||||
}
|
||||
}
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadHints);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadInlineHints);
|
||||
final HashMap<Integer, Integer> inlineDatesCopy = new HashMap<>(inlineDates);
|
||||
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
MessagesStorage.getInstance().getDatabase().executeFast("DELETE FROM chat_hints WHERE 1").stepThis().dispose();
|
||||
MessagesStorage.getInstance().getDatabase().beginTransaction();
|
||||
MessagesStorage.getInstance().putUsersAndChats(topPeers.users, topPeers.chats, false, false);
|
||||
|
||||
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO chat_hints VALUES(?, ?, ?, ?)");
|
||||
for (int a = 0; a < topPeers.categories.size(); a++) {
|
||||
int type;
|
||||
TLRPC.TL_topPeerCategoryPeers category = topPeers.categories.get(a);
|
||||
if (category.category instanceof TLRPC.TL_topPeerCategoryBotsInline) {
|
||||
type = 1;
|
||||
} else {
|
||||
type = 0;
|
||||
}
|
||||
for (int b = 0; b < category.peers.size(); b++) {
|
||||
TLRPC.TL_topPeer peer = category.peers.get(b);
|
||||
int did;
|
||||
if (peer.peer instanceof TLRPC.TL_peerUser) {
|
||||
did = peer.peer.user_id;
|
||||
} else if (peer.peer instanceof TLRPC.TL_peerChat) {
|
||||
did = -peer.peer.chat_id;
|
||||
} else {
|
||||
did = -peer.peer.channel_id;
|
||||
}
|
||||
Integer date = inlineDatesCopy.get(did);
|
||||
state.requery();
|
||||
state.bindInteger(1, did);
|
||||
state.bindInteger(2, type);
|
||||
state.bindDouble(3, peer.rating);
|
||||
state.bindInteger(4, date != null ? date : 0);
|
||||
state.step();
|
||||
}
|
||||
}
|
||||
|
||||
state.dispose();
|
||||
|
||||
MessagesStorage.getInstance().getDatabase().commitTransaction();
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
UserConfig.lastHintsSyncTime = (int) (System.currentTimeMillis() / 1000);
|
||||
UserConfig.saveConfig(false);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});*/
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeInline(final int uid) {
|
||||
TLRPC.TL_topPeerCategoryPeers category = null;
|
||||
for (int a = 0; a < inlineBots.size(); a++) {
|
||||
if (inlineBots.get(a).peer.user_id == uid) {
|
||||
inlineBots.remove(a);
|
||||
/*TLRPC.TL_contacts_resetTopPeerRating req = new TLRPC.TL_contacts_resetTopPeerRating();
|
||||
req.category = new TLRPC.TL_topPeerCategoryBotsInline();
|
||||
req.peer = MessagesController.getInputPeer(uid);
|
||||
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, TLRPC.TL_error error) {
|
||||
|
||||
}
|
||||
});
|
||||
deletePeer(uid, 1);
|
||||
*/
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadInlineHints);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void removePeer(final int uid) {
|
||||
TLRPC.TL_topPeerCategoryPeers category = null;
|
||||
for (int a = 0; a < hints.size(); a++) {
|
||||
if (hints.get(a).peer.user_id == uid) {
|
||||
hints.remove(a);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadHints);
|
||||
/*TLRPC.TL_contacts_resetTopPeerRating req = new TLRPC.TL_contacts_resetTopPeerRating();
|
||||
req.category = new TLRPC.TL_topPeerCategoryCorrespondents();
|
||||
req.peer = MessagesController.getInputPeer(uid);
|
||||
deletePeer(uid, 0);
|
||||
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, TLRPC.TL_error error) {
|
||||
|
||||
}
|
||||
});*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void increasePeerRaiting(final long did) {
|
||||
final int lower_id = (int) did;
|
||||
if (lower_id <= 0) {
|
||||
return;
|
||||
}
|
||||
//remove chats and bots for now
|
||||
final TLRPC.User user = lower_id > 0 ? MessagesController.getInstance().getUser(lower_id) : null;
|
||||
//final TLRPC.Chat chat = lower_id < 0 ? MessagesController.getInstance().getChat(-lower_id) : null;
|
||||
if (user == null || user.bot/*&& chat == null || ChatObject.isChannel(chat) && !chat.megagroup*/) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
double dt = 0;
|
||||
try {
|
||||
int lastTime = 0;
|
||||
int lastMid = 0;
|
||||
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT MAX(mid), MAX(date) FROM messages WHERE uid = %d AND out = 1", did));
|
||||
if (cursor.next()) {
|
||||
lastMid = cursor.intValue(0);
|
||||
lastTime = cursor.intValue(1);
|
||||
}
|
||||
cursor.dispose();
|
||||
if (lastMid > 0) {
|
||||
cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT date FROM messages WHERE uid = %d AND mid < %d AND out = 1 ORDER BY date DESC", did, lastMid));
|
||||
if (cursor.next()) {
|
||||
dt = (lastTime - cursor.intValue(0));
|
||||
}
|
||||
cursor.dispose();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
final double dtFinal = dt;
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
TLRPC.TL_topPeer peer = null;
|
||||
for (int a = 0; a < hints.size(); a++) {
|
||||
TLRPC.TL_topPeer p = hints.get(a);
|
||||
if (lower_id < 0 && (p.peer.chat_id == -lower_id || p.peer.channel_id == -lower_id) || lower_id > 0 && p.peer.user_id == lower_id) {
|
||||
peer = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (peer == null) {
|
||||
peer = new TLRPC.TL_topPeer();
|
||||
if (lower_id > 0) {
|
||||
peer.peer = new TLRPC.TL_peerUser();
|
||||
peer.peer.user_id = lower_id;
|
||||
} else {
|
||||
peer.peer = new TLRPC.TL_peerChat();
|
||||
peer.peer.chat_id = -lower_id;
|
||||
}
|
||||
hints.add(peer);
|
||||
}
|
||||
peer.rating += Math.exp(dtFinal / MessagesController.getInstance().ratingDecay);
|
||||
Collections.sort(hints, new Comparator<TLRPC.TL_topPeer>() {
|
||||
@Override
|
||||
public int compare(TLRPC.TL_topPeer lhs, TLRPC.TL_topPeer rhs) {
|
||||
if (lhs.rating > rhs.rating) {
|
||||
return -1;
|
||||
} else if (lhs.rating < rhs.rating) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
savePeer((int) did, 0, peer.rating);
|
||||
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.reloadHints);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -1,439 +0,0 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 2.0.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
|
||||
package com.b44t.messenger.query;
|
||||
|
||||
import com.b44t.messenger.ChatObject;
|
||||
import com.b44t.messenger.MessagesController;
|
||||
import com.b44t.messenger.MrMailbox;
|
||||
import com.b44t.messenger.MrMsg;
|
||||
import com.b44t.messenger.NotificationCenter;
|
||||
import com.b44t.messenger.Utilities;
|
||||
import com.b44t.messenger.TLRPC;
|
||||
|
||||
public class SharedMediaQuery {
|
||||
|
||||
public final static int MEDIA_PHOTOVIDEO = 0;
|
||||
public final static int MEDIA_FILE = 1;
|
||||
public final static int MEDIA_AUDIO = 2;
|
||||
public final static int MEDIA_URL = 3;
|
||||
public final static int MEDIA_MUSIC = 4;
|
||||
public final static int MEDIA_TYPES_COUNT = 5;
|
||||
|
||||
public static void loadMedia(final long uid, final int offset, final int count, final int max_id, final int type, final boolean fromCache, final int classGuid) {
|
||||
final boolean isChannel = false;//(int) uid < 0 && ChatObject.isChannel(-(int) uid);
|
||||
|
||||
int lower_part = (int)uid;
|
||||
if (fromCache || lower_part == 0) {
|
||||
loadMediaDatabase(uid, offset, count, max_id, type, classGuid, isChannel);
|
||||
} else {
|
||||
TLRPC.TL_messages_search req = new TLRPC.TL_messages_search();
|
||||
req.offset = offset;
|
||||
req.limit = count + 1;
|
||||
req.max_id = max_id;
|
||||
if (type == MEDIA_PHOTOVIDEO) {
|
||||
req.filter = new TLRPC.TL_inputMessagesFilterPhotoVideo();
|
||||
} else if (type == MEDIA_FILE) {
|
||||
req.filter = new TLRPC.TL_inputMessagesFilterDocument();
|
||||
} else if (type == MEDIA_AUDIO) {
|
||||
req.filter = new TLRPC.TL_inputMessagesFilterVoice();
|
||||
} else if (type == MEDIA_URL) {
|
||||
req.filter = new TLRPC.TL_inputMessagesFilterUrl();
|
||||
} else if (type == MEDIA_MUSIC) {
|
||||
req.filter = new TLRPC.TL_inputMessagesFilterMusic();
|
||||
}
|
||||
req.q = "";
|
||||
req.peer = MessagesController.getInputPeer(lower_part);
|
||||
if (req.peer == null) {
|
||||
return;
|
||||
}
|
||||
/*int reqId = ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, TLRPC.TL_error error) {
|
||||
if (error == null) {
|
||||
final TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
|
||||
boolean topReached;
|
||||
if (res.messages.size() > count) {
|
||||
topReached = false;
|
||||
res.messages.remove(res.messages.size() - 1);
|
||||
} else {
|
||||
topReached = true;
|
||||
}
|
||||
processLoadedMedia(res, uid, offset, count, max_id, type, false, classGuid, isChannel, topReached);
|
||||
}
|
||||
}
|
||||
});
|
||||
ConnectionsManager.getInstance().bindRequestToGuid(reqId, classGuid);*/
|
||||
}
|
||||
}
|
||||
|
||||
public static void getMediaCount(final long uid, final int type, final int classGuid, boolean fromCache) {
|
||||
|
||||
Utilities.globalQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
int[] media = new int[0];
|
||||
if( type == SharedMediaQuery.MEDIA_PHOTOVIDEO ) {
|
||||
media = MrMailbox.getChatMedia((int)uid, MrMsg.MR_MSG_IMAGE, MrMsg.MR_MSG_VIDEO);
|
||||
}
|
||||
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.mediaCountDidLoaded,
|
||||
uid, media.length, false /*not from cache*/, type, media);
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
int lower_part = (int)uid;
|
||||
if (fromCache || lower_part == 0) {
|
||||
getMediaCountDatabase(uid, type, classGuid);
|
||||
} else {
|
||||
TLRPC.TL_messages_search req = new TLRPC.TL_messages_search();
|
||||
req.offset = 0;
|
||||
req.limit = 1;
|
||||
req.max_id = 0;
|
||||
if (type == MEDIA_PHOTOVIDEO) {
|
||||
req.filter = new TLRPC.TL_inputMessagesFilterPhotoVideo();
|
||||
} else if (type == MEDIA_FILE) {
|
||||
req.filter = new TLRPC.TL_inputMessagesFilterDocument();
|
||||
} else if (type == MEDIA_AUDIO) {
|
||||
req.filter = new TLRPC.TL_inputMessagesFilterVoice();
|
||||
} else if (type == MEDIA_URL) {
|
||||
req.filter = new TLRPC.TL_inputMessagesFilterUrl();
|
||||
} else if (type == MEDIA_MUSIC) {
|
||||
req.filter = new TLRPC.TL_inputMessagesFilterMusic();
|
||||
}
|
||||
req.q = "";
|
||||
req.peer = MessagesController.getInputPeer(lower_part);
|
||||
if (req.peer == null) {
|
||||
return;
|
||||
}
|
||||
int reqId = ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, TLRPC.TL_error error) {
|
||||
if (error == null) {
|
||||
final TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
|
||||
//MessagesStorage.getInstance().putUsersAndChats(res.users, res.chats, true, true);
|
||||
int count;
|
||||
if (res instanceof TLRPC.TL_messages_messages) {
|
||||
count = res.messages.size();
|
||||
} else {
|
||||
count = res.count;
|
||||
}
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
MessagesController.getInstance().putUsers(res.users, false);
|
||||
MessagesController.getInstance().putChats(res.chats, false);
|
||||
}
|
||||
});
|
||||
|
||||
processLoadedMediaCount(count, uid, type, classGuid, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
ConnectionsManager.getInstance().bindRequestToGuid(reqId, classGuid);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
public static int getMediaType(TLRPC.Message message) {
|
||||
if (message == null) {
|
||||
return -1;
|
||||
}
|
||||
if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
|
||||
return MEDIA_PHOTOVIDEO;
|
||||
} else if (message.media instanceof TLRPC.TL_messageMediaDocument) {
|
||||
if (MessageObject.isVoiceMessage(message)) {
|
||||
return MEDIA_AUDIO;
|
||||
} else if (MessageObject.isVideoMessage(message)) {
|
||||
return MEDIA_PHOTOVIDEO;
|
||||
} else if (MessageObject.isStickerMessage(message)) {
|
||||
return -1;
|
||||
} else if (MessageObject.isMusicMessage(message)) {
|
||||
return MEDIA_MUSIC;
|
||||
} else {
|
||||
return MEDIA_FILE;
|
||||
}
|
||||
} else if (!message.entities.isEmpty()) {
|
||||
for (int a = 0; a < message.entities.size(); a++) {
|
||||
TLRPC.MessageEntity entity = message.entities.get(a);
|
||||
if (entity instanceof TLRPC.TL_messageEntityUrl || entity instanceof TLRPC.TL_messageEntityTextUrl || entity instanceof TLRPC.TL_messageEntityEmail) {
|
||||
return MEDIA_URL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
private static void processLoadedMedia(final TLRPC.messages_Messages res, final long uid, int offset, int count, int max_id, final int type, final boolean fromCache, final int classGuid, final boolean isChannel, final boolean topReached) {
|
||||
int lower_part = (int)uid;
|
||||
if (fromCache && res.messages.isEmpty() && lower_part != 0) {
|
||||
loadMedia(uid, offset, count, max_id, type, false, classGuid);
|
||||
} else {
|
||||
if (!fromCache) {
|
||||
ImageLoader.saveMessagesThumbs(res.messages);
|
||||
//MessagesStorage.getInstance().putUsersAndChats(res.users, res.chats, true, true);
|
||||
putMediaDatabase(uid, type, res.messages, max_id, topReached);
|
||||
}
|
||||
|
||||
final HashMap<Integer, TLRPC.User> usersDict = new HashMap<>();
|
||||
for (int a = 0; a < res.users.size(); a++) {
|
||||
TLRPC.User u = res.users.get(a);
|
||||
usersDict.put(u.id, u);
|
||||
}
|
||||
final ArrayList<MessageObject> objects = new ArrayList<>();
|
||||
for (int a = 0; a < res.messages.size(); a++) {
|
||||
TLRPC.Message message = res.messages.get(a);
|
||||
objects.add(new MessageObject(message, usersDict, true));
|
||||
}
|
||||
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int totalCount = res.count;
|
||||
MessagesController.getInstance().putUsers(res.users, fromCache);
|
||||
MessagesController.getInstance().putChats(res.chats, fromCache);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.mediaDidLoaded, uid, totalCount, objects, classGuid, type, topReached);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
private static void loadMediaDatabase(final long uid, final int offset, final int count, final int max_id, final int type, final int classGuid, final boolean isChannel) {
|
||||
/*
|
||||
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
boolean topReached = false;
|
||||
TLRPC.TL_messages_messages res = new TLRPC.TL_messages_messages();
|
||||
try {
|
||||
ArrayList<Integer> usersToLoad = new ArrayList<>();
|
||||
ArrayList<Integer> chatsToLoad = new ArrayList<>();
|
||||
int countToLoad = count + 1;
|
||||
|
||||
SQLiteCursor cursor;
|
||||
SQLiteDatabase database = MessagesStorage.getInstance().getDatabase();
|
||||
boolean isEnd = false;
|
||||
if ((int) uid != 0) {
|
||||
int channelId = 0;
|
||||
long messageMaxId = max_id;
|
||||
if (isChannel) {
|
||||
channelId = -(int) uid;
|
||||
}
|
||||
if (messageMaxId != 0 && channelId != 0) {
|
||||
messageMaxId |= ((long) channelId) << 32;
|
||||
}
|
||||
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT start FROM media_holes_v2 WHERE uid = %d AND type = %d AND start IN (0, 1)", uid, type));
|
||||
if (cursor.next()) {
|
||||
isEnd = cursor.intValue(0) == 1;
|
||||
cursor.dispose();
|
||||
} else {
|
||||
cursor.dispose();
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid) FROM media_v2 WHERE uid = %d AND type = %d AND mid > 0", uid, type));
|
||||
if (cursor.next()) {
|
||||
int mid = cursor.intValue(0);
|
||||
if (mid != 0) {
|
||||
SQLitePreparedStatement state = database.executeFast("REPLACE INTO media_holes_v2 VALUES(?, ?, ?, ?)");
|
||||
state.requery();
|
||||
state.bindLong(1, uid);
|
||||
state.bindInteger(2, type);
|
||||
state.bindInteger(3, 0);
|
||||
state.bindInteger(4, mid);
|
||||
state.step();
|
||||
state.dispose();
|
||||
}
|
||||
}
|
||||
cursor.dispose();
|
||||
}
|
||||
|
||||
if (messageMaxId != 0) {
|
||||
long holeMessageId = 0;
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT end FROM media_holes_v2 WHERE uid = %d AND type = %d AND end <= %d ORDER BY end DESC LIMIT 1", uid, type, max_id));
|
||||
if (cursor.next()) {
|
||||
holeMessageId = cursor.intValue(0);
|
||||
if (channelId != 0) {
|
||||
holeMessageId |= ((long) channelId) << 32;
|
||||
}
|
||||
}
|
||||
cursor.dispose();
|
||||
if (holeMessageId > 1) {
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v2 WHERE uid = %d AND mid > 0 AND mid < %d AND mid >= %d AND type = %d ORDER BY date DESC, mid DESC LIMIT %d", uid, messageMaxId, holeMessageId, type, countToLoad));
|
||||
} else {
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v2 WHERE uid = %d AND mid > 0 AND mid < %d AND type = %d ORDER BY date DESC, mid DESC LIMIT %d", uid, messageMaxId, type, countToLoad));
|
||||
}
|
||||
} else {
|
||||
long holeMessageId = 0;
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT max(end) FROM media_holes_v2 WHERE uid = %d AND type = %d", uid, type));
|
||||
if (cursor.next()) {
|
||||
holeMessageId = cursor.intValue(0);
|
||||
if (channelId != 0) {
|
||||
holeMessageId |= ((long) channelId) << 32;
|
||||
}
|
||||
}
|
||||
cursor.dispose();
|
||||
if (holeMessageId > 1) {
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v2 WHERE uid = %d AND mid >= %d AND type = %d ORDER BY date DESC, mid DESC LIMIT %d,%d", uid, holeMessageId, type, offset, countToLoad));
|
||||
} else {
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v2 WHERE uid = %d AND mid > 0 AND type = %d ORDER BY date DESC, mid DESC LIMIT %d,%d", uid, type, offset, countToLoad));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
isEnd = true;
|
||||
if (max_id != 0) {
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid, r.random_id FROM media_v2 as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid > %d AND type = %d ORDER BY m.mid ASC LIMIT %d", uid, max_id, type, countToLoad));
|
||||
} else {
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid, r.random_id FROM media_v2 as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND type = %d ORDER BY m.mid ASC LIMIT %d,%d", uid, type, offset, countToLoad));
|
||||
}
|
||||
}
|
||||
|
||||
while (cursor.next()) {
|
||||
NativeByteBuffer data = cursor.byteBufferValue(0);
|
||||
if (data != null) {
|
||||
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
|
||||
data.reuse();
|
||||
message.id = cursor.intValue(1);
|
||||
message.dialog_id = uid;
|
||||
if ((int) uid == 0) {
|
||||
message.random_id = cursor.longValue(2);
|
||||
}
|
||||
res.messages.add(message);
|
||||
if (message.from_id > 0) {
|
||||
if (!usersToLoad.contains(message.from_id)) {
|
||||
usersToLoad.add(message.from_id);
|
||||
}
|
||||
} else {
|
||||
if (!chatsToLoad.contains(-message.from_id)) {
|
||||
chatsToLoad.add(-message.from_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cursor.dispose();
|
||||
|
||||
if (!usersToLoad.isEmpty()) {
|
||||
//MessagesStorage.getInstance().getUsersInternal(TextUtils.join(",", usersToLoad), res.users);
|
||||
}
|
||||
if (!chatsToLoad.isEmpty()) {
|
||||
//MessagesStorage.getInstance().getChatsInternal(TextUtils.join(",", chatsToLoad), res.chats);
|
||||
}
|
||||
if (res.messages.size() > count) {
|
||||
topReached = false;
|
||||
res.messages.remove(res.messages.size() - 1);
|
||||
} else {
|
||||
topReached = isEnd;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
res.messages.clear();
|
||||
res.chats.clear();
|
||||
res.users.clear();
|
||||
FileLog.e("messenger", e);
|
||||
} finally {
|
||||
processLoadedMedia(res, uid, offset, count, max_id, type, true, classGuid, isChannel, topReached);
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
private static void putMediaDatabase(final long uid, final int type, final ArrayList<TLRPC.Message> messages, final int max_id, final boolean topReached) {
|
||||
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (messages.isEmpty() || topReached) {
|
||||
MessagesStorage.getInstance().doneHolesInMedia(uid, max_id, type);
|
||||
if (messages.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
MessagesStorage.getInstance().getDatabase().beginTransaction();
|
||||
SQLitePreparedStatement state2 = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO media_v2 VALUES(?, ?, ?, ?, ?)");
|
||||
for (TLRPC.Message message : messages) {
|
||||
if (canAddMessageToMedia(message)) {
|
||||
|
||||
long messageId = message.id;
|
||||
if (message.to_id.channel_id != 0) {
|
||||
messageId |= ((long) message.to_id.channel_id) << 32;
|
||||
}
|
||||
|
||||
state2.requery();
|
||||
NativeByteBuffer data = new NativeByteBuffer(message.getObjectSize());
|
||||
message.serializeToStream(data);
|
||||
state2.bindLong(1, messageId);
|
||||
state2.bindLong(2, uid);
|
||||
state2.bindInteger(3, message.date);
|
||||
state2.bindInteger(4, type);
|
||||
state2.bindByteBuffer(5, data);
|
||||
state2.step();
|
||||
data.reuse();
|
||||
}
|
||||
}
|
||||
state2.dispose();
|
||||
if (!topReached || max_id != 0) {
|
||||
int minId = topReached ? 1 : messages.get(messages.size() - 1).id;
|
||||
if (max_id != 0) {
|
||||
MessagesStorage.getInstance().closeHolesInMedia(uid, minId, max_id, type);
|
||||
} else {
|
||||
MessagesStorage.getInstance().closeHolesInMedia(uid, minId, Integer.MAX_VALUE, type);
|
||||
}
|
||||
}
|
||||
MessagesStorage.getInstance().getDatabase().commitTransaction();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
public static void loadMusic(final long uid, final int max_id) {
|
||||
/*
|
||||
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final ArrayList<MessageObject> arrayList = new ArrayList<>();
|
||||
try {
|
||||
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v2 WHERE uid = %d AND mid < %d AND type = %d ORDER BY date DESC, mid DESC LIMIT 1000", uid, max_id, MEDIA_MUSIC));
|
||||
|
||||
while (cursor.next()) {
|
||||
NativeByteBuffer data = cursor.byteBufferValue(0);
|
||||
if (data != null) {
|
||||
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
|
||||
data.reuse();
|
||||
if (MessageObject.isMusicMessage(message)) {
|
||||
message.id = cursor.intValue(1);
|
||||
message.dialog_id = uid;
|
||||
arrayList.add(0, new MessageObject(mess age, null, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
cursor.dispose();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.musicDidLoaded, uid, arrayList);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -1,519 +0,0 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
|
||||
package com.b44t.messenger.query;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.b44t.messenger.NotificationCenter;
|
||||
import com.b44t.messenger.TLRPC;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class StickersQuery {
|
||||
|
||||
private static int loadHash;
|
||||
private static int loadDate;
|
||||
private static ArrayList<TLRPC.TL_messages_stickerSet> stickerSets = new ArrayList<>();
|
||||
private static HashMap<Long, TLRPC.TL_messages_stickerSet> stickerSetsById = new HashMap<>();
|
||||
private static HashMap<String, TLRPC.TL_messages_stickerSet> stickerSetsByName = new HashMap<>();
|
||||
private static HashMap<Long, String> stickersByEmoji = new HashMap<>();
|
||||
private static HashMap<Long, TLRPC.Document> stickersById = new HashMap<>();
|
||||
private static HashMap<String, ArrayList<TLRPC.Document>> allStickers = new HashMap<>();
|
||||
|
||||
private static boolean loadingStickers;
|
||||
private static boolean stickersLoaded;
|
||||
|
||||
public static void cleanup() {
|
||||
loadHash = 0;
|
||||
loadDate = 0;
|
||||
allStickers.clear();
|
||||
stickerSets.clear();
|
||||
stickersByEmoji.clear();
|
||||
stickerSetsById.clear();
|
||||
stickerSetsByName.clear();
|
||||
loadingStickers = false;
|
||||
stickersLoaded = false;
|
||||
}
|
||||
|
||||
public static void checkStickers() {
|
||||
if (!loadingStickers && (!stickersLoaded || Math.abs(System.currentTimeMillis() / 1000 - loadDate) >= 60 * 60)) {
|
||||
loadStickers(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public static boolean isLoadingStickers() {
|
||||
return loadingStickers;
|
||||
}
|
||||
*/
|
||||
|
||||
public static TLRPC.Document getStickerById(long id) {
|
||||
TLRPC.Document document = stickersById.get(id);
|
||||
if (document != null) {
|
||||
long setId = getStickerSetId(document);
|
||||
TLRPC.TL_messages_stickerSet stickerSet = stickerSetsById.get(setId);
|
||||
if (stickerSet != null && stickerSet.set.disabled) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return document;
|
||||
}
|
||||
|
||||
public static TLRPC.TL_messages_stickerSet getStickerSetByName(String name) {
|
||||
return stickerSetsByName.get(name);
|
||||
}
|
||||
|
||||
public static TLRPC.TL_messages_stickerSet getStickerSetById(Long id) {
|
||||
return stickerSetsById.get(id);
|
||||
}
|
||||
|
||||
public static HashMap<String, ArrayList<TLRPC.Document>> getAllStickers() {
|
||||
return allStickers;
|
||||
}
|
||||
|
||||
public static ArrayList<TLRPC.TL_messages_stickerSet> getStickerSets() {
|
||||
return stickerSets;
|
||||
}
|
||||
|
||||
public static boolean isStickerPackInstalled(long id) {
|
||||
return stickerSetsById.containsKey(id);
|
||||
}
|
||||
|
||||
public static boolean isStickerPackInstalled(String name) {
|
||||
return stickerSetsByName.containsKey(name);
|
||||
}
|
||||
|
||||
public static String getEmojiForSticker(long id) {
|
||||
String value = stickersByEmoji.get(id);
|
||||
return value != null ? value : "";
|
||||
}
|
||||
|
||||
/*
|
||||
public static void reorderStickers(final ArrayList<Long> order) {
|
||||
Collections.sort(stickerSets, new Comparator<TLRPC.TL_messages_stickerSet>() {
|
||||
@Override
|
||||
public int compare(TLRPC.TL_messages_stickerSet lhs, TLRPC.TL_messages_stickerSet rhs) {
|
||||
int index1 = order.indexOf(lhs.set.id);
|
||||
int index2 = order.indexOf(rhs.set.id);
|
||||
if (index1 > index2) {
|
||||
return 1;
|
||||
} else if (index1 < index2) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
loadHash = calcStickersHash(stickerSets);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.stickersDidLoaded);
|
||||
StickersQuery.loadStickers(false, true);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
public static void calcNewHash() {
|
||||
loadHash = calcStickersHash(stickerSets);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
public static void addNewStickerSet(final TLRPC.TL_messages_stickerSet set) {
|
||||
if (stickerSetsById.containsKey(set.set.id) || stickerSetsByName.containsKey(set.set.short_name)) {
|
||||
return;
|
||||
}
|
||||
stickerSets.add(0, set);
|
||||
stickerSetsById.put(set.set.id, set);
|
||||
stickerSetsByName.put(set.set.short_name, set);
|
||||
for (int a = 0; a < set.documents.size(); a++) {
|
||||
TLRPC.Document document = set.documents.get(a);
|
||||
stickersById.put(document.id, document);
|
||||
}
|
||||
for (int a = 0; a < set.packs.size(); a++) {
|
||||
TLRPC.TL_stickerPack stickerPack = set.packs.get(a);
|
||||
stickerPack.emoticon = stickerPack.emoticon.replace("\uFE0F", "");
|
||||
ArrayList<TLRPC.Document> arrayList = allStickers.get(stickerPack.emoticon);
|
||||
if (arrayList == null) {
|
||||
arrayList = new ArrayList<>();
|
||||
allStickers.put(stickerPack.emoticon, arrayList);
|
||||
}
|
||||
for (int c = 0; c < stickerPack.documents.size(); c++) {
|
||||
Long id = stickerPack.documents.get(c);
|
||||
if (!stickersByEmoji.containsKey(id)) {
|
||||
stickersByEmoji.put(id, stickerPack.emoticon);
|
||||
}
|
||||
TLRPC.Document sticker = stickersById.get(id);
|
||||
if (sticker != null) {
|
||||
arrayList.add(sticker);
|
||||
}
|
||||
}
|
||||
}
|
||||
loadHash = calcStickersHash(stickerSets);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.stickersDidLoaded);
|
||||
StickersQuery.loadStickers(false, true);
|
||||
}
|
||||
*/
|
||||
|
||||
public static void loadStickers(boolean cache, boolean force) {
|
||||
if (loadingStickers) {
|
||||
return;
|
||||
}
|
||||
loadingStickers = true;
|
||||
if (cache) {
|
||||
/*
|
||||
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ArrayList<TLRPC.TL_messages_stickerSet> newStickerArray = null;
|
||||
int date = 0;
|
||||
int hash = 0;
|
||||
SQLiteCursor cursor = null;
|
||||
try {
|
||||
cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT data, date, hash FROM stickers_v2 WHERE 1");
|
||||
if (cursor.next()) {
|
||||
NativeByteBuffer data = cursor.byteBufferValue(0);
|
||||
if (data != null) {
|
||||
newStickerArray = new ArrayList<>();
|
||||
int count = data.readInt32(false);
|
||||
for (int a = 0; a < count; a++) {
|
||||
TLRPC.TL_messages_stickerSet stickerSet = TLRPC.TL_messages_stickerSet.TLdeserialize(data, data.readInt32(false), false);
|
||||
newStickerArray.add(stickerSet);
|
||||
}
|
||||
data.reuse();
|
||||
}
|
||||
date = cursor.intValue(1);
|
||||
hash = calcStickersHash(newStickerArray);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
FileLog.e("messenger", e);
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.dispose();
|
||||
}
|
||||
}
|
||||
processLoadedStickers(newStickerArray, true, date, hash);
|
||||
}
|
||||
});
|
||||
*/
|
||||
} else {
|
||||
/*final TLRPC.TL_messages_getAllStickers req = new TLRPC.TL_messages_getAllStickers();
|
||||
req.hash = force ? 0 : loadHash;
|
||||
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(final TLObject response, final TLRPC.TL_error error) {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (response instanceof TLRPC.TL_messages_allStickers) {
|
||||
final HashMap<Long, TLRPC.TL_messages_stickerSet> newStickerSets = new HashMap<>();
|
||||
final ArrayList<TLRPC.TL_messages_stickerSet> newStickerArray = new ArrayList<>();
|
||||
final TLRPC.TL_messages_allStickers res = (TLRPC.TL_messages_allStickers) response;
|
||||
|
||||
for (int a = 0; a < res.sets.size(); a++) {
|
||||
final TLRPC.StickerSet stickerSet = res.sets.get(a);
|
||||
|
||||
TLRPC.TL_messages_stickerSet oldSet = stickerSetsById.get(stickerSet.id);
|
||||
if (oldSet != null && oldSet.set.hash == stickerSet.hash) {
|
||||
oldSet.set.disabled = stickerSet.disabled;
|
||||
oldSet.set.installed = stickerSet.installed;
|
||||
oldSet.set.official = stickerSet.official;
|
||||
newStickerSets.put(oldSet.set.id, oldSet);
|
||||
newStickerArray.add(oldSet);
|
||||
|
||||
if (newStickerSets.size() == res.sets.size()) {
|
||||
processLoadedStickers(newStickerArray, false, (int) (System.currentTimeMillis() / 1000), res.hash);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
newStickerArray.add(null);
|
||||
final int index = a;
|
||||
|
||||
TLRPC.TL_messages_getStickerSet req = new TLRPC.TL_messages_getStickerSet();
|
||||
req.stickerset = new TLRPC.TL_inputStickerSetID();
|
||||
req.stickerset.id = stickerSet.id;
|
||||
req.stickerset.access_hash = stickerSet.access_hash;
|
||||
|
||||
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(final TLObject response, final TLRPC.TL_error error) {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
TLRPC.TL_messages_stickerSet res1 = (TLRPC.TL_messages_stickerSet) response;
|
||||
newStickerArray.set(index, res1);
|
||||
newStickerSets.put(stickerSet.id, res1);
|
||||
if (newStickerSets.size() == res.sets.size()) {
|
||||
processLoadedStickers(newStickerArray, false, (int) (System.currentTimeMillis() / 1000), res.hash);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
processLoadedStickers(null, false, (int) (System.currentTimeMillis() / 1000), req.hash);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});*/
|
||||
}
|
||||
}
|
||||
|
||||
private static void putStickersToCache(ArrayList<TLRPC.TL_messages_stickerSet> stickers, final int date, final int hash) {
|
||||
final ArrayList<TLRPC.TL_messages_stickerSet> stickersFinal = stickers != null ? new ArrayList<>(stickers) : null;
|
||||
/*
|
||||
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (stickersFinal != null) {
|
||||
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO stickers_v2 VALUES(?, ?, ?, ?)");
|
||||
state.requery();
|
||||
int size = 4;
|
||||
for (int a = 0; a < stickersFinal.size(); a++) {
|
||||
size += stickersFinal.get(a).getObjectSize();
|
||||
}
|
||||
NativeByteBuffer data = new NativeByteBuffer(size);
|
||||
data.writeInt32(stickersFinal.size());
|
||||
for (int a = 0; a < stickersFinal.size(); a++) {
|
||||
stickersFinal.get(a).serializeToStream(data);
|
||||
}
|
||||
state.bindInteger(1, 1);
|
||||
state.bindByteBuffer(2, data);
|
||||
state.bindInteger(3, date);
|
||||
state.bindInteger(4, hash);
|
||||
state.step();
|
||||
data.reuse();
|
||||
state.dispose();
|
||||
} else {
|
||||
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("UPDATE stickers_v2 SET date = ?");
|
||||
state.requery();
|
||||
state.bindInteger(1, date);
|
||||
state.step();
|
||||
state.dispose();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
public static String getStickerSetName(long setId) {
|
||||
TLRPC.TL_messages_stickerSet stickerSet = stickerSetsById.get(setId);
|
||||
return stickerSet != null ? stickerSet.set.short_name : null;
|
||||
}
|
||||
*/
|
||||
|
||||
public static long getStickerSetId(TLRPC.Document document) {
|
||||
for (int a = 0; a < document.attributes.size(); a++) {
|
||||
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
|
||||
if (attribute instanceof TLRPC.TL_documentAttributeSticker) {
|
||||
if (attribute.stickerset instanceof TLRPC.TL_inputStickerSetID) {
|
||||
return attribute.stickerset.id;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static int calcStickersHash(ArrayList<TLRPC.TL_messages_stickerSet> sets) {
|
||||
long acc = 0;
|
||||
for (int a = 0; a < sets.size(); a++) {
|
||||
TLRPC.StickerSet set = sets.get(a).set;
|
||||
if (set.disabled) {
|
||||
continue;
|
||||
}
|
||||
acc = ((acc * 20261) + 0x80000000L + set.hash) % 0x80000000L;
|
||||
}
|
||||
return (int) acc;
|
||||
}
|
||||
|
||||
/*
|
||||
private static void processLoadedStickers(final ArrayList<TLRPC.TL_messages_stickerSet> res, final boolean cache, final int date, final int hash) {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
loadingStickers = false;
|
||||
stickersLoaded = true;
|
||||
}
|
||||
});
|
||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (cache && (res == null || Math.abs(System.currentTimeMillis() / 1000 - date) >= 60 * 60) || !cache && res == null && hash == 0) {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (res != null && hash != 0) {
|
||||
loadHash = hash;
|
||||
}
|
||||
loadStickers(false, false);
|
||||
}
|
||||
}, res == null && !cache ? 1000 : 0);
|
||||
if (res == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (res != null) {
|
||||
try {
|
||||
final ArrayList<TLRPC.TL_messages_stickerSet> stickerSetsNew = new ArrayList<>();
|
||||
final HashMap<Long, TLRPC.TL_messages_stickerSet> stickerSetsByIdNew = new HashMap<>();
|
||||
final HashMap<String, TLRPC.TL_messages_stickerSet> stickerSetsByNameNew = new HashMap<>();
|
||||
final HashMap<Long, String> stickersByEmojiNew = new HashMap<>();
|
||||
final HashMap<Long, TLRPC.Document> stickersByIdNew = new HashMap<>();
|
||||
final HashMap<String, ArrayList<TLRPC.Document>> allStickersNew = new HashMap<>();
|
||||
|
||||
for (int a = 0; a < res.size(); a++) {
|
||||
TLRPC.TL_messages_stickerSet stickerSet = res.get(a);
|
||||
if (stickerSet == null) {
|
||||
continue;
|
||||
}
|
||||
stickerSetsNew.add(stickerSet);
|
||||
stickerSetsByIdNew.put(stickerSet.set.id, stickerSet);
|
||||
stickerSetsByNameNew.put(stickerSet.set.short_name, stickerSet);
|
||||
|
||||
for (int b = 0; b < stickerSet.documents.size(); b++) {
|
||||
TLRPC.Document document = stickerSet.documents.get(b);
|
||||
if (document == null || document instanceof TLRPC.TL_documentEmpty) {
|
||||
continue;
|
||||
}
|
||||
stickersByIdNew.put(document.id, document);
|
||||
}
|
||||
if (!stickerSet.set.disabled) {
|
||||
for (int b = 0; b < stickerSet.packs.size(); b++) {
|
||||
TLRPC.TL_stickerPack stickerPack = stickerSet.packs.get(b);
|
||||
if (stickerPack == null || stickerPack.emoticon == null) {
|
||||
continue;
|
||||
}
|
||||
stickerPack.emoticon = stickerPack.emoticon.replace("\uFE0F", "");
|
||||
ArrayList<TLRPC.Document> arrayList = allStickersNew.get(stickerPack.emoticon);
|
||||
if (arrayList == null) {
|
||||
arrayList = new ArrayList<>();
|
||||
allStickersNew.put(stickerPack.emoticon, arrayList);
|
||||
}
|
||||
for (int c = 0; c < stickerPack.documents.size(); c++) {
|
||||
Long id = stickerPack.documents.get(c);
|
||||
if (!stickersByEmojiNew.containsKey(id)) {
|
||||
stickersByEmojiNew.put(id, stickerPack.emoticon);
|
||||
}
|
||||
TLRPC.Document sticker = stickersByIdNew.get(id);
|
||||
if (sticker != null) {
|
||||
arrayList.add(sticker);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!cache) {
|
||||
putStickersToCache(stickerSetsNew, date, hash);
|
||||
}
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
stickersById = stickersByIdNew;
|
||||
stickerSetsById = stickerSetsByIdNew;
|
||||
stickerSetsByName = stickerSetsByNameNew;
|
||||
stickerSets = stickerSetsNew;
|
||||
allStickers = allStickersNew;
|
||||
stickersByEmoji = stickersByEmojiNew;
|
||||
loadHash = hash;
|
||||
loadDate = date;
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.stickersDidLoaded);
|
||||
}
|
||||
});
|
||||
} catch (Throwable e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
} else if (!cache) {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
loadDate = date;
|
||||
}
|
||||
});
|
||||
putStickersToCache(null, date, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
public static void removeStickersSet(final Context context, TLRPC.StickerSet stickerSet, int hide) {
|
||||
TLRPC.TL_inputStickerSetID stickerSetID = new TLRPC.TL_inputStickerSetID();
|
||||
stickerSetID.access_hash = stickerSet.access_hash;
|
||||
stickerSetID.id = stickerSet.id;
|
||||
if (hide != 0) {
|
||||
stickerSet.disabled = hide == 1;
|
||||
for (int a = 0; a < stickerSets.size(); a++) {
|
||||
TLRPC.TL_messages_stickerSet set = stickerSets.get(a);
|
||||
if (set.set.id == stickerSet.id) {
|
||||
stickerSets.remove(a);
|
||||
if (hide == 2) {
|
||||
stickerSets.add(0, set);
|
||||
} else {
|
||||
for (int b = stickerSets.size() - 1; b >= 0; b--) {
|
||||
if (stickerSets.get(b).set.disabled) {
|
||||
continue;
|
||||
}
|
||||
stickerSets.add(b + 1, set);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
loadHash = calcStickersHash(stickerSets);
|
||||
putStickersToCache(stickerSets, loadDate, loadHash);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.stickersDidLoaded);
|
||||
/*TLRPC.TL_messages_installStickerSet req = new TLRPC.TL_messages_installStickerSet();
|
||||
req.stickerset = stickerSetID;
|
||||
req.disabled = hide == 1;
|
||||
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, final TLRPC.TL_error error) {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
loadStickers(false, false);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
});*/
|
||||
} else {
|
||||
/*TLRPC.TL_messages_uninstallStickerSet req = new TLRPC.TL_messages_uninstallStickerSet();
|
||||
req.stickerset = stickerSetID;
|
||||
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, final TLRPC.TL_error error) {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (error == null) {
|
||||
Toast.makeText(context, LocaleController.getString("StickersRemoved", R.string.StickersRemoved), Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(context, LocaleController.getString("ErrorOccurred", R.string.ErrorOccurred), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
loadStickers(false, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
});*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,592 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.b44t.messenger.support.util;
|
||||
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.annotation.WorkerThread;
|
||||
import android.util.Log;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
/**
|
||||
* A utility class that supports asynchronous content loading.
|
||||
* <p>
|
||||
* It can be used to load Cursor data in chunks without querying the Cursor on the UI Thread while
|
||||
* keeping UI and cache synchronous for better user experience.
|
||||
* <p>
|
||||
* It loads the data on a background thread and keeps only a limited number of fixed sized
|
||||
* chunks in memory at all times.
|
||||
* <p>
|
||||
* {@link AsyncListUtil} queries the currently visible range through {@link ViewCallback},
|
||||
* loads the required data items in the background through {@link DataCallback}, and notifies a
|
||||
* {@link ViewCallback} when the data is loaded. It may load some extra items for smoother
|
||||
* scrolling.
|
||||
* <p>
|
||||
* Note that this class uses a single thread to load the data, so it suitable to load data from
|
||||
* secondary storage such as disk, but not from network.
|
||||
* <p>
|
||||
* This class is designed to work with {@link android.support.v7.widget.RecyclerView}, but it does
|
||||
* not depend on it and can be used with other list views.
|
||||
*
|
||||
*/
|
||||
public class AsyncListUtil<T> {
|
||||
private static final String TAG = "AsyncListUtil";
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
final Class<T> mTClass;
|
||||
final int mTileSize;
|
||||
final DataCallback<T> mDataCallback;
|
||||
final ViewCallback mViewCallback;
|
||||
|
||||
final TileList<T> mTileList;
|
||||
|
||||
final ThreadUtil.MainThreadCallback<T> mMainThreadProxy;
|
||||
final ThreadUtil.BackgroundCallback<T> mBackgroundProxy;
|
||||
|
||||
final int[] mTmpRange = new int[2];
|
||||
final int[] mPrevRange = new int[2];
|
||||
final int[] mTmpRangeExtended = new int[2];
|
||||
|
||||
private boolean mAllowScrollHints;
|
||||
private int mScrollHint = ViewCallback.HINT_SCROLL_NONE;
|
||||
|
||||
private int mItemCount = 0;
|
||||
|
||||
int mDisplayedGeneration = 0;
|
||||
int mRequestedGeneration = mDisplayedGeneration;
|
||||
|
||||
final private SparseIntArray mMissingPositions = new SparseIntArray();
|
||||
|
||||
private void log(String s, Object... args) {
|
||||
Log.d(TAG, "[MAIN] " + String.format(s, args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an AsyncListUtil.
|
||||
*
|
||||
* @param klass Class of the data item.
|
||||
* @param tileSize Number of item per chunk loaded at once.
|
||||
* @param dataCallback Data access callback.
|
||||
* @param viewCallback Callback for querying visible item range and update notifications.
|
||||
*/
|
||||
public AsyncListUtil(Class<T> klass, int tileSize, DataCallback<T> dataCallback,
|
||||
ViewCallback viewCallback) {
|
||||
mTClass = klass;
|
||||
mTileSize = tileSize;
|
||||
mDataCallback = dataCallback;
|
||||
mViewCallback = viewCallback;
|
||||
|
||||
mTileList = new TileList<T>(mTileSize);
|
||||
|
||||
ThreadUtil<T> threadUtil = new MessageThreadUtil<T>();
|
||||
mMainThreadProxy = threadUtil.getMainThreadProxy(mMainThreadCallback);
|
||||
mBackgroundProxy = threadUtil.getBackgroundProxy(mBackgroundCallback);
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
private boolean isRefreshPending() {
|
||||
return mRequestedGeneration != mDisplayedGeneration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the currently visible item range.
|
||||
*
|
||||
* <p>
|
||||
* Identifies the data items that have not been loaded yet and initiates loading them in the
|
||||
* background. Should be called from the view's scroll listener (such as
|
||||
* {@link android.support.v7.widget.RecyclerView.OnScrollListener#onScrolled}).
|
||||
*/
|
||||
public void onRangeChanged() {
|
||||
if (isRefreshPending()) {
|
||||
return; // Will update range will the refresh result arrives.
|
||||
}
|
||||
updateRange();
|
||||
mAllowScrollHints = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces reloading the data.
|
||||
* <p>
|
||||
* Discards all the cached data and reloads all required data items for the currently visible
|
||||
* range. To be called when the data item count and/or contents has changed.
|
||||
*/
|
||||
public void refresh() {
|
||||
mMissingPositions.clear();
|
||||
mBackgroundProxy.refresh(++mRequestedGeneration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data item at the given position or <code>null</code> if it has not been loaded
|
||||
* yet.
|
||||
*
|
||||
* <p>
|
||||
* If this method has been called for a specific position and returned <code>null</code>, then
|
||||
* {@link ViewCallback#onItemLoaded(int)} will be called when it finally loads. Note that if
|
||||
* this position stays outside of the cached item range (as defined by
|
||||
* {@link ViewCallback#extendRangeInto} method), then the callback will never be called for
|
||||
* this position.
|
||||
*
|
||||
* @param position Item position.
|
||||
*
|
||||
* @return The data item at the given position or <code>null</code> if it has not been loaded
|
||||
* yet.
|
||||
*/
|
||||
public T getItem(int position) {
|
||||
if (position < 0 || position >= mItemCount) {
|
||||
throw new IndexOutOfBoundsException(position + " is not within 0 and " + mItemCount);
|
||||
}
|
||||
T item = mTileList.getItemAt(position);
|
||||
if (item == null && !isRefreshPending()) {
|
||||
mMissingPositions.put(position, 0);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of items in the data set.
|
||||
*
|
||||
* <p>
|
||||
* This is the number returned by a recent call to
|
||||
* {@link DataCallback#refreshData()}.
|
||||
*
|
||||
* @return Number of items.
|
||||
*/
|
||||
public int getItemCount() {
|
||||
return mItemCount;
|
||||
}
|
||||
|
||||
private void updateRange() {
|
||||
mViewCallback.getItemRangeInto(mTmpRange);
|
||||
if (mTmpRange[0] > mTmpRange[1] || mTmpRange[0] < 0) {
|
||||
return;
|
||||
}
|
||||
if (mTmpRange[1] >= mItemCount) {
|
||||
// Invalid range may arrive soon after the refresh.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mAllowScrollHints) {
|
||||
mScrollHint = ViewCallback.HINT_SCROLL_NONE;
|
||||
} else if (mTmpRange[0] > mPrevRange[1] || mPrevRange[0] > mTmpRange[1]) {
|
||||
// Ranges do not intersect, long leap not a scroll.
|
||||
mScrollHint = ViewCallback.HINT_SCROLL_NONE;
|
||||
} else if (mTmpRange[0] < mPrevRange[0]) {
|
||||
mScrollHint = ViewCallback.HINT_SCROLL_DESC;
|
||||
} else if (mTmpRange[0] > mPrevRange[0]) {
|
||||
mScrollHint = ViewCallback.HINT_SCROLL_ASC;
|
||||
}
|
||||
|
||||
mPrevRange[0] = mTmpRange[0];
|
||||
mPrevRange[1] = mTmpRange[1];
|
||||
|
||||
mViewCallback.extendRangeInto(mTmpRange, mTmpRangeExtended, mScrollHint);
|
||||
mTmpRangeExtended[0] = Math.min(mTmpRange[0], Math.max(mTmpRangeExtended[0], 0));
|
||||
mTmpRangeExtended[1] =
|
||||
Math.max(mTmpRange[1], Math.min(mTmpRangeExtended[1], mItemCount - 1));
|
||||
|
||||
mBackgroundProxy.updateRange(mTmpRange[0], mTmpRange[1],
|
||||
mTmpRangeExtended[0], mTmpRangeExtended[1], mScrollHint);
|
||||
}
|
||||
|
||||
private final ThreadUtil.MainThreadCallback<T>
|
||||
mMainThreadCallback = new ThreadUtil.MainThreadCallback<T>() {
|
||||
@Override
|
||||
public void updateItemCount(int generation, int itemCount) {
|
||||
if (DEBUG) {
|
||||
log("updateItemCount: size=%d, gen #%d", itemCount, generation);
|
||||
}
|
||||
if (!isRequestedGeneration(generation)) {
|
||||
return;
|
||||
}
|
||||
mItemCount = itemCount;
|
||||
mViewCallback.onDataRefresh();
|
||||
mDisplayedGeneration = mRequestedGeneration;
|
||||
recycleAllTiles();
|
||||
|
||||
mAllowScrollHints = false; // Will be set to true after a first real scroll.
|
||||
// There will be no scroll event if the size change does not affect the current range.
|
||||
updateRange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTile(int generation, TileList.Tile<T> tile) {
|
||||
if (!isRequestedGeneration(generation)) {
|
||||
if (DEBUG) {
|
||||
log("recycling an older generation tile @%d", tile.mStartPosition);
|
||||
}
|
||||
mBackgroundProxy.recycleTile(tile);
|
||||
return;
|
||||
}
|
||||
TileList.Tile<T> duplicate = mTileList.addOrReplace(tile);
|
||||
if (duplicate != null) {
|
||||
Log.e(TAG, "duplicate tile @" + duplicate.mStartPosition);
|
||||
mBackgroundProxy.recycleTile(duplicate);
|
||||
}
|
||||
if (DEBUG) {
|
||||
log("gen #%d, added tile @%d, total tiles: %d",
|
||||
generation, tile.mStartPosition, mTileList.size());
|
||||
}
|
||||
int endPosition = tile.mStartPosition + tile.mItemCount;
|
||||
int index = 0;
|
||||
while (index < mMissingPositions.size()) {
|
||||
final int position = mMissingPositions.keyAt(index);
|
||||
if (tile.mStartPosition <= position && position < endPosition) {
|
||||
mMissingPositions.removeAt(index);
|
||||
mViewCallback.onItemLoaded(position);
|
||||
} else {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTile(int generation, int position) {
|
||||
if (!isRequestedGeneration(generation)) {
|
||||
return;
|
||||
}
|
||||
TileList.Tile<T> tile = mTileList.removeAtPos(position);
|
||||
if (tile == null) {
|
||||
Log.e(TAG, "tile not found @" + position);
|
||||
return;
|
||||
}
|
||||
if (DEBUG) {
|
||||
log("recycling tile @%d, total tiles: %d", tile.mStartPosition, mTileList.size());
|
||||
}
|
||||
mBackgroundProxy.recycleTile(tile);
|
||||
}
|
||||
|
||||
private void recycleAllTiles() {
|
||||
if (DEBUG) {
|
||||
log("recycling all %d tiles", mTileList.size());
|
||||
}
|
||||
for (int i = 0; i < mTileList.size(); i++) {
|
||||
mBackgroundProxy.recycleTile(mTileList.getAtIndex(i));
|
||||
}
|
||||
mTileList.clear();
|
||||
}
|
||||
|
||||
private boolean isRequestedGeneration(int generation) {
|
||||
return generation == mRequestedGeneration;
|
||||
}
|
||||
};
|
||||
|
||||
private final ThreadUtil.BackgroundCallback<T>
|
||||
mBackgroundCallback = new ThreadUtil.BackgroundCallback<T>() {
|
||||
|
||||
private TileList.Tile<T> mRecycledRoot;
|
||||
|
||||
final SparseBooleanArray mLoadedTiles = new SparseBooleanArray();
|
||||
|
||||
private int mGeneration;
|
||||
private int mItemCount;
|
||||
|
||||
private int mFirstRequiredTileStart;
|
||||
private int mLastRequiredTileStart;
|
||||
|
||||
@Override
|
||||
public void refresh(int generation) {
|
||||
mGeneration = generation;
|
||||
mLoadedTiles.clear();
|
||||
mItemCount = mDataCallback.refreshData();
|
||||
mMainThreadProxy.updateItemCount(mGeneration, mItemCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRange(int rangeStart, int rangeEnd, int extRangeStart, int extRangeEnd,
|
||||
int scrollHint) {
|
||||
if (DEBUG) {
|
||||
log("updateRange: %d..%d extended to %d..%d, scroll hint: %d",
|
||||
rangeStart, rangeEnd, extRangeStart, extRangeEnd, scrollHint);
|
||||
}
|
||||
|
||||
if (rangeStart > rangeEnd) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int firstVisibleTileStart = getTileStart(rangeStart);
|
||||
final int lastVisibleTileStart = getTileStart(rangeEnd);
|
||||
|
||||
mFirstRequiredTileStart = getTileStart(extRangeStart);
|
||||
mLastRequiredTileStart = getTileStart(extRangeEnd);
|
||||
if (DEBUG) {
|
||||
log("requesting tile range: %d..%d",
|
||||
mFirstRequiredTileStart, mLastRequiredTileStart);
|
||||
}
|
||||
|
||||
// All pending tile requests are removed by ThreadUtil at this point.
|
||||
// Re-request all required tiles in the most optimal order.
|
||||
if (scrollHint == ViewCallback.HINT_SCROLL_DESC) {
|
||||
requestTiles(mFirstRequiredTileStart, lastVisibleTileStart, scrollHint, true);
|
||||
requestTiles(lastVisibleTileStart + mTileSize, mLastRequiredTileStart, scrollHint,
|
||||
false);
|
||||
} else {
|
||||
requestTiles(firstVisibleTileStart, mLastRequiredTileStart, scrollHint, false);
|
||||
requestTiles(mFirstRequiredTileStart, firstVisibleTileStart - mTileSize, scrollHint,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
private int getTileStart(int position) {
|
||||
return position - position % mTileSize;
|
||||
}
|
||||
|
||||
private void requestTiles(int firstTileStart, int lastTileStart, int scrollHint,
|
||||
boolean backwards) {
|
||||
for (int i = firstTileStart; i <= lastTileStart; i += mTileSize) {
|
||||
int tileStart = backwards ? (lastTileStart + firstTileStart - i) : i;
|
||||
if (DEBUG) {
|
||||
log("requesting tile @%d", tileStart);
|
||||
}
|
||||
mBackgroundProxy.loadTile(tileStart, scrollHint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadTile(int position, int scrollHint) {
|
||||
if (isTileLoaded(position)) {
|
||||
if (DEBUG) {
|
||||
log("already loaded tile @%d", position);
|
||||
}
|
||||
return;
|
||||
}
|
||||
TileList.Tile<T> tile = acquireTile();
|
||||
tile.mStartPosition = position;
|
||||
tile.mItemCount = Math.min(mTileSize, mItemCount - tile.mStartPosition);
|
||||
mDataCallback.fillData(tile.mItems, tile.mStartPosition, tile.mItemCount);
|
||||
flushTileCache(scrollHint);
|
||||
addTile(tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recycleTile(TileList.Tile<T> tile) {
|
||||
if (DEBUG) {
|
||||
log("recycling tile @%d", tile.mStartPosition);
|
||||
}
|
||||
mDataCallback.recycleData(tile.mItems, tile.mItemCount);
|
||||
|
||||
tile.mNext = mRecycledRoot;
|
||||
mRecycledRoot = tile;
|
||||
}
|
||||
|
||||
private TileList.Tile<T> acquireTile() {
|
||||
if (mRecycledRoot != null) {
|
||||
TileList.Tile<T> result = mRecycledRoot;
|
||||
mRecycledRoot = mRecycledRoot.mNext;
|
||||
return result;
|
||||
}
|
||||
return new TileList.Tile<T>(mTClass, mTileSize);
|
||||
}
|
||||
|
||||
private boolean isTileLoaded(int position) {
|
||||
return mLoadedTiles.get(position);
|
||||
}
|
||||
|
||||
private void addTile(TileList.Tile<T> tile) {
|
||||
mLoadedTiles.put(tile.mStartPosition, true);
|
||||
mMainThreadProxy.addTile(mGeneration, tile);
|
||||
if (DEBUG) {
|
||||
log("loaded tile @%d, total tiles: %d", tile.mStartPosition, mLoadedTiles.size());
|
||||
}
|
||||
}
|
||||
|
||||
private void removeTile(int position) {
|
||||
mLoadedTiles.delete(position);
|
||||
mMainThreadProxy.removeTile(mGeneration, position);
|
||||
if (DEBUG) {
|
||||
log("flushed tile @%d, total tiles: %s", position, mLoadedTiles.size());
|
||||
}
|
||||
}
|
||||
|
||||
private void flushTileCache(int scrollHint) {
|
||||
final int cacheSizeLimit = mDataCallback.getMaxCachedTiles();
|
||||
while (mLoadedTiles.size() >= cacheSizeLimit) {
|
||||
int firstLoadedTileStart = mLoadedTiles.keyAt(0);
|
||||
int lastLoadedTileStart = mLoadedTiles.keyAt(mLoadedTiles.size() - 1);
|
||||
int startMargin = mFirstRequiredTileStart - firstLoadedTileStart;
|
||||
int endMargin = lastLoadedTileStart - mLastRequiredTileStart;
|
||||
if (startMargin > 0 && (startMargin >= endMargin ||
|
||||
(scrollHint == ViewCallback.HINT_SCROLL_ASC))) {
|
||||
removeTile(firstLoadedTileStart);
|
||||
} else if (endMargin > 0 && (startMargin < endMargin ||
|
||||
(scrollHint == ViewCallback.HINT_SCROLL_DESC))){
|
||||
removeTile(lastLoadedTileStart);
|
||||
} else {
|
||||
// Could not flush on either side, bail out.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void log(String s, Object... args) {
|
||||
Log.d(TAG, "[BKGR] " + String.format(s, args));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The callback that provides data access for {@link AsyncListUtil}.
|
||||
*
|
||||
* <p>
|
||||
* All methods are called on the background thread.
|
||||
*/
|
||||
public static abstract class DataCallback<T> {
|
||||
|
||||
/**
|
||||
* Refresh the data set and return the new data item count.
|
||||
*
|
||||
* <p>
|
||||
* If the data is being accessed through {@link android.database.Cursor} this is where
|
||||
* the new cursor should be created.
|
||||
*
|
||||
* @return Data item count.
|
||||
*/
|
||||
@WorkerThread
|
||||
public abstract int refreshData();
|
||||
|
||||
/**
|
||||
* Fill the given tile.
|
||||
*
|
||||
* <p>
|
||||
* The provided tile might be a recycled tile, in which case it will already have objects.
|
||||
* It is suggested to re-use these objects if possible in your use case.
|
||||
*
|
||||
* @param startPosition The start position in the list.
|
||||
* @param itemCount The data item count.
|
||||
* @param data The data item array to fill into. Should not be accessed beyond
|
||||
* <code>itemCount</code>.
|
||||
*/
|
||||
@WorkerThread
|
||||
public abstract void fillData(T[] data, int startPosition, int itemCount);
|
||||
|
||||
/**
|
||||
* Recycle the objects created in {@link #fillData} if necessary.
|
||||
*
|
||||
*
|
||||
* @param data Array of data items. Should not be accessed beyond <code>itemCount</code>.
|
||||
* @param itemCount The data item count.
|
||||
*/
|
||||
@WorkerThread
|
||||
public void recycleData(T[] data, int itemCount) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns tile cache size limit (in tiles).
|
||||
*
|
||||
* <p>
|
||||
* The actual number of cached tiles will be the maximum of this value and the number of
|
||||
* tiles that is required to cover the range returned by
|
||||
* {@link ViewCallback#extendRangeInto(int[], int[], int)}.
|
||||
* <p>
|
||||
* For example, if this method returns 10, and the most
|
||||
* recent call to {@link ViewCallback#extendRangeInto(int[], int[], int)} returned
|
||||
* {100, 179}, and the tile size is 5, then the maximum number of cached tiles will be 16.
|
||||
* <p>
|
||||
* However, if the tile size is 20, then the maximum number of cached tiles will be 10.
|
||||
* <p>
|
||||
* The default implementation returns 10.
|
||||
*
|
||||
* @return Maximum cache size.
|
||||
*/
|
||||
@WorkerThread
|
||||
public int getMaxCachedTiles() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The callback that links {@link AsyncListUtil} with the list view.
|
||||
*
|
||||
* <p>
|
||||
* All methods are called on the main thread.
|
||||
*/
|
||||
public static abstract class ViewCallback {
|
||||
|
||||
/**
|
||||
* No scroll direction hint available.
|
||||
*/
|
||||
public static final int HINT_SCROLL_NONE = 0;
|
||||
|
||||
/**
|
||||
* Scrolling in descending order (from higher to lower positions in the order of the backing
|
||||
* storage).
|
||||
*/
|
||||
public static final int HINT_SCROLL_DESC = 1;
|
||||
|
||||
/**
|
||||
* Scrolling in ascending order (from lower to higher positions in the order of the backing
|
||||
* storage).
|
||||
*/
|
||||
public static final int HINT_SCROLL_ASC = 2;
|
||||
|
||||
/**
|
||||
* Compute the range of visible item positions.
|
||||
* <p>
|
||||
* outRange[0] is the position of the first visible item (in the order of the backing
|
||||
* storage).
|
||||
* <p>
|
||||
* outRange[1] is the position of the last visible item (in the order of the backing
|
||||
* storage).
|
||||
* <p>
|
||||
* Negative positions and positions greater or equal to {@link #getItemCount} are invalid.
|
||||
* If the returned range contains invalid positions it is ignored (no item will be loaded).
|
||||
*
|
||||
* @param outRange The visible item range.
|
||||
*/
|
||||
@UiThread
|
||||
public abstract void getItemRangeInto(int[] outRange);
|
||||
|
||||
/**
|
||||
* Compute a wider range of items that will be loaded for smoother scrolling.
|
||||
*
|
||||
* <p>
|
||||
* If there is no scroll hint, the default implementation extends the visible range by half
|
||||
* its length in both directions. If there is a scroll hint, the range is extended by
|
||||
* its full length in the scroll direction, and by half in the other direction.
|
||||
* <p>
|
||||
* For example, if <code>range</code> is <code>{100, 200}</code> and <code>scrollHint</code>
|
||||
* is {@link #HINT_SCROLL_ASC}, then <code>outRange</code> will be <code>{50, 300}</code>.
|
||||
* <p>
|
||||
* However, if <code>scrollHint</code> is {@link #HINT_SCROLL_NONE}, then
|
||||
* <code>outRange</code> will be <code>{50, 250}</code>
|
||||
*
|
||||
* @param range Visible item range.
|
||||
* @param outRange Extended range.
|
||||
* @param scrollHint The scroll direction hint.
|
||||
*/
|
||||
@UiThread
|
||||
public void extendRangeInto(int[] range, int[] outRange, int scrollHint) {
|
||||
final int fullRange = range[1] - range[0] + 1;
|
||||
final int halfRange = fullRange / 2;
|
||||
outRange[0] = range[0] - (scrollHint == HINT_SCROLL_DESC ? fullRange : halfRange);
|
||||
outRange[1] = range[1] + (scrollHint == HINT_SCROLL_ASC ? fullRange : halfRange);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entire data set has changed.
|
||||
*/
|
||||
@UiThread
|
||||
public abstract void onDataRefresh();
|
||||
|
||||
/**
|
||||
* Called when an item at the given position is loaded.
|
||||
* @param position Item position.
|
||||
*/
|
||||
@UiThread
|
||||
public abstract void onItemLoaded(int position);
|
||||
}
|
||||
}
|
||||
@@ -1,281 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.b44t.messenger.support.util;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.support.v4.content.ParallelExecutorCompat;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
class MessageThreadUtil<T> implements ThreadUtil<T> {
|
||||
|
||||
public MainThreadCallback<T> getMainThreadProxy(final MainThreadCallback<T> callback) {
|
||||
return new MainThreadCallback<T>() {
|
||||
final private MessageQueue mQueue = new MessageQueue();
|
||||
final private Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
private static final int UPDATE_ITEM_COUNT = 1;
|
||||
private static final int ADD_TILE = 2;
|
||||
private static final int REMOVE_TILE = 3;
|
||||
|
||||
@Override
|
||||
public void updateItemCount(int generation, int itemCount) {
|
||||
sendMessage(SyncQueueItem.obtainMessage(UPDATE_ITEM_COUNT, generation, itemCount));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTile(int generation, TileList.Tile<T> tile) {
|
||||
sendMessage(SyncQueueItem.obtainMessage(ADD_TILE, generation, tile));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTile(int generation, int position) {
|
||||
sendMessage(SyncQueueItem.obtainMessage(REMOVE_TILE, generation, position));
|
||||
}
|
||||
|
||||
private void sendMessage(SyncQueueItem msg) {
|
||||
mQueue.sendMessage(msg);
|
||||
mMainThreadHandler.post(mMainThreadRunnable);
|
||||
}
|
||||
|
||||
private Runnable mMainThreadRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SyncQueueItem msg = mQueue.next();
|
||||
while (msg != null) {
|
||||
switch (msg.what) {
|
||||
case UPDATE_ITEM_COUNT:
|
||||
callback.updateItemCount(msg.arg1, msg.arg2);
|
||||
break;
|
||||
case ADD_TILE:
|
||||
//noinspection unchecked
|
||||
callback.addTile(msg.arg1, (TileList.Tile<T>) msg.data);
|
||||
break;
|
||||
case REMOVE_TILE:
|
||||
callback.removeTile(msg.arg1, msg.arg2);
|
||||
break;
|
||||
default:
|
||||
Log.e("ThreadUtil", "Unsupported message, what=" + msg.what);
|
||||
}
|
||||
msg = mQueue.next();
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
public BackgroundCallback<T> getBackgroundProxy(final BackgroundCallback<T> callback) {
|
||||
return new BackgroundCallback<T>() {
|
||||
final private MessageQueue mQueue = new MessageQueue();
|
||||
final private Executor mExecutor = ParallelExecutorCompat.getParallelExecutor();
|
||||
AtomicBoolean mBackgroundRunning = new AtomicBoolean(false);
|
||||
|
||||
private static final int REFRESH = 1;
|
||||
private static final int UPDATE_RANGE = 2;
|
||||
private static final int LOAD_TILE = 3;
|
||||
private static final int RECYCLE_TILE = 4;
|
||||
|
||||
@Override
|
||||
public void refresh(int generation) {
|
||||
sendMessageAtFrontOfQueue(SyncQueueItem.obtainMessage(REFRESH, generation, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRange(int rangeStart, int rangeEnd,
|
||||
int extRangeStart, int extRangeEnd, int scrollHint) {
|
||||
sendMessageAtFrontOfQueue(SyncQueueItem.obtainMessage(UPDATE_RANGE,
|
||||
rangeStart, rangeEnd, extRangeStart, extRangeEnd, scrollHint, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadTile(int position, int scrollHint) {
|
||||
sendMessage(SyncQueueItem.obtainMessage(LOAD_TILE, position, scrollHint));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recycleTile(TileList.Tile<T> tile) {
|
||||
sendMessage(SyncQueueItem.obtainMessage(RECYCLE_TILE, 0, tile));
|
||||
}
|
||||
|
||||
private void sendMessage(SyncQueueItem msg) {
|
||||
mQueue.sendMessage(msg);
|
||||
maybeExecuteBackgroundRunnable();
|
||||
}
|
||||
|
||||
private void sendMessageAtFrontOfQueue(SyncQueueItem msg) {
|
||||
mQueue.sendMessageAtFrontOfQueue(msg);
|
||||
maybeExecuteBackgroundRunnable();
|
||||
}
|
||||
|
||||
private void maybeExecuteBackgroundRunnable() {
|
||||
if (mBackgroundRunning.compareAndSet(false, true)) {
|
||||
mExecutor.execute(mBackgroundRunnable);
|
||||
}
|
||||
}
|
||||
|
||||
private Runnable mBackgroundRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
SyncQueueItem msg = mQueue.next();
|
||||
if (msg == null) {
|
||||
break;
|
||||
}
|
||||
switch (msg.what) {
|
||||
case REFRESH:
|
||||
mQueue.removeMessages(REFRESH);
|
||||
callback.refresh(msg.arg1);
|
||||
break;
|
||||
case UPDATE_RANGE:
|
||||
mQueue.removeMessages(UPDATE_RANGE);
|
||||
mQueue.removeMessages(LOAD_TILE);
|
||||
callback.updateRange(
|
||||
msg.arg1, msg.arg2, msg.arg3, msg.arg4, msg.arg5);
|
||||
break;
|
||||
case LOAD_TILE:
|
||||
callback.loadTile(msg.arg1, msg.arg2);
|
||||
break;
|
||||
case RECYCLE_TILE:
|
||||
//noinspection unchecked
|
||||
callback.recycleTile((TileList.Tile<T>) msg.data);
|
||||
break;
|
||||
default:
|
||||
Log.e("ThreadUtil", "Unsupported message, what=" + msg.what);
|
||||
}
|
||||
}
|
||||
mBackgroundRunning.set(false);
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Replica of android.os.Message. Unfortunately, cannot use it without a Handler and don't want
|
||||
* to create a thread just for this component.
|
||||
*/
|
||||
static class SyncQueueItem {
|
||||
|
||||
private static SyncQueueItem sPool;
|
||||
private static final Object sPoolLock = new Object();
|
||||
private SyncQueueItem next;
|
||||
public int what;
|
||||
public int arg1;
|
||||
public int arg2;
|
||||
public int arg3;
|
||||
public int arg4;
|
||||
public int arg5;
|
||||
public Object data;
|
||||
|
||||
void recycle() {
|
||||
next = null;
|
||||
what = arg1 = arg2 = arg3 = arg4 = arg5 = 0;
|
||||
data = null;
|
||||
synchronized (sPoolLock) {
|
||||
if (sPool != null) {
|
||||
next = sPool;
|
||||
}
|
||||
sPool = this;
|
||||
}
|
||||
}
|
||||
|
||||
static SyncQueueItem obtainMessage(int what, int arg1, int arg2, int arg3, int arg4,
|
||||
int arg5, Object data) {
|
||||
synchronized (sPoolLock) {
|
||||
final SyncQueueItem item;
|
||||
if (sPool == null) {
|
||||
item = new SyncQueueItem();
|
||||
} else {
|
||||
item = sPool;
|
||||
sPool = sPool.next;
|
||||
item.next = null;
|
||||
}
|
||||
item.what = what;
|
||||
item.arg1 = arg1;
|
||||
item.arg2 = arg2;
|
||||
item.arg3 = arg3;
|
||||
item.arg4 = arg4;
|
||||
item.arg5 = arg5;
|
||||
item.data = data;
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
static SyncQueueItem obtainMessage(int what, int arg1, int arg2) {
|
||||
return obtainMessage(what, arg1, arg2, 0, 0, 0, null);
|
||||
}
|
||||
|
||||
static SyncQueueItem obtainMessage(int what, int arg1, Object data) {
|
||||
return obtainMessage(what, arg1, 0, 0, 0, 0, data);
|
||||
}
|
||||
}
|
||||
|
||||
static class MessageQueue {
|
||||
|
||||
private SyncQueueItem mRoot;
|
||||
|
||||
synchronized SyncQueueItem next() {
|
||||
if (mRoot == null) {
|
||||
return null;
|
||||
}
|
||||
final SyncQueueItem next = mRoot;
|
||||
mRoot = mRoot.next;
|
||||
return next;
|
||||
}
|
||||
|
||||
synchronized void sendMessageAtFrontOfQueue(SyncQueueItem item) {
|
||||
item.next = mRoot;
|
||||
mRoot = item;
|
||||
}
|
||||
|
||||
synchronized void sendMessage(SyncQueueItem item) {
|
||||
if (mRoot == null) {
|
||||
mRoot = item;
|
||||
return;
|
||||
}
|
||||
SyncQueueItem last = mRoot;
|
||||
while (last.next != null) {
|
||||
last = last.next;
|
||||
}
|
||||
last.next = item;
|
||||
}
|
||||
|
||||
synchronized void removeMessages(int what) {
|
||||
while (mRoot != null && mRoot.what == what) {
|
||||
SyncQueueItem item = mRoot;
|
||||
mRoot = mRoot.next;
|
||||
item.recycle();
|
||||
}
|
||||
if (mRoot != null) {
|
||||
SyncQueueItem prev = mRoot;
|
||||
SyncQueueItem item = prev.next;
|
||||
while (item != null) {
|
||||
SyncQueueItem next = item.next;
|
||||
if (item.what == what) {
|
||||
prev.next = next;
|
||||
item.recycle();
|
||||
} else {
|
||||
prev = item;
|
||||
}
|
||||
item = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,891 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.b44t.messenger.support.util;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* A Sorted list implementation that can keep items in order and also notify for changes in the
|
||||
* list
|
||||
* such that it can be bound to a {@link android.support.v7.widget.RecyclerView.Adapter
|
||||
* RecyclerView.Adapter}.
|
||||
* <p>
|
||||
* It keeps items ordered using the {@link Callback#compare(Object, Object)} method and uses
|
||||
* binary search to retrieve items. If the sorting criteria of your items may change, make sure you
|
||||
* call appropriate methods while editing them to avoid data inconsistencies.
|
||||
* <p>
|
||||
* You can control the order of items and change notifications via the {@link Callback} parameter.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class SortedList<T> {
|
||||
|
||||
/**
|
||||
* Used by {@link #indexOf(Object)} when he item cannot be found in the list.
|
||||
*/
|
||||
public static final int INVALID_POSITION = -1;
|
||||
|
||||
private static final int MIN_CAPACITY = 10;
|
||||
private static final int CAPACITY_GROWTH = MIN_CAPACITY;
|
||||
private static final int INSERTION = 1;
|
||||
private static final int DELETION = 1 << 1;
|
||||
private static final int LOOKUP = 1 << 2;
|
||||
T[] mData;
|
||||
|
||||
/**
|
||||
* A copy of the previous list contents used during the merge phase of addAll.
|
||||
*/
|
||||
private T[] mOldData;
|
||||
private int mOldDataStart;
|
||||
private int mOldDataSize;
|
||||
|
||||
/**
|
||||
* The size of the valid portion of mData during the merge phase of addAll.
|
||||
*/
|
||||
private int mMergedSize;
|
||||
|
||||
|
||||
/**
|
||||
* The callback instance that controls the behavior of the SortedList and get notified when
|
||||
* changes happen.
|
||||
*/
|
||||
private Callback mCallback;
|
||||
|
||||
private BatchedCallback mBatchedCallback;
|
||||
|
||||
private int mSize;
|
||||
private final Class<T> mTClass;
|
||||
|
||||
/**
|
||||
* Creates a new SortedList of type T.
|
||||
*
|
||||
* @param klass The class of the contents of the SortedList.
|
||||
* @param callback The callback that controls the behavior of SortedList.
|
||||
*/
|
||||
public SortedList(Class<T> klass, Callback<T> callback) {
|
||||
this(klass, callback, MIN_CAPACITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new SortedList of type T.
|
||||
*
|
||||
* @param klass The class of the contents of the SortedList.
|
||||
* @param callback The callback that controls the behavior of SortedList.
|
||||
* @param initialCapacity The initial capacity to hold items.
|
||||
*/
|
||||
public SortedList(Class<T> klass, Callback<T> callback, int initialCapacity) {
|
||||
mTClass = klass;
|
||||
mData = (T[]) Array.newInstance(klass, initialCapacity);
|
||||
mCallback = callback;
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of items in the list.
|
||||
*
|
||||
* @return The number of items in the list.
|
||||
*/
|
||||
public int size() {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given item to the list. If this is a new item, SortedList calls
|
||||
* {@link Callback#onInserted(int, int)}.
|
||||
* <p>
|
||||
* If the item already exists in the list and its sorting criteria is not changed, it is
|
||||
* replaced with the existing Item. SortedList uses
|
||||
* {@link Callback#areItemsTheSame(Object, Object)} to check if two items are the same item
|
||||
* and uses {@link Callback#areContentsTheSame(Object, Object)} to decide whether it should
|
||||
* call {@link Callback#onChanged(int, int)} or not. In both cases, it always removes the
|
||||
* reference to the old item and puts the new item into the backing array even if
|
||||
* {@link Callback#areContentsTheSame(Object, Object)} returns false.
|
||||
* <p>
|
||||
* If the sorting criteria of the item is changed, SortedList won't be able to find
|
||||
* its duplicate in the list which will result in having a duplicate of the Item in the list.
|
||||
* If you need to update sorting criteria of an item that already exists in the list,
|
||||
* use {@link #updateItemAt(int, Object)}. You can find the index of the item using
|
||||
* {@link #indexOf(Object)} before you update the object.
|
||||
*
|
||||
* @param item The item to be added into the list.
|
||||
*
|
||||
* @return The index of the newly added item.
|
||||
* @see {@link Callback#compare(Object, Object)}
|
||||
* @see {@link Callback#areItemsTheSame(Object, Object)}
|
||||
* @see {@link Callback#areContentsTheSame(Object, Object)}}
|
||||
*/
|
||||
public int add(T item) {
|
||||
throwIfMerging();
|
||||
return add(item, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given items to the list. Equivalent to calling {@link SortedList#add} in a loop,
|
||||
* except the callback events may be in a different order/granularity since addAll can batch
|
||||
* them for better performance.
|
||||
* <p>
|
||||
* If allowed, may modify the input array and even take the ownership over it in order
|
||||
* to avoid extra memory allocation during sorting and deduplication.
|
||||
* </p>
|
||||
* @param items Array of items to be added into the list.
|
||||
* @param mayModifyInput If true, SortedList is allowed to modify the input.
|
||||
* @see {@link SortedList#addAll(T[] items)}.
|
||||
*/
|
||||
public void addAll(T[] items, boolean mayModifyInput) {
|
||||
throwIfMerging();
|
||||
if (items.length == 0) {
|
||||
return;
|
||||
}
|
||||
if (mayModifyInput) {
|
||||
addAllInternal(items);
|
||||
} else {
|
||||
T[] copy = (T[]) Array.newInstance(mTClass, items.length);
|
||||
System.arraycopy(items, 0, copy, 0, items.length);
|
||||
addAllInternal(copy);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given items to the list. Does not modify the input.
|
||||
*
|
||||
* @see {@link SortedList#addAll(T[] items, boolean mayModifyInput)}
|
||||
*
|
||||
* @param items Array of items to be added into the list.
|
||||
*/
|
||||
public void addAll(T... items) {
|
||||
addAll(items, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given items to the list. Does not modify the input.
|
||||
*
|
||||
* @see {@link SortedList#addAll(T[] items, boolean mayModifyInput)}
|
||||
*
|
||||
* @param items Collection of items to be added into the list.
|
||||
*/
|
||||
public void addAll(Collection<T> items) {
|
||||
T[] copy = (T[]) Array.newInstance(mTClass, items.size());
|
||||
addAll(items.toArray(copy), true);
|
||||
}
|
||||
|
||||
private void addAllInternal(T[] newItems) {
|
||||
final boolean forceBatchedUpdates = !(mCallback instanceof BatchedCallback);
|
||||
if (forceBatchedUpdates) {
|
||||
beginBatchedUpdates();
|
||||
}
|
||||
|
||||
mOldData = mData;
|
||||
mOldDataStart = 0;
|
||||
mOldDataSize = mSize;
|
||||
|
||||
Arrays.sort(newItems, mCallback); // Arrays.sort is stable.
|
||||
|
||||
final int newSize = deduplicate(newItems);
|
||||
if (mSize == 0) {
|
||||
mData = newItems;
|
||||
mSize = newSize;
|
||||
mMergedSize = newSize;
|
||||
mCallback.onInserted(0, newSize);
|
||||
} else {
|
||||
merge(newItems, newSize);
|
||||
}
|
||||
|
||||
mOldData = null;
|
||||
|
||||
if (forceBatchedUpdates) {
|
||||
endBatchedUpdates();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove duplicate items, leaving only the last item from each group of "same" items.
|
||||
* Move the remaining items to the beginning of the array.
|
||||
*
|
||||
* @return Number of deduplicated items at the beginning of the array.
|
||||
*/
|
||||
private int deduplicate(T[] items) {
|
||||
if (items.length == 0) {
|
||||
throw new IllegalArgumentException("Input array must be non-empty");
|
||||
}
|
||||
|
||||
// Keep track of the range of equal items at the end of the output.
|
||||
// Start with the range containing just the first item.
|
||||
int rangeStart = 0;
|
||||
int rangeEnd = 1;
|
||||
|
||||
for (int i = 1; i < items.length; ++i) {
|
||||
T currentItem = items[i];
|
||||
|
||||
int compare = mCallback.compare(items[rangeStart], currentItem);
|
||||
if (compare > 0) {
|
||||
throw new IllegalArgumentException("Input must be sorted in ascending order.");
|
||||
}
|
||||
|
||||
if (compare == 0) {
|
||||
// The range of equal items continues, update it.
|
||||
final int sameItemPos = findSameItem(currentItem, items, rangeStart, rangeEnd);
|
||||
if (sameItemPos != INVALID_POSITION) {
|
||||
// Replace the duplicate item.
|
||||
items[sameItemPos] = currentItem;
|
||||
} else {
|
||||
// Expand the range.
|
||||
if (rangeEnd != i) { // Avoid redundant copy.
|
||||
items[rangeEnd] = currentItem;
|
||||
}
|
||||
rangeEnd++;
|
||||
}
|
||||
} else {
|
||||
// The range has ended. Reset it to contain just the current item.
|
||||
if (rangeEnd != i) { // Avoid redundant copy.
|
||||
items[rangeEnd] = currentItem;
|
||||
}
|
||||
rangeStart = rangeEnd++;
|
||||
}
|
||||
}
|
||||
return rangeEnd;
|
||||
}
|
||||
|
||||
|
||||
private int findSameItem(T item, T[] items, int from, int to) {
|
||||
for (int pos = from; pos < to; pos++) {
|
||||
if (mCallback.areItemsTheSame(items[pos], item)) {
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
return INVALID_POSITION;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method assumes that newItems are sorted and deduplicated.
|
||||
*/
|
||||
private void merge(T[] newData, int newDataSize) {
|
||||
final int mergedCapacity = mSize + newDataSize + CAPACITY_GROWTH;
|
||||
mData = (T[]) Array.newInstance(mTClass, mergedCapacity);
|
||||
mMergedSize = 0;
|
||||
|
||||
int newDataStart = 0;
|
||||
while (mOldDataStart < mOldDataSize || newDataStart < newDataSize) {
|
||||
if (mOldDataStart == mOldDataSize) {
|
||||
// No more old items, copy the remaining new items.
|
||||
int itemCount = newDataSize - newDataStart;
|
||||
System.arraycopy(newData, newDataStart, mData, mMergedSize, itemCount);
|
||||
mMergedSize += itemCount;
|
||||
mSize += itemCount;
|
||||
mCallback.onInserted(mMergedSize - itemCount, itemCount);
|
||||
break;
|
||||
}
|
||||
|
||||
if (newDataStart == newDataSize) {
|
||||
// No more new items, copy the remaining old items.
|
||||
int itemCount = mOldDataSize - mOldDataStart;
|
||||
System.arraycopy(mOldData, mOldDataStart, mData, mMergedSize, itemCount);
|
||||
mMergedSize += itemCount;
|
||||
break;
|
||||
}
|
||||
|
||||
T oldItem = mOldData[mOldDataStart];
|
||||
T newItem = newData[newDataStart];
|
||||
int compare = mCallback.compare(oldItem, newItem);
|
||||
if (compare > 0) {
|
||||
// New item is lower, output it.
|
||||
mData[mMergedSize++] = newItem;
|
||||
mSize++;
|
||||
newDataStart++;
|
||||
mCallback.onInserted(mMergedSize - 1, 1);
|
||||
} else if (compare == 0 && mCallback.areItemsTheSame(oldItem, newItem)) {
|
||||
// Items are the same. Output the new item, but consume both.
|
||||
mData[mMergedSize++] = newItem;
|
||||
newDataStart++;
|
||||
mOldDataStart++;
|
||||
if (!mCallback.areContentsTheSame(oldItem, newItem)) {
|
||||
mCallback.onChanged(mMergedSize - 1, 1);
|
||||
}
|
||||
} else {
|
||||
// Old item is lower than or equal to (but not the same as the new). Output it.
|
||||
// New item with the same sort order will be inserted later.
|
||||
mData[mMergedSize++] = oldItem;
|
||||
mOldDataStart++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void throwIfMerging() {
|
||||
if (mOldData != null) {
|
||||
throw new IllegalStateException("Cannot call this method from within addAll");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Batches adapter updates that happen between calling this method until calling
|
||||
* {@link #endBatchedUpdates()}. For example, if you add multiple items in a loop
|
||||
* and they are placed into consecutive indices, SortedList calls
|
||||
* {@link Callback#onInserted(int, int)} only once with the proper item count. If an event
|
||||
* cannot be merged with the previous event, the previous event is dispatched
|
||||
* to the callback instantly.
|
||||
* <p>
|
||||
* After running your data updates, you <b>must</b> call {@link #endBatchedUpdates()}
|
||||
* which will dispatch any deferred data change event to the current callback.
|
||||
* <p>
|
||||
* A sample implementation may look like this:
|
||||
* <pre>
|
||||
* mSortedList.beginBatchedUpdates();
|
||||
* try {
|
||||
* mSortedList.add(item1)
|
||||
* mSortedList.add(item2)
|
||||
* mSortedList.remove(item3)
|
||||
* ...
|
||||
* } finally {
|
||||
* mSortedList.endBatchedUpdates();
|
||||
* }
|
||||
* </pre>
|
||||
* <p>
|
||||
* Instead of using this method to batch calls, you can use a Callback that extends
|
||||
* {@link BatchedCallback}. In that case, you must make sure that you are manually calling
|
||||
* {@link BatchedCallback#dispatchLastEvent()} right after you complete your data changes.
|
||||
* Failing to do so may create data inconsistencies with the Callback.
|
||||
* <p>
|
||||
* If the current Callback in an instance of {@link BatchedCallback}, calling this method
|
||||
* has no effect.
|
||||
*/
|
||||
public void beginBatchedUpdates() {
|
||||
throwIfMerging();
|
||||
if (mCallback instanceof BatchedCallback) {
|
||||
return;
|
||||
}
|
||||
if (mBatchedCallback == null) {
|
||||
mBatchedCallback = new BatchedCallback(mCallback);
|
||||
}
|
||||
mCallback = mBatchedCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the update transaction and dispatches any remaining event to the callback.
|
||||
*/
|
||||
public void endBatchedUpdates() {
|
||||
throwIfMerging();
|
||||
if (mCallback instanceof BatchedCallback) {
|
||||
((BatchedCallback) mCallback).dispatchLastEvent();
|
||||
}
|
||||
if (mCallback == mBatchedCallback) {
|
||||
mCallback = mBatchedCallback.mWrappedCallback;
|
||||
}
|
||||
}
|
||||
|
||||
private int add(T item, boolean notify) {
|
||||
int index = findIndexOf(item, mData, 0, mSize, INSERTION);
|
||||
if (index == INVALID_POSITION) {
|
||||
index = 0;
|
||||
} else if (index < mSize) {
|
||||
T existing = mData[index];
|
||||
if (mCallback.areItemsTheSame(existing, item)) {
|
||||
if (mCallback.areContentsTheSame(existing, item)) {
|
||||
//no change but still replace the item
|
||||
mData[index] = item;
|
||||
return index;
|
||||
} else {
|
||||
mData[index] = item;
|
||||
mCallback.onChanged(index, 1);
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
addToData(index, item);
|
||||
if (notify) {
|
||||
mCallback.onInserted(index, 1);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the provided item from the list and calls {@link Callback#onRemoved(int, int)}.
|
||||
*
|
||||
* @param item The item to be removed from the list.
|
||||
*
|
||||
* @return True if item is removed, false if item cannot be found in the list.
|
||||
*/
|
||||
public boolean remove(T item) {
|
||||
throwIfMerging();
|
||||
return remove(item, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the item at the given index and calls {@link Callback#onRemoved(int, int)}.
|
||||
*
|
||||
* @param index The index of the item to be removed.
|
||||
*
|
||||
* @return The removed item.
|
||||
*/
|
||||
public T removeItemAt(int index) {
|
||||
throwIfMerging();
|
||||
T item = get(index);
|
||||
removeItemAtIndex(index, true);
|
||||
return item;
|
||||
}
|
||||
|
||||
private boolean remove(T item, boolean notify) {
|
||||
int index = findIndexOf(item, mData, 0, mSize, DELETION);
|
||||
if (index == INVALID_POSITION) {
|
||||
return false;
|
||||
}
|
||||
removeItemAtIndex(index, notify);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void removeItemAtIndex(int index, boolean notify) {
|
||||
System.arraycopy(mData, index + 1, mData, index, mSize - index - 1);
|
||||
mSize--;
|
||||
mData[mSize] = null;
|
||||
if (notify) {
|
||||
mCallback.onRemoved(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the item at the given index and calls {@link Callback#onChanged(int, int)} and/or
|
||||
* {@link Callback#onMoved(int, int)} if necessary.
|
||||
* <p>
|
||||
* You can use this method if you need to change an existing Item such that its position in the
|
||||
* list may change.
|
||||
* <p>
|
||||
* If the new object is a different object (<code>get(index) != item</code>) and
|
||||
* {@link Callback#areContentsTheSame(Object, Object)} returns <code>true</code>, SortedList
|
||||
* avoids calling {@link Callback#onChanged(int, int)} otherwise it calls
|
||||
* {@link Callback#onChanged(int, int)}.
|
||||
* <p>
|
||||
* If the new position of the item is different than the provided <code>index</code>,
|
||||
* SortedList
|
||||
* calls {@link Callback#onMoved(int, int)}.
|
||||
*
|
||||
* @param index The index of the item to replace
|
||||
* @param item The item to replace the item at the given Index.
|
||||
* @see #add(Object)
|
||||
*/
|
||||
public void updateItemAt(int index, T item) {
|
||||
throwIfMerging();
|
||||
final T existing = get(index);
|
||||
// assume changed if the same object is given back
|
||||
boolean contentsChanged = existing == item || !mCallback.areContentsTheSame(existing, item);
|
||||
if (existing != item) {
|
||||
// different items, we can use comparison and may avoid lookup
|
||||
final int cmp = mCallback.compare(existing, item);
|
||||
if (cmp == 0) {
|
||||
mData[index] = item;
|
||||
if (contentsChanged) {
|
||||
mCallback.onChanged(index, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (contentsChanged) {
|
||||
mCallback.onChanged(index, 1);
|
||||
}
|
||||
// TODO this done in 1 pass to avoid shifting twice.
|
||||
removeItemAtIndex(index, false);
|
||||
int newIndex = add(item, false);
|
||||
if (index != newIndex) {
|
||||
mCallback.onMoved(index, newIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method can be used to recalculate the position of the item at the given index, without
|
||||
* triggering an {@link Callback#onChanged(int, int)} callback.
|
||||
* <p>
|
||||
* If you are editing objects in the list such that their position in the list may change but
|
||||
* you don't want to trigger an onChange animation, you can use this method to re-position it.
|
||||
* If the item changes position, SortedList will call {@link Callback#onMoved(int, int)}
|
||||
* without
|
||||
* calling {@link Callback#onChanged(int, int)}.
|
||||
* <p>
|
||||
* A sample usage may look like:
|
||||
*
|
||||
* <pre>
|
||||
* final int position = mSortedList.indexOf(item);
|
||||
* item.incrementPriority(); // assume items are sorted by priority
|
||||
* mSortedList.recalculatePositionOfItemAt(position);
|
||||
* </pre>
|
||||
* In the example above, because the sorting criteria of the item has been changed,
|
||||
* mSortedList.indexOf(item) will not be able to find the item. This is why the code above
|
||||
* first
|
||||
* gets the position before editing the item, edits it and informs the SortedList that item
|
||||
* should be repositioned.
|
||||
*
|
||||
* @param index The current index of the Item whose position should be re-calculated.
|
||||
* @see #updateItemAt(int, Object)
|
||||
* @see #add(Object)
|
||||
*/
|
||||
public void recalculatePositionOfItemAt(int index) {
|
||||
throwIfMerging();
|
||||
// TODO can be improved
|
||||
final T item = get(index);
|
||||
removeItemAtIndex(index, false);
|
||||
int newIndex = add(item, false);
|
||||
if (index != newIndex) {
|
||||
mCallback.onMoved(index, newIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the item at the given index.
|
||||
*
|
||||
* @param index The index of the item to retrieve.
|
||||
*
|
||||
* @return The item at the given index.
|
||||
* @throws java.lang.IndexOutOfBoundsException if provided index is negative or larger than the
|
||||
* size of the list.
|
||||
*/
|
||||
public T get(int index) throws IndexOutOfBoundsException {
|
||||
if (index >= mSize || index < 0) {
|
||||
throw new IndexOutOfBoundsException("Asked to get item at " + index + " but size is "
|
||||
+ mSize);
|
||||
}
|
||||
if (mOldData != null) {
|
||||
// The call is made from a callback during addAll execution. The data is split
|
||||
// between mData and mOldData.
|
||||
if (index >= mMergedSize) {
|
||||
return mOldData[index - mMergedSize + mOldDataStart];
|
||||
}
|
||||
}
|
||||
return mData[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of the provided item.
|
||||
*
|
||||
* @param item The item to query for position.
|
||||
*
|
||||
* @return The position of the provided item or {@link #INVALID_POSITION} if item is not in the
|
||||
* list.
|
||||
*/
|
||||
public int indexOf(T item) {
|
||||
if (mOldData != null) {
|
||||
int index = findIndexOf(item, mData, 0, mMergedSize, LOOKUP);
|
||||
if (index != INVALID_POSITION) {
|
||||
return index;
|
||||
}
|
||||
index = findIndexOf(item, mOldData, mOldDataStart, mOldDataSize, LOOKUP);
|
||||
if (index != INVALID_POSITION) {
|
||||
return index - mOldDataStart + mMergedSize;
|
||||
}
|
||||
return INVALID_POSITION;
|
||||
}
|
||||
return findIndexOf(item, mData, 0, mSize, LOOKUP);
|
||||
}
|
||||
|
||||
private int findIndexOf(T item, T[] mData, int left, int right, int reason) {
|
||||
while (left < right) {
|
||||
final int middle = (left + right) / 2;
|
||||
T myItem = mData[middle];
|
||||
final int cmp = mCallback.compare(myItem, item);
|
||||
if (cmp < 0) {
|
||||
left = middle + 1;
|
||||
} else if (cmp == 0) {
|
||||
if (mCallback.areItemsTheSame(myItem, item)) {
|
||||
return middle;
|
||||
} else {
|
||||
int exact = linearEqualitySearch(item, middle, left, right);
|
||||
if (reason == INSERTION) {
|
||||
return exact == INVALID_POSITION ? middle : exact;
|
||||
} else {
|
||||
return exact;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
right = middle;
|
||||
}
|
||||
}
|
||||
return reason == INSERTION ? left : INVALID_POSITION;
|
||||
}
|
||||
|
||||
private int linearEqualitySearch(T item, int middle, int left, int right) {
|
||||
// go left
|
||||
for (int next = middle - 1; next >= left; next--) {
|
||||
T nextItem = mData[next];
|
||||
int cmp = mCallback.compare(nextItem, item);
|
||||
if (cmp != 0) {
|
||||
break;
|
||||
}
|
||||
if (mCallback.areItemsTheSame(nextItem, item)) {
|
||||
return next;
|
||||
}
|
||||
}
|
||||
for (int next = middle + 1; next < right; next++) {
|
||||
T nextItem = mData[next];
|
||||
int cmp = mCallback.compare(nextItem, item);
|
||||
if (cmp != 0) {
|
||||
break;
|
||||
}
|
||||
if (mCallback.areItemsTheSame(nextItem, item)) {
|
||||
return next;
|
||||
}
|
||||
}
|
||||
return INVALID_POSITION;
|
||||
}
|
||||
|
||||
private void addToData(int index, T item) {
|
||||
if (index > mSize) {
|
||||
throw new IndexOutOfBoundsException(
|
||||
"cannot add item to " + index + " because size is " + mSize);
|
||||
}
|
||||
if (mSize == mData.length) {
|
||||
// we are at the limit enlarge
|
||||
T[] newData = (T[]) Array.newInstance(mTClass, mData.length + CAPACITY_GROWTH);
|
||||
System.arraycopy(mData, 0, newData, 0, index);
|
||||
newData[index] = item;
|
||||
System.arraycopy(mData, index, newData, index + 1, mSize - index);
|
||||
mData = newData;
|
||||
} else {
|
||||
// just shift, we fit
|
||||
System.arraycopy(mData, index, mData, index + 1, mSize - index);
|
||||
mData[index] = item;
|
||||
}
|
||||
mSize++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all items from the SortedList.
|
||||
*/
|
||||
public void clear() {
|
||||
throwIfMerging();
|
||||
if (mSize == 0) {
|
||||
return;
|
||||
}
|
||||
final int prevSize = mSize;
|
||||
Arrays.fill(mData, 0, prevSize, null);
|
||||
mSize = 0;
|
||||
mCallback.onRemoved(0, prevSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* The class that controls the behavior of the {@link SortedList}.
|
||||
* <p>
|
||||
* It defines how items should be sorted and how duplicates should be handled.
|
||||
* <p>
|
||||
* SortedList calls the callback methods on this class to notify changes about the underlying
|
||||
* data.
|
||||
*/
|
||||
public static abstract class Callback<T2> implements Comparator<T2> {
|
||||
|
||||
/**
|
||||
* Similar to {@link java.util.Comparator#compare(Object, Object)}, should compare two and
|
||||
* return how they should be ordered.
|
||||
*
|
||||
* @param o1 The first object to compare.
|
||||
* @param o2 The second object to compare.
|
||||
*
|
||||
* @return a negative integer, zero, or a positive integer as the
|
||||
* first argument is less than, equal to, or greater than the
|
||||
* second.
|
||||
*/
|
||||
abstract public int compare(T2 o1, T2 o2);
|
||||
|
||||
/**
|
||||
* Called by the SortedList when an item is inserted at the given position.
|
||||
*
|
||||
* @param position The position of the new item.
|
||||
* @param count The number of items that have been added.
|
||||
*/
|
||||
abstract public void onInserted(int position, int count);
|
||||
|
||||
/**
|
||||
* Called by the SortedList when an item is removed from the given position.
|
||||
*
|
||||
* @param position The position of the item which has been removed.
|
||||
* @param count The number of items which have been removed.
|
||||
*/
|
||||
abstract public void onRemoved(int position, int count);
|
||||
|
||||
/**
|
||||
* Called by the SortedList when an item changes its position in the list.
|
||||
*
|
||||
* @param fromPosition The previous position of the item before the move.
|
||||
* @param toPosition The new position of the item.
|
||||
*/
|
||||
abstract public void onMoved(int fromPosition, int toPosition);
|
||||
|
||||
/**
|
||||
* Called by the SortedList when the item at the given position is updated.
|
||||
*
|
||||
* @param position The position of the item which has been updated.
|
||||
* @param count The number of items which has changed.
|
||||
*/
|
||||
abstract public void onChanged(int position, int count);
|
||||
|
||||
/**
|
||||
* Called by the SortedList when it wants to check whether two items have the same data
|
||||
* or not. SortedList uses this information to decide whether it should call
|
||||
* {@link #onChanged(int, int)} or not.
|
||||
* <p>
|
||||
* SortedList uses this method to check equality instead of {@link Object#equals(Object)}
|
||||
* so
|
||||
* that you can change its behavior depending on your UI.
|
||||
* <p>
|
||||
* For example, if you are using SortedList with a {@link android.support.v7.widget.RecyclerView.Adapter
|
||||
* RecyclerView.Adapter}, you should
|
||||
* return whether the items' visual representations are the same or not.
|
||||
*
|
||||
* @param oldItem The previous representation of the object.
|
||||
* @param newItem The new object that replaces the previous one.
|
||||
*
|
||||
* @return True if the contents of the items are the same or false if they are different.
|
||||
*/
|
||||
abstract public boolean areContentsTheSame(T2 oldItem, T2 newItem);
|
||||
|
||||
/**
|
||||
* Called by the SortedList to decide whether two object represent the same Item or not.
|
||||
* <p>
|
||||
* For example, if your items have unique ids, this method should check their equality.
|
||||
*
|
||||
* @param item1 The first item to check.
|
||||
* @param item2 The second item to check.
|
||||
*
|
||||
* @return True if the two items represent the same object or false if they are different.
|
||||
*/
|
||||
abstract public boolean areItemsTheSame(T2 item1, T2 item2);
|
||||
}
|
||||
|
||||
/**
|
||||
* A callback implementation that can batch notify events dispatched by the SortedList.
|
||||
* <p>
|
||||
* This class can be useful if you want to do multiple operations on a SortedList but don't
|
||||
* want to dispatch each event one by one, which may result in a performance issue.
|
||||
* <p>
|
||||
* For example, if you are going to add multiple items to a SortedList, BatchedCallback call
|
||||
* convert individual <code>onInserted(index, 1)</code> calls into one
|
||||
* <code>onInserted(index, N)</code> if items are added into consecutive indices. This change
|
||||
* can help RecyclerView resolve changes much more easily.
|
||||
* <p>
|
||||
* If consecutive changes in the SortedList are not suitable for batching, BatchingCallback
|
||||
* dispatches them as soon as such case is detected. After your edits on the SortedList is
|
||||
* complete, you <b>must</b> always call {@link BatchedCallback#dispatchLastEvent()} to flush
|
||||
* all changes to the Callback.
|
||||
*/
|
||||
public static class BatchedCallback<T2> extends Callback<T2> {
|
||||
|
||||
private final Callback<T2> mWrappedCallback;
|
||||
static final int TYPE_NONE = 0;
|
||||
static final int TYPE_ADD = 1;
|
||||
static final int TYPE_REMOVE = 2;
|
||||
static final int TYPE_CHANGE = 3;
|
||||
static final int TYPE_MOVE = 4;
|
||||
|
||||
int mLastEventType = TYPE_NONE;
|
||||
int mLastEventPosition = -1;
|
||||
int mLastEventCount = -1;
|
||||
|
||||
/**
|
||||
* Creates a new BatchedCallback that wraps the provided Callback.
|
||||
*
|
||||
* @param wrappedCallback The Callback which should received the data change callbacks.
|
||||
* Other method calls (e.g. {@link #compare(Object, Object)} from
|
||||
* the SortedList are directly forwarded to this Callback.
|
||||
*/
|
||||
public BatchedCallback(Callback<T2> wrappedCallback) {
|
||||
mWrappedCallback = wrappedCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(T2 o1, T2 o2) {
|
||||
return mWrappedCallback.compare(o1, o2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInserted(int position, int count) {
|
||||
if (mLastEventType == TYPE_ADD && position >= mLastEventPosition
|
||||
&& position <= mLastEventPosition + mLastEventCount) {
|
||||
mLastEventCount += count;
|
||||
mLastEventPosition = Math.min(position, mLastEventPosition);
|
||||
return;
|
||||
}
|
||||
dispatchLastEvent();
|
||||
mLastEventPosition = position;
|
||||
mLastEventCount = count;
|
||||
mLastEventType = TYPE_ADD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoved(int position, int count) {
|
||||
if (mLastEventType == TYPE_REMOVE && mLastEventPosition == position) {
|
||||
mLastEventCount += count;
|
||||
return;
|
||||
}
|
||||
dispatchLastEvent();
|
||||
mLastEventPosition = position;
|
||||
mLastEventCount = count;
|
||||
mLastEventType = TYPE_REMOVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoved(int fromPosition, int toPosition) {
|
||||
dispatchLastEvent();//moves are not merged
|
||||
mWrappedCallback.onMoved(fromPosition, toPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChanged(int position, int count) {
|
||||
if (mLastEventType == TYPE_CHANGE &&
|
||||
!(position > mLastEventPosition + mLastEventCount
|
||||
|| position + count < mLastEventPosition)) {
|
||||
// take potential overlap into account
|
||||
int previousEnd = mLastEventPosition + mLastEventCount;
|
||||
mLastEventPosition = Math.min(position, mLastEventPosition);
|
||||
mLastEventCount = Math.max(previousEnd, position + count) - mLastEventPosition;
|
||||
return;
|
||||
}
|
||||
dispatchLastEvent();
|
||||
mLastEventPosition = position;
|
||||
mLastEventCount = count;
|
||||
mLastEventType = TYPE_CHANGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(T2 oldItem, T2 newItem) {
|
||||
return mWrappedCallback.areContentsTheSame(oldItem, newItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areItemsTheSame(T2 item1, T2 item2) {
|
||||
return mWrappedCallback.areItemsTheSame(item1, item2);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method dispatches any pending event notifications to the wrapped Callback.
|
||||
* You <b>must</b> always call this method after you are done with editing the SortedList.
|
||||
*/
|
||||
public void dispatchLastEvent() {
|
||||
if (mLastEventType == TYPE_NONE) {
|
||||
return;
|
||||
}
|
||||
switch (mLastEventType) {
|
||||
case TYPE_ADD:
|
||||
mWrappedCallback.onInserted(mLastEventPosition, mLastEventCount);
|
||||
break;
|
||||
case TYPE_REMOVE:
|
||||
mWrappedCallback.onRemoved(mLastEventPosition, mLastEventCount);
|
||||
break;
|
||||
case TYPE_CHANGE:
|
||||
mWrappedCallback.onChanged(mLastEventPosition, mLastEventCount);
|
||||
break;
|
||||
}
|
||||
mLastEventType = TYPE_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.b44t.messenger.support.util;
|
||||
|
||||
interface ThreadUtil<T> {
|
||||
|
||||
interface MainThreadCallback<T> {
|
||||
|
||||
void updateItemCount(int generation, int itemCount);
|
||||
|
||||
void addTile(int generation, TileList.Tile<T> tile);
|
||||
|
||||
void removeTile(int generation, int position);
|
||||
}
|
||||
|
||||
interface BackgroundCallback<T> {
|
||||
|
||||
void refresh(int generation);
|
||||
|
||||
void updateRange(int rangeStart, int rangeEnd, int extRangeStart, int extRangeEnd,
|
||||
int scrollHint);
|
||||
|
||||
void loadTile(int position, int scrollHint);
|
||||
|
||||
void recycleTile(TileList.Tile<T> tile);
|
||||
}
|
||||
|
||||
MainThreadCallback<T> getMainThreadProxy(MainThreadCallback<T> callback);
|
||||
|
||||
BackgroundCallback<T> getBackgroundProxy(BackgroundCallback<T> callback);
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.b44t.messenger.support.util;
|
||||
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
/**
|
||||
* A sparse collection of tiles sorted for efficient access.
|
||||
*/
|
||||
class TileList<T> {
|
||||
|
||||
final int mTileSize;
|
||||
|
||||
// Keyed by start position.
|
||||
private final SparseArray<Tile<T>> mTiles = new SparseArray<Tile<T>>(10);
|
||||
|
||||
Tile<T> mLastAccessedTile;
|
||||
|
||||
public TileList(int tileSize) {
|
||||
mTileSize = tileSize;
|
||||
}
|
||||
|
||||
public T getItemAt(int pos) {
|
||||
if (mLastAccessedTile == null || !mLastAccessedTile.containsPosition(pos)) {
|
||||
final int startPosition = pos - (pos % mTileSize);
|
||||
final int index = mTiles.indexOfKey(startPosition);
|
||||
if (index < 0) {
|
||||
return null;
|
||||
}
|
||||
mLastAccessedTile = mTiles.valueAt(index);
|
||||
}
|
||||
return mLastAccessedTile.getByPosition(pos);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return mTiles.size();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
mTiles.clear();
|
||||
}
|
||||
|
||||
public Tile<T> getAtIndex(int index) {
|
||||
return mTiles.valueAt(index);
|
||||
}
|
||||
|
||||
public Tile<T> addOrReplace(Tile<T> newTile) {
|
||||
final int index = mTiles.indexOfKey(newTile.mStartPosition);
|
||||
if (index < 0) {
|
||||
mTiles.put(newTile.mStartPosition, newTile);
|
||||
return null;
|
||||
}
|
||||
Tile<T> oldTile = mTiles.valueAt(index);
|
||||
mTiles.setValueAt(index, newTile);
|
||||
if (mLastAccessedTile == oldTile) {
|
||||
mLastAccessedTile = newTile;
|
||||
}
|
||||
return oldTile;
|
||||
}
|
||||
|
||||
public Tile<T> removeAtPos(int startPosition) {
|
||||
Tile<T> tile = mTiles.get(startPosition);
|
||||
if (mLastAccessedTile == tile) {
|
||||
mLastAccessedTile = null;
|
||||
}
|
||||
mTiles.delete(startPosition);
|
||||
return tile;
|
||||
}
|
||||
|
||||
public static class Tile<T> {
|
||||
public final T[] mItems;
|
||||
public int mStartPosition;
|
||||
public int mItemCount;
|
||||
Tile<T> mNext; // Used only for pooling recycled tiles.
|
||||
|
||||
public Tile(Class<T> klass, int size) {
|
||||
//noinspection unchecked
|
||||
mItems = (T[]) Array.newInstance(klass, size);
|
||||
}
|
||||
|
||||
boolean containsPosition(int pos) {
|
||||
return mStartPosition <= pos && pos < mStartPosition + mItemCount;
|
||||
}
|
||||
|
||||
T getByPosition(int pos) {
|
||||
return mItems[pos - mStartPosition];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,460 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package com.b44t.messenger.support.widget;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Like a SparseArray, but with the ability to offset key ranges for bulk insertions/deletions.
|
||||
*/
|
||||
class PositionMap<E> implements Cloneable {
|
||||
private static final Object DELETED = new Object();
|
||||
private boolean mGarbage = false;
|
||||
|
||||
private int[] mKeys;
|
||||
private Object[] mValues;
|
||||
private int mSize;
|
||||
|
||||
/**
|
||||
* Creates a new SparseArray containing no mappings.
|
||||
*/
|
||||
public PositionMap() {
|
||||
this(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new PositionMap containing no mappings that will not
|
||||
* require any additional memory allocation to store the specified
|
||||
* number of mappings. If you supply an initial capacity of 0, the
|
||||
* sparse array will be initialized with a light-weight representation
|
||||
* not requiring any additional array allocations.
|
||||
*/
|
||||
public PositionMap(int initialCapacity) {
|
||||
if (initialCapacity == 0) {
|
||||
mKeys = ContainerHelpers.EMPTY_INTS;
|
||||
mValues = ContainerHelpers.EMPTY_OBJECTS;
|
||||
} else {
|
||||
initialCapacity = idealIntArraySize(initialCapacity);
|
||||
mKeys = new int[initialCapacity];
|
||||
mValues = new Object[initialCapacity];
|
||||
}
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public PositionMap<E> clone() {
|
||||
PositionMap<E> clone = null;
|
||||
try {
|
||||
clone = (PositionMap<E>) super.clone();
|
||||
clone.mKeys = mKeys.clone();
|
||||
clone.mValues = mValues.clone();
|
||||
} catch (CloneNotSupportedException cnse) {
|
||||
/* ignore */
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Object mapped from the specified key, or <code>null</code>
|
||||
* if no such mapping has been made.
|
||||
*/
|
||||
public E get(int key) {
|
||||
return get(key, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Object mapped from the specified key, or the specified Object
|
||||
* if no such mapping has been made.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public E get(int key, E valueIfKeyNotFound) {
|
||||
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
|
||||
if (i < 0 || mValues[i] == DELETED) {
|
||||
return valueIfKeyNotFound;
|
||||
} else {
|
||||
return (E) mValues[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the mapping from the specified key, if there was any.
|
||||
*/
|
||||
public void delete(int key) {
|
||||
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
|
||||
if (i >= 0) {
|
||||
if (mValues[i] != DELETED) {
|
||||
mValues[i] = DELETED;
|
||||
mGarbage = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for {@link #delete(int)}.
|
||||
*/
|
||||
public void remove(int key) {
|
||||
delete(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the mapping at the specified index.
|
||||
*/
|
||||
public void removeAt(int index) {
|
||||
if (mValues[index] != DELETED) {
|
||||
mValues[index] = DELETED;
|
||||
mGarbage = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a range of mappings as a batch.
|
||||
*
|
||||
* @param index Index to begin at
|
||||
* @param size Number of mappings to remove
|
||||
*/
|
||||
public void removeAtRange(int index, int size) {
|
||||
final int end = Math.min(mSize, index + size);
|
||||
for (int i = index; i < end; i++) {
|
||||
removeAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
public void insertKeyRange(int keyStart, int count) {
|
||||
|
||||
}
|
||||
|
||||
public void removeKeyRange(ArrayList<E> removedItems, int keyStart, int count) {
|
||||
|
||||
}
|
||||
|
||||
private void gc() {
|
||||
// Log.e("SparseArray", "gc start with " + mSize);
|
||||
|
||||
int n = mSize;
|
||||
int o = 0;
|
||||
int[] keys = mKeys;
|
||||
Object[] values = mValues;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
Object val = values[i];
|
||||
|
||||
if (val != DELETED) {
|
||||
if (i != o) {
|
||||
keys[o] = keys[i];
|
||||
values[o] = val;
|
||||
values[i] = null;
|
||||
}
|
||||
|
||||
o++;
|
||||
}
|
||||
}
|
||||
|
||||
mGarbage = false;
|
||||
mSize = o;
|
||||
|
||||
// Log.e("SparseArray", "gc end with " + mSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a mapping from the specified key to the specified value,
|
||||
* replacing the previous mapping from the specified key if there
|
||||
* was one.
|
||||
*/
|
||||
public void put(int key, E value) {
|
||||
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
|
||||
if (i >= 0) {
|
||||
mValues[i] = value;
|
||||
} else {
|
||||
i = ~i;
|
||||
|
||||
if (i < mSize && mValues[i] == DELETED) {
|
||||
mKeys[i] = key;
|
||||
mValues[i] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mGarbage && mSize >= mKeys.length) {
|
||||
gc();
|
||||
|
||||
// Search again because indices may have changed.
|
||||
i = ~ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
}
|
||||
|
||||
if (mSize >= mKeys.length) {
|
||||
int n = idealIntArraySize(mSize + 1);
|
||||
|
||||
int[] nkeys = new int[n];
|
||||
Object[] nvalues = new Object[n];
|
||||
|
||||
// Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
|
||||
System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
|
||||
System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
|
||||
|
||||
mKeys = nkeys;
|
||||
mValues = nvalues;
|
||||
}
|
||||
|
||||
if (mSize - i != 0) {
|
||||
// Log.e("SparseArray", "move " + (mSize - i));
|
||||
System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
|
||||
System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
|
||||
}
|
||||
|
||||
mKeys[i] = key;
|
||||
mValues[i] = value;
|
||||
mSize++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of key-value mappings that this SparseArray
|
||||
* currently stores.
|
||||
*/
|
||||
public int size() {
|
||||
if (mGarbage) {
|
||||
gc();
|
||||
}
|
||||
|
||||
return mSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an index in the range <code>0...size()-1</code>, returns
|
||||
* the key from the <code>index</code>th key-value mapping that this
|
||||
* SparseArray stores.
|
||||
*/
|
||||
public int keyAt(int index) {
|
||||
if (mGarbage) {
|
||||
gc();
|
||||
}
|
||||
|
||||
return mKeys[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an index in the range <code>0...size()-1</code>, returns
|
||||
* the value from the <code>index</code>th key-value mapping that this
|
||||
* SparseArray stores.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public E valueAt(int index) {
|
||||
if (mGarbage) {
|
||||
gc();
|
||||
}
|
||||
|
||||
return (E) mValues[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an index in the range <code>0...size()-1</code>, sets a new
|
||||
* value for the <code>index</code>th key-value mapping that this
|
||||
* SparseArray stores.
|
||||
*/
|
||||
public void setValueAt(int index, E value) {
|
||||
if (mGarbage) {
|
||||
gc();
|
||||
}
|
||||
|
||||
mValues[index] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index for which {@link #keyAt} would return the
|
||||
* specified key, or a negative number if the specified
|
||||
* key is not mapped.
|
||||
*/
|
||||
public int indexOfKey(int key) {
|
||||
if (mGarbage) {
|
||||
gc();
|
||||
}
|
||||
|
||||
return ContainerHelpers.binarySearch(mKeys, mSize, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an index for which {@link #valueAt} would return the
|
||||
* specified key, or a negative number if no keys map to the
|
||||
* specified value.
|
||||
* <p>Beware that this is a linear search, unlike lookups by key,
|
||||
* and that multiple keys can map to the same value and this will
|
||||
* find only one of them.
|
||||
* <p>Note also that unlike most collections' {@code indexOf} methods,
|
||||
* this method compares values using {@code ==} rather than {@code equals}.
|
||||
*/
|
||||
public int indexOfValue(E value) {
|
||||
if (mGarbage) {
|
||||
gc();
|
||||
}
|
||||
|
||||
for (int i = 0; i < mSize; i++)
|
||||
if (mValues[i] == value)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all key-value mappings from this SparseArray.
|
||||
*/
|
||||
public void clear() {
|
||||
int n = mSize;
|
||||
Object[] values = mValues;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
values[i] = null;
|
||||
}
|
||||
|
||||
mSize = 0;
|
||||
mGarbage = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a key/value pair into the array, optimizing for the case where
|
||||
* the key is greater than all existing keys in the array.
|
||||
*/
|
||||
public void append(int key, E value) {
|
||||
if (mSize != 0 && key <= mKeys[mSize - 1]) {
|
||||
put(key, value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mGarbage && mSize >= mKeys.length) {
|
||||
gc();
|
||||
}
|
||||
|
||||
int pos = mSize;
|
||||
if (pos >= mKeys.length) {
|
||||
int n = idealIntArraySize(pos + 1);
|
||||
|
||||
int[] nkeys = new int[n];
|
||||
Object[] nvalues = new Object[n];
|
||||
|
||||
// Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
|
||||
System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
|
||||
System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
|
||||
|
||||
mKeys = nkeys;
|
||||
mValues = nvalues;
|
||||
}
|
||||
|
||||
mKeys[pos] = key;
|
||||
mValues[pos] = value;
|
||||
mSize = pos + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>This implementation composes a string by iterating over its mappings. If
|
||||
* this map contains itself as a value, the string "(this Map)"
|
||||
* will appear in its place.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
if (size() <= 0) {
|
||||
return "{}";
|
||||
}
|
||||
|
||||
StringBuilder buffer = new StringBuilder(mSize * 28);
|
||||
buffer.append('{');
|
||||
for (int i=0; i<mSize; i++) {
|
||||
if (i > 0) {
|
||||
buffer.append(", ");
|
||||
}
|
||||
int key = keyAt(i);
|
||||
buffer.append(key);
|
||||
buffer.append('=');
|
||||
Object value = valueAt(i);
|
||||
if (value != this) {
|
||||
buffer.append(value);
|
||||
} else {
|
||||
buffer.append("(this Map)");
|
||||
}
|
||||
}
|
||||
buffer.append('}');
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
static int idealByteArraySize(int need) {
|
||||
for (int i = 4; i < 32; i++)
|
||||
if (need <= (1 << i) - 12)
|
||||
return (1 << i) - 12;
|
||||
|
||||
return need;
|
||||
}
|
||||
|
||||
static int idealBooleanArraySize(int need) {
|
||||
return idealByteArraySize(need);
|
||||
}
|
||||
|
||||
static int idealShortArraySize(int need) {
|
||||
return idealByteArraySize(need * 2) / 2;
|
||||
}
|
||||
|
||||
static int idealCharArraySize(int need) {
|
||||
return idealByteArraySize(need * 2) / 2;
|
||||
}
|
||||
|
||||
static int idealIntArraySize(int need) {
|
||||
return idealByteArraySize(need * 4) / 4;
|
||||
}
|
||||
|
||||
static int idealFloatArraySize(int need) {
|
||||
return idealByteArraySize(need * 4) / 4;
|
||||
}
|
||||
|
||||
static int idealObjectArraySize(int need) {
|
||||
return idealByteArraySize(need * 4) / 4;
|
||||
}
|
||||
|
||||
static int idealLongArraySize(int need) {
|
||||
return idealByteArraySize(need * 8) / 8;
|
||||
}
|
||||
|
||||
static class ContainerHelpers {
|
||||
static final boolean[] EMPTY_BOOLEANS = new boolean[0];
|
||||
static final int[] EMPTY_INTS = new int[0];
|
||||
static final long[] EMPTY_LONGS = new long[0];
|
||||
static final Object[] EMPTY_OBJECTS = new Object[0];
|
||||
|
||||
// This is Arrays.binarySearch(), but doesn't do any argument validation.
|
||||
static int binarySearch(int[] array, int size, int value) {
|
||||
int lo = 0;
|
||||
int hi = size - 1;
|
||||
|
||||
while (lo <= hi) {
|
||||
final int mid = (lo + hi) >>> 1;
|
||||
final int midVal = array[mid];
|
||||
|
||||
if (midVal < value) {
|
||||
lo = mid + 1;
|
||||
} else if (midVal > value) {
|
||||
hi = mid - 1;
|
||||
} else {
|
||||
return mid; // value found
|
||||
}
|
||||
}
|
||||
return ~lo; // value not present
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-3040
File diff suppressed because it is too large
Load Diff
-59
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.b44t.messenger.support.widget.util;
|
||||
|
||||
import com.b44t.messenger.support.util.SortedList;
|
||||
import com.b44t.messenger.support.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* A {@link SortedList.Callback} implementation that can bind a {@link SortedList} to a
|
||||
* {@link RecyclerView.Adapter}.
|
||||
*/
|
||||
public abstract class SortedListAdapterCallback<T2> extends SortedList.Callback<T2> {
|
||||
|
||||
final RecyclerView.Adapter mAdapter;
|
||||
|
||||
/**
|
||||
* Creates a {@link SortedList.Callback} that will forward data change events to the provided
|
||||
* Adapter.
|
||||
*
|
||||
* @param adapter The Adapter instance which should receive events from the SortedList.
|
||||
*/
|
||||
public SortedListAdapterCallback(RecyclerView.Adapter adapter) {
|
||||
mAdapter = adapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInserted(int position, int count) {
|
||||
mAdapter.notifyItemRangeInserted(position, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoved(int position, int count) {
|
||||
mAdapter.notifyItemRangeRemoved(position, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoved(int fromPosition, int toPosition) {
|
||||
mAdapter.notifyItemMoved(fromPosition, toPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChanged(int position, int count) {
|
||||
mAdapter.notifyItemRangeChanged(position, count);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger.video;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger.video;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger.video;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.messenger.video;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Messenger Android Frontend
|
||||
* Copyright (C) 2016 Björn Petersen Software Design and Development
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
@@ -20,7 +20,6 @@
|
||||
*******************************************************************************
|
||||
*
|
||||
* File: MrAccoutSettingsActivity.java
|
||||
* Authors: Björn Petersen
|
||||
* Purpose: Let the user configure his name
|
||||
*
|
||||
******************************************************************************/
|
||||
@@ -41,9 +40,7 @@ import android.widget.ListView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.b44t.messenger.AndroidUtilities;
|
||||
import com.b44t.messenger.ContactsController;
|
||||
import com.b44t.messenger.LocaleController;
|
||||
import com.b44t.messenger.MessagesController;
|
||||
import com.b44t.messenger.MrMailbox;
|
||||
import com.b44t.messenger.NotificationCenter;
|
||||
import com.b44t.messenger.R;
|
||||
@@ -53,7 +50,7 @@ import com.b44t.ui.ActionBar.ActionBarMenu;
|
||||
import com.b44t.ui.ActionBar.BaseFragment;
|
||||
import com.b44t.ui.Adapters.BaseFragmentAdapter;
|
||||
import com.b44t.ui.Cells.HeaderCell;
|
||||
import com.b44t.ui.Cells.MrEditTextCell;
|
||||
import com.b44t.ui.Cells.EditTextCell;
|
||||
import com.b44t.ui.Cells.ShadowSectionCell;
|
||||
import com.b44t.ui.Cells.TextInfoPrivacyCell;
|
||||
import com.b44t.ui.Components.LayoutHelper;
|
||||
@@ -88,15 +85,15 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
|
||||
private final int typeShadowSection = 2;
|
||||
private final int typeSection = 3;
|
||||
|
||||
MrEditTextCell addrCell; // warning all these objects may be null!
|
||||
MrEditTextCell mailPwCell;
|
||||
MrEditTextCell mailServerCell;
|
||||
MrEditTextCell mailPortCell;
|
||||
MrEditTextCell mailUserCell;
|
||||
MrEditTextCell sendPwCell;
|
||||
MrEditTextCell sendServerCell;
|
||||
MrEditTextCell sendPortCell;
|
||||
MrEditTextCell sendUserCell;
|
||||
EditTextCell addrCell; // warning all these objects may be null!
|
||||
EditTextCell mailPwCell;
|
||||
EditTextCell mailServerCell;
|
||||
EditTextCell mailPortCell;
|
||||
EditTextCell mailUserCell;
|
||||
EditTextCell sendPwCell;
|
||||
EditTextCell sendServerCell;
|
||||
EditTextCell sendPortCell;
|
||||
EditTextCell sendUserCell;
|
||||
|
||||
// misc.
|
||||
private View doneButton;
|
||||
@@ -312,7 +309,11 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.mainUserInfoChanged);
|
||||
}
|
||||
else {
|
||||
Toast.makeText(getParentActivity(), LocaleController.getString("CannotConnect", R.string.CannotConnect), Toast.LENGTH_LONG).show();
|
||||
String err = MrMailbox.getErrorDescr();
|
||||
if( err.isEmpty() ) {
|
||||
err = LocaleController.getString("CannotConnect", R.string.CannotConnect);
|
||||
}
|
||||
Toast.makeText(getParentActivity(), err, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -388,7 +389,7 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
|
||||
if (type == typeTextEntry) {
|
||||
if (i == rowAddr) {
|
||||
if( addrCell==null) {
|
||||
addrCell = new MrEditTextCell(mContext);
|
||||
addrCell = new EditTextCell(mContext);
|
||||
addrCell.setValueHintAndLabel(MrMailbox.getConfig("addr", ""),
|
||||
"", LocaleController.getString("MyEmailAddress", R.string.MyEmailAddress), false);
|
||||
addrCell.getEditTextView().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
|
||||
@@ -397,7 +398,7 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
|
||||
}
|
||||
else if (i == rowMailPw) {
|
||||
if( mailPwCell==null) {
|
||||
mailPwCell = new MrEditTextCell(mContext);
|
||||
mailPwCell = new EditTextCell(mContext);
|
||||
mailPwCell.setValueHintAndLabel(MrMailbox.getConfig("mail_pw", ""),
|
||||
"", LocaleController.getString("Password", R.string.Password), false);
|
||||
mailPwCell.getEditTextView().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||
@@ -406,7 +407,7 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
|
||||
}
|
||||
else if (i == rowMailServer) {
|
||||
if( mailServerCell==null) {
|
||||
mailServerCell = new MrEditTextCell(mContext);
|
||||
mailServerCell = new EditTextCell(mContext);
|
||||
mailServerCell.setValueHintAndLabel(MrMailbox.getConfig("mail_server", ""),
|
||||
LocaleController.getString("Automatic", R.string.Automatic), LocaleController.getString("ImapServer", R.string.ImapServer), false);
|
||||
}
|
||||
@@ -414,7 +415,7 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
|
||||
}
|
||||
else if (i == rowMailPort) {
|
||||
if( mailPortCell==null) {
|
||||
mailPortCell = new MrEditTextCell(mContext);
|
||||
mailPortCell = new EditTextCell(mContext);
|
||||
mailPortCell.setValueHintAndLabel(MrMailbox.getConfig("mail_port", ""),
|
||||
LocaleController.getString("Default", R.string.Default), LocaleController.getString("ImapPort", R.string.ImapPort), false);
|
||||
}
|
||||
@@ -422,7 +423,7 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
|
||||
}
|
||||
else if (i == rowMailUser) {
|
||||
if( mailUserCell==null) {
|
||||
mailUserCell = new MrEditTextCell(mContext);
|
||||
mailUserCell = new EditTextCell(mContext);
|
||||
mailUserCell.setValueHintAndLabel(MrMailbox.getConfig("mail_user", ""),
|
||||
LocaleController.getString("FromAbove", R.string.FromAbove), LocaleController.getString("ImapLoginname", R.string.ImapLoginname), false);
|
||||
}
|
||||
@@ -430,7 +431,7 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
|
||||
}
|
||||
else if (i == rowSendServer) {
|
||||
if( sendServerCell==null) {
|
||||
sendServerCell = new MrEditTextCell(mContext);
|
||||
sendServerCell = new EditTextCell(mContext);
|
||||
sendServerCell.setValueHintAndLabel(MrMailbox.getConfig("send_server", ""),
|
||||
LocaleController.getString("Automatic", R.string.Automatic), LocaleController.getString("SmtpServer", R.string.SmtpServer), false);
|
||||
}
|
||||
@@ -438,7 +439,7 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
|
||||
}
|
||||
else if (i == rowSendPort) {
|
||||
if( sendPortCell==null) {
|
||||
sendPortCell = new MrEditTextCell(mContext);
|
||||
sendPortCell = new EditTextCell(mContext);
|
||||
sendPortCell.setValueHintAndLabel(MrMailbox.getConfig("send_port", ""),
|
||||
LocaleController.getString("Default", R.string.Default), LocaleController.getString("SmtpPort", R.string.SmtpPort), false);
|
||||
}
|
||||
@@ -446,7 +447,7 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
|
||||
}
|
||||
else if (i == rowSendUser) {
|
||||
if( sendUserCell==null) {
|
||||
sendUserCell = new MrEditTextCell(mContext);
|
||||
sendUserCell = new EditTextCell(mContext);
|
||||
sendUserCell.setValueHintAndLabel(MrMailbox.getConfig("send_user", ""),
|
||||
LocaleController.getString("FromAbove", R.string.FromAbove), LocaleController.getString("SmtpLoginname", R.string.SmtpLoginname), false);
|
||||
}
|
||||
@@ -454,7 +455,7 @@ public class AccountSettingsActivity extends BaseFragment implements Notificatio
|
||||
}
|
||||
else if (i == rowSendPw) {
|
||||
if( sendPwCell==null) {
|
||||
sendPwCell = new MrEditTextCell(mContext);
|
||||
sendPwCell = new EditTextCell(mContext);
|
||||
sendPwCell.setValueHintAndLabel(MrMailbox.getConfig("send_pw", ""),
|
||||
LocaleController.getString("FromAbove", R.string.FromAbove), LocaleController.getString("SmtpPassword", R.string.SmtpPassword), false);
|
||||
sendPwCell.getEditTextView().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.ui.ActionBar;
|
||||
|
||||
@@ -43,14 +58,13 @@ public class ActionBar extends FrameLayout {
|
||||
private ImageView backButtonImageView;
|
||||
private SimpleTextView titleTextView;
|
||||
private SimpleTextView subtitleTextView;
|
||||
private View actionModeTop;
|
||||
//private View actionModeTop;
|
||||
private ActionBarMenu menu;
|
||||
private ActionBarMenu actionMode;
|
||||
private boolean occupyStatusBar = Build.VERSION.SDK_INT >= 21;
|
||||
private boolean actionModeVisible;
|
||||
private boolean addToContainer = true;
|
||||
private boolean interceptTouches = true;
|
||||
private int extraHeight;
|
||||
private AnimatorSet actionModeAnimation;
|
||||
|
||||
private boolean allowOverlayTitle;
|
||||
@@ -194,7 +208,7 @@ public class ActionBar extends FrameLayout {
|
||||
return actionMode;
|
||||
}
|
||||
actionMode = new ActionBarMenu(getContext(), this);
|
||||
actionMode.setBackgroundColor(0xffffffff);
|
||||
actionMode.setBackgroundColor(0xfff8f8f8);
|
||||
addView(actionMode, indexOfChild(backButtonImageView));
|
||||
actionMode.setPadding(0, occupyStatusBar ? AndroidUtilities.statusBarHeight : 0, 0, 0);
|
||||
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)actionMode.getLayoutParams();
|
||||
@@ -204,6 +218,7 @@ public class ActionBar extends FrameLayout {
|
||||
actionMode.setLayoutParams(layoutParams);
|
||||
actionMode.setVisibility(INVISIBLE);
|
||||
|
||||
/*
|
||||
if (occupyStatusBar && actionModeTop == null) {
|
||||
actionModeTop = new View(getContext());
|
||||
actionModeTop.setBackgroundColor(0x99000000);
|
||||
@@ -215,6 +230,7 @@ public class ActionBar extends FrameLayout {
|
||||
actionModeTop.setLayoutParams(layoutParams);
|
||||
actionModeTop.setVisibility(INVISIBLE);
|
||||
}
|
||||
*/
|
||||
|
||||
return actionMode;
|
||||
}
|
||||
@@ -226,9 +242,9 @@ public class ActionBar extends FrameLayout {
|
||||
actionModeVisible = true;
|
||||
ArrayList<Animator> animators = new ArrayList<>();
|
||||
animators.add(ObjectAnimator.ofFloat(actionMode, "alpha", 0.0f, 1.0f));
|
||||
if (occupyStatusBar && actionModeTop != null) {
|
||||
/*if (occupyStatusBar && actionModeTop != null) {
|
||||
animators.add(ObjectAnimator.ofFloat(actionModeTop, "alpha", 0.0f, 1.0f));
|
||||
}
|
||||
}*/
|
||||
if (actionModeAnimation != null) {
|
||||
actionModeAnimation.cancel();
|
||||
}
|
||||
@@ -239,9 +255,9 @@ public class ActionBar extends FrameLayout {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
actionMode.setVisibility(VISIBLE);
|
||||
if (occupyStatusBar && actionModeTop != null) {
|
||||
/*if (occupyStatusBar && actionModeTop != null) {
|
||||
actionModeTop.setVisibility(VISIBLE);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -284,9 +300,9 @@ public class ActionBar extends FrameLayout {
|
||||
actionModeVisible = false;
|
||||
ArrayList<Animator> animators = new ArrayList<>();
|
||||
animators.add(ObjectAnimator.ofFloat(actionMode, "alpha", 0.0f));
|
||||
if (occupyStatusBar && actionModeTop != null) {
|
||||
/*if (occupyStatusBar && actionModeTop != null) {
|
||||
animators.add(ObjectAnimator.ofFloat(actionModeTop, "alpha", 0.0f));
|
||||
}
|
||||
}*/
|
||||
if (actionModeAnimation != null) {
|
||||
actionModeAnimation.cancel();
|
||||
}
|
||||
@@ -299,9 +315,9 @@ public class ActionBar extends FrameLayout {
|
||||
if (actionModeAnimation != null && actionModeAnimation.equals(animation)) {
|
||||
actionModeAnimation = null;
|
||||
actionMode.setVisibility(INVISIBLE);
|
||||
if (occupyStatusBar && actionModeTop != null) {
|
||||
/*if (occupyStatusBar && actionModeTop != null) {
|
||||
actionModeTop.setVisibility(INVISIBLE);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,6 +347,7 @@ public class ActionBar extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public void showActionModeTop() {
|
||||
if (occupyStatusBar && actionModeTop == null) {
|
||||
actionModeTop = new View(getContext());
|
||||
@@ -343,6 +360,7 @@ public class ActionBar extends FrameLayout {
|
||||
actionModeTop.setLayoutParams(layoutParams);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public boolean isActionModeShowed() {
|
||||
return actionMode != null && actionModeVisible;
|
||||
@@ -366,10 +384,6 @@ public class ActionBar extends FrameLayout {
|
||||
interceptTouches = value;
|
||||
}
|
||||
|
||||
public void setExtraHeight(int value) {
|
||||
extraHeight = value;
|
||||
}
|
||||
|
||||
public void closeSearchField() {
|
||||
if (!isSearchFieldVisible || menu == null) {
|
||||
return;
|
||||
@@ -391,7 +405,7 @@ public class ActionBar extends FrameLayout {
|
||||
int actionBarHeight = getCurrentActionBarHeight();
|
||||
int actionBarHeightSpec = MeasureSpec.makeMeasureSpec(actionBarHeight, MeasureSpec.EXACTLY);
|
||||
|
||||
setMeasuredDimension(width, actionBarHeight + (occupyStatusBar ? AndroidUtilities.statusBarHeight : 0) + extraHeight);
|
||||
setMeasuredDimension(width, actionBarHeight + (occupyStatusBar ? AndroidUtilities.statusBarHeight : 0));
|
||||
|
||||
int textLeft;
|
||||
if (backButtonImageView != null && backButtonImageView.getVisibility() != GONE) {
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.ui.ActionBar;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.ui.ActionBar;
|
||||
|
||||
@@ -31,6 +46,7 @@ public class ActionBarMenu extends LinearLayout {
|
||||
super(context);
|
||||
}
|
||||
|
||||
/*
|
||||
public View addItemResource(int id, int resourceId) {
|
||||
LayoutInflater li = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
View view = li.inflate(resourceId, null);
|
||||
@@ -48,6 +64,7 @@ public class ActionBarMenu extends LinearLayout {
|
||||
});
|
||||
return view;
|
||||
}
|
||||
*/
|
||||
|
||||
public ActionBarMenuItem addItem(int id, Drawable drawable) { /* */
|
||||
return addItem(id, 0, parentActionBar.itemsBackgroundColor, drawable, AndroidUtilities.dp(48));
|
||||
@@ -129,10 +146,10 @@ public class ActionBarMenu extends LinearLayout {
|
||||
if (item.hasSubMenu()) {
|
||||
item.toggleSubMenu();
|
||||
break;
|
||||
} else if (item.overrideMenuClick) {
|
||||
} /*else if (item.overrideMenuClick) {
|
||||
onItemClick((Integer) item.getTag());
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.ui.ActionBar;
|
||||
|
||||
@@ -55,6 +70,12 @@ public class ActionBarMenuItem extends FrameLayout {
|
||||
|
||||
public void onSearchPressed(EditText editText) {
|
||||
}
|
||||
|
||||
public void onUpPressed() {
|
||||
}
|
||||
|
||||
public void onDownPressed() {
|
||||
}
|
||||
}
|
||||
|
||||
public interface ActionBarMenuItemDelegate {
|
||||
@@ -65,21 +86,23 @@ public class ActionBarMenuItem extends FrameLayout {
|
||||
private ActionBarMenu parentMenu;
|
||||
private ActionBarPopupWindow popupWindow;
|
||||
private EditText searchField;
|
||||
private ImageView clearButton;
|
||||
private ImageView searchUpButton;
|
||||
private ImageView searchDownButton;
|
||||
private SimpleTextView searchCountText;
|
||||
protected ImageView iconView;
|
||||
private FrameLayout searchContainer;
|
||||
private LinearLayout searchContainer;
|
||||
private boolean isSearchField = false;
|
||||
private ActionBarMenuItemSearchListener listener;
|
||||
private Rect rect;
|
||||
private int[] location;
|
||||
private View selectedMenuView;
|
||||
private Runnable showMenuRunnable;
|
||||
private boolean showFromBottom;
|
||||
//private boolean showFromBottom;
|
||||
private int menuHeight = AndroidUtilities.dp(16);
|
||||
private int subMenuOpenSide = 0;
|
||||
private ActionBarMenuItemDelegate delegate;
|
||||
private boolean allowCloseAnimation = true;
|
||||
protected boolean overrideMenuClick;
|
||||
//protected boolean overrideMenuClick;
|
||||
private boolean processedPopupClick;
|
||||
|
||||
public ActionBarMenuItem(Context context, ActionBarMenu menu, int backgroundColor) {
|
||||
@@ -179,12 +202,14 @@ public class ActionBarMenuItem extends FrameLayout {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
public void setShowFromBottom(boolean value) { /* */
|
||||
/*
|
||||
public void setShowFromBottom(boolean value) {
|
||||
showFromBottom = value;
|
||||
if (popupLayout != null) {
|
||||
popupLayout.setShowedFromBotton(showFromBottom);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public void setSubMenuOpenSide(int side) {
|
||||
subMenuOpenSide = side;
|
||||
@@ -239,7 +264,7 @@ public class ActionBarMenuItem extends FrameLayout {
|
||||
textView.setCompoundDrawablesWithIntrinsicBounds(null, null, getResources().getDrawable(icon), null);
|
||||
}
|
||||
}
|
||||
popupLayout.setShowedFromBotton(showFromBottom);
|
||||
//popupLayout.setShowedFromBotton(showFromBottom);
|
||||
popupLayout.addView(textView);
|
||||
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams();
|
||||
if (LocaleController.isRTL) {
|
||||
@@ -296,7 +321,8 @@ public class ActionBarMenuItem extends FrameLayout {
|
||||
popupWindow.setClippingEnabled(true);
|
||||
popupWindow.setInputMethodMode(ActionBarPopupWindow.INPUT_METHOD_NOT_NEEDED);
|
||||
popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED);
|
||||
popupLayout.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(1000), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(1000), MeasureSpec.AT_MOST));
|
||||
int wh = MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(1000), MeasureSpec.AT_MOST);
|
||||
popupLayout.measure(wh, wh);
|
||||
popupWindow.getContentView().setFocusableInTouchMode(true);
|
||||
popupWindow.getContentView().setOnKeyListener(new OnKeyListener() {
|
||||
@Override
|
||||
@@ -374,17 +400,19 @@ public class ActionBarMenuItem extends FrameLayout {
|
||||
return searchField;
|
||||
}
|
||||
|
||||
/*
|
||||
public ActionBarMenuItem setOverrideMenuClick(boolean value) {
|
||||
overrideMenuClick = value;
|
||||
return this;
|
||||
}
|
||||
*/
|
||||
|
||||
public ActionBarMenuItem setIsSearchField(boolean value) {
|
||||
public ActionBarMenuItem setIsSearchField(boolean value, boolean applyHack) {
|
||||
if (parentMenu == null) {
|
||||
return this;
|
||||
}
|
||||
if (value && searchContainer == null) {
|
||||
searchContainer = new FrameLayout(getContext());
|
||||
searchContainer = new LinearLayout(getContext());
|
||||
parentMenu.addView(searchContainer, 0);
|
||||
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) searchContainer.getLayoutParams();
|
||||
layoutParams.weight = 1;
|
||||
@@ -403,6 +431,7 @@ public class ActionBarMenuItem extends FrameLayout {
|
||||
searchField.setPadding(0, 0, 0, 0);
|
||||
int inputType = searchField.getInputType() | EditorInfo.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
|
||||
searchField.setInputType(inputType);
|
||||
searchField.setImeOptions(EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_EXTRACT_UI); // IME_ACTION_SEARCH is confusing as we use a real time search and the search is already performed when the user will hit the "search" button
|
||||
searchField.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
|
||||
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
||||
return false;
|
||||
@@ -443,9 +472,6 @@ public class ActionBarMenuItem extends FrameLayout {
|
||||
if (listener != null) {
|
||||
listener.onTextChanged(searchField);
|
||||
}
|
||||
if (clearButton != null) {
|
||||
clearButton.setAlpha(s == null || s.length() == 0 ? 0.6f : 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -461,38 +487,87 @@ public class ActionBarMenuItem extends FrameLayout {
|
||||
} catch (Exception e) {
|
||||
//nothing to do
|
||||
}
|
||||
searchField.setImeOptions(EditorInfo.IME_FLAG_NO_FULLSCREEN | EditorInfo.IME_ACTION_SEARCH);
|
||||
searchField.setTextIsSelectable(false);
|
||||
searchContainer.addView(searchField);
|
||||
FrameLayout.LayoutParams layoutParams2 = (FrameLayout.LayoutParams) searchField.getLayoutParams();
|
||||
layoutParams2.width = LayoutHelper.MATCH_PARENT;
|
||||
layoutParams2.gravity = Gravity.CENTER_VERTICAL;
|
||||
layoutParams2.height = AndroidUtilities.dp(36);
|
||||
layoutParams2.rightMargin = AndroidUtilities.dp(48);
|
||||
searchField.setLayoutParams(layoutParams2);
|
||||
if( applyHack ) {
|
||||
searchField.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (hasFocus) {
|
||||
// This is a HACK: normally, the soft keyboard should show up automatically whenever the user
|
||||
// clicks the search input field - however, if the user selected an item in the search and comes back to the search result,
|
||||
// a click on the search input field does ... nothing.
|
||||
AndroidUtilities.showKeyboard(v);
|
||||
// ... maybe re-setting the soft input mode may help, I've not tested this.
|
||||
// finally, a combinaction of showKeyboard()/hideKeyboard() will show up the keyboard on the next click, too.
|
||||
//parentMenu.getParent().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
clearButton = new ImageView(getContext());
|
||||
clearButton.setImageResource(R.drawable.ic_close_white);
|
||||
clearButton.setScaleType(ImageView.ScaleType.CENTER);
|
||||
clearButton.setOnClickListener(new OnClickListener() {
|
||||
searchContainer.addView(searchField, LayoutHelper.createLinear(48, 48, 10.0f, Gravity.CENTER_VERTICAL));
|
||||
|
||||
searchCountText = new SimpleTextView(getContext());
|
||||
searchCountText.setTextColor(Theme.ACTION_BAR_SUBTITLE_COLOR);
|
||||
searchCountText.setTextSize(14);
|
||||
searchCountText.setText("1/10");
|
||||
searchCountText.setVisibility(View.GONE);
|
||||
searchContainer.addView(searchCountText, LayoutHelper.createLinear(48, LayoutHelper.WRAP_CONTENT, Gravity.LEFT|Gravity.CENTER_VERTICAL));
|
||||
|
||||
searchUpButton = new ImageView(getContext());
|
||||
searchUpButton.setImageResource(R.drawable.search_up);
|
||||
searchUpButton.setScaleType(ImageView.ScaleType.CENTER);
|
||||
searchContainer.addView(searchUpButton, LayoutHelper.createLinear(48, 48, Gravity.CENTER_VERTICAL));
|
||||
searchUpButton.setVisibility(View.GONE);
|
||||
searchUpButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
searchField.setText("");
|
||||
searchField.requestFocus();
|
||||
AndroidUtilities.showKeyboard(searchField);
|
||||
listener.onUpPressed();
|
||||
}
|
||||
});
|
||||
|
||||
searchDownButton = new ImageView(getContext());
|
||||
searchDownButton.setImageResource(R.drawable.search_down);
|
||||
searchDownButton.setScaleType(ImageView.ScaleType.CENTER);
|
||||
searchContainer.addView(searchDownButton, LayoutHelper.createLinear(48, 48, Gravity.CENTER_VERTICAL));
|
||||
searchDownButton.setVisibility(View.GONE);
|
||||
searchDownButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
listener.onDownPressed();
|
||||
}
|
||||
});
|
||||
searchContainer.addView(clearButton);
|
||||
layoutParams2 = (FrameLayout.LayoutParams) clearButton.getLayoutParams();
|
||||
layoutParams2.width = AndroidUtilities.dp(48);
|
||||
layoutParams2.gravity = Gravity.CENTER_VERTICAL | Gravity.RIGHT;
|
||||
layoutParams2.height = LayoutHelper.MATCH_PARENT;
|
||||
clearButton.setLayoutParams(layoutParams2);
|
||||
}
|
||||
isSearchField = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setExtraSearchInfo(String text, boolean upDown, boolean enableUp, boolean enableDown)
|
||||
{
|
||||
if( searchCountText!=null && searchUpButton!=null && searchDownButton!=null ) {
|
||||
if( text!=null && !text.isEmpty() ) {
|
||||
searchCountText.setVisibility(View.VISIBLE);
|
||||
searchCountText.setText(text);
|
||||
}
|
||||
else {
|
||||
searchCountText.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if( upDown ) {
|
||||
searchUpButton.setVisibility(View.VISIBLE);
|
||||
searchUpButton.setEnabled(enableUp);
|
||||
searchUpButton.setAlpha(enableUp ? 1.0f : 0.25f);
|
||||
searchDownButton.setVisibility(View.VISIBLE);
|
||||
searchDownButton.setEnabled(enableDown);
|
||||
searchDownButton.setAlpha(enableDown ? 1.0f : 0.25f);
|
||||
}
|
||||
else {
|
||||
searchUpButton.setVisibility(View.GONE);
|
||||
searchDownButton.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSearchField() {
|
||||
return isSearchField;
|
||||
}
|
||||
@@ -517,16 +592,17 @@ public class ActionBarMenuItem extends FrameLayout {
|
||||
|
||||
private void updateOrShowPopup(boolean show, boolean update) {
|
||||
int offsetY;
|
||||
if (showFromBottom) {
|
||||
/*if (showFromBottom) {
|
||||
getLocationOnScreen(location);
|
||||
int diff = location[1] - AndroidUtilities.statusBarHeight + getMeasuredHeight() - menuHeight;
|
||||
offsetY = -menuHeight;
|
||||
if (diff < 0) {
|
||||
offsetY -= diff;
|
||||
}
|
||||
} else {
|
||||
} else*/ {
|
||||
if (parentMenu != null && subMenuOpenSide == 0) {
|
||||
offsetY = -parentMenu.parentActionBar.getMeasuredHeight() + parentMenu.getTop();
|
||||
ActionBarMenu pm = parentMenu.parentActionBar.createMenu(); // for normal items, this is identical to parentMenu; for the action bar we take the normal menu as a a reference for the position
|
||||
offsetY = -pm.parentActionBar.getMeasuredHeight() + pm.getTop();
|
||||
} else {
|
||||
offsetY = -getMeasuredHeight();
|
||||
}
|
||||
@@ -537,14 +613,14 @@ public class ActionBarMenuItem extends FrameLayout {
|
||||
}
|
||||
|
||||
if (subMenuOpenSide == 0) {
|
||||
if (showFromBottom) {
|
||||
/*if (showFromBottom) {
|
||||
if (show) {
|
||||
popupWindow.showAsDropDown(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth(), offsetY);
|
||||
}
|
||||
if (update) {
|
||||
popupWindow.update(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth(), offsetY, -1, -1);
|
||||
}
|
||||
} else {
|
||||
} else*/ {
|
||||
if (parentMenu != null) {
|
||||
View parent = parentMenu.parentActionBar;
|
||||
if (show) {
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
//Thanks to https://github.com/JakeWharton/ActionBarSherlock/
|
||||
|
||||
@@ -74,7 +89,7 @@ public class ActionBarPopupWindow extends PopupWindow {
|
||||
private float backScaleY = 1;
|
||||
private int backAlpha = 255;
|
||||
private int lastStartedChild = 0;
|
||||
private boolean showedFromBotton;
|
||||
//private boolean showedFromBotton;
|
||||
private HashMap<View, Integer> positions = new HashMap<>();
|
||||
|
||||
private ScrollView scrollView;
|
||||
@@ -108,9 +123,11 @@ public class ActionBarPopupWindow extends PopupWindow {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public void setShowedFromBotton(boolean value) {
|
||||
showedFromBotton = value;
|
||||
}
|
||||
*/
|
||||
|
||||
public void setDispatchKeyEventListener(OnDispatchKeyEventListener listener) {
|
||||
mOnDispatchKeyEventListener = listener;
|
||||
@@ -130,16 +147,16 @@ public class ActionBarPopupWindow extends PopupWindow {
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setBackScaleY(float value) {
|
||||
public void setBackScaleY(float value) { /* AFAIK this and the other "back" functions are used for some animations */
|
||||
backScaleY = value;
|
||||
if (animationEnabled) {
|
||||
int count = getItemsCount();
|
||||
int visibleCount = 0;
|
||||
/*int visibleCount = 0;
|
||||
for (int a = 0; a < count; a++) {
|
||||
visibleCount += getItemAt(a).getVisibility() == VISIBLE ? 1 : 0;
|
||||
}
|
||||
}*/
|
||||
int height = getMeasuredHeight() - AndroidUtilities.dp(16);
|
||||
if (showedFromBotton) {
|
||||
/*if (showedFromBotton) {
|
||||
for (int a = lastStartedChild; a >= 0; a--) {
|
||||
View child = getItemAt(a);
|
||||
if (child.getVisibility() != VISIBLE) {
|
||||
@@ -152,7 +169,7 @@ public class ActionBarPopupWindow extends PopupWindow {
|
||||
lastStartedChild = a - 1;
|
||||
startChildAnimation(child);
|
||||
}
|
||||
} else {
|
||||
} else*/ {
|
||||
for (int a = lastStartedChild; a < count; a++) {
|
||||
View child = getItemAt(a);
|
||||
if (child.getVisibility() != VISIBLE) {
|
||||
@@ -175,7 +192,7 @@ public class ActionBarPopupWindow extends PopupWindow {
|
||||
AnimatorSet animatorSet = new AnimatorSet();
|
||||
animatorSet.playTogether(
|
||||
ObjectAnimator.ofFloat(child, "alpha", 0.0f, 1.0f),
|
||||
ObjectAnimator.ofFloat(child, "translationY", AndroidUtilities.dp(showedFromBotton ? 6 : -6), 0));
|
||||
ObjectAnimator.ofFloat(child, "translationY", AndroidUtilities.dp(/*showedFromBotton ? 6 :*/ -6), 0));
|
||||
animatorSet.setDuration(180);
|
||||
animatorSet.setInterpolator(decelerateInterpolator);
|
||||
animatorSet.start();
|
||||
@@ -208,9 +225,9 @@ public class ActionBarPopupWindow extends PopupWindow {
|
||||
protected void onDraw(Canvas canvas) {
|
||||
if (backgroundDrawable != null) {
|
||||
backgroundDrawable.setAlpha(backAlpha);
|
||||
if (showedFromBotton) {
|
||||
/*if (showedFromBotton) {
|
||||
backgroundDrawable.setBounds(0, (int) (getMeasuredHeight() * (1.0f - backScaleY)), (int) (getMeasuredWidth() * backScaleX), getMeasuredHeight());
|
||||
} else {
|
||||
} else*/ {
|
||||
backgroundDrawable.setBounds(0, 0, (int) (getMeasuredWidth() * backScaleX), (int) (getMeasuredHeight() * backScaleY));
|
||||
}
|
||||
backgroundDrawable.draw(canvas);
|
||||
@@ -330,9 +347,9 @@ public class ActionBarPopupWindow extends PopupWindow {
|
||||
child.setAlpha(0.0f);
|
||||
visibleCount++;
|
||||
}
|
||||
if (content.showedFromBotton) {
|
||||
/*if (content.showedFromBotton) {
|
||||
content.lastStartedChild = count - 1;
|
||||
} else {
|
||||
} else*/ {
|
||||
content.lastStartedChild = 0;
|
||||
}
|
||||
windowAnimatorSet = new AnimatorSet();
|
||||
@@ -397,7 +414,7 @@ public class ActionBarPopupWindow extends PopupWindow {
|
||||
ActionBarPopupWindowLayout content = (ActionBarPopupWindowLayout) getContentView();
|
||||
windowAnimatorSet = new AnimatorSet();
|
||||
windowAnimatorSet.playTogether(
|
||||
ObjectAnimator.ofFloat(content, "translationY", AndroidUtilities.dp(content.showedFromBotton ? 5 : -5)),
|
||||
ObjectAnimator.ofFloat(content, "translationY", AndroidUtilities.dp(/*content.showedFromBotton ? 5 :*/ -5)),
|
||||
ObjectAnimator.ofFloat(content, "alpha", 0.0f));
|
||||
windowAnimatorSet.setDuration(150);
|
||||
windowAnimatorSet.addListener(new Animator.AnimatorListener() {
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.ui.ActionBar;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.ui.ActionBar;
|
||||
|
||||
@@ -304,12 +319,4 @@ public class BaseFragment {
|
||||
protected void onDialogDismiss(Dialog dialog) {
|
||||
|
||||
}
|
||||
|
||||
public Dialog getVisibleDialog() {
|
||||
return visibleDialog;
|
||||
}
|
||||
|
||||
public void setVisibleDialog(Dialog dialog) {
|
||||
visibleDialog = dialog;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.ui.ActionBar;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.ui.ActionBar;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.ui.ActionBar;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.ui.ActionBar;
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.ui.ActionBar;
|
||||
|
||||
@@ -24,10 +39,11 @@ import android.os.Build;
|
||||
import com.b44t.messenger.AndroidUtilities;
|
||||
import com.b44t.messenger.ApplicationLoader;
|
||||
import com.b44t.messenger.R;
|
||||
import com.b44t.ui.Components.ChatAttachAlert;
|
||||
|
||||
public class Theme {
|
||||
|
||||
public static final int ACTION_BAR_COLOR = 0xff415e6b;
|
||||
public static final int ACTION_BAR_COLOR = 0xff415e6b; // also used for the notification icon background
|
||||
public static final int ACTION_BAR_PHOTO_VIEWER_COLOR = 0x7f000000;
|
||||
public static final int ACTION_BAR_MEDIA_PICKER_COLOR = 0xff333333;
|
||||
public static final int ACTION_BAR_PLAYER_COLOR = 0xffffffff;
|
||||
@@ -52,21 +68,14 @@ public class Theme {
|
||||
public static final int DIALOGS_PRINTING_TEXT_COLOR = 0xff4d83b3;
|
||||
public static final int DIALOGS_DRAFT_TEXT_COLOR = 0xffdd4b39;
|
||||
|
||||
public static final int CHAT_UNREAD_TEXT_COLOR = 0xff5695cc;
|
||||
public static final int CHAT_ADD_CONTACT_TEXT_COLOR = 0xff4a82b5;
|
||||
public static final int CHAT_REPORT_SPAM_TEXT_COLOR = 0xffcf5957;
|
||||
public static final int CHAT_BOTTOM_OVERLAY_TEXT_COLOR = 0xff7f7f7f;
|
||||
public static final int CHAT_GIF_HINT_TEXT_COLOR = 0xffffffff;
|
||||
public static final int CHAT_EMPTY_VIEW_TEXT_COLOR = 0xffffffff;
|
||||
public static final int CHAT_SEARCH_COUNT_TEXT_COLOR = 0xff4e9ad4;
|
||||
|
||||
public static final int INAPP_PLAYER_PERFORMER_TEXT_COLOR = 0xff2f3438;
|
||||
public static final int INAPP_PLAYER_TITLE_TEXT_COLOR = 0xff2f3438;
|
||||
public static final int INAPP_PLAYER_BACKGROUND_COLOR = 0xffffffff;
|
||||
|
||||
public static final int REPLY_PANEL_NAME_TEXT_COLOR = 0xff3a8ccf;
|
||||
public static final int REPLY_PANEL_MESSAGE_TEXT_COLOR = 0xff222222;
|
||||
|
||||
public static final int ALERT_PANEL_NAME_TEXT_COLOR = 0xff3a8ccf;
|
||||
public static final int ALERT_PANEL_MESSAGE_TEXT_COLOR = 0xff999999;
|
||||
|
||||
@@ -80,7 +89,6 @@ public class Theme {
|
||||
|
||||
public static final int MSG_SELECTED_BACKGROUND_COLOR = 0x6633b5e5;
|
||||
public static final int MSG_WEB_PREVIEW_DURATION_TEXT_COLOR = 0xffffffff;
|
||||
public static final int MSG_SECRET_TIME_TEXT_COLOR = 0xffe4e2e0;
|
||||
public static final int MSG_STICKER_NAME_TEXT_COLOR = 0xffffffff;
|
||||
public static final int MSG_IN_FORDWARDED_NAME_TEXT_COLOR = 0xff3886c7;
|
||||
public static final int MSG_OUT_FORDWARDED_NAME_TEXT_COLOR = 0xff55ab4f;
|
||||
@@ -166,10 +174,6 @@ public class Theme {
|
||||
public static Drawable backgroundDrawableInSelected;
|
||||
public static Drawable backgroundDrawableOut;
|
||||
public static Drawable backgroundDrawableOutSelected;
|
||||
public static Drawable backgroundMediaDrawableIn;
|
||||
public static Drawable backgroundMediaDrawableInSelected;
|
||||
public static Drawable backgroundMediaDrawableOut;
|
||||
public static Drawable backgroundMediaDrawableOutSelected;
|
||||
public static Drawable checkDrawable;
|
||||
public static Drawable halfCheckDrawable;
|
||||
public static Drawable clockDrawable;
|
||||
@@ -208,10 +212,6 @@ public class Theme {
|
||||
backgroundDrawableInSelected = context.getResources().getDrawable(R.drawable.msg_in_selected);
|
||||
backgroundDrawableOut = context.getResources().getDrawable(R.drawable.msg_out);
|
||||
backgroundDrawableOutSelected = context.getResources().getDrawable(R.drawable.msg_out_selected);
|
||||
backgroundMediaDrawableIn = context.getResources().getDrawable(R.drawable.msg_in_photo);
|
||||
backgroundMediaDrawableInSelected = context.getResources().getDrawable(R.drawable.msg_in_photo_selected);
|
||||
backgroundMediaDrawableOut = context.getResources().getDrawable(R.drawable.msg_out_photo);
|
||||
backgroundMediaDrawableOutSelected = context.getResources().getDrawable(R.drawable.msg_out_photo_selected);
|
||||
checkDrawable = context.getResources().getDrawable(R.drawable.msg_check);
|
||||
halfCheckDrawable = context.getResources().getDrawable(R.drawable.msg_halfcheck);
|
||||
clockDrawable = context.getResources().getDrawable(R.drawable.msg_clock);
|
||||
@@ -281,9 +281,6 @@ public class Theme {
|
||||
|
||||
shareIconDrawable = context.getResources().getDrawable(R.drawable.ic_ab_reply);
|
||||
|
||||
geoInDrawable = context.getResources().getDrawable(R.drawable.location_b);
|
||||
geoOutDrawable = context.getResources().getDrawable(R.drawable.location_g);
|
||||
|
||||
cornerOuter[0] = context.getResources().getDrawable(R.drawable.corner_out_tl);
|
||||
cornerOuter[1] = context.getResources().getDrawable(R.drawable.corner_out_tr);
|
||||
cornerOuter[2] = context.getResources().getDrawable(R.drawable.corner_out_br);
|
||||
@@ -310,14 +307,14 @@ public class Theme {
|
||||
|
||||
public static void loadChatResources(Context context) {
|
||||
if (attachButtonDrawables[0] == null) {
|
||||
attachButtonDrawables[0] = context.getResources().getDrawable(R.drawable.attach_camera_states);
|
||||
attachButtonDrawables[1] = context.getResources().getDrawable(R.drawable.attach_gallery_states);
|
||||
attachButtonDrawables[2] = context.getResources().getDrawable(R.drawable.attach_video_states);
|
||||
attachButtonDrawables[3] = context.getResources().getDrawable(R.drawable.attach_audio_states);
|
||||
attachButtonDrawables[4] = context.getResources().getDrawable(R.drawable.attach_file_states);
|
||||
attachButtonDrawables[5] = context.getResources().getDrawable(R.drawable.attach_contact_states);
|
||||
attachButtonDrawables[6] = context.getResources().getDrawable(R.drawable.attach_location_states);
|
||||
attachButtonDrawables[7] = context.getResources().getDrawable(R.drawable.attach_hide_states);
|
||||
attachButtonDrawables[ChatAttachAlert.ATTACH_BUTTON_IDX_CAMERA] = context.getResources().getDrawable(R.drawable.attach_camera_states);
|
||||
attachButtonDrawables[ChatAttachAlert.ATTACH_BUTTON_IDX_GALLERY] = context.getResources().getDrawable(R.drawable.attach_gallery_states);
|
||||
attachButtonDrawables[ChatAttachAlert.ATTACH_BUTTON_IDX_VIDEO] = context.getResources().getDrawable(R.drawable.attach_video_states);
|
||||
attachButtonDrawables[ChatAttachAlert.ATTACH_BUTTON_IDX_MUSIC] = context.getResources().getDrawable(R.drawable.attach_audio_states);
|
||||
attachButtonDrawables[ChatAttachAlert.ATTACH_BUTTON_IDX_FILE] = context.getResources().getDrawable(R.drawable.attach_file_states);
|
||||
attachButtonDrawables[ChatAttachAlert.ATTACH_BUTTON_IDX_CONTACT] = context.getResources().getDrawable(R.drawable.attach_contact_states);
|
||||
attachButtonDrawables[ChatAttachAlert.ATTACH_BUTTON_IDX_LOCATION] = context.getResources().getDrawable(R.drawable.attach_location_states);
|
||||
attachButtonDrawables[ChatAttachAlert.ATTACH_BUTTON_IDX_SENDSELECTED]= context.getResources().getDrawable(R.drawable.attach_hide_states);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 1.3.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.ui.Adapters;
|
||||
|
||||
|
||||
@@ -1,212 +0,0 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
|
||||
package com.b44t.ui.Adapters;
|
||||
|
||||
import com.b44t.messenger.ConnectionsManager;
|
||||
import com.b44t.messenger.TLObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class BaseSearchAdapter extends BaseFragmentAdapter {
|
||||
|
||||
protected static class HashtagObject {
|
||||
}
|
||||
|
||||
protected ArrayList<TLObject> globalSearch = new ArrayList<>();
|
||||
private int reqId = 0;
|
||||
protected String lastFoundUsername = null;
|
||||
|
||||
protected ArrayList<HashtagObject> hashtags;
|
||||
|
||||
public void queryServerSearch(final String query, final boolean allowChats, final boolean allowBots) {
|
||||
if (reqId != 0) {
|
||||
ConnectionsManager.getInstance().cancelRequest(reqId, true);
|
||||
reqId = 0;
|
||||
}
|
||||
if (query == null || query.length() < 5) {
|
||||
globalSearch.clear();
|
||||
notifyDataSetChanged();
|
||||
return;
|
||||
}
|
||||
/*TLRPC.TL_contacts_search req = new TLRPC.TL_contacts_search();
|
||||
req.q = query;
|
||||
req.limit = 50;*/
|
||||
/*final int currentReqId = ++lastReqId; */
|
||||
reqId = 0; /* ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(final TLObject response, final TLRPC.TL_error error) {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (currentReqId == lastReqId) {
|
||||
if (error == null) {
|
||||
TLRPC.TL_contacts_found res = (TLRPC.TL_contacts_found) response;
|
||||
globalSearch.clear();
|
||||
if (allowChats) {
|
||||
for (int a = 0; a < res.chats.size(); a++) {
|
||||
globalSearch.add(res.chats.get(a));
|
||||
}
|
||||
}
|
||||
for (int a = 0; a < res.users.size(); a++) {
|
||||
if (!allowBots && res.users.get(a).bot) {
|
||||
continue;
|
||||
}
|
||||
globalSearch.add(res.users.get(a));
|
||||
}
|
||||
lastFoundUsername = query;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
reqId = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
}, ConnectionsManager.RequestFlagFailOnServerErrors);*/
|
||||
}
|
||||
|
||||
/*
|
||||
public void loadRecentHashtags() {
|
||||
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT id, date FROM hashtag_recent_v2 WHERE 1");
|
||||
final ArrayList<HashtagObject> arrayList = new ArrayList<>();
|
||||
final HashMap<String, HashtagObject> hashMap = new HashMap<>();
|
||||
while (cursor.next()) {
|
||||
HashtagObject hashtagObject = new HashtagObject();
|
||||
hashtagObject.hashtag = cursor.stringValue(0);
|
||||
hashtagObject.date = cursor.intValue(1);
|
||||
arrayList.add(hashtagObject);
|
||||
hashMap.put(hashtagObject.hashtag, hashtagObject);
|
||||
}
|
||||
cursor.dispose();
|
||||
Collections.sort(arrayList, new Comparator<HashtagObject>() {
|
||||
@Override
|
||||
public int compare(HashtagObject lhs, HashtagObject rhs) {
|
||||
if (lhs.date < rhs.date) {
|
||||
return 1;
|
||||
} else if (lhs.date > rhs.date) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setHashtags(arrayList, hashMap);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
public void addHashtagsFromMessage(String message) {
|
||||
if (message == null) {
|
||||
return;
|
||||
}
|
||||
boolean changed = false;
|
||||
Pattern pattern = Pattern.compile("(^|\\s)#[\\w@\\.]+");
|
||||
Matcher matcher = pattern.matcher(message);
|
||||
while (matcher.find()) {
|
||||
int start = matcher.start();
|
||||
int end = matcher.end();
|
||||
if (message.charAt(start) != '@' && message.charAt(start) != '#') {
|
||||
start++;
|
||||
}
|
||||
String hashtag = message.substring(start, end);
|
||||
if (hashtagsByText == null) {
|
||||
hashtagsByText = new HashMap<>();
|
||||
hashtags = new ArrayList<>();
|
||||
}
|
||||
HashtagObject hashtagObject = hashtagsByText.get(hashtag);
|
||||
if (hashtagObject == null) {
|
||||
hashtagObject = new HashtagObject();
|
||||
hashtagObject.hashtag = hashtag;
|
||||
hashtagsByText.put(hashtagObject.hashtag, hashtagObject);
|
||||
} else {
|
||||
hashtags.remove(hashtagObject);
|
||||
}
|
||||
hashtagObject.date = (int) (System.currentTimeMillis() / 1000);
|
||||
hashtags.add(0, hashtagObject);
|
||||
changed = true;
|
||||
}
|
||||
if (changed) {
|
||||
putRecentHashtags(hashtags);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
private void putRecentHashtags(final ArrayList<HashtagObject> arrayList) {
|
||||
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
MessagesStorage.getInstance().getDatabase().beginTransaction();
|
||||
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO hashtag_recent_v2 VALUES(?, ?)");
|
||||
for (int a = 0; a < arrayList.size(); a++) {
|
||||
if (a == 100) {
|
||||
break;
|
||||
}
|
||||
HashtagObject hashtagObject = arrayList.get(a);
|
||||
state.requery();
|
||||
state.bindString(1, hashtagObject.hashtag);
|
||||
state.bindInteger(2, hashtagObject.date);
|
||||
state.step();
|
||||
}
|
||||
state.dispose();
|
||||
MessagesStorage.getInstance().getDatabase().commitTransaction();
|
||||
if (arrayList.size() >= 100) {
|
||||
MessagesStorage.getInstance().getDatabase().beginTransaction();
|
||||
for (int a = 100; a < arrayList.size(); a++) {
|
||||
MessagesStorage.getInstance().getDatabase().executeFast("DELETE FROM hashtag_recent_v2 WHERE id = '" + arrayList.get(a).hashtag + "'").stepThis().dispose();
|
||||
}
|
||||
MessagesStorage.getInstance().getDatabase().commitTransaction();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
public void clearRecentHashtags() {
|
||||
hashtags = new ArrayList<>();
|
||||
hashtagsByText = new HashMap<>();
|
||||
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
MessagesStorage.getInstance().getDatabase().executeFast("DELETE FROM hashtag_recent_v2 WHERE 1").stepThis().dispose();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
protected void setHashtags(ArrayList<HashtagObject> arrayList, HashMap<String, HashtagObject> hashMap) {
|
||||
hashtags = arrayList;
|
||||
hashtagsByText = hashMap;
|
||||
hashtagsLoadedFromDb = true;
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -1,213 +0,0 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 3.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
|
||||
package com.b44t.ui.Adapters;
|
||||
|
||||
import com.b44t.messenger.support.widget.RecyclerView;
|
||||
import com.b44t.messenger.ConnectionsManager;
|
||||
import com.b44t.messenger.TLObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public abstract class BaseSearchAdapterRecycler extends RecyclerView.Adapter {
|
||||
|
||||
protected static class HashtagObject {
|
||||
String hashtag;
|
||||
int date;
|
||||
}
|
||||
|
||||
protected ArrayList<TLObject> globalSearch = new ArrayList<>();
|
||||
private int reqId = 0;
|
||||
protected String lastFoundUsername = null;
|
||||
|
||||
protected ArrayList<HashtagObject> hashtags;
|
||||
protected HashMap<String, HashtagObject> hashtagsByText;
|
||||
protected boolean hashtagsLoadedFromDb = false;
|
||||
|
||||
public void queryServerSearch(final String query, final boolean allowChats) {
|
||||
if (reqId != 0) {
|
||||
ConnectionsManager.getInstance().cancelRequest(reqId, true);
|
||||
reqId = 0;
|
||||
}
|
||||
if (query == null || query.length() < 5) {
|
||||
globalSearch.clear();
|
||||
notifyDataSetChanged();
|
||||
return;
|
||||
}
|
||||
/*TLRPC.TL_contacts_search req = new TLRPC.TL_contacts_search();
|
||||
req.q = query;
|
||||
req.limit = 50;*/
|
||||
/*final int currentReqId = ++lastReqId; =*/
|
||||
reqId = 0; /*ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(final TLObject response, final TLRPC.TL_error error) {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (currentReqId == lastReqId) {
|
||||
if (error == null) {
|
||||
TLRPC.TL_contacts_found res = (TLRPC.TL_contacts_found) response;
|
||||
globalSearch.clear();
|
||||
if (allowChats) {
|
||||
for (int a = 0; a < res.chats.size(); a++) {
|
||||
globalSearch.add(res.chats.get(a));
|
||||
}
|
||||
}
|
||||
for (int a = 0; a < res.users.size(); a++) {
|
||||
globalSearch.add(res.users.get(a));
|
||||
}
|
||||
lastFoundUsername = query;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
reqId = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
}, ConnectionsManager.RequestFlagFailOnServerErrors);*/
|
||||
}
|
||||
|
||||
public void loadRecentHashtags() {
|
||||
/*
|
||||
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT id, date FROM hashtag_recent_v2 WHERE 1");
|
||||
final ArrayList<HashtagObject> arrayList = new ArrayList<>();
|
||||
final HashMap<String, HashtagObject> hashMap = new HashMap<>();
|
||||
while (cursor.next()) {
|
||||
HashtagObject hashtagObject = new HashtagObject();
|
||||
hashtagObject.hashtag = cursor.stringValue(0);
|
||||
hashtagObject.date = cursor.intValue(1);
|
||||
arrayList.add(hashtagObject);
|
||||
hashMap.put(hashtagObject.hashtag, hashtagObject);
|
||||
}
|
||||
cursor.dispose();
|
||||
Collections.sort(arrayList, new Comparator<HashtagObject>() {
|
||||
@Override
|
||||
public int compare(HashtagObject lhs, HashtagObject rhs) {
|
||||
if (lhs.date < rhs.date) {
|
||||
return 1;
|
||||
} else if (lhs.date > rhs.date) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setHashtags(arrayList, hashMap);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
public void addHashtagsFromMessage(CharSequence message) {
|
||||
if (message == null) {
|
||||
return;
|
||||
}
|
||||
boolean changed = false;
|
||||
Pattern pattern = Pattern.compile("(^|\\s)#[\\w@\\.]+");
|
||||
Matcher matcher = pattern.matcher(message);
|
||||
while (matcher.find()) {
|
||||
int start = matcher.start();
|
||||
int end = matcher.end();
|
||||
if (message.charAt(start) != '@' && message.charAt(start) != '#') {
|
||||
start++;
|
||||
}
|
||||
String hashtag = message.subSequence(start, end).toString();
|
||||
if (hashtagsByText == null) {
|
||||
hashtagsByText = new HashMap<>();
|
||||
hashtags = new ArrayList<>();
|
||||
}
|
||||
HashtagObject hashtagObject = hashtagsByText.get(hashtag);
|
||||
if (hashtagObject == null) {
|
||||
hashtagObject = new HashtagObject();
|
||||
hashtagObject.hashtag = hashtag;
|
||||
hashtagsByText.put(hashtagObject.hashtag, hashtagObject);
|
||||
} else {
|
||||
hashtags.remove(hashtagObject);
|
||||
}
|
||||
hashtagObject.date = (int) (System.currentTimeMillis() / 1000);
|
||||
hashtags.add(0, hashtagObject);
|
||||
changed = true;
|
||||
}
|
||||
if (changed) {
|
||||
putRecentHashtags(hashtags);
|
||||
}
|
||||
}
|
||||
|
||||
private void putRecentHashtags(final ArrayList<HashtagObject> arrayList) {
|
||||
/*
|
||||
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
MessagesStorage.getInstance().getDatabase().beginTransaction();
|
||||
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO hashtag_recent_v2 VALUES(?, ?)");
|
||||
for (int a = 0; a < arrayList.size(); a++) {
|
||||
if (a == 100) {
|
||||
break;
|
||||
}
|
||||
HashtagObject hashtagObject = arrayList.get(a);
|
||||
state.requery();
|
||||
state.bindString(1, hashtagObject.hashtag);
|
||||
state.bindInteger(2, hashtagObject.date);
|
||||
state.step();
|
||||
}
|
||||
state.dispose();
|
||||
MessagesStorage.getInstance().getDatabase().commitTransaction();
|
||||
if (arrayList.size() >= 100) {
|
||||
MessagesStorage.getInstance().getDatabase().beginTransaction();
|
||||
for (int a = 100; a < arrayList.size(); a++) {
|
||||
MessagesStorage.getInstance().getDatabase().executeFast("DELETE FROM hashtag_recent_v2 WHERE id = '" + arrayList.get(a).hashtag + "'").stepThis().dispose();
|
||||
}
|
||||
MessagesStorage.getInstance().getDatabase().commitTransaction();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
public void clearRecentHashtags() {
|
||||
hashtags = new ArrayList<>();
|
||||
hashtagsByText = new HashMap<>();
|
||||
/*
|
||||
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
MessagesStorage.getInstance().getDatabase().executeFast("DELETE FROM hashtag_recent_v2 WHERE 1").stepThis().dispose();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("messenger", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
protected void setHashtags(ArrayList<HashtagObject> arrayList, HashMap<String, HashtagObject> hashMap) {
|
||||
hashtags = arrayList;
|
||||
hashtagsByText = hashMap;
|
||||
hashtagsLoadedFromDb = true;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,25 @@
|
||||
/*
|
||||
* This part of the Delta Chat fronted is based on Telegram which is covered by the following note:
|
||||
/*******************************************************************************
|
||||
*
|
||||
* This is the source code of Telegram for Android v. 1.3.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
* Messenger Android Frontend
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2016.
|
||||
*/
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
package com.b44t.ui.Adapters;
|
||||
|
||||
@@ -82,8 +95,7 @@ public class ContactsAdapter extends BaseFragmentAdapter {
|
||||
if(curr_user_index>=0 && curr_user_index<contactIds.length) {
|
||||
int curr_user_id = contactIds[curr_user_index];
|
||||
MrContact mrContact = MrMailbox.getContact(curr_user_id);
|
||||
((UserCell) convertView).setData(curr_user_id, 0, mrContact.getDisplayName(),
|
||||
mrContact.getAddr(), 0);
|
||||
((UserCell) convertView).setData(mrContact, 0);
|
||||
if (checkedMap != null) {
|
||||
((UserCell) convertView).setChecked(checkedMap.containsKey(curr_user_id), !scrolling);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user