mirror of
https://github.com/MGislv/NekoX.git
synced 2024-06-30 22:22:57 +00:00
Update to 3.3.1
This commit is contained in:
parent
496c336d5f
commit
74def22213
|
@ -7,22 +7,16 @@ repositories {
|
|||
dependencies {
|
||||
compile 'com.android.support:support-v4:23.1.+'
|
||||
compile 'com.google.android.gms:play-services:3.2.+'
|
||||
compile 'net.hockeyapp.android:HockeySDK:3.5.+'
|
||||
compile 'net.hockeyapp.android:HockeySDK:3.6.+'
|
||||
compile 'com.googlecode.mp4parser:isoparser:1.0.+'
|
||||
compile 'org.apache.httpcomponents:httpmime:4.2.1'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion '23.0.1'
|
||||
buildToolsVersion '23.0.2'
|
||||
|
||||
useLibrary 'org.apache.http.legacy'
|
||||
|
||||
packagingOptions {
|
||||
exclude 'META-INF/NOTICE.txt'
|
||||
exclude 'META-INF/LICENSE.txt'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
|
@ -30,7 +24,10 @@ android {
|
|||
|
||||
signingConfigs {
|
||||
debug {
|
||||
storeFile file("config/debug.keystore")
|
||||
storeFile file("config/release.keystore")
|
||||
storePassword RELEASE_STORE_PASSWORD
|
||||
keyAlias RELEASE_KEY_ALIAS
|
||||
keyPassword RELEASE_KEY_PASSWORD
|
||||
}
|
||||
|
||||
release {
|
||||
|
@ -46,6 +43,7 @@ android {
|
|||
debuggable true
|
||||
jniDebuggable true
|
||||
signingConfig signingConfigs.debug
|
||||
applicationIdSuffix ".beta"
|
||||
}
|
||||
|
||||
release {
|
||||
|
@ -81,7 +79,7 @@ android {
|
|||
defaultConfig {
|
||||
minSdkVersion 8
|
||||
targetSdkVersion 23
|
||||
versionCode 654
|
||||
versionName "3.2.6"
|
||||
versionCode 685
|
||||
versionName "3.3.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,13 +21,13 @@
|
|||
<application
|
||||
android:allowBackup="false"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/AppName"
|
||||
android:label="@string/AppNameBeta"
|
||||
android:theme="@style/Theme.TMessages.Start"
|
||||
android:name=".ApplicationLoader"
|
||||
android:hardwareAccelerated="@bool/useHardwareAcceleration"
|
||||
android:largeHeap="true">
|
||||
|
||||
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzaSyCTNmNqbWovP9ETcAob98YlrfOQEAC0CJ4" />
|
||||
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzaSyA-t0jLPjUt2FxrA8VPK2EiYHcYcboIR6k" />
|
||||
|
||||
<activity android:name="net.hockeyapp.android.UpdateActivity" />
|
||||
|
||||
|
|
|
@ -187,7 +187,7 @@ include $(CLEAR_VARS)
|
|||
LOCAL_PRELINK_MODULE := false
|
||||
LOCAL_STATIC_LIBRARIES := webp sqlite tgnet breakpad
|
||||
|
||||
LOCAL_MODULE := tmessages.14
|
||||
LOCAL_MODULE := tmessages.15
|
||||
LOCAL_CFLAGS := -w -std=c11 -Os -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64
|
||||
LOCAL_CFLAGS += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -fno-math-errno
|
||||
LOCAL_CFLAGS += -DANDROID_NDK -DDISABLE_IMPORTGL -fno-strict-aliasing -fprefetch-loop-arrays -DAVOID_TABLES -DANDROID_TILE_BASED_DECODE -DANDROID_ARMV6_IDCT -ffast-math
|
||||
|
|
|
@ -96,7 +96,7 @@ void sendRequest(JNIEnv *env, jclass c, jint object, jobject onComplete, jobject
|
|||
if (onQuickAck != nullptr) {
|
||||
jniEnv->CallVoidMethod(onQuickAck, jclass_QuickAckDelegate_run);
|
||||
}
|
||||
}), flags, datacenterId, (ConnectionType) connetionType, immediate, onComplete, onQuickAck);
|
||||
}), flags, datacenterId, (ConnectionType) connetionType, immediate, token, onComplete, onQuickAck);
|
||||
}
|
||||
|
||||
void cancelRequest(JNIEnv *env, jclass c, jint token, jboolean notifyServer) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -31,7 +31,7 @@
|
|||
** part of the build process.
|
||||
*/
|
||||
#ifndef _SQLITE3_H_
|
||||
#define _SQLITE3_H_
|
||||
#define _SQLITE3_H_
|
||||
#include <stdarg.h> /* Needed for the definition of va_list */
|
||||
|
||||
/*
|
||||
|
@ -111,9 +111,9 @@ extern "C" {
|
|||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||
** [sqlite_version()] and [sqlite_source_id()].
|
||||
*/
|
||||
#define SQLITE_VERSION "3.8.11.1"
|
||||
#define SQLITE_VERSION_NUMBER 3008011
|
||||
#define SQLITE_SOURCE_ID "2015-07-29 20:00:57 cf538e2783e468bbc25e7cb2a9ee64d3e0e80b2f"
|
||||
#define SQLITE_VERSION "3.9.2"
|
||||
#define SQLITE_VERSION_NUMBER 3009002
|
||||
#define SQLITE_SOURCE_ID "2015-11-02 18:31:45 bda77dda9697c463c3d0704014d51627fceee328"
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-Time Library Version Numbers
|
||||
|
@ -124,7 +124,7 @@ extern "C" {
|
|||
** but are associated with the library instead of the header file. ^(Cautious
|
||||
** programmers might include assert() statements in their application to
|
||||
** verify that values returned by these interfaces match the macros in
|
||||
** the header, and thus insure that the application is
|
||||
** the header, and thus ensure that the application is
|
||||
** compiled with matching library and header files.
|
||||
**
|
||||
** <blockquote><pre>
|
||||
|
@ -374,7 +374,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
|
|||
** Restrictions:
|
||||
**
|
||||
** <ul>
|
||||
** <li> The application must insure that the 1st parameter to sqlite3_exec()
|
||||
** <li> The application must ensure that the 1st parameter to sqlite3_exec()
|
||||
** is a valid and open [database connection].
|
||||
** <li> The application must not close the [database connection] specified by
|
||||
** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running.
|
||||
|
@ -477,6 +477,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_exec(
|
|||
#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8))
|
||||
#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8))
|
||||
#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8))
|
||||
#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
|
||||
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
|
||||
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
|
||||
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
|
||||
|
@ -1366,9 +1367,11 @@ SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void);
|
|||
** applications and so this routine is usually not necessary. It is
|
||||
** provided to support rare applications with unusual needs.
|
||||
**
|
||||
** The sqlite3_config() interface is not threadsafe. The application
|
||||
** must insure that no other SQLite interfaces are invoked by other
|
||||
** threads while sqlite3_config() is running. Furthermore, sqlite3_config()
|
||||
** <b>The sqlite3_config() interface is not threadsafe. The application
|
||||
** must ensure that no other SQLite interfaces are invoked by other
|
||||
** threads while sqlite3_config() is running.</b>
|
||||
**
|
||||
** The sqlite3_config() interface
|
||||
** may only be invoked prior to library initialization using
|
||||
** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
|
||||
** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
|
||||
|
@ -3373,7 +3376,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
|
|||
**
|
||||
** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
|
||||
** [prepared statement] S has been stepped at least once using
|
||||
** [sqlite3_step(S)] but has not run to completion and/or has not
|
||||
** [sqlite3_step(S)] but has neither run to completion (returned
|
||||
** [SQLITE_DONE] from [sqlite3_step(S)]) nor
|
||||
** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S)
|
||||
** interface returns false if S is a NULL pointer. If S is not a
|
||||
** NULL pointer and is not a pointer to a valid [prepared statement]
|
||||
|
@ -3626,7 +3630,7 @@ SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt*,
|
|||
**
|
||||
** See also: [sqlite3_bind_blob|sqlite3_bind()],
|
||||
** [sqlite3_bind_parameter_count()], and
|
||||
** [sqlite3_bind_parameter_index()].
|
||||
** [sqlite3_bind_parameter_name()].
|
||||
*/
|
||||
SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
|
||||
|
||||
|
@ -4355,6 +4359,22 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*);
|
|||
SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*);
|
||||
SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Finding The Subtype Of SQL Values
|
||||
** METHOD: sqlite3_value
|
||||
**
|
||||
** The sqlite3_value_subtype(V) function returns the subtype for
|
||||
** an [application-defined SQL function] argument V. The subtype
|
||||
** information can be used to pass a limited amount of context from
|
||||
** one SQL function to another. Use the [sqlite3_result_subtype()]
|
||||
** routine to set the subtype for the return value of an SQL function.
|
||||
**
|
||||
** SQLite makes no use of subtype itself. It merely passes the subtype
|
||||
** from the result of one [application-defined SQL function] into the
|
||||
** input of another.
|
||||
*/
|
||||
SQLITE_API unsigned int SQLITE_STDCALL sqlite3_value_subtype(sqlite3_value*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Copy And Free SQL Values
|
||||
** METHOD: sqlite3_value
|
||||
|
@ -4654,6 +4674,21 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context*, sqlite3_va
|
|||
SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context*, int n);
|
||||
SQLITE_API int SQLITE_STDCALL sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
|
||||
|
||||
|
||||
/*
|
||||
** CAPI3REF: Setting The Subtype Of An SQL Function
|
||||
** METHOD: sqlite3_context
|
||||
**
|
||||
** The sqlite3_result_subtype(C,T) function causes the subtype of
|
||||
** the result from the [application-defined SQL function] with
|
||||
** [sqlite3_context] C to be the value T. Only the lower 8 bits
|
||||
** of the subtype T are preserved in current versions of SQLite;
|
||||
** higher order bits are discarded.
|
||||
** The number of subtype bytes preserved by SQLite might increase
|
||||
** in future releases of SQLite.
|
||||
*/
|
||||
SQLITE_API void SQLITE_STDCALL sqlite3_result_subtype(sqlite3_context*,unsigned int);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Define New Collating Sequences
|
||||
** METHOD: sqlite3
|
||||
|
@ -5599,13 +5634,31 @@ struct sqlite3_module {
|
|||
** ^The estimatedRows value is an estimate of the number of rows that
|
||||
** will be returned by the strategy.
|
||||
**
|
||||
** The xBestIndex method may optionally populate the idxFlags field with a
|
||||
** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
|
||||
** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
|
||||
** assumes that the strategy may visit at most one row.
|
||||
**
|
||||
** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
|
||||
** SQLite also assumes that if a call to the xUpdate() method is made as
|
||||
** part of the same statement to delete or update a virtual table row and the
|
||||
** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
|
||||
** any database changes. In other words, if the xUpdate() returns
|
||||
** SQLITE_CONSTRAINT, the database contents must be exactly as they were
|
||||
** before xUpdate was called. By contrast, if SQLITE_INDEX_SCAN_UNIQUE is not
|
||||
** set and xUpdate returns SQLITE_CONSTRAINT, any database changes made by
|
||||
** the xUpdate method are automatically rolled back by SQLite.
|
||||
**
|
||||
** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
|
||||
** structure for SQLite version 3.8.2. If a virtual table extension is
|
||||
** used with an SQLite version earlier than 3.8.2, the results of attempting
|
||||
** to read or write the estimatedRows field are undefined (but are likely
|
||||
** to included crashing the application). The estimatedRows field should
|
||||
** therefore only be used if [sqlite3_libversion_number()] returns a
|
||||
** value greater than or equal to 3008002.
|
||||
** value greater than or equal to 3008002. Similarly, the idxFlags field
|
||||
** was added for version 3.9.0. It may therefore only be used if
|
||||
** sqlite3_libversion_number() returns a value greater than or equal to
|
||||
** 3009000.
|
||||
*/
|
||||
struct sqlite3_index_info {
|
||||
/* Inputs */
|
||||
|
@ -5633,8 +5686,15 @@ struct sqlite3_index_info {
|
|||
double estimatedCost; /* Estimated cost of using this index */
|
||||
/* Fields below are only available in SQLite 3.8.2 and later */
|
||||
sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
|
||||
/* Fields below are only available in SQLite 3.9.0 and later */
|
||||
int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */
|
||||
};
|
||||
|
||||
/*
|
||||
** CAPI3REF: Virtual Table Scan Flags
|
||||
*/
|
||||
#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
|
||||
|
||||
/*
|
||||
** CAPI3REF: Virtual Table Constraint Operator Codes
|
||||
**
|
||||
|
@ -6092,6 +6152,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs*);
|
|||
** <li> SQLITE_MUTEX_STATIC_APP1
|
||||
** <li> SQLITE_MUTEX_STATIC_APP2
|
||||
** <li> SQLITE_MUTEX_STATIC_APP3
|
||||
** <li> SQLITE_MUTEX_STATIC_VFS1
|
||||
** <li> SQLITE_MUTEX_STATIC_VFS2
|
||||
** <li> SQLITE_MUTEX_STATIC_VFS3
|
||||
** </ul>
|
||||
**
|
||||
** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
|
||||
|
@ -7858,3 +7921,523 @@ struct sqlite3_rtree_query_info {
|
|||
|
||||
#endif /* ifndef _SQLITE3RTREE_H_ */
|
||||
|
||||
/*
|
||||
** 2014 May 31
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
******************************************************************************
|
||||
**
|
||||
** Interfaces to extend FTS5. Using the interfaces defined in this file,
|
||||
** FTS5 may be extended with:
|
||||
**
|
||||
** * custom tokenizers, and
|
||||
** * custom auxiliary functions.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _FTS5_H
|
||||
#define _FTS5_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
** CUSTOM AUXILIARY FUNCTIONS
|
||||
**
|
||||
** Virtual table implementations may overload SQL functions by implementing
|
||||
** the sqlite3_module.xFindFunction() method.
|
||||
*/
|
||||
|
||||
typedef struct Fts5ExtensionApi Fts5ExtensionApi;
|
||||
typedef struct Fts5Context Fts5Context;
|
||||
typedef struct Fts5PhraseIter Fts5PhraseIter;
|
||||
|
||||
typedef void (*fts5_extension_function)(
|
||||
const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
|
||||
Fts5Context *pFts, /* First arg to pass to pApi functions */
|
||||
sqlite3_context *pCtx, /* Context for returning result/error */
|
||||
int nVal, /* Number of values in apVal[] array */
|
||||
sqlite3_value **apVal /* Array of trailing arguments */
|
||||
);
|
||||
|
||||
struct Fts5PhraseIter {
|
||||
const unsigned char *a;
|
||||
const unsigned char *b;
|
||||
};
|
||||
|
||||
/*
|
||||
** EXTENSION API FUNCTIONS
|
||||
**
|
||||
** xUserData(pFts):
|
||||
** Return a copy of the context pointer the extension function was
|
||||
** registered with.
|
||||
**
|
||||
** xColumnTotalSize(pFts, iCol, pnToken):
|
||||
** If parameter iCol is less than zero, set output variable *pnToken
|
||||
** to the total number of tokens in the FTS5 table. Or, if iCol is
|
||||
** non-negative but less than the number of columns in the table, return
|
||||
** the total number of tokens in column iCol, considering all rows in
|
||||
** the FTS5 table.
|
||||
**
|
||||
** If parameter iCol is greater than or equal to the number of columns
|
||||
** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
|
||||
** an OOM condition or IO error), an appropriate SQLite error code is
|
||||
** returned.
|
||||
**
|
||||
** xColumnCount(pFts):
|
||||
** Return the number of columns in the table.
|
||||
**
|
||||
** xColumnSize(pFts, iCol, pnToken):
|
||||
** If parameter iCol is less than zero, set output variable *pnToken
|
||||
** to the total number of tokens in the current row. Or, if iCol is
|
||||
** non-negative but less than the number of columns in the table, set
|
||||
** *pnToken to the number of tokens in column iCol of the current row.
|
||||
**
|
||||
** If parameter iCol is greater than or equal to the number of columns
|
||||
** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
|
||||
** an OOM condition or IO error), an appropriate SQLite error code is
|
||||
** returned.
|
||||
**
|
||||
** xColumnText:
|
||||
** This function attempts to retrieve the text of column iCol of the
|
||||
** current document. If successful, (*pz) is set to point to a buffer
|
||||
** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
|
||||
** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
|
||||
** if an error occurs, an SQLite error code is returned and the final values
|
||||
** of (*pz) and (*pn) are undefined.
|
||||
**
|
||||
** xPhraseCount:
|
||||
** Returns the number of phrases in the current query expression.
|
||||
**
|
||||
** xPhraseSize:
|
||||
** Returns the number of tokens in phrase iPhrase of the query. Phrases
|
||||
** are numbered starting from zero.
|
||||
**
|
||||
** xInstCount:
|
||||
** Set *pnInst to the total number of occurrences of all phrases within
|
||||
** the query within the current row. Return SQLITE_OK if successful, or
|
||||
** an error code (i.e. SQLITE_NOMEM) if an error occurs.
|
||||
**
|
||||
** xInst:
|
||||
** Query for the details of phrase match iIdx within the current row.
|
||||
** Phrase matches are numbered starting from zero, so the iIdx argument
|
||||
** should be greater than or equal to zero and smaller than the value
|
||||
** output by xInstCount().
|
||||
**
|
||||
** Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM)
|
||||
** if an error occurs.
|
||||
**
|
||||
** xRowid:
|
||||
** Returns the rowid of the current row.
|
||||
**
|
||||
** xTokenize:
|
||||
** Tokenize text using the tokenizer belonging to the FTS5 table.
|
||||
**
|
||||
** xQueryPhrase(pFts5, iPhrase, pUserData, xCallback):
|
||||
** This API function is used to query the FTS table for phrase iPhrase
|
||||
** of the current query. Specifically, a query equivalent to:
|
||||
**
|
||||
** ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
|
||||
**
|
||||
** with $p set to a phrase equivalent to the phrase iPhrase of the
|
||||
** current query is executed. For each row visited, the callback function
|
||||
** passed as the fourth argument is invoked. The context and API objects
|
||||
** passed to the callback function may be used to access the properties of
|
||||
** each matched row. Invoking Api.xUserData() returns a copy of the pointer
|
||||
** passed as the third argument to pUserData.
|
||||
**
|
||||
** If the callback function returns any value other than SQLITE_OK, the
|
||||
** query is abandoned and the xQueryPhrase function returns immediately.
|
||||
** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
|
||||
** Otherwise, the error code is propagated upwards.
|
||||
**
|
||||
** If the query runs to completion without incident, SQLITE_OK is returned.
|
||||
** Or, if some error occurs before the query completes or is aborted by
|
||||
** the callback, an SQLite error code is returned.
|
||||
**
|
||||
**
|
||||
** xSetAuxdata(pFts5, pAux, xDelete)
|
||||
**
|
||||
** Save the pointer passed as the second argument as the extension functions
|
||||
** "auxiliary data". The pointer may then be retrieved by the current or any
|
||||
** future invocation of the same fts5 extension function made as part of
|
||||
** of the same MATCH query using the xGetAuxdata() API.
|
||||
**
|
||||
** Each extension function is allocated a single auxiliary data slot for
|
||||
** each FTS query (MATCH expression). If the extension function is invoked
|
||||
** more than once for a single FTS query, then all invocations share a
|
||||
** single auxiliary data context.
|
||||
**
|
||||
** If there is already an auxiliary data pointer when this function is
|
||||
** invoked, then it is replaced by the new pointer. If an xDelete callback
|
||||
** was specified along with the original pointer, it is invoked at this
|
||||
** point.
|
||||
**
|
||||
** The xDelete callback, if one is specified, is also invoked on the
|
||||
** auxiliary data pointer after the FTS5 query has finished.
|
||||
**
|
||||
** If an error (e.g. an OOM condition) occurs within this function, an
|
||||
** the auxiliary data is set to NULL and an error code returned. If the
|
||||
** xDelete parameter was not NULL, it is invoked on the auxiliary data
|
||||
** pointer before returning.
|
||||
**
|
||||
**
|
||||
** xGetAuxdata(pFts5, bClear)
|
||||
**
|
||||
** Returns the current auxiliary data pointer for the fts5 extension
|
||||
** function. See the xSetAuxdata() method for details.
|
||||
**
|
||||
** If the bClear argument is non-zero, then the auxiliary data is cleared
|
||||
** (set to NULL) before this function returns. In this case the xDelete,
|
||||
** if any, is not invoked.
|
||||
**
|
||||
**
|
||||
** xRowCount(pFts5, pnRow)
|
||||
**
|
||||
** This function is used to retrieve the total number of rows in the table.
|
||||
** In other words, the same value that would be returned by:
|
||||
**
|
||||
** SELECT count(*) FROM ftstable;
|
||||
**
|
||||
** xPhraseFirst()
|
||||
** This function is used, along with type Fts5PhraseIter and the xPhraseNext
|
||||
** method, to iterate through all instances of a single query phrase within
|
||||
** the current row. This is the same information as is accessible via the
|
||||
** xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient
|
||||
** to use, this API may be faster under some circumstances. To iterate
|
||||
** through instances of phrase iPhrase, use the following code:
|
||||
**
|
||||
** Fts5PhraseIter iter;
|
||||
** int iCol, iOff;
|
||||
** for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
|
||||
** iOff>=0;
|
||||
** pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
|
||||
** ){
|
||||
** // An instance of phrase iPhrase at offset iOff of column iCol
|
||||
** }
|
||||
**
|
||||
** The Fts5PhraseIter structure is defined above. Applications should not
|
||||
** modify this structure directly - it should only be used as shown above
|
||||
** with the xPhraseFirst() and xPhraseNext() API methods.
|
||||
**
|
||||
** xPhraseNext()
|
||||
** See xPhraseFirst above.
|
||||
*/
|
||||
struct Fts5ExtensionApi {
|
||||
int iVersion; /* Currently always set to 1 */
|
||||
|
||||
void *(*xUserData)(Fts5Context*);
|
||||
|
||||
int (*xColumnCount)(Fts5Context*);
|
||||
int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
|
||||
int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken);
|
||||
|
||||
int (*xTokenize)(Fts5Context*,
|
||||
const char *pText, int nText, /* Text to tokenize */
|
||||
void *pCtx, /* Context passed to xToken() */
|
||||
int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
|
||||
);
|
||||
|
||||
int (*xPhraseCount)(Fts5Context*);
|
||||
int (*xPhraseSize)(Fts5Context*, int iPhrase);
|
||||
|
||||
int (*xInstCount)(Fts5Context*, int *pnInst);
|
||||
int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff);
|
||||
|
||||
sqlite3_int64 (*xRowid)(Fts5Context*);
|
||||
int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn);
|
||||
int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken);
|
||||
|
||||
int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData,
|
||||
int(*)(const Fts5ExtensionApi*,Fts5Context*,void*)
|
||||
);
|
||||
int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*));
|
||||
void *(*xGetAuxdata)(Fts5Context*, int bClear);
|
||||
|
||||
void (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
|
||||
void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
|
||||
};
|
||||
|
||||
/*
|
||||
** CUSTOM AUXILIARY FUNCTIONS
|
||||
*************************************************************************/
|
||||
|
||||
/*************************************************************************
|
||||
** CUSTOM TOKENIZERS
|
||||
**
|
||||
** Applications may also register custom tokenizer types. A tokenizer
|
||||
** is registered by providing fts5 with a populated instance of the
|
||||
** following structure. All structure methods must be defined, setting
|
||||
** any member of the fts5_tokenizer struct to NULL leads to undefined
|
||||
** behaviour. The structure methods are expected to function as follows:
|
||||
**
|
||||
** xCreate:
|
||||
** This function is used to allocate and inititalize a tokenizer instance.
|
||||
** A tokenizer instance is required to actually tokenize text.
|
||||
**
|
||||
** The first argument passed to this function is a copy of the (void*)
|
||||
** pointer provided by the application when the fts5_tokenizer object
|
||||
** was registered with FTS5 (the third argument to xCreateTokenizer()).
|
||||
** The second and third arguments are an array of nul-terminated strings
|
||||
** containing the tokenizer arguments, if any, specified following the
|
||||
** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
|
||||
** to create the FTS5 table.
|
||||
**
|
||||
** The final argument is an output variable. If successful, (*ppOut)
|
||||
** should be set to point to the new tokenizer handle and SQLITE_OK
|
||||
** returned. If an error occurs, some value other than SQLITE_OK should
|
||||
** be returned. In this case, fts5 assumes that the final value of *ppOut
|
||||
** is undefined.
|
||||
**
|
||||
** xDelete:
|
||||
** This function is invoked to delete a tokenizer handle previously
|
||||
** allocated using xCreate(). Fts5 guarantees that this function will
|
||||
** be invoked exactly once for each successful call to xCreate().
|
||||
**
|
||||
** xTokenize:
|
||||
** This function is expected to tokenize the nText byte string indicated
|
||||
** by argument pText. pText may or may not be nul-terminated. The first
|
||||
** argument passed to this function is a pointer to an Fts5Tokenizer object
|
||||
** returned by an earlier call to xCreate().
|
||||
**
|
||||
** The second argument indicates the reason that FTS5 is requesting
|
||||
** tokenization of the supplied text. This is always one of the following
|
||||
** four values:
|
||||
**
|
||||
** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
|
||||
** or removed from the FTS table. The tokenizer is being invoked to
|
||||
** determine the set of tokens to add to (or delete from) the
|
||||
** FTS index.
|
||||
**
|
||||
** <li> <b>FTS5_TOKENIZE_QUERY</b> - A MATCH query is being executed
|
||||
** against the FTS index. The tokenizer is being called to tokenize
|
||||
** a bareword or quoted string specified as part of the query.
|
||||
**
|
||||
** <li> <b>(FTS5_TOKENIZE_QUERY | FTS5_TOKENIZE_PREFIX)</b> - Same as
|
||||
** FTS5_TOKENIZE_QUERY, except that the bareword or quoted string is
|
||||
** followed by a "*" character, indicating that the last token
|
||||
** returned by the tokenizer will be treated as a token prefix.
|
||||
**
|
||||
** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to
|
||||
** satisfy an fts5_api.xTokenize() request made by an auxiliary
|
||||
** function. Or an fts5_api.xColumnSize() request made by the same
|
||||
** on a columnsize=0 database.
|
||||
** </ul>
|
||||
**
|
||||
** For each token in the input string, the supplied callback xToken() must
|
||||
** be invoked. The first argument to it should be a copy of the pointer
|
||||
** passed as the second argument to xTokenize(). The third and fourth
|
||||
** arguments are a pointer to a buffer containing the token text, and the
|
||||
** size of the token in bytes. The 4th and 5th arguments are the byte offsets
|
||||
** of the first byte of and first byte immediately following the text from
|
||||
** which the token is derived within the input.
|
||||
**
|
||||
** The second argument passed to the xToken() callback ("tflags") should
|
||||
** normally be set to 0. The exception is if the tokenizer supports
|
||||
** synonyms. In this case see the discussion below for details.
|
||||
**
|
||||
** FTS5 assumes the xToken() callback is invoked for each token in the
|
||||
** order that they occur within the input text.
|
||||
**
|
||||
** If an xToken() callback returns any value other than SQLITE_OK, then
|
||||
** the tokenization should be abandoned and the xTokenize() method should
|
||||
** immediately return a copy of the xToken() return value. Or, if the
|
||||
** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
|
||||
** if an error occurs with the xTokenize() implementation itself, it
|
||||
** may abandon the tokenization and return any error code other than
|
||||
** SQLITE_OK or SQLITE_DONE.
|
||||
**
|
||||
** SYNONYM SUPPORT
|
||||
**
|
||||
** Custom tokenizers may also support synonyms. Consider a case in which a
|
||||
** user wishes to query for a phrase such as "first place". Using the
|
||||
** built-in tokenizers, the FTS5 query 'first + place' will match instances
|
||||
** of "first place" within the document set, but not alternative forms
|
||||
** such as "1st place". In some applications, it would be better to match
|
||||
** all instances of "first place" or "1st place" regardless of which form
|
||||
** the user specified in the MATCH query text.
|
||||
**
|
||||
** There are several ways to approach this in FTS5:
|
||||
**
|
||||
** <ol><li> By mapping all synonyms to a single token. In this case, the
|
||||
** In the above example, this means that the tokenizer returns the
|
||||
** same token for inputs "first" and "1st". Say that token is in
|
||||
** fact "first", so that when the user inserts the document "I won
|
||||
** 1st place" entries are added to the index for tokens "i", "won",
|
||||
** "first" and "place". If the user then queries for '1st + place',
|
||||
** the tokenizer substitutes "first" for "1st" and the query works
|
||||
** as expected.
|
||||
**
|
||||
** <li> By adding multiple synonyms for a single term to the FTS index.
|
||||
** In this case, when tokenizing query text, the tokenizer may
|
||||
** provide multiple synonyms for a single term within the document.
|
||||
** FTS5 then queries the index for each synonym individually. For
|
||||
** example, faced with the query:
|
||||
**
|
||||
** <codeblock>
|
||||
** ... MATCH 'first place'</codeblock>
|
||||
**
|
||||
** the tokenizer offers both "1st" and "first" as synonyms for the
|
||||
** first token in the MATCH query and FTS5 effectively runs a query
|
||||
** similar to:
|
||||
**
|
||||
** <codeblock>
|
||||
** ... MATCH '(first OR 1st) place'</codeblock>
|
||||
**
|
||||
** except that, for the purposes of auxiliary functions, the query
|
||||
** still appears to contain just two phrases - "(first OR 1st)"
|
||||
** being treated as a single phrase.
|
||||
**
|
||||
** <li> By adding multiple synonyms for a single term to the FTS index.
|
||||
** Using this method, when tokenizing document text, the tokenizer
|
||||
** provides multiple synonyms for each token. So that when a
|
||||
** document such as "I won first place" is tokenized, entries are
|
||||
** added to the FTS index for "i", "won", "first", "1st" and
|
||||
** "place".
|
||||
**
|
||||
** This way, even if the tokenizer does not provide synonyms
|
||||
** when tokenizing query text (it should not - to do would be
|
||||
** inefficient), it doesn't matter if the user queries for
|
||||
** 'first + place' or '1st + place', as there are entires in the
|
||||
** FTS index corresponding to both forms of the first token.
|
||||
** </ol>
|
||||
**
|
||||
** Whether it is parsing document or query text, any call to xToken that
|
||||
** specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit
|
||||
** is considered to supply a synonym for the previous token. For example,
|
||||
** when parsing the document "I won first place", a tokenizer that supports
|
||||
** synonyms would call xToken() 5 times, as follows:
|
||||
**
|
||||
** <codeblock>
|
||||
** xToken(pCtx, 0, "i", 1, 0, 1);
|
||||
** xToken(pCtx, 0, "won", 3, 2, 5);
|
||||
** xToken(pCtx, 0, "first", 5, 6, 11);
|
||||
** xToken(pCtx, FTS5_TOKEN_COLOCATED, "1st", 3, 6, 11);
|
||||
** xToken(pCtx, 0, "place", 5, 12, 17);
|
||||
**</codeblock>
|
||||
**
|
||||
** It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time
|
||||
** xToken() is called. Multiple synonyms may be specified for a single token
|
||||
** by making multiple calls to xToken(FTS5_TOKEN_COLOCATED) in sequence.
|
||||
** There is no limit to the number of synonyms that may be provided for a
|
||||
** single token.
|
||||
**
|
||||
** In many cases, method (1) above is the best approach. It does not add
|
||||
** extra data to the FTS index or require FTS5 to query for multiple terms,
|
||||
** so it is efficient in terms of disk space and query speed. However, it
|
||||
** does not support prefix queries very well. If, as suggested above, the
|
||||
** token "first" is subsituted for "1st" by the tokenizer, then the query:
|
||||
**
|
||||
** <codeblock>
|
||||
** ... MATCH '1s*'</codeblock>
|
||||
**
|
||||
** will not match documents that contain the token "1st" (as the tokenizer
|
||||
** will probably not map "1s" to any prefix of "first").
|
||||
**
|
||||
** For full prefix support, method (3) may be preferred. In this case,
|
||||
** because the index contains entries for both "first" and "1st", prefix
|
||||
** queries such as 'fi*' or '1s*' will match correctly. However, because
|
||||
** extra entries are added to the FTS index, this method uses more space
|
||||
** within the database.
|
||||
**
|
||||
** Method (2) offers a midpoint between (1) and (3). Using this method,
|
||||
** a query such as '1s*' will match documents that contain the literal
|
||||
** token "1st", but not "first" (assuming the tokenizer is not able to
|
||||
** provide synonyms for prefixes). However, a non-prefix query like '1st'
|
||||
** will match against "1st" and "first". This method does not require
|
||||
** extra disk space, as no extra entries are added to the FTS index.
|
||||
** On the other hand, it may require more CPU cycles to run MATCH queries,
|
||||
** as separate queries of the FTS index are required for each synonym.
|
||||
**
|
||||
** When using methods (2) or (3), it is important that the tokenizer only
|
||||
** provide synonyms when tokenizing document text (method (2)) or query
|
||||
** text (method (3)), not both. Doing so will not cause any errors, but is
|
||||
** inefficient.
|
||||
*/
|
||||
typedef struct Fts5Tokenizer Fts5Tokenizer;
|
||||
typedef struct fts5_tokenizer fts5_tokenizer;
|
||||
struct fts5_tokenizer {
|
||||
int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
|
||||
void (*xDelete)(Fts5Tokenizer*);
|
||||
int (*xTokenize)(Fts5Tokenizer*,
|
||||
void *pCtx,
|
||||
int flags, /* Mask of FTS5_TOKENIZE_* flags */
|
||||
const char *pText, int nText,
|
||||
int (*xToken)(
|
||||
void *pCtx, /* Copy of 2nd argument to xTokenize() */
|
||||
int tflags, /* Mask of FTS5_TOKEN_* flags */
|
||||
const char *pToken, /* Pointer to buffer containing token */
|
||||
int nToken, /* Size of token in bytes */
|
||||
int iStart, /* Byte offset of token within input text */
|
||||
int iEnd /* Byte offset of end of token within input text */
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
/* Flags that may be passed as the third argument to xTokenize() */
|
||||
#define FTS5_TOKENIZE_QUERY 0x0001
|
||||
#define FTS5_TOKENIZE_PREFIX 0x0002
|
||||
#define FTS5_TOKENIZE_DOCUMENT 0x0004
|
||||
#define FTS5_TOKENIZE_AUX 0x0008
|
||||
|
||||
/* Flags that may be passed by the tokenizer implementation back to FTS5
|
||||
** as the third argument to the supplied xToken callback. */
|
||||
#define FTS5_TOKEN_COLOCATED 0x0001 /* Same position as prev. token */
|
||||
|
||||
/*
|
||||
** END OF CUSTOM TOKENIZERS
|
||||
*************************************************************************/
|
||||
|
||||
/*************************************************************************
|
||||
** FTS5 EXTENSION REGISTRATION API
|
||||
*/
|
||||
typedef struct fts5_api fts5_api;
|
||||
struct fts5_api {
|
||||
int iVersion; /* Currently always set to 2 */
|
||||
|
||||
/* Create a new tokenizer */
|
||||
int (*xCreateTokenizer)(
|
||||
fts5_api *pApi,
|
||||
const char *zName,
|
||||
void *pContext,
|
||||
fts5_tokenizer *pTokenizer,
|
||||
void (*xDestroy)(void*)
|
||||
);
|
||||
|
||||
/* Find an existing tokenizer */
|
||||
int (*xFindTokenizer)(
|
||||
fts5_api *pApi,
|
||||
const char *zName,
|
||||
void **ppContext,
|
||||
fts5_tokenizer *pTokenizer
|
||||
);
|
||||
|
||||
/* Create a new auxiliary function */
|
||||
int (*xCreateFunction)(
|
||||
fts5_api *pApi,
|
||||
const char *zName,
|
||||
void *pContext,
|
||||
fts5_extension_function xFunction,
|
||||
void (*xDestroy)(void*)
|
||||
);
|
||||
};
|
||||
|
||||
/*
|
||||
** END OF REGISTRATION API
|
||||
*************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of the 'extern "C"' block */
|
||||
#endif
|
||||
|
||||
#endif /* _FTS5_H */
|
||||
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* Copyright Nikolai Kudashov, 2015.
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include "Config.h"
|
||||
#include "ConnectionsManager.h"
|
||||
#include "FileLog.h"
|
||||
|
@ -16,9 +17,10 @@ Config::Config(std::string fileName) {
|
|||
backupPath = configPath + ".bak";
|
||||
FILE *backup = fopen(backupPath.c_str(), "rb");
|
||||
if (backup != nullptr) {
|
||||
DEBUG_D("Config(%p, %s) backup file found %s", this, configPath.c_str(), backupPath.c_str());
|
||||
fclose(backup);
|
||||
remove(configPath.c_str());
|
||||
rename(backupPath.c_str(), configPath.c_str());
|
||||
fclose(backup);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,10 +30,14 @@ NativeByteBuffer *Config::readConfig() {
|
|||
if (file != nullptr) {
|
||||
fseek(file, 0, SEEK_END);
|
||||
long fileSize = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
if (fseek(file, 0, SEEK_SET)) {
|
||||
DEBUG_E("Config(%p, %s) failed fseek to begin, reopen it", this, configPath.c_str());
|
||||
fclose(file);
|
||||
file = fopen(configPath.c_str(), "rb");
|
||||
}
|
||||
uint32_t size = 0;
|
||||
int bytesRead = fread(&size, sizeof(uint32_t), 1, file);
|
||||
DEBUG_D("Config(%p, %s) load, size = %u", this, configPath.c_str(), size);
|
||||
DEBUG_D("Config(%p, %s) load, size = %u, fileSize = %u", this, configPath.c_str(), size, (uint32_t) fileSize);
|
||||
if (bytesRead > 0 && size > 0 && (int32_t) size < fileSize) {
|
||||
buffer = BuffersStorage::getInstance().getFreeBuffer(size);
|
||||
if (fread(buffer->bytes(), sizeof(uint8_t), size, file) != size) {
|
||||
|
@ -45,6 +51,7 @@ NativeByteBuffer *Config::readConfig() {
|
|||
}
|
||||
|
||||
void Config::writeConfig(NativeByteBuffer *buffer) {
|
||||
DEBUG_D("Config(%p, %s) start write config", this, configPath.c_str());
|
||||
FILE *file = fopen(configPath.c_str(), "rb");
|
||||
FILE *backup = fopen(backupPath.c_str(), "rb");
|
||||
bool error = false;
|
||||
|
@ -65,21 +72,53 @@ void Config::writeConfig(NativeByteBuffer *buffer) {
|
|||
return;
|
||||
}
|
||||
file = fopen(configPath.c_str(), "wb");
|
||||
if (chmod(configPath.c_str(), 0660)) {
|
||||
DEBUG_E("Config(%p, %s) chmod failed", this, configPath.c_str());
|
||||
}
|
||||
if (file == nullptr) {
|
||||
DEBUG_E("Config(%p, %s) unable to open file for writing", this, configPath.c_str());
|
||||
return;
|
||||
}
|
||||
uint32_t size = buffer->position();
|
||||
if (fwrite(&size, sizeof(uint32_t), 1, file) == 1) {
|
||||
if (fwrite(buffer->bytes(), sizeof(uint8_t), size, file) != size) {
|
||||
DEBUG_E("Config(%p, %s) failed to write config data to file", this, configPath.c_str());
|
||||
error = true;
|
||||
}
|
||||
} else {
|
||||
DEBUG_E("Config(%p, %s) failed to write config size to file", this, configPath.c_str());
|
||||
error = true;
|
||||
}
|
||||
fclose(file);
|
||||
if (error) {
|
||||
remove(configPath.c_str());
|
||||
if (fflush(file)) {
|
||||
DEBUG_E("Config(%p, %s) fflush failed", this, configPath.c_str());
|
||||
error = true;
|
||||
}
|
||||
int fd = fileno(file);
|
||||
if (fd == -1) {
|
||||
DEBUG_E("Config(%p, %s) fileno failed", this, configPath.c_str());
|
||||
error = true;
|
||||
} else {
|
||||
remove(backupPath.c_str());
|
||||
DEBUG_D("Config(%p, %s) fileno = %d", this, configPath.c_str(), fd);
|
||||
}
|
||||
if (fd != -1 && fsync(fd) == -1) {
|
||||
DEBUG_E("Config(%p, %s) fsync failed", this, configPath.c_str());
|
||||
error = true;
|
||||
}
|
||||
if (fclose(file)) {
|
||||
DEBUG_E("Config(%p, %s) fclose failed", this, configPath.c_str());
|
||||
error = true;
|
||||
}
|
||||
if (error) {
|
||||
DEBUG_E("Config(%p, %s) failed to write config", this, configPath.c_str());
|
||||
if (remove(configPath.c_str())) {
|
||||
DEBUG_E("Config(%p, %s) remove config failed", this, configPath.c_str());
|
||||
}
|
||||
} else {
|
||||
if (remove(backupPath.c_str())) {
|
||||
DEBUG_E("Config(%p, %s) remove backup failed failed", this, configPath.c_str());
|
||||
}
|
||||
}
|
||||
if (!error) {
|
||||
DEBUG_D("Config(%p, %s) config write ok", this, configPath.c_str());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -220,7 +220,7 @@ void ConnectionsManager::select() {
|
|||
return;
|
||||
} else {
|
||||
lastPauseTime = now;
|
||||
DEBUG_D("don't sleep 10 seconds because of salt, upload or download request");
|
||||
DEBUG_D("don't sleep 30 seconds because of salt, upload or download request");
|
||||
}
|
||||
}
|
||||
if (networkPaused) {
|
||||
|
@ -595,7 +595,7 @@ void ConnectionsManager::onConnectionConnected(Connection *connection) {
|
|||
} else {
|
||||
if (networkPaused && lastPauseTime != 0) {
|
||||
lastPauseTime = getCurrentTimeMillis();
|
||||
nextSleepTimeout = 10000;
|
||||
nextSleepTimeout = 30000;
|
||||
}
|
||||
processRequestQueue(connection->getConnectionType(), datacenter->getDatacenterId());
|
||||
}
|
||||
|
@ -821,6 +821,7 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
|
|||
Request *request = iter->get();
|
||||
Datacenter *requestDatacenter = getDatacenterWithId(request->datacenterId);
|
||||
if (request->messageId < response->first_msg_id && request->connectionType & connection->getConnectionType() && requestDatacenter != nullptr && requestDatacenter->getDatacenterId() == datacenter->getDatacenterId()) {
|
||||
DEBUG_D("clear request %p - %s", request->rawRequest, typeid(*request->rawRequest).name());
|
||||
request->clear(true);
|
||||
}
|
||||
}
|
||||
|
@ -943,6 +944,7 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
|
|||
for (requestsIter iter = runningRequests.begin(); iter != runningRequests.end(); iter++) {
|
||||
Request *request = iter->get();
|
||||
if (request->respondsToMessageId(resultMid)) {
|
||||
DEBUG_D("got response for request %p - %s", request->rawRequest, typeid(*request->rawRequest).name());
|
||||
bool discardResponse = false;
|
||||
bool isError = false;
|
||||
bool allowInitConnection = true;
|
||||
|
@ -984,8 +986,16 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
|
|||
}
|
||||
|
||||
discardResponse = true;
|
||||
request->failedByFloodWait = true;
|
||||
request->failedByFloodWait = waitTime;
|
||||
request->startTime = 0;
|
||||
request->minStartTime = (int32_t) (getCurrentTimeMillis() / 1000 + waitTime);
|
||||
} else if (error->error_code == 400) {
|
||||
static std::string waitFailed = "MSG_WAIT_FAILED";
|
||||
if (error->error_message.find(waitFailed) != std::string::npos) {
|
||||
discardResponse = true;
|
||||
request->minStartTime = (int32_t) (getCurrentTimeMillis() / 1000 + 1);
|
||||
request->startTime = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!discardResponse) {
|
||||
|
@ -1124,10 +1134,10 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
|
|||
if ((request->connectionType & ConnectionTypeDownload) == 0) {
|
||||
continue;
|
||||
}
|
||||
if (request->respondsToMessageId(resultMid)) {
|
||||
Datacenter *requestDatacenter = getDatacenterWithId(request->datacenterId);
|
||||
if (requestDatacenter != nullptr && requestDatacenter->getDatacenterId() == datacenter->getDatacenterId()) {
|
||||
request->retryCount = 0;
|
||||
request->failedBySalt = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1208,7 +1218,7 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
|
|||
} else if (connection->connectionType == ConnectionTypePush && typeInfo == typeid(TL_updatesTooLong)) {
|
||||
if (networkPaused) {
|
||||
lastPauseTime = getCurrentTimeMillis();
|
||||
nextSleepTimeout = 10000;
|
||||
nextSleepTimeout = 30000;
|
||||
DEBUG_D("received internal push: wakeup network in background");
|
||||
} else if (lastPauseTime != 0) {
|
||||
lastPauseTime = getCurrentTimeMillis();
|
||||
|
@ -1364,12 +1374,6 @@ void ConnectionsManager::sendRequest(TLObject *object, onCompleteFunc onComplete
|
|||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
int32_t ConnectionsManager::sendRequest(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, uint32_t flags, uint32_t datacenterId, ConnectionType connetionType, bool immediate, jobject ptr1, jobject ptr2) {
|
||||
int32_t requestToken = lastRequestToken++;
|
||||
sendRequest(object, onComplete, onQuickAck, flags, datacenterId, connetionType, immediate, requestToken, ptr1, ptr2);
|
||||
return requestToken;
|
||||
}
|
||||
|
||||
void ConnectionsManager::sendRequest(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, uint32_t flags, uint32_t datacenterId, ConnectionType connetionType, bool immediate, int32_t requestToken, jobject ptr1, jobject ptr2) {
|
||||
if (!currentUserId && !(flags & RequestFlagWithoutLogin)) {
|
||||
DEBUG_D("can't do request without login %s", typeid(*object).name());
|
||||
|
@ -1489,7 +1493,7 @@ void ConnectionsManager::cancelRequestInternal(int32_t token, bool notifyServer,
|
|||
Request *request = iter->get();
|
||||
if (request->requestToken == token) {
|
||||
request->cancelled = true;
|
||||
DEBUG_D("cancelled queued rpc request %s", typeid(*request->rawRequest).name());
|
||||
DEBUG_D("cancelled queued rpc request %p - %s", request->rawRequest, typeid(*request->rawRequest).name());
|
||||
requestsQueue.erase(iter);
|
||||
if (removeFromClass) {
|
||||
removeRequestFromGuid(token);
|
||||
|
@ -1507,7 +1511,7 @@ void ConnectionsManager::cancelRequestInternal(int32_t token, bool notifyServer,
|
|||
sendRequest(dropAnswer, nullptr, nullptr, RequestFlagEnableUnauthorized | RequestFlagWithoutLogin | RequestFlagFailOnServerErrors, request->datacenterId, request->connectionType, true);
|
||||
}
|
||||
request->cancelled = true;
|
||||
DEBUG_D("cancelled running rpc request %s", typeid(*request->rawRequest).name());
|
||||
DEBUG_D("cancelled running rpc request %p - %s", request->rawRequest, typeid(*request->rawRequest).name());
|
||||
runningRequests.erase(iter);
|
||||
if (removeFromClass) {
|
||||
removeRequestFromGuid(token);
|
||||
|
@ -1795,7 +1799,12 @@ void ConnectionsManager::processRequestQueue(uint32_t connectionTypes, uint32_t
|
|||
forceThisRequest = false;
|
||||
}
|
||||
|
||||
if (forceThisRequest || (abs(currentTime - request->startTime) > maxTimeout && (currentTime > request->minStartTime || abs(currentTime - request->minStartTime) > 60))) {
|
||||
if (forceThisRequest || (abs(currentTime - request->startTime) > maxTimeout &&
|
||||
(currentTime >= request->minStartTime ||
|
||||
(request->failedByFloodWait != 0 && (request->minStartTime - currentTime) > request->failedByFloodWait) ||
|
||||
(request->failedByFloodWait == 0 && abs(currentTime - request->minStartTime) >= 60))
|
||||
)
|
||||
) {
|
||||
if (!forceThisRequest && request->connectionToken > 0) {
|
||||
if (request->connectionType & ConnectionTypeGeneric && request->connectionToken == connection->getConnectionToken()) {
|
||||
DEBUG_D("request token is valid, not retrying %s", typeInfo.name());
|
||||
|
@ -1816,25 +1825,29 @@ void ConnectionsManager::processRequestQueue(uint32_t connectionTypes, uint32_t
|
|||
|
||||
request->retryCount++;
|
||||
|
||||
if (!request->failedBySalt && request->connectionType & ConnectionTypeDownload) {
|
||||
uint32_t retryMax = 10;
|
||||
if (!(request->requestFlags & RequestFlagForceDownload)) {
|
||||
if (request->failedByFloodWait) {
|
||||
retryMax = 1;
|
||||
} else {
|
||||
retryMax = 6;
|
||||
if (!request->failedBySalt) {
|
||||
if (request->connectionType & ConnectionTypeDownload) {
|
||||
uint32_t retryMax = 10;
|
||||
if (!(request->requestFlags & RequestFlagForceDownload)) {
|
||||
if (request->failedByFloodWait) {
|
||||
retryMax = 1;
|
||||
} else {
|
||||
retryMax = 6;
|
||||
}
|
||||
}
|
||||
if (request->retryCount >= retryMax) {
|
||||
DEBUG_E("timed out %s", typeInfo.name());
|
||||
TL_error *error = new TL_error();
|
||||
error->code = -123;
|
||||
error->text = "RETRY_LIMIT";
|
||||
request->onComplete(nullptr, error);
|
||||
delete error;
|
||||
iter = runningRequests.erase(iter);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (request->retryCount >= retryMax) {
|
||||
DEBUG_E("timed out %s", typeInfo.name());
|
||||
TL_error *error = new TL_error();
|
||||
error->code = -123;
|
||||
error->text = "RETRY_LIMIT";
|
||||
request->onComplete(nullptr, error);
|
||||
delete error;
|
||||
iter = runningRequests.erase(iter);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
request->failedBySalt = false;
|
||||
}
|
||||
|
||||
if (request->messageSeqNo == 0) {
|
||||
|
@ -2103,9 +2116,11 @@ void ConnectionsManager::processRequestQueue(uint32_t connectionTypes, uint32_t
|
|||
TL_invokeAfterMsg *request = new TL_invokeAfterMsg();
|
||||
request->msg_id = lastSentMessageRpcId;
|
||||
if (message->outgoingBody != nullptr) {
|
||||
DEBUG_D("wrap outgoingBody(%p, %s) to TL_invokeAfterMsg", message->outgoingBody, typeid(*message->outgoingBody).name());
|
||||
request->outgoingQuery = message->outgoingBody;
|
||||
message->outgoingBody = nullptr;
|
||||
} else {
|
||||
DEBUG_D("wrap body(%p, %s) to TL_invokeAfterMsg", message->body.get(), typeid(*message->body.get()).name());
|
||||
request->query = std::move(message->body);
|
||||
}
|
||||
message->body = std::unique_ptr<TLObject>(request);
|
||||
|
@ -2407,7 +2422,7 @@ void ConnectionsManager::resumeNetwork(bool partial) {
|
|||
if (partial) {
|
||||
if (networkPaused) {
|
||||
lastPauseTime = getCurrentTimeMillis();
|
||||
nextSleepTimeout = 10000;
|
||||
nextSleepTimeout = 30000;
|
||||
networkPaused = false;
|
||||
DEBUG_D("wakeup network in background");
|
||||
} else if (lastPauseTime != 0) {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <functional>
|
||||
#include <sys/epoll.h>
|
||||
#include <map>
|
||||
#include <atomic>
|
||||
#include <bits/unique_ptr.h>
|
||||
#include "Defines.h"
|
||||
|
||||
|
@ -63,7 +64,6 @@ public:
|
|||
void updateDcSettings(uint32_t datacenterId);
|
||||
|
||||
#ifdef ANDROID
|
||||
int32_t sendRequest(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, uint32_t flags, uint32_t datacenterId, ConnectionType connetionType, bool immediate, jobject ptr1, jobject ptr2);
|
||||
void sendRequest(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, uint32_t flags, uint32_t datacenterId, ConnectionType connetionType, bool immediate, int32_t requestToken, jobject ptr1, jobject ptr2);
|
||||
static void useJavaVM(JavaVM *vm, bool useJavaByteBuffers);
|
||||
#endif
|
||||
|
@ -120,7 +120,7 @@ private:
|
|||
std::map<int32_t, std::vector<std::int32_t>> quickAckIdToRequestIds;
|
||||
int32_t pingTime;
|
||||
bool testBackend = false;
|
||||
volatile uint32_t lastRequestToken = 1;
|
||||
std::atomic<uint32_t> lastRequestToken{1};
|
||||
uint32_t currentDatacenterId = 0;
|
||||
uint32_t movingToDatacenterId = DEFAULT_DATACENTER_ID;
|
||||
int64_t pushSessionId = 0;
|
||||
|
|
|
@ -668,9 +668,7 @@ void Datacenter::onHandshakeConnectionConnected(Connection *connection) {
|
|||
if (handshakeState == 0 || !needResendData) {
|
||||
return;
|
||||
}
|
||||
if (handshakeRequest != nullptr) {
|
||||
sendRequestData(handshakeRequest, true);
|
||||
}
|
||||
beginHandshake(false);
|
||||
}
|
||||
|
||||
inline uint64_t gcd(uint64_t a, uint64_t b) {
|
||||
|
@ -1383,6 +1381,7 @@ NativeByteBuffer *Datacenter::createRequestsData(std::vector<std::unique_ptr<Net
|
|||
int64_t currentTime = ConnectionsManager::getInstance().getCurrentTimeMillis() + (int64_t) timeDifference * 1000;
|
||||
|
||||
if (messageTime < currentTime - 30000 || messageTime > currentTime + 25000) {
|
||||
DEBUG_D("wrap message in container");
|
||||
TL_msg_container *messageContainer = new TL_msg_container();
|
||||
messageContainer->messages.push_back(std::move(networkMessage->message));
|
||||
|
||||
|
@ -1395,6 +1394,7 @@ NativeByteBuffer *Datacenter::createRequestsData(std::vector<std::unique_ptr<Net
|
|||
messageSeqNo = networkMessage->message->seqno;
|
||||
}
|
||||
} else {
|
||||
DEBUG_D("start write messages to container");
|
||||
TL_msg_container *messageContainer = new TL_msg_container();
|
||||
size_t count = requests.size();
|
||||
for (uint32_t a = 0; a < count; a++) {
|
||||
|
|
|
@ -18,7 +18,9 @@
|
|||
FILE *logFile = nullptr;
|
||||
|
||||
void FileLog::init(std::string path) {
|
||||
logFile = fopen(path.c_str(), "w");
|
||||
if (path.size() > 0) {
|
||||
logFile = fopen(path.c_str(), "w");
|
||||
}
|
||||
}
|
||||
|
||||
void FileLog::e(const char *message, ...) {
|
||||
|
|
|
@ -931,7 +931,7 @@ void TL_config::readParams(NativeByteBuffer *stream, bool &error) {
|
|||
dc_options.push_back(std::unique_ptr<TL_dcOption>(object));
|
||||
}
|
||||
chat_size_max = stream->readInt32(&error);
|
||||
broadcast_size_max = stream->readInt32(&error);
|
||||
megagroup_size_max = stream->readInt32(&error);
|
||||
forwarded_count_max = stream->readInt32(&error);
|
||||
online_update_period_ms = stream->readInt32(&error);
|
||||
offline_blur_timeout_ms = stream->readInt32(&error);
|
||||
|
@ -971,7 +971,7 @@ void TL_config::serializeToStream(NativeByteBuffer *stream) {
|
|||
dc_options[a]->serializeToStream(stream);
|
||||
}
|
||||
stream->writeInt32(chat_size_max);
|
||||
stream->writeInt32(broadcast_size_max);
|
||||
stream->writeInt32(megagroup_size_max);
|
||||
stream->writeInt32(forwarded_count_max);
|
||||
stream->writeInt32(online_update_period_ms);
|
||||
stream->writeInt32(offline_blur_timeout_ms);
|
||||
|
|
|
@ -657,7 +657,7 @@ public:
|
|||
class TL_config : public TLObject {
|
||||
|
||||
public:
|
||||
static const uint32_t constructor = 0x4e32b894;
|
||||
static const uint32_t constructor = 0x6cb6e65e;
|
||||
|
||||
int32_t date;
|
||||
int32_t expires;
|
||||
|
@ -665,7 +665,7 @@ public:
|
|||
int32_t this_dc;
|
||||
std::vector<std::unique_ptr<TL_dcOption>> dc_options;
|
||||
int32_t chat_size_max;
|
||||
int32_t broadcast_size_max;
|
||||
int32_t megagroup_size_max;
|
||||
int32_t forwarded_count_max;
|
||||
int32_t online_update_period_ms;
|
||||
int32_t offline_blur_timeout_ms;
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
int32_t requestToken;
|
||||
uint32_t retryCount = 0;
|
||||
bool failedBySalt = false;
|
||||
bool failedByFloodWait = false;
|
||||
int32_t failedByFloodWait = 0;
|
||||
ConnectionType connectionType;
|
||||
uint32_t requestFlags;
|
||||
bool completed = false;
|
||||
|
|
Binary file not shown.
Binary file not shown.
BIN
TMessagesProj/libs/armeabi/libtmessages.15.so
Executable file
BIN
TMessagesProj/libs/armeabi/libtmessages.15.so
Executable file
Binary file not shown.
Binary file not shown.
|
@ -43,7 +43,6 @@
|
|||
android:allowBackup="false"
|
||||
android:hardwareAccelerated="@bool/useHardwareAcceleration"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/AppName"
|
||||
android:largeHeap="true"
|
||||
android:theme="@style/Theme.TMessages.Start">
|
||||
|
||||
|
@ -159,7 +158,7 @@
|
|||
</service>
|
||||
|
||||
<service
|
||||
android:name=".TgChooserTargetService"
|
||||
android:name="org.telegram.messenger.TgChooserTargetService"
|
||||
android:label="@string/AppName"
|
||||
android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
|
||||
<intent-filter>
|
||||
|
|
|
@ -1,53 +1,53 @@
|
|||
1876;JM;Jamaica
|
||||
1869;KN;Saint Kitts & Nevis
|
||||
1868;TT;Trinidad & Tobago
|
||||
1784;VC;Saint Vincent & the Grenadines
|
||||
1767;DM;Dominica
|
||||
1758;LC;Saint Lucia
|
||||
1721;SX;Sint Maarten
|
||||
1684;AS;American Samoa
|
||||
1671;GU;Guam
|
||||
1670;MP;Northern Mariana Islands
|
||||
1664;MS;Montserrat
|
||||
1649;TC;Turks & Caicos Islands
|
||||
1473;GD;Grenada
|
||||
1441;BM;Bermuda
|
||||
1345;KY;Cayman Islands
|
||||
1340;VI;US Virgin Islands
|
||||
1284;VG;British Virgin Islands
|
||||
1268;AG;Antigua & Barbuda
|
||||
1264;AI;Anguilla
|
||||
1246;BB;Barbados
|
||||
1242;BS;Bahamas
|
||||
998;UZ;Uzbekistan
|
||||
996;KG;Kyrgyzstan
|
||||
995;GE;Georgia
|
||||
994;AZ;Azerbaijan
|
||||
993;TM;Turkmenistan
|
||||
992;TJ;Tajikistan
|
||||
977;NP;Nepal
|
||||
976;MN;Mongolia
|
||||
975;BT;Bhutan
|
||||
974;QA;Qatar
|
||||
973;BH;Bahrain
|
||||
972;IL;Israel
|
||||
971;AE;United Arab Emirates
|
||||
970;PS;Palestine
|
||||
968;OM;Oman
|
||||
967;YE;Yemen
|
||||
966;SA;Saudi Arabia
|
||||
965;KW;Kuwait
|
||||
964;IQ;Iraq
|
||||
963;SY;Syrian Arab Republic
|
||||
962;JO;Jordan
|
||||
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
|
||||
886;TW;Taiwan
|
||||
960;MV;Maldives;XXX XXXX
|
||||
886;TW;Taiwan;XXX XXX XXX
|
||||
880;BD;Bangladesh
|
||||
856;LA;Laos
|
||||
856;LA;Laos;XX XX XXX XXX
|
||||
855;KH;Cambodia
|
||||
853;MO;Macau
|
||||
852;HK;Hong Kong
|
||||
853;MO;Macau;XXXX XXXX
|
||||
852;HK;Hong Kong;X XXX XXXX
|
||||
850;KP;North Korea
|
||||
692;MH;Marshall Islands
|
||||
691;FM;Micronesia
|
||||
|
@ -67,166 +67,166 @@
|
|||
676;TO;Tonga
|
||||
675;PG;Papua New Guinea
|
||||
674;NR;Nauru
|
||||
673;BN;Brunei Darussalam
|
||||
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
|
||||
597;SR;Suriname
|
||||
598;UY;Uruguay;X XXX XXXX
|
||||
597;SR;Suriname;XXX XXXX
|
||||
596;MQ;Martinique
|
||||
595;PY;Paraguay
|
||||
595;PY;Paraguay;XXX XXX XXX
|
||||
594;GF;French Guiana
|
||||
593;EC;Ecuador
|
||||
593;EC;Ecuador;XX XXX XXXX
|
||||
592;GY;Guyana
|
||||
591;BO;Bolivia
|
||||
590;GP;Guadeloupe
|
||||
591;BO;Bolivia;X XXX XXXX
|
||||
590;GP;Guadeloupe;XXX XX XX XX
|
||||
509;HT;Haiti
|
||||
508;PM;Saint Pierre & Miquelon
|
||||
507;PA;Panama
|
||||
506;CR;Costa Rica
|
||||
505;NI;Nicaragua
|
||||
504;HN;Honduras
|
||||
503;SV;El Salvador
|
||||
502;GT;Guatemala
|
||||
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
|
||||
420;CZ;Czech Republic
|
||||
389;MK;Macedonia
|
||||
387;BA;Bosnia & Herzegovina
|
||||
386;SI;Slovenia
|
||||
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
|
||||
380;UA;Ukraine
|
||||
378;SM;San Marino
|
||||
377;MC;Monaco
|
||||
376;AD;Andorra
|
||||
375;BY;Belarus
|
||||
374;AM;Armenia
|
||||
373;MD;Moldova
|
||||
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
|
||||
370;LT;Lithuania
|
||||
371;LV;Latvia;XXX XXXXX
|
||||
370;LT;Lithuania;XXX XXXXX
|
||||
359;BG;Bulgaria
|
||||
358;FI;Finland
|
||||
357;CY;Cyprus
|
||||
356;MT;Malta
|
||||
355;AL;Albania
|
||||
354;IS;Iceland
|
||||
353;IE;Ireland
|
||||
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
|
||||
350;GI;Gibraltar
|
||||
299;GL;Greenland
|
||||
298;FO;Faroe Islands
|
||||
297;AW;Aruba
|
||||
291;ER;Eritrea
|
||||
290;SH;Saint Helena
|
||||
269;KM;Comoros
|
||||
268;SZ;Swaziland
|
||||
267;BW;Botswana
|
||||
266;LS;Lesotho
|
||||
265;MW;Malawi
|
||||
264;NA;Namibia
|
||||
263;ZW;Zimbabwe
|
||||
262;RE;Réunion
|
||||
261;MG;Madagascar
|
||||
260;ZM;Zambia
|
||||
258;MZ;Mozambique
|
||||
257;BI;Burundi
|
||||
256;UG;Uganda
|
||||
255;TZ;Tanzania
|
||||
254;KE;Kenya
|
||||
253;DJ;Djibouti
|
||||
252;SO;Somalia
|
||||
251;ET;Ethiopia
|
||||
250;RW;Rwanda
|
||||
249;SD;Sudan
|
||||
248;SC;Seychelles
|
||||
247;SH;Saint Helena
|
||||
246;IO;Diego Garcia
|
||||
245;GW;Guinea-Bissau
|
||||
244;AO;Angola
|
||||
243;CD;Congo (Dem. Rep.)
|
||||
242;CG;Congo (Rep.)
|
||||
241;GA;Gabon
|
||||
240;GQ;Equatorial Guinea
|
||||
239;ST;São Tomé & Príncipe
|
||||
238;CV;Cape Verde
|
||||
237;CM;Cameroon
|
||||
236;CF;Central African Rep.
|
||||
235;TD;Chad
|
||||
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
|
||||
232;SL;Sierra Leone;XX XXX XXX
|
||||
231;LR;Liberia
|
||||
230;MU;Mauritius
|
||||
229;BJ;Benin
|
||||
228;TG;Togo
|
||||
227;NE;Niger
|
||||
226;BF;Burkina Faso
|
||||
225;CI;Côte d`Ivoire
|
||||
224;GN;Guinea
|
||||
223;ML;Mali
|
||||
222;MR;Mauritania
|
||||
221;SN;Senegal
|
||||
220;GM;Gambia
|
||||
218;LY;Libya
|
||||
216;TN;Tunisia
|
||||
213;DZ;Algeria
|
||||
212;MA;Morocco
|
||||
211;SS;South Sudan
|
||||
98;IR;Iran
|
||||
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
|
||||
93;AF;Afghanistan
|
||||
92;PK;Pakistan
|
||||
91;IN;India
|
||||
90;TR;Turkey
|
||||
86;CN;China
|
||||
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
|
||||
66;TH;Thailand
|
||||
65;SG;Singapore
|
||||
81;JP;Japan;XX XXXX XXXX
|
||||
66;TH;Thailand;X XXXX XXXX
|
||||
65;SG;Singapore;XXXX XXXX
|
||||
64;NZ;New Zealand
|
||||
63;PH;Philippines
|
||||
63;PH;Philippines;XXX XXX XXXX
|
||||
62;ID;Indonesia
|
||||
61;AU;Australia
|
||||
61;AU;Australia;XXX XXX XXX
|
||||
60;MY;Malaysia
|
||||
58;VE;Venezuela
|
||||
57;CO;Colombia
|
||||
56;CL;Chile
|
||||
55;BR;Brazil
|
||||
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
|
||||
53;CU;Cuba;XXXX XXXX
|
||||
52;MX;Mexico
|
||||
51;PE;Peru
|
||||
51;PE;Peru;XXX XXX XXX
|
||||
49;DE;Germany
|
||||
48;PL;Poland
|
||||
47;NO;Norway
|
||||
46;SE;Sweden
|
||||
45;DK;Denmark
|
||||
44;GB;United Kingdom
|
||||
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
|
||||
40;RO;Romania
|
||||
41;CH;Switzerland;XX XXX XXXX
|
||||
40;RO;Romania;XXX XXX XXX
|
||||
39;IT;Italy
|
||||
36;HU;Hungary
|
||||
34;ES;Spain
|
||||
33;FR;France
|
||||
32;BE;Belgium
|
||||
31;NL;Netherlands
|
||||
30;GR;Greece
|
||||
27;ZA;South Africa
|
||||
20;EG;Egypt
|
||||
7;KZ;Kazakhstan
|
||||
7;RU;Russian Federation
|
||||
1;PR;Puerto Rico
|
||||
1;DO;Dominican Rep.
|
||||
1;CA;Canada
|
||||
1;US;USA
|
||||
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
|
|
@ -75,6 +75,7 @@ import java.util.ArrayList;
|
|||
import java.util.Date;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class AndroidUtilities {
|
||||
|
||||
|
@ -93,6 +94,36 @@ public class AndroidUtilities {
|
|||
private static Boolean isTablet = null;
|
||||
private static int adjustOwnerClassGuid = 0;
|
||||
|
||||
public static Pattern WEB_URL = null;
|
||||
static {
|
||||
try {
|
||||
final String GOOD_IRI_CHAR = "a-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";
|
||||
final Pattern IP_ADDRESS = Pattern.compile(
|
||||
"((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]"
|
||||
+ "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]"
|
||||
+ "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
|
||||
+ "|[1-9][0-9]|[0-9]))");
|
||||
final String IRI = "[" + GOOD_IRI_CHAR + "]([" + GOOD_IRI_CHAR + "\\-]{0,61}[" + GOOD_IRI_CHAR + "]){0,1}";
|
||||
final String GOOD_GTLD_CHAR = "a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";
|
||||
final String GTLD = "[" + GOOD_GTLD_CHAR + "]{2,63}";
|
||||
final String HOST_NAME = "(" + IRI + "\\.)+" + GTLD;
|
||||
final Pattern DOMAIN_NAME = Pattern.compile("(" + HOST_NAME + "|" + IP_ADDRESS + ")");
|
||||
WEB_URL = Pattern.compile(
|
||||
"((?:(http|https|Http|Https):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
|
||||
+ "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
|
||||
+ "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
|
||||
+ "(?:" + DOMAIN_NAME + ")"
|
||||
+ "(?:\\:\\d{1,5})?)" // plus option port number
|
||||
+ "(\\/(?:(?:[" + GOOD_IRI_CHAR + "\\;\\/\\?\\:\\@\\&\\=\\#\\~" // plus option query params
|
||||
+ "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?"
|
||||
+ "(?:\\b|$)");
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static {
|
||||
density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
|
||||
leftBaseline = isTablet() ? 80 : 72;
|
||||
|
@ -735,7 +766,7 @@ public class AndroidUtilities {
|
|||
}*/
|
||||
|
||||
public static void checkForCrashes(Activity context) {
|
||||
CrashManager.register(context, BuildVars.HOCKEY_APP_HASH, new CrashManagerListener() {
|
||||
CrashManager.register(context, BuildVars.DEBUG_VERSION ? BuildVars.HOCKEY_APP_HASH_DEBUG : BuildVars.HOCKEY_APP_HASH, new CrashManagerListener() {
|
||||
@Override
|
||||
public boolean includeDeviceData() {
|
||||
return true;
|
||||
|
@ -745,7 +776,7 @@ public class AndroidUtilities {
|
|||
|
||||
public static void checkForUpdates(Activity context) {
|
||||
if (BuildVars.DEBUG_VERSION) {
|
||||
UpdateManager.register(context, BuildVars.HOCKEY_APP_HASH);
|
||||
UpdateManager.register(context, BuildVars.DEBUG_VERSION ? BuildVars.HOCKEY_APP_HASH_DEBUG : BuildVars.HOCKEY_APP_HASH);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -327,18 +327,23 @@ public class ApplicationLoader extends Application {
|
|||
}
|
||||
|
||||
private void initPlayServices() {
|
||||
if (checkPlayServices()) {
|
||||
gcm = GoogleCloudMessaging.getInstance(this);
|
||||
regid = getRegistrationId();
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (checkPlayServices()) {
|
||||
gcm = GoogleCloudMessaging.getInstance(ApplicationLoader.this);
|
||||
regid = getRegistrationId();
|
||||
|
||||
if (regid.length() == 0) {
|
||||
registerInBackground();
|
||||
} else {
|
||||
sendRegistrationIdToBackend(false);
|
||||
if (regid.length() == 0) {
|
||||
registerInBackground();
|
||||
} else {
|
||||
sendRegistrationIdToBackend(false);
|
||||
}
|
||||
} else {
|
||||
FileLog.d("tmessages", "No valid Google Play Services APK found.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FileLog.d("tmessages", "No valid Google Play Services APK found.");
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
private boolean checkPlayServices() {
|
||||
|
|
|
@ -21,6 +21,6 @@ public class AutoMessageHeardReceiver extends BroadcastReceiver {
|
|||
if (dialog_id == 0 || max_id == 0) {
|
||||
return;
|
||||
}
|
||||
MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, 0, true, false);
|
||||
MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, true, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,6 @@ public class AutoMessageReplyReceiver extends BroadcastReceiver {
|
|||
return;
|
||||
}
|
||||
SendMessagesHelper.getInstance().sendMessage(text.toString(), dialog_id, null, null, true, false);
|
||||
MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, 0, true, false);
|
||||
MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, true, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,10 +10,11 @@ package org.telegram.messenger;
|
|||
|
||||
public class BuildVars {
|
||||
public static boolean DEBUG_VERSION = false;
|
||||
public static int BUILD_VERSION = 654;
|
||||
public static int BUILD_VERSION = 685;
|
||||
public static int APP_ID = 0; //obtain your own APP_ID at https://core.telegram.org/api/obtaining_api_id
|
||||
public static String APP_HASH = ""; //obtain your own APP_HASH at https://core.telegram.org/api/obtaining_api_id
|
||||
public static String HOCKEY_APP_HASH = "your-hockeyapp-api-key-here";
|
||||
public static String HOCKEY_APP_HASH_DEBUG = "your-hockeyapp-api-key-here";
|
||||
public static String GCM_SENDER_ID = "760348033672";
|
||||
public static String SEND_LOGS_EMAIL = "email@gmail.com";
|
||||
public static String BING_SEARCH_KEY = ""; //obtain your own KEY at https://www.bing.com/dev/en-us/dev-center
|
||||
|
|
|
@ -16,17 +16,18 @@ public class ChatObject {
|
|||
public static final int CHAT_TYPE_BROADCAST = 1;
|
||||
public static final int CHAT_TYPE_CHANNEL = 2;
|
||||
public static final int CHAT_TYPE_USER = 3;
|
||||
public static final int CHAT_TYPE_MEGAGROUP = 4;
|
||||
|
||||
public static boolean isLeftFromChat(TLRPC.Chat chat) {
|
||||
return chat == null || chat instanceof TLRPC.TL_chatForbidden || chat instanceof TLRPC.TL_channelForbidden || (chat.flags & TLRPC.CHAT_FLAG_USER_LEFT) != 0;
|
||||
return chat == null || chat instanceof TLRPC.TL_chatEmpty || chat instanceof TLRPC.TL_chatForbidden || chat instanceof TLRPC.TL_channelForbidden || chat.left || chat.deactivated;
|
||||
}
|
||||
|
||||
public static boolean isKickedFromChat(TLRPC.Chat chat) {
|
||||
return chat == null || chat instanceof TLRPC.TL_chatForbidden || chat instanceof TLRPC.TL_channelForbidden || (chat.flags & TLRPC.CHAT_FLAG_USER_KICKED) != 0;
|
||||
return chat == null || chat instanceof TLRPC.TL_chatEmpty || chat instanceof TLRPC.TL_chatForbidden || chat instanceof TLRPC.TL_channelForbidden || chat.kicked || chat.deactivated;
|
||||
}
|
||||
|
||||
public static boolean isNotInChat(TLRPC.Chat chat) {
|
||||
return chat == null || chat instanceof TLRPC.TL_chatForbidden || chat instanceof TLRPC.TL_channelForbidden || (chat.flags & TLRPC.CHAT_FLAG_USER_LEFT) != 0 || (chat.flags & TLRPC.CHAT_FLAG_USER_KICKED) != 0;
|
||||
return chat == null || chat instanceof TLRPC.TL_chatEmpty || chat instanceof TLRPC.TL_chatForbidden || chat instanceof TLRPC.TL_channelForbidden || chat.left || chat.kicked || chat.deactivated;
|
||||
}
|
||||
|
||||
public static boolean isChannel(TLRPC.Chat chat) {
|
||||
|
@ -40,11 +41,11 @@ public class ChatObject {
|
|||
|
||||
public static boolean isCanWriteToChannel(int chatId) {
|
||||
TLRPC.Chat chat = MessagesController.getInstance().getChat(chatId);
|
||||
return chat != null && ((chat.flags & TLRPC.CHAT_FLAG_ADMIN) != 0 || (chat.flags & TLRPC.CHAT_FLAG_USER_IS_EDITOR) != 0);
|
||||
return chat != null && (chat.creator || chat.editor || chat.megagroup);
|
||||
}
|
||||
|
||||
public static boolean canWriteToChat(TLRPC.Chat chat) {
|
||||
return !isChannel(chat) || (chat.flags & TLRPC.CHAT_FLAG_ADMIN) != 0 || (chat.flags & TLRPC.CHAT_FLAG_USER_IS_EDITOR) != 0 || (chat.flags & TLRPC.CHAT_FLAG_IS_BROADCAST) == 0;
|
||||
return !isChannel(chat) || chat.creator || chat.editor || !chat.broadcast;
|
||||
}
|
||||
|
||||
public static TLRPC.Chat getChatByDialog(long did) {
|
||||
|
|
|
@ -208,8 +208,8 @@ public class ContactsController {
|
|||
try {
|
||||
accounts = am.getAccountsByType("org.telegram.account");
|
||||
if (accounts != null && accounts.length > 0) {
|
||||
for (Account c : accounts) {
|
||||
am.removeAccount(c, null, null);
|
||||
for (int a = 0; a < accounts.length; a++) {
|
||||
am.removeAccount(accounts[a], null, null);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -221,7 +221,7 @@ public class ContactsController {
|
|||
if (UserConfig.isClientActivated()) {
|
||||
if (accounts.length == 1) {
|
||||
Account acc = accounts[0];
|
||||
if (!acc.name.equals(UserConfig.getCurrentUser().phone)) {
|
||||
if (!acc.name.equals("" + UserConfig.getClientUserId())) {
|
||||
recreateAccount = true;
|
||||
} else {
|
||||
currentAccount = acc;
|
||||
|
@ -236,12 +236,16 @@ public class ContactsController {
|
|||
}
|
||||
}
|
||||
if (recreateAccount) {
|
||||
for (Account c : accounts) {
|
||||
am.removeAccount(c, null, null);
|
||||
try {
|
||||
for (int a = 0; a < accounts.length; a++) {
|
||||
am.removeAccount(accounts[a], null, null);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
if (UserConfig.isClientActivated()) {
|
||||
try {
|
||||
currentAccount = new Account(UserConfig.getCurrentUser().phone, "org.telegram.messenger");
|
||||
currentAccount = new Account("" + UserConfig.getClientUserId(), "org.telegram.messenger");
|
||||
am.addAccountExplicitly(currentAccount, "", null);
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
|
@ -254,8 +258,8 @@ public class ContactsController {
|
|||
try {
|
||||
AccountManager am = AccountManager.get(ApplicationLoader.applicationContext);
|
||||
Account[] accounts = am.getAccountsByType("org.telegram.messenger");
|
||||
for (Account c : accounts) {
|
||||
am.removeAccount(c, null, null);
|
||||
for (int a = 0; a < accounts.length; a++) {
|
||||
am.removeAccount(accounts[a], null, null);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
@ -277,7 +281,7 @@ public class ContactsController {
|
|||
private boolean checkContactsInternal() {
|
||||
boolean reload = false;
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
|
||||
if (!hasContactsPermission()) {
|
||||
return false;
|
||||
}
|
||||
ContentResolver cr = ApplicationLoader.applicationContext.getContentResolver();
|
||||
|
@ -334,7 +338,7 @@ public class ContactsController {
|
|||
private HashMap<Integer, Contact> readContactsFromPhoneBook() {
|
||||
HashMap<Integer, Contact> contactsMap = new HashMap<>();
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
|
||||
if (!hasContactsPermission()) {
|
||||
return contactsMap;
|
||||
}
|
||||
ContentResolver cr = ApplicationLoader.applicationContext.getContentResolver();
|
||||
|
@ -1044,7 +1048,7 @@ public class ContactsController {
|
|||
sortedSectionsArray.add(key);
|
||||
}
|
||||
arr.add(value);
|
||||
if ((user.flags & TLRPC.USER_FLAG_MUTUAL_CONTACT) != 0) {
|
||||
if (user.mutual_contact) {
|
||||
arr = sectionsDictMutual.get(key);
|
||||
if (arr == null) {
|
||||
arr = new ArrayList<>();
|
||||
|
@ -1280,9 +1284,34 @@ public class ContactsController {
|
|||
sortedUsersSectionsArray = sortedSectionsArray;
|
||||
}
|
||||
|
||||
private boolean hasContactsPermission() {
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
return ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
ContentResolver cr = ApplicationLoader.applicationContext.getContentResolver();
|
||||
cursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projectionPhones, null, null, null);
|
||||
if (cursor == null || cursor.getCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
} finally {
|
||||
try {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void performWriteContactsToPhoneBookInternal(ArrayList<TLRPC.TL_contact> contactsArray) {
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
|
||||
if (!hasContactsPermission()) {
|
||||
return;
|
||||
}
|
||||
Uri rawContactUri = ContactsContract.RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, currentAccount.name).appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, currentAccount.type).build();
|
||||
|
@ -1294,7 +1323,8 @@ public class ContactsController {
|
|||
}
|
||||
c1.close();
|
||||
|
||||
for (TLRPC.TL_contact u : contactsArray) {
|
||||
for (int a = 0; a < contactsArray.size(); a++) {
|
||||
TLRPC.TL_contact u = contactsArray.get(a);
|
||||
if (!bookContacts.containsKey(u.user_id)) {
|
||||
TLRPC.User user = MessagesController.getInstance().getUser(u.user_id);
|
||||
addContactToPhoneBook(user, false);
|
||||
|
@ -1486,7 +1516,7 @@ public class ContactsController {
|
|||
if (currentAccount == null || user == null || user.phone == null || user.phone.length() == 0) {
|
||||
return -1;
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
|
||||
if (!hasContactsPermission()) {
|
||||
return -1;
|
||||
}
|
||||
long res = -1;
|
||||
|
@ -1536,7 +1566,9 @@ public class ContactsController {
|
|||
query.add(builder.build());
|
||||
try {
|
||||
ContentProviderResult[] result = contentResolver.applyBatch(ContactsContract.AUTHORITY, query);
|
||||
res = Long.parseLong(result[0].uri.getLastPathSegment());
|
||||
if (result != null && result.length > 0 && result[0].uri != null) {
|
||||
res = Long.parseLong(result[0].uri.getLastPathSegment());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
|
@ -1547,7 +1579,7 @@ public class ContactsController {
|
|||
}
|
||||
|
||||
private void deleteContactFromPhoneBook(int uid) {
|
||||
if (Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
|
||||
if (!hasContactsPermission()) {
|
||||
return;
|
||||
}
|
||||
synchronized (observerLock) {
|
||||
|
|
|
@ -12,9 +12,12 @@ import android.os.Handler;
|
|||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class DispatchQueue extends Thread {
|
||||
public volatile Handler handler = null;
|
||||
private final Object handlerSyncObject = new Object();
|
||||
|
||||
private volatile Handler handler = null;
|
||||
private CountDownLatch syncLatch = new CountDownLatch(1);
|
||||
|
||||
public DispatchQueue(final String threadName) {
|
||||
setName(threadName);
|
||||
|
@ -22,40 +25,24 @@ public class DispatchQueue extends Thread {
|
|||
}
|
||||
|
||||
private void sendMessage(Message msg, int delay) {
|
||||
if (handler == null) {
|
||||
try {
|
||||
synchronized (handlerSyncObject) {
|
||||
handlerSyncObject.wait();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (handler != null) {
|
||||
try {
|
||||
syncLatch.await();
|
||||
if (delay <= 0) {
|
||||
handler.sendMessage(msg);
|
||||
} else {
|
||||
handler.sendMessageDelayed(msg, delay);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelRunnable(Runnable runnable) {
|
||||
if (handler == null) {
|
||||
synchronized (handlerSyncObject) {
|
||||
if (handler == null) {
|
||||
try {
|
||||
handlerSyncObject.wait();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (handler != null) {
|
||||
try {
|
||||
syncLatch.await();
|
||||
handler.removeCallbacks(runnable);
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,39 +51,32 @@ public class DispatchQueue extends Thread {
|
|||
}
|
||||
|
||||
public void postRunnable(Runnable runnable, long delay) {
|
||||
if (handler == null) {
|
||||
synchronized (handlerSyncObject) {
|
||||
if (handler == null) {
|
||||
try {
|
||||
handlerSyncObject.wait();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (handler != null) {
|
||||
try {
|
||||
syncLatch.await();
|
||||
if (delay <= 0) {
|
||||
handler.post(runnable);
|
||||
} else {
|
||||
handler.postDelayed(runnable, delay);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void cleanupQueue() {
|
||||
if (handler != null) {
|
||||
try {
|
||||
syncLatch.await();
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Looper.prepare();
|
||||
synchronized (handlerSyncObject) {
|
||||
handler = new Handler();
|
||||
handlerSyncObject.notify();
|
||||
}
|
||||
handler = new Handler();
|
||||
syncLatch.countDown();
|
||||
Looper.loop();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -266,10 +266,7 @@ public class Emoji {
|
|||
}
|
||||
|
||||
if (!canvas.quickReject(b.left, b.top, b.right, b.bottom, Canvas.EdgeType.AA)) {
|
||||
canvas.save();
|
||||
canvas.clipRect(b);
|
||||
canvas.drawBitmap(emojiBmp[info.page][info.page2], info.rect, b, fullSize ? null : paint);
|
||||
canvas.restore();
|
||||
canvas.drawBitmap(emojiBmp[info.page][info.page2], info.rect, b, paint);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -468,7 +468,7 @@ public class FileLoadOperation {
|
|||
delegate.didFailedLoadingFile(FileLoadOperation.this, 2);
|
||||
} else {
|
||||
if (location != null) {
|
||||
FileLog.e("tmessages", "" + location + " id = " + location.id + " access_hash = " + location.access_hash + " volume_id = " + location.local_id + " secret = " + location.secret);
|
||||
FileLog.e("tmessages", "" + location + " id = " + location.id + " local_id = " + location.local_id + " access_hash = " + location.access_hash + " volume_id = " + location.volume_id + " secret = " + location.secret);
|
||||
}
|
||||
cleanup();
|
||||
delegate.didFailedLoadingFile(FileLoadOperation.this, 0);
|
||||
|
|
|
@ -753,7 +753,8 @@ public class FileLoader {
|
|||
fileLoaderQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (File file : files) {
|
||||
for (int a = 0; a < files.size(); a++) {
|
||||
File file = files.get(a);
|
||||
if (file.exists()) {
|
||||
try {
|
||||
if (!file.delete()) {
|
||||
|
@ -763,6 +764,16 @@ public class FileLoader {
|
|||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
File qFile = new File(file.getPath(), "q_" + file.getName());
|
||||
if (qFile.exists()) {
|
||||
if (!file.delete()) {
|
||||
file.deleteOnExit();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -67,6 +67,9 @@ public class FileLog {
|
|||
}
|
||||
|
||||
public static String getNetworkLogPath() {
|
||||
if (!BuildVars.DEBUG_VERSION) {
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
File sdCard = ApplicationLoader.applicationContext.getExternalFilesDir(null);
|
||||
if (sdCard == null) {
|
||||
|
|
|
@ -75,7 +75,7 @@ public class ImageLoader {
|
|||
private HashMap<String, Runnable> retryHttpsTasks = new HashMap<>();
|
||||
private int currentHttpFileLoadTasksCount = 0;
|
||||
|
||||
protected VMRuntimeHack runtimeHack = null;
|
||||
public VMRuntimeHack runtimeHack = null;
|
||||
private String ignoreRemoval = null;
|
||||
|
||||
private volatile long lastCacheOutTime = 0;
|
||||
|
@ -1162,7 +1162,18 @@ public class ImageLoader {
|
|||
FileLog.e("tmessages", "file system changed");
|
||||
Runnable r = new Runnable() {
|
||||
public void run() {
|
||||
FileLoader.getInstance().setMediaDirs(createMediaPaths());
|
||||
cacheOutQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final HashMap<Integer, File> paths = createMediaPaths();
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
FileLoader.getInstance().setMediaDirs(paths);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
if (Intent.ACTION_MEDIA_UNMOUNTED.equals(intent.getAction())) {
|
||||
|
@ -1186,7 +1197,35 @@ public class ImageLoader {
|
|||
filter.addDataScheme("file");
|
||||
ApplicationLoader.applicationContext.registerReceiver(receiver, filter);
|
||||
|
||||
FileLoader.getInstance().setMediaDirs(createMediaPaths());
|
||||
HashMap<Integer, File> mediaDirs = new HashMap<>();
|
||||
File cachePath = AndroidUtilities.getCacheDir();
|
||||
if (!cachePath.isDirectory()) {
|
||||
try {
|
||||
cachePath.mkdirs();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
new File(cachePath, ".nomedia").createNewFile();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
mediaDirs.put(FileLoader.MEDIA_DIR_CACHE, cachePath);
|
||||
FileLoader.getInstance().setMediaDirs(mediaDirs);
|
||||
|
||||
cacheOutQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final HashMap<Integer, File> paths = createMediaPaths();
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
FileLoader.getInstance().setMediaDirs(paths);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public HashMap<Integer, File> createMediaPaths() {
|
||||
|
|
|
@ -46,14 +46,14 @@ public class LocaleController {
|
|||
public static boolean isRTL = false;
|
||||
public static int nameDisplayOrder = 1;
|
||||
private static boolean is24HourFormat = false;
|
||||
public static FastDateFormat formatterDay;
|
||||
public static FastDateFormat formatterWeek;
|
||||
public static FastDateFormat formatterMonth;
|
||||
public static FastDateFormat formatterYear;
|
||||
public static FastDateFormat formatterMonthYear;
|
||||
public static FastDateFormat formatterYearMax;
|
||||
public static FastDateFormat chatDate;
|
||||
public static FastDateFormat chatFullDate;
|
||||
public FastDateFormat formatterDay;
|
||||
public FastDateFormat formatterWeek;
|
||||
public FastDateFormat formatterMonth;
|
||||
public FastDateFormat formatterYear;
|
||||
public FastDateFormat formatterMonthYear;
|
||||
public FastDateFormat formatterYearMax;
|
||||
public FastDateFormat chatDate;
|
||||
public FastDateFormat chatFullDate;
|
||||
|
||||
private HashMap<String, PluralRules> allRules = new HashMap<>();
|
||||
|
||||
|
@ -671,9 +671,9 @@ public class LocaleController {
|
|||
int dateYear = rightNow.get(Calendar.YEAR);
|
||||
|
||||
if (year == dateYear) {
|
||||
return chatDate.format(date * 1000);
|
||||
return getInstance().chatDate.format(date * 1000);
|
||||
}
|
||||
return chatFullDate.format(date * 1000);
|
||||
return getInstance().chatFullDate.format(date * 1000);
|
||||
}
|
||||
|
||||
public static String formatDate(long date) {
|
||||
|
@ -686,13 +686,13 @@ public class LocaleController {
|
|||
int dateYear = rightNow.get(Calendar.YEAR);
|
||||
|
||||
if (dateDay == day && year == dateYear) {
|
||||
return formatterDay.format(new Date(date * 1000));
|
||||
return getInstance().formatterDay.format(new Date(date * 1000));
|
||||
} else if (dateDay + 1 == day && year == dateYear) {
|
||||
return getString("Yesterday", R.string.Yesterday);
|
||||
} else if (year == dateYear) {
|
||||
return formatterMonth.format(new Date(date * 1000));
|
||||
return getInstance().formatterMonth.format(new Date(date * 1000));
|
||||
} else {
|
||||
return formatterYear.format(new Date(date * 1000));
|
||||
return getInstance().formatterYear.format(new Date(date * 1000));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
|
@ -710,7 +710,7 @@ public class LocaleController {
|
|||
int dateYear = rightNow.get(Calendar.YEAR);
|
||||
|
||||
if (dateDay == day && year == dateYear) {
|
||||
return String.format("%s %s %s", LocaleController.getString("LastSeen", R.string.LastSeen), LocaleController.getString("TodayAt", R.string.TodayAt), formatterDay.format(new Date(date * 1000)));
|
||||
return String.format("%s %s %s", LocaleController.getString("LastSeen", R.string.LastSeen), LocaleController.getString("TodayAt", R.string.TodayAt), getInstance().formatterDay.format(new Date(date * 1000)));
|
||||
/*int diff = (int) (ConnectionsManager.getInstance().getCurrentTime() - date) / 60;
|
||||
if (diff < 1) {
|
||||
return LocaleController.getString("LastSeenNow", R.string.LastSeenNow);
|
||||
|
@ -720,12 +720,12 @@ public class LocaleController {
|
|||
return LocaleController.formatPluralString("LastSeenHours", (int) Math.ceil(diff / 60.0f));
|
||||
}*/
|
||||
} else if (dateDay + 1 == day && year == dateYear) {
|
||||
return String.format("%s %s %s", LocaleController.getString("LastSeen", R.string.LastSeen), LocaleController.getString("YesterdayAt", R.string.YesterdayAt), formatterDay.format(new Date(date * 1000)));
|
||||
return String.format("%s %s %s", LocaleController.getString("LastSeen", R.string.LastSeen), LocaleController.getString("YesterdayAt", R.string.YesterdayAt), getInstance().formatterDay.format(new Date(date * 1000)));
|
||||
} else if (year == dateYear) {
|
||||
String format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, formatterMonth.format(new Date(date * 1000)), formatterDay.format(new Date(date * 1000)));
|
||||
String format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, getInstance().formatterMonth.format(new Date(date * 1000)), getInstance().formatterDay.format(new Date(date * 1000)));
|
||||
return String.format("%s %s", LocaleController.getString("LastSeenDate", R.string.LastSeenDate), format);
|
||||
} else {
|
||||
String format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, formatterYear.format(new Date(date * 1000)), formatterDay.format(new Date(date * 1000)));
|
||||
String format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, getInstance().formatterYear.format(new Date(date * 1000)), getInstance().formatterDay.format(new Date(date * 1000)));
|
||||
return String.format("%s %s", LocaleController.getString("LastSeenDate", R.string.LastSeenDate), format);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -780,15 +780,15 @@ public class LocaleController {
|
|||
int dateYear = rightNow.get(Calendar.YEAR);
|
||||
|
||||
if (year != dateYear) {
|
||||
return formatterYear.format(new Date(date * 1000));
|
||||
return getInstance().formatterYear.format(new Date(date * 1000));
|
||||
} else {
|
||||
int dayDiff = dateDay - day;
|
||||
if(dayDiff == 0 || dayDiff == -1 && (int)(System.currentTimeMillis() / 1000) - date < 60 * 60 * 8) {
|
||||
return formatterDay.format(new Date(date * 1000));
|
||||
return getInstance().formatterDay.format(new Date(date * 1000));
|
||||
} else if(dayDiff > -7 && dayDiff <= -1) {
|
||||
return formatterWeek.format(new Date(date * 1000));
|
||||
return getInstance().formatterWeek.format(new Date(date * 1000));
|
||||
} else {
|
||||
return formatterMonth.format(new Date(date * 1000));
|
||||
return getInstance().formatterMonth.format(new Date(date * 1000));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -542,13 +542,18 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
|
|||
shuffleMusic = preferences.getBoolean("shuffleMusic", false);
|
||||
repeatMode = preferences.getInt("repeatMode", 0);
|
||||
|
||||
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidFailedLoad);
|
||||
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidLoaded);
|
||||
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileLoadProgressChanged);
|
||||
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileUploadProgressChanged);
|
||||
NotificationCenter.getInstance().addObserver(this, NotificationCenter.messagesDeleted);
|
||||
NotificationCenter.getInstance().addObserver(this, NotificationCenter.removeAllMessagesFromDialog);
|
||||
NotificationCenter.getInstance().addObserver(this, NotificationCenter.musicDidLoaded);
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
NotificationCenter.getInstance().addObserver(MediaController.this, NotificationCenter.FileDidFailedLoad);
|
||||
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.messagesDeleted);
|
||||
NotificationCenter.getInstance().addObserver(MediaController.this, NotificationCenter.removeAllMessagesFromDialog);
|
||||
NotificationCenter.getInstance().addObserver(MediaController.this, NotificationCenter.musicDidLoaded);
|
||||
}
|
||||
});
|
||||
|
||||
BroadcastReceiver networkStateReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
|
@ -1117,7 +1122,8 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
|
|||
try {
|
||||
ArrayList<SendMessagesHelper.DelayedMessage> delayedMessages = SendMessagesHelper.getInstance().getDelayedMessages(fileName);
|
||||
if (delayedMessages != null) {
|
||||
for (SendMessagesHelper.DelayedMessage delayedMessage : delayedMessages) {
|
||||
for (int a = 0; a < delayedMessages.size(); a++) {
|
||||
SendMessagesHelper.DelayedMessage delayedMessage = delayedMessages.get(a);
|
||||
if (delayedMessage.encryptedChat == null) {
|
||||
long dialog_id = delayedMessage.obj.getDialogId();
|
||||
Long lastTime = typingTimes.get(dialog_id);
|
||||
|
@ -2477,7 +2483,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
|
|||
Cursor cursor = null;
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT < 23 || Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projectionPhotos, "", null, MediaStore.Images.Media.DATE_TAKEN + " DESC");
|
||||
cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projectionPhotos, null, null, MediaStore.Images.Media.DATE_TAKEN + " DESC");
|
||||
if (cursor != null) {
|
||||
int imageIdColumn = cursor.getColumnIndex(MediaStore.Images.Media._ID);
|
||||
int bucketIdColumn = cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_ID);
|
||||
|
@ -2540,7 +2546,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
|
|||
if (Build.VERSION.SDK_INT < 23 || Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
albums.clear();
|
||||
AlbumEntry allVideosAlbum = null;
|
||||
cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projectionVideo, "", null, MediaStore.Video.Media.DATE_TAKEN + " DESC");
|
||||
cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projectionVideo, null, null, MediaStore.Video.Media.DATE_TAKEN + " DESC");
|
||||
if (cursor != null) {
|
||||
int imageIdColumn = cursor.getColumnIndex(MediaStore.Video.Media._ID);
|
||||
int bucketIdColumn = cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_ID);
|
||||
|
|
|
@ -21,6 +21,7 @@ import android.text.style.URLSpan;
|
|||
import android.text.util.Linkify;
|
||||
|
||||
import org.telegram.tgnet.ConnectionsManager;
|
||||
import org.telegram.tgnet.TLObject;
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
import org.telegram.ui.Components.TypefaceSpan;
|
||||
import org.telegram.ui.Components.URLSpanBotCommand;
|
||||
|
@ -77,6 +78,10 @@ public class MessageObject {
|
|||
public ArrayList<TextLayoutBlock> textLayoutBlocks;
|
||||
|
||||
public MessageObject(TLRPC.Message message, AbstractMap<Integer, TLRPC.User> users, boolean generateLayout) {
|
||||
this(message, users, null, generateLayout);
|
||||
}
|
||||
|
||||
public MessageObject(TLRPC.Message message, AbstractMap<Integer, TLRPC.User> users, AbstractMap<Integer, TLRPC.Chat> chats, boolean generateLayout) {
|
||||
if (textPaint == null) {
|
||||
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
|
||||
textPaint.setColor(0xff000000);
|
||||
|
@ -88,7 +93,7 @@ public class MessageObject {
|
|||
messageOwner = message;
|
||||
|
||||
if (message.replyMessage != null) {
|
||||
replyMessageObject = new MessageObject(message.replyMessage, users, false);
|
||||
replyMessageObject = new MessageObject(message.replyMessage, users, chats, false);
|
||||
}
|
||||
|
||||
if (message instanceof TLRPC.TL_messageService) {
|
||||
|
@ -143,39 +148,56 @@ public class MessageObject {
|
|||
}
|
||||
}
|
||||
} else if (message.action instanceof TLRPC.TL_messageActionChatAddUser) {
|
||||
TLRPC.User whoUser = null;
|
||||
if (users != null) {
|
||||
whoUser = users.get(message.action.user_id);
|
||||
int singleUserId = messageOwner.action.user_id;
|
||||
if (singleUserId == 0 && messageOwner.action.users.size() == 1) {
|
||||
singleUserId = messageOwner.action.users.get(0);
|
||||
}
|
||||
if (whoUser == null) {
|
||||
whoUser = MessagesController.getInstance().getUser(message.action.user_id);
|
||||
}
|
||||
if (message.to_id.channel_id != 0) {
|
||||
if (whoUser != null && whoUser.id != UserConfig.getClientUserId()) {
|
||||
messageText = replaceWithLink(LocaleController.getString("ChannelAddedBy", R.string.ChannelAddedBy), "un1", whoUser);
|
||||
} else {
|
||||
messageText = LocaleController.getString("ChannelJoined", R.string.ChannelJoined);
|
||||
if (singleUserId != 0) {
|
||||
TLRPC.User whoUser = null;
|
||||
if (users != null) {
|
||||
whoUser = users.get(singleUserId);
|
||||
}
|
||||
} else {
|
||||
if (whoUser != null && fromUser != null) {
|
||||
if (whoUser.id == fromUser.id) {
|
||||
if (isOut()) {
|
||||
messageText = LocaleController.getString("ActionAddUserSelfYou", R.string.ActionAddUserSelfYou);
|
||||
if (whoUser == null) {
|
||||
whoUser = MessagesController.getInstance().getUser(singleUserId);
|
||||
}
|
||||
if (message.to_id.channel_id != 0 && !isMegagroup()) {
|
||||
if (whoUser != null && whoUser.id != UserConfig.getClientUserId()) {
|
||||
if (isMegagroup()) {
|
||||
messageText = replaceWithLink(LocaleController.getString("MegaAddedBy", R.string.MegaAddedBy), "un1", whoUser);
|
||||
} else {
|
||||
messageText = replaceWithLink(LocaleController.getString("ActionAddUserSelf", R.string.ActionAddUserSelf), "un1", fromUser);
|
||||
messageText = replaceWithLink(LocaleController.getString("ChannelAddedBy", R.string.ChannelAddedBy), "un1", whoUser);
|
||||
}
|
||||
} else {
|
||||
if (isOut()) {
|
||||
messageText = replaceWithLink(LocaleController.getString("ActionYouAddUser", R.string.ActionYouAddUser), "un2", whoUser);
|
||||
} else if (message.action.user_id == UserConfig.getClientUserId()) {
|
||||
messageText = replaceWithLink(LocaleController.getString("ActionAddUserYou", R.string.ActionAddUserYou), "un1", fromUser);
|
||||
} else {
|
||||
messageText = replaceWithLink(LocaleController.getString("ActionAddUser", R.string.ActionAddUser), "un2", whoUser);
|
||||
messageText = replaceWithLink(messageText, "un1", fromUser);
|
||||
}
|
||||
messageText = LocaleController.getString("ChannelJoined", R.string.ChannelJoined);
|
||||
}
|
||||
} else {
|
||||
messageText = LocaleController.getString("ActionAddUser", R.string.ActionAddUser).replace("un2", "").replace("un1", "");
|
||||
if (whoUser != null && fromUser != null) {
|
||||
if (whoUser.id == fromUser.id) {
|
||||
if (isOut()) {
|
||||
messageText = LocaleController.getString("ActionAddUserSelfYou", R.string.ActionAddUserSelfYou);
|
||||
} else {
|
||||
messageText = replaceWithLink(LocaleController.getString("ActionAddUserSelf", R.string.ActionAddUserSelf), "un1", fromUser);
|
||||
}
|
||||
} else {
|
||||
if (isOut()) {
|
||||
messageText = replaceWithLink(LocaleController.getString("ActionYouAddUser", R.string.ActionYouAddUser), "un2", whoUser);
|
||||
} else if (singleUserId == UserConfig.getClientUserId()) {
|
||||
messageText = replaceWithLink(LocaleController.getString("ActionAddUserYou", R.string.ActionAddUserYou), "un1", fromUser);
|
||||
} else {
|
||||
messageText = replaceWithLink(LocaleController.getString("ActionAddUser", R.string.ActionAddUser), "un2", whoUser);
|
||||
messageText = replaceWithLink(messageText, "un1", fromUser);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
messageText = LocaleController.getString("ActionAddUser", R.string.ActionAddUser).replace("un2", "").replace("un1", "");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isOut()) {
|
||||
messageText = replaceWithLink(LocaleController.getString("ActionYouAddUser", R.string.ActionYouAddUser), "un2", message.action.users, users);
|
||||
} else {
|
||||
messageText = replaceWithLink(LocaleController.getString("ActionAddUser", R.string.ActionAddUser), "un2", message.action.users, users);
|
||||
messageText = replaceWithLink(messageText, "un1", fromUser);
|
||||
}
|
||||
}
|
||||
} else if (message.action instanceof TLRPC.TL_messageActionChatJoinedByLink) {
|
||||
|
@ -189,7 +211,7 @@ public class MessageObject {
|
|||
messageText = LocaleController.getString("ActionInviteUser", R.string.ActionInviteUser).replace("un1", "");
|
||||
}
|
||||
} else if (message.action instanceof TLRPC.TL_messageActionChatEditPhoto) {
|
||||
if (message.to_id.channel_id != 0) {
|
||||
if (message.to_id.channel_id != 0 && !isMegagroup()) {
|
||||
messageText = LocaleController.getString("ActionChannelChangedPhoto", R.string.ActionChannelChangedPhoto);
|
||||
} else {
|
||||
if (isOut()) {
|
||||
|
@ -203,7 +225,7 @@ public class MessageObject {
|
|||
}
|
||||
}
|
||||
} else if (message.action instanceof TLRPC.TL_messageActionChatEditTitle) {
|
||||
if (message.to_id.channel_id != 0) {
|
||||
if (message.to_id.channel_id != 0 && !isMegagroup()) {
|
||||
messageText = LocaleController.getString("ActionChannelChangedTitle", R.string.ActionChannelChangedTitle).replace("un2", message.action.title);
|
||||
} else {
|
||||
if (isOut()) {
|
||||
|
@ -217,7 +239,7 @@ public class MessageObject {
|
|||
}
|
||||
}
|
||||
} else if (message.action instanceof TLRPC.TL_messageActionChatDeletePhoto) {
|
||||
if (message.to_id.channel_id != 0) {
|
||||
if (message.to_id.channel_id != 0 && !isMegagroup()) {
|
||||
messageText = LocaleController.getString("ActionChannelRemovedPhoto", R.string.ActionChannelRemovedPhoto);
|
||||
} else {
|
||||
if (isOut()) {
|
||||
|
@ -253,7 +275,13 @@ public class MessageObject {
|
|||
}
|
||||
}
|
||||
} else if (message.action instanceof TLRPC.TL_messageActionLoginUnknownLocation) {
|
||||
String date = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, LocaleController.formatterYear.format(((long) message.date) * 1000), LocaleController.formatterDay.format(((long) message.date) * 1000));
|
||||
String date;
|
||||
long time = ((long) message.date) * 1000;
|
||||
if (LocaleController.getInstance().formatterDay != null && LocaleController.getInstance().formatterYear != null) {
|
||||
date = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, LocaleController.getInstance().formatterYear.format(time), LocaleController.getInstance().formatterDay.format(time));
|
||||
} else {
|
||||
date = "" + message.date;
|
||||
}
|
||||
TLRPC.User to_user = UserConfig.getCurrentUser();
|
||||
if (to_user == null) {
|
||||
if (users != null) {
|
||||
|
@ -315,7 +343,15 @@ public class MessageObject {
|
|||
} else if (message.action instanceof TLRPC.TL_messageActionCreatedBroadcastList) {
|
||||
messageText = LocaleController.formatString("YouCreatedBroadcastList", R.string.YouCreatedBroadcastList);
|
||||
} else if (message.action instanceof TLRPC.TL_messageActionChannelCreate) {
|
||||
messageText = LocaleController.getString("ActionCreateChannel", R.string.ActionCreateChannel);
|
||||
if (isMegagroup()) {
|
||||
messageText = LocaleController.getString("ActionCreateMega", R.string.ActionCreateMega);
|
||||
} else {
|
||||
messageText = LocaleController.getString("ActionCreateChannel", R.string.ActionCreateChannel);
|
||||
}
|
||||
} else if (message.action instanceof TLRPC.TL_messageActionChatMigrateTo) {
|
||||
messageText = LocaleController.getString("ActionMigrateFromGroup", R.string.ActionMigrateFromGroup);
|
||||
} else if (message.action instanceof TLRPC.TL_messageActionChannelMigrateFrom) {
|
||||
messageText = LocaleController.getString("ActionMigrateFromGroup", R.string.ActionMigrateFromGroup);
|
||||
}
|
||||
}
|
||||
} else if (!isMediaEmpty()) {
|
||||
|
@ -353,6 +389,9 @@ public class MessageObject {
|
|||
} else {
|
||||
messageText = message.message;
|
||||
}
|
||||
if (messageText == null) {
|
||||
messageText = "";
|
||||
}
|
||||
if (generateLayout) {
|
||||
messageText = Emoji.replaceEmoji(messageText, textPaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
|
||||
}
|
||||
|
@ -360,7 +399,7 @@ public class MessageObject {
|
|||
if (message instanceof TLRPC.TL_message || message instanceof TLRPC.TL_messageForwarded_old2) {
|
||||
if (isMediaEmpty()) {
|
||||
contentType = type = 0;
|
||||
if (messageText.length() == 0) {
|
||||
if (messageText == null || messageText.length() == 0) {
|
||||
messageText = "Empty message";
|
||||
}
|
||||
} else if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
|
||||
|
@ -423,6 +462,8 @@ public class MessageObject {
|
|||
dateKey = String.format("%d_%02d_%02d", dateYear, dateMonth, dateDay);
|
||||
if (contentType == 1 || contentType == 2 || contentType == 0 || contentType == 8) {
|
||||
monthKey = String.format("%d_%02d", dateYear, dateMonth);
|
||||
} else if (contentType == 9) {
|
||||
//dateKey = "0_0_0";
|
||||
}
|
||||
|
||||
if (messageOwner.message != null && messageOwner.id < 0 && messageOwner.message.length() > 6 && messageOwner.media instanceof TLRPC.TL_messageMediaVideo) {
|
||||
|
@ -513,13 +554,50 @@ public class MessageObject {
|
|||
}
|
||||
}
|
||||
|
||||
public CharSequence replaceWithLink(CharSequence source, String param, TLRPC.User user) {
|
||||
public CharSequence replaceWithLink(CharSequence source, String param, ArrayList<Integer> uids, AbstractMap<Integer, TLRPC.User> usersDict) {
|
||||
int start = TextUtils.indexOf(source, param);
|
||||
if (start >= 0) {
|
||||
String name = UserObject.getUserName(user);
|
||||
URLSpanNoUnderlineBold span = new URLSpanNoUnderlineBold("" + user.id);
|
||||
SpannableStringBuilder names = new SpannableStringBuilder("");
|
||||
for (int a = 0; a < uids.size(); a++) {
|
||||
TLRPC.User user = null;
|
||||
if (usersDict != null) {
|
||||
user = usersDict.get(uids.get(a));
|
||||
}
|
||||
if (user == null) {
|
||||
user = MessagesController.getInstance().getUser(uids.get(a));
|
||||
}
|
||||
if (user != null) {
|
||||
String name = UserObject.getUserName(user);
|
||||
start = names.length();
|
||||
if (names.length() != 0) {
|
||||
names.append(", ");
|
||||
}
|
||||
names.append(name);
|
||||
names.setSpan(new URLSpanNoUnderlineBold("" + user.id), start, start + name.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
}
|
||||
return TextUtils.replace(source, new String[]{param}, new CharSequence[]{names});
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
public CharSequence replaceWithLink(CharSequence source, String param, TLObject object) {
|
||||
int start = TextUtils.indexOf(source, param);
|
||||
if (start >= 0) {
|
||||
String name;
|
||||
int id;
|
||||
if (object instanceof TLRPC.User) {
|
||||
name = UserObject.getUserName((TLRPC.User) object);
|
||||
id = ((TLRPC.User) object).id;
|
||||
} else if (object instanceof TLRPC.Chat) {
|
||||
name = ((TLRPC.Chat) object).title;
|
||||
id = -((TLRPC.Chat) object).id;
|
||||
} else {
|
||||
name = "";
|
||||
id = 0;
|
||||
}
|
||||
SpannableStringBuilder builder = new SpannableStringBuilder(TextUtils.replace(source, new String[]{param}, new String[]{name}));
|
||||
builder.setSpan(span, start, start + name.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
builder.setSpan(new URLSpanNoUnderlineBold("" + id), start, start + name.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
return builder;
|
||||
}
|
||||
return source;
|
||||
|
@ -647,6 +725,7 @@ public class MessageObject {
|
|||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
linkDescription = Emoji.replaceEmoji(linkDescription, textPaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -662,12 +741,12 @@ public class MessageObject {
|
|||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
addUsernamesAndHashtags(caption);
|
||||
addUsernamesAndHashtags(caption, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void addUsernamesAndHashtags(CharSequence charSequence) {
|
||||
private static void addUsernamesAndHashtags(CharSequence charSequence, boolean botCommands) {
|
||||
try {
|
||||
if (urlPattern == null) {
|
||||
urlPattern = Pattern.compile("(^|\\s)/[a-zA-Z@\\d_]{1,255}|(^|\\s)@[a-zA-Z\\d_]{5,32}|(^|\\s)#[\\w\\.]+");
|
||||
|
@ -679,20 +758,29 @@ public class MessageObject {
|
|||
if (charSequence.charAt(start) != '@' && charSequence.charAt(start) != '#' && charSequence.charAt(start) != '/') {
|
||||
start++;
|
||||
}
|
||||
URLSpanNoUnderline url;
|
||||
URLSpanNoUnderline url = null;
|
||||
if (charSequence.charAt(start) == '/') {
|
||||
url = new URLSpanBotCommand(charSequence.subSequence(start, end).toString());
|
||||
if (botCommands) {
|
||||
url = new URLSpanBotCommand(charSequence.subSequence(start, end).toString());
|
||||
}
|
||||
} else {
|
||||
url = new URLSpanNoUnderline(charSequence.subSequence(start, end).toString());
|
||||
}
|
||||
((Spannable) charSequence).setSpan(url, start, end, 0);
|
||||
if (url != null) {
|
||||
((Spannable) charSequence).setSpan(url, start, end, 0);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void addLinks(CharSequence messageText) {
|
||||
addLinks(messageText, true);
|
||||
}
|
||||
|
||||
public static void addLinks(CharSequence messageText, boolean botCommands) {
|
||||
if (messageText instanceof Spannable && containsUrls(messageText)) {
|
||||
if (messageText.length() < 100) {
|
||||
try {
|
||||
|
@ -707,7 +795,7 @@ public class MessageObject {
|
|||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
addUsernamesAndHashtags(messageText);
|
||||
addUsernamesAndHashtags(messageText, botCommands);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -755,7 +843,7 @@ public class MessageObject {
|
|||
spannable.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), entity.offset, entity.offset + entity.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
} else if (entity instanceof TLRPC.TL_messageEntityItalic) {
|
||||
spannable.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/ritalic.ttf")), entity.offset, entity.offset + entity.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
} else if (entity instanceof TLRPC.TL_messageEntityCode) {
|
||||
} else if (entity instanceof TLRPC.TL_messageEntityCode || entity instanceof TLRPC.TL_messageEntityPre) {
|
||||
spannable.setSpan(new TypefaceSpan(Typeface.MONOSPACE), entity.offset, entity.offset + entity.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
} else if (!useManualParse) {
|
||||
String url = messageOwner.message.substring(entity.offset, entity.offset + entity.length);
|
||||
|
@ -940,23 +1028,23 @@ public class MessageObject {
|
|||
}
|
||||
|
||||
public boolean isOut() {
|
||||
return (messageOwner.flags & TLRPC.MESSAGE_FLAG_OUT) != 0;
|
||||
return messageOwner.out;
|
||||
}
|
||||
|
||||
public boolean isOutOwner() {
|
||||
return (messageOwner.flags & TLRPC.MESSAGE_FLAG_OUT) != 0 && messageOwner.from_id > 0;
|
||||
return messageOwner.out && messageOwner.from_id > 0;
|
||||
}
|
||||
|
||||
public boolean isUnread() {
|
||||
return (messageOwner.flags & TLRPC.MESSAGE_FLAG_UNREAD) != 0;
|
||||
return messageOwner.unread;
|
||||
}
|
||||
|
||||
public boolean isContentUnread() {
|
||||
return (messageOwner.flags & TLRPC.MESSAGE_FLAG_CONTENT_UNREAD) != 0;
|
||||
return messageOwner.media_unread;
|
||||
}
|
||||
|
||||
public void setIsRead() {
|
||||
messageOwner.flags &= ~TLRPC.MESSAGE_FLAG_UNREAD;
|
||||
messageOwner.unread = false;
|
||||
}
|
||||
|
||||
public int getUnradFlags() {
|
||||
|
@ -965,17 +1053,17 @@ public class MessageObject {
|
|||
|
||||
public static int getUnreadFlags(TLRPC.Message message) {
|
||||
int flags = 0;
|
||||
if ((message.flags & TLRPC.MESSAGE_FLAG_UNREAD) == 0) {
|
||||
if (!message.unread) {
|
||||
flags |= 1;
|
||||
}
|
||||
if ((message.flags & TLRPC.MESSAGE_FLAG_CONTENT_UNREAD) == 0) {
|
||||
if (!message.media_unread) {
|
||||
flags |= 2;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
public void setContentIsRead() {
|
||||
messageOwner.flags &= ~TLRPC.MESSAGE_FLAG_CONTENT_UNREAD;
|
||||
messageOwner.media_unread = false;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
|
@ -983,66 +1071,73 @@ public class MessageObject {
|
|||
}
|
||||
|
||||
public boolean isSecretPhoto() {
|
||||
return messageOwner instanceof TLRPC.TL_message_secret && messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && messageOwner.ttl != 0 && messageOwner.ttl <= 60;
|
||||
return messageOwner instanceof TLRPC.TL_message_secret && messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && messageOwner.ttl > 0 && messageOwner.ttl <= 60;
|
||||
}
|
||||
|
||||
public boolean isSecretMedia() {
|
||||
return messageOwner instanceof TLRPC.TL_message_secret &&
|
||||
(messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && messageOwner.ttl != 0 && messageOwner.ttl <= 60 ||
|
||||
(messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && messageOwner.ttl > 0 && messageOwner.ttl <= 60 ||
|
||||
messageOwner.media instanceof TLRPC.TL_messageMediaAudio ||
|
||||
messageOwner.media instanceof TLRPC.TL_messageMediaVideo);
|
||||
}
|
||||
|
||||
public static void setUnreadFlags(TLRPC.Message message, int flag) {
|
||||
if ((flag & 1) == 0) {
|
||||
message.flags |= TLRPC.MESSAGE_FLAG_UNREAD;
|
||||
} else {
|
||||
message.flags &= ~TLRPC.MESSAGE_FLAG_UNREAD;
|
||||
}
|
||||
if ((flag & 2) == 0) {
|
||||
message.flags |= TLRPC.MESSAGE_FLAG_CONTENT_UNREAD;
|
||||
} else {
|
||||
message.flags &= ~TLRPC.MESSAGE_FLAG_CONTENT_UNREAD;
|
||||
}
|
||||
message.unread = (flag & 1) == 0;
|
||||
message.media_unread = (flag & 2) == 0;
|
||||
}
|
||||
|
||||
public static boolean isUnread(TLRPC.Message message) {
|
||||
return (message.flags & TLRPC.MESSAGE_FLAG_UNREAD) != 0;
|
||||
return message.unread;
|
||||
}
|
||||
|
||||
public static boolean isContentUnread(TLRPC.Message message) {
|
||||
return (message.flags & TLRPC.MESSAGE_FLAG_CONTENT_UNREAD) != 0;
|
||||
return message.media_unread;
|
||||
}
|
||||
|
||||
public boolean isImportant() {
|
||||
return isImportant(messageOwner);
|
||||
}
|
||||
|
||||
public boolean isMegagroup() {
|
||||
return isMegagroup(messageOwner);
|
||||
}
|
||||
|
||||
public static boolean isImportant(TLRPC.Message message) {
|
||||
return message.to_id.channel_id != 0 && (message.from_id <= 0 || (message.flags & TLRPC.MESSAGE_FLAG_MENTION) != 0 || (message.flags & TLRPC.MESSAGE_FLAG_OUT) != 0 || (message.flags & TLRPC.MESSAGE_FLAG_HAS_FROM_ID) == 0);
|
||||
if (isMegagroup(message)) {
|
||||
return message.from_id <= 0;
|
||||
}
|
||||
return message.to_id.channel_id != 0 && (message.from_id <= 0 || message.mentioned || message.out || (message.flags & TLRPC.MESSAGE_FLAG_HAS_FROM_ID) == 0);
|
||||
}
|
||||
|
||||
public static boolean isMegagroup(TLRPC.Message message) {
|
||||
return (message.flags & TLRPC.MESSAGE_FLAG_MEGAGROUP) != 0;
|
||||
}
|
||||
|
||||
public static boolean isOut(TLRPC.Message message) {
|
||||
return (message.flags & TLRPC.MESSAGE_FLAG_OUT) != 0;
|
||||
return message.out;
|
||||
}
|
||||
|
||||
public long getDialogId() {
|
||||
if (messageOwner.dialog_id == 0) {
|
||||
if (messageOwner.to_id.chat_id != 0) {
|
||||
if (messageOwner.to_id.chat_id < 0) {
|
||||
messageOwner.dialog_id = AndroidUtilities.makeBroadcastId(messageOwner.to_id.chat_id);
|
||||
return getDialogId(messageOwner);
|
||||
}
|
||||
|
||||
public static long getDialogId(TLRPC.Message message) {
|
||||
if (message.dialog_id == 0 && message.to_id != null) {
|
||||
if (message.to_id.chat_id != 0) {
|
||||
if (message.to_id.chat_id < 0) {
|
||||
message.dialog_id = AndroidUtilities.makeBroadcastId(message.to_id.chat_id);
|
||||
} else {
|
||||
messageOwner.dialog_id = -messageOwner.to_id.chat_id;
|
||||
message.dialog_id = -message.to_id.chat_id;
|
||||
}
|
||||
} else if (messageOwner.to_id.channel_id != 0) {
|
||||
messageOwner.dialog_id = -messageOwner.to_id.channel_id;
|
||||
} else if (isOut()) {
|
||||
messageOwner.dialog_id = messageOwner.to_id.user_id;
|
||||
} else if (message.to_id.channel_id != 0) {
|
||||
message.dialog_id = -message.to_id.channel_id;
|
||||
} else if (isOut(message)) {
|
||||
message.dialog_id = message.to_id.user_id;
|
||||
} else {
|
||||
messageOwner.dialog_id = messageOwner.from_id;
|
||||
message.dialog_id = message.from_id;
|
||||
}
|
||||
}
|
||||
return messageOwner.dialog_id;
|
||||
return message.dialog_id;
|
||||
}
|
||||
|
||||
public boolean isSending() {
|
||||
|
@ -1274,6 +1369,9 @@ public class MessageObject {
|
|||
}
|
||||
|
||||
public static boolean canDeleteMessage(TLRPC.Message message, TLRPC.Chat chat) {
|
||||
if (message.id < 0) {
|
||||
return true;
|
||||
}
|
||||
if (chat == null && message.to_id.channel_id != 0) {
|
||||
chat = MessagesController.getInstance().getChat(message.to_id.channel_id);
|
||||
}
|
||||
|
@ -1281,13 +1379,13 @@ public class MessageObject {
|
|||
if (message.id == 1) {
|
||||
return false;
|
||||
}
|
||||
if ((chat.flags & TLRPC.CHAT_FLAG_ADMIN) != 0) {
|
||||
if (chat.creator) {
|
||||
return true;
|
||||
} else if ((chat.flags & TLRPC.CHAT_FLAG_USER_IS_EDITOR) != 0) {
|
||||
} else if (chat.editor) {
|
||||
if (isOut(message) || message.from_id > 0) {
|
||||
return true;
|
||||
}
|
||||
} else if ((chat.flags & TLRPC.CHAT_FLAG_USER_IS_MODERATOR) != 0) {
|
||||
} else if (chat.moderator) {
|
||||
if (message.from_id > 0) {
|
||||
return true;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,19 +1,20 @@
|
|||
package org.telegram.messenger;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
|
||||
import net.hockeyapp.android.Constants;
|
||||
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.mime.MultipartEntity;
|
||||
import org.apache.http.entity.mime.content.FileBody;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import net.hockeyapp.android.utils.SimpleMultipartEntity;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -24,7 +25,7 @@ public class NativeCrashManager {
|
|||
for (String dumpFilename : filenames) {
|
||||
String logFilename = createLogFile();
|
||||
if (logFilename != null) {
|
||||
uploadDumpAndLog(activity, BuildVars.HOCKEY_APP_HASH, dumpFilename, logFilename);
|
||||
uploadDumpAndLog(activity, BuildVars.DEBUG_VERSION ? BuildVars.HOCKEY_APP_HASH_DEBUG : BuildVars.HOCKEY_APP_HASH, dumpFilename, logFilename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,17 +62,29 @@ public class NativeCrashManager {
|
|||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
DefaultHttpClient httpClient = new DefaultHttpClient();
|
||||
HttpPost httpPost = new HttpPost("https://rink.hockeyapp.net/api/2/apps/" + identifier + "/crashes/upload");
|
||||
MultipartEntity entity = new MultipartEntity();
|
||||
File dumpFile = new File(Constants.FILES_PATH, dumpFilename);
|
||||
entity.addPart("attachment0", new FileBody(dumpFile));
|
||||
File logFile = new File(Constants.FILES_PATH, logFilename);
|
||||
entity.addPart("log", new FileBody(logFile));
|
||||
httpPost.setEntity(entity);
|
||||
httpClient.execute(httpPost);
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
SimpleMultipartEntity entity = new SimpleMultipartEntity();
|
||||
entity.writeFirstBoundaryIfNeeds();
|
||||
|
||||
Uri attachmentUri = Uri.fromFile(new File(Constants.FILES_PATH, dumpFilename));
|
||||
InputStream input = activity.getContentResolver().openInputStream(attachmentUri);
|
||||
entity.addPart("attachment0", attachmentUri.getLastPathSegment(), input, false);
|
||||
|
||||
attachmentUri = Uri.fromFile(new File(Constants.FILES_PATH, logFilename));
|
||||
input = activity.getContentResolver().openInputStream(attachmentUri);
|
||||
entity.addPart("log", attachmentUri.getLastPathSegment(), input, false);
|
||||
|
||||
entity.writeLastBoundaryIfNeeds();
|
||||
|
||||
HttpURLConnection urlConnection = (HttpURLConnection) new URL("https://rink.hockeyapp.net/api/2/apps/" + identifier + "/crashes/upload").openConnection();
|
||||
urlConnection.setDoOutput(true);
|
||||
urlConnection.setRequestMethod("POST");
|
||||
urlConnection.setRequestProperty("Content-Type", entity.getContentType());
|
||||
urlConnection.setRequestProperty("Content-Length", String.valueOf(entity.getContentLength()));
|
||||
urlConnection.getOutputStream().write(entity.getOutputStream().toByteArray());
|
||||
|
||||
urlConnection.connect();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
activity.deleteFile(logFilename);
|
||||
activity.deleteFile(dumpFilename);
|
||||
|
|
|
@ -23,7 +23,7 @@ import java.util.zip.ZipFile;
|
|||
|
||||
public class NativeLoader {
|
||||
|
||||
private final static int LIB_VERSION = 14;
|
||||
private final static int LIB_VERSION = 15;
|
||||
private final static String LIB_NAME = "tmessages." + LIB_VERSION;
|
||||
private final static String LIB_SO_NAME = "lib" + LIB_NAME + ".so";
|
||||
private final static String LOCALE_LIB_SO_NAME = "lib" + LIB_NAME + "loc.so";
|
||||
|
|
|
@ -195,6 +195,87 @@ public class NotificationsController {
|
|||
});
|
||||
}
|
||||
|
||||
public void removeNotificationsForDialog(long did) {
|
||||
NotificationsController.getInstance().processReadMessages(null, did, 0, Integer.MAX_VALUE, false);
|
||||
HashMap<Long, Integer> dialogsToUpdate = new HashMap<>();
|
||||
dialogsToUpdate.put(did, 0);
|
||||
NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate);
|
||||
}
|
||||
|
||||
public void removeDeletedMessagesFromNotifications(final SparseArray<ArrayList<Integer>> deletedMessages) {
|
||||
final ArrayList<MessageObject> popupArray = popupMessages.isEmpty() ? null : new ArrayList<>(popupMessages);
|
||||
notificationsQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int old_unread_count = total_unread_count;
|
||||
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE);
|
||||
for (int a = 0; a < deletedMessages.size(); a++) {
|
||||
int key = deletedMessages.keyAt(a);
|
||||
long dialog_id = -key;
|
||||
ArrayList<Integer> mids = deletedMessages.get(key);
|
||||
Integer currentCount = pushDialogs.get(dialog_id);
|
||||
if (currentCount == null) {
|
||||
currentCount = 0;
|
||||
}
|
||||
Integer newCount = currentCount;
|
||||
for (int b = 0; b < mids.size(); b++) {
|
||||
long mid = mids.get(b);
|
||||
mid |= ((long) key) << 32;
|
||||
MessageObject messageObject = pushMessagesDict.get(mid);
|
||||
if (messageObject != null) {
|
||||
pushMessagesDict.remove(mid);
|
||||
delayedPushMessages.remove(messageObject);
|
||||
pushMessages.remove(messageObject);
|
||||
if (isPersonalMessage(messageObject)) {
|
||||
personal_count--;
|
||||
}
|
||||
if (popupArray != null) {
|
||||
popupArray.remove(messageObject);
|
||||
}
|
||||
newCount--;
|
||||
}
|
||||
}
|
||||
if (newCount <= 0) {
|
||||
newCount = 0;
|
||||
smartNotificationsDialogs.remove(dialog_id);
|
||||
}
|
||||
if (!newCount.equals(currentCount)) {
|
||||
total_unread_count -= currentCount;
|
||||
total_unread_count += newCount;
|
||||
pushDialogs.put(dialog_id, newCount);
|
||||
}
|
||||
if (newCount == 0) {
|
||||
pushDialogs.remove(dialog_id);
|
||||
pushDialogsOverrideMention.remove(dialog_id);
|
||||
if (popupArray != null && pushMessages.isEmpty() && !popupArray.isEmpty()) {
|
||||
popupArray.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (popupArray != null) {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
popupMessages = popupArray;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (old_unread_count != total_unread_count) {
|
||||
if (!notifyCheck) {
|
||||
delayedPushMessages.clear();
|
||||
showOrUpdateNotification(notifyCheck);
|
||||
} else {
|
||||
scheduleNotificationDelay(lastOnlineFromOtherDevice > ConnectionsManager.getInstance().getCurrentTime());
|
||||
}
|
||||
}
|
||||
notifyCheck = false;
|
||||
if (preferences.getBoolean("badgeNumber", true)) {
|
||||
setBadge(total_unread_count);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void processReadMessages(final SparseArray<Long> inbox, final long dialog_id, final int max_date, final int max_id, final boolean isPopup) {
|
||||
final ArrayList<MessageObject> popupArray = popupMessages.isEmpty() ? null : new ArrayList<>(popupMessages);
|
||||
notificationsQueue.postRunnable(new Runnable() {
|
||||
|
@ -314,7 +395,7 @@ public class NotificationsController {
|
|||
playInChatSound();
|
||||
continue;
|
||||
}
|
||||
if ((messageObject.messageOwner.flags & TLRPC.MESSAGE_FLAG_MENTION) != 0) {
|
||||
if (messageObject.messageOwner.mentioned) {
|
||||
dialog_id = messageObject.messageOwner.from_id;
|
||||
}
|
||||
if (isPersonalMessage(messageObject)) {
|
||||
|
@ -490,7 +571,7 @@ public class NotificationsController {
|
|||
}
|
||||
long dialog_id = messageObject.getDialogId();
|
||||
long original_dialog_id = dialog_id;
|
||||
if ((messageObject.messageOwner.flags & TLRPC.MESSAGE_FLAG_MENTION) != 0) {
|
||||
if (messageObject.messageOwner.mentioned) {
|
||||
dialog_id = messageObject.messageOwner.from_id;
|
||||
}
|
||||
Boolean value = settingsCache.get(dialog_id);
|
||||
|
@ -650,7 +731,7 @@ public class NotificationsController {
|
|||
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
|
||||
msg = LocaleController.formatString("NotificationContactNewPhoto", R.string.NotificationContactNewPhoto, name);
|
||||
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionLoginUnknownLocation) {
|
||||
String date = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, LocaleController.formatterYear.format(((long) messageObject.messageOwner.date) * 1000), LocaleController.formatterDay.format(((long) messageObject.messageOwner.date) * 1000));
|
||||
String date = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, LocaleController.getInstance().formatterYear.format(((long) messageObject.messageOwner.date) * 1000), LocaleController.getInstance().formatterDay.format(((long) messageObject.messageOwner.date) * 1000));
|
||||
msg = LocaleController.formatString("NotificationUnrecognizedDevice", R.string.NotificationUnrecognizedDevice, UserConfig.getCurrentUser().first_name, date, messageObject.messageOwner.action.title, messageObject.messageOwner.action.address);
|
||||
}
|
||||
} else {
|
||||
|
@ -690,35 +771,54 @@ public class NotificationsController {
|
|||
if (preferences.getBoolean("EnablePreviewGroup", true)) {
|
||||
if (messageObject.messageOwner instanceof TLRPC.TL_messageService) {
|
||||
if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatAddUser) {
|
||||
if (messageObject.messageOwner.to_id.channel_id != 0) {
|
||||
TLRPC.User user = MessagesController.getInstance().getUser(messageObject.messageOwner.action.user_id);
|
||||
if (user != null) {
|
||||
name = UserObject.getUserName(user);
|
||||
} else {
|
||||
name = "";
|
||||
}
|
||||
msg = LocaleController.formatString("ChannelAddedByNotification", R.string.ChannelAddedByNotification, name, chat.title);
|
||||
} else {
|
||||
if (messageObject.messageOwner.action.user_id == UserConfig.getClientUserId()) {
|
||||
msg = LocaleController.formatString("NotificationInvitedToGroup", R.string.NotificationInvitedToGroup, name, chat.title);
|
||||
} else {
|
||||
TLRPC.User u2 = MessagesController.getInstance().getUser(messageObject.messageOwner.action.user_id);
|
||||
if (u2 == null) {
|
||||
return null;
|
||||
}
|
||||
if (from_id == u2.id) {
|
||||
msg = LocaleController.formatString("NotificationGroupAddSelf", R.string.NotificationGroupAddSelf, name, chat.title);
|
||||
int singleUserId = messageObject.messageOwner.action.user_id;
|
||||
if (singleUserId == 0 && messageObject.messageOwner.action.users.size() == 1) {
|
||||
singleUserId = messageObject.messageOwner.action.users.get(0);
|
||||
}
|
||||
if (singleUserId != 0) {
|
||||
if (messageObject.messageOwner.to_id.channel_id != 0 && !messageObject.isMegagroup()) {
|
||||
TLRPC.User user = MessagesController.getInstance().getUser(singleUserId);
|
||||
if (user != null) {
|
||||
name = UserObject.getUserName(user);
|
||||
} else {
|
||||
msg = LocaleController.formatString("NotificationGroupAddMember", R.string.NotificationGroupAddMember, name, chat.title, UserObject.getUserName(u2));
|
||||
name = "";
|
||||
}
|
||||
msg = LocaleController.formatString("ChannelAddedByNotification", R.string.ChannelAddedByNotification, name, chat.title);
|
||||
} else {
|
||||
if (singleUserId == UserConfig.getClientUserId()) {
|
||||
msg = LocaleController.formatString("NotificationInvitedToGroup", R.string.NotificationInvitedToGroup, name, chat.title);
|
||||
} else {
|
||||
TLRPC.User u2 = MessagesController.getInstance().getUser(singleUserId);
|
||||
if (u2 == null) {
|
||||
return null;
|
||||
}
|
||||
if (from_id == u2.id) {
|
||||
msg = LocaleController.formatString("NotificationGroupAddSelf", R.string.NotificationGroupAddSelf, name, chat.title);
|
||||
} else {
|
||||
msg = LocaleController.formatString("NotificationGroupAddMember", R.string.NotificationGroupAddMember, name, chat.title, UserObject.getUserName(u2));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
StringBuilder names = new StringBuilder("");
|
||||
for (int a = 0; a < messageObject.messageOwner.action.users.size(); a++) {
|
||||
TLRPC.User user = MessagesController.getInstance().getUser(messageObject.messageOwner.action.users.get(a));
|
||||
if (user != null) {
|
||||
String name2 = UserObject.getUserName(user);
|
||||
if (names.length() != 0) {
|
||||
names.append(", ");
|
||||
}
|
||||
names.append(name2);
|
||||
}
|
||||
}
|
||||
msg = LocaleController.formatString("NotificationGroupAddMember", R.string.NotificationGroupAddMember, name, chat.title, names.toString());
|
||||
}
|
||||
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatJoinedByLink) {
|
||||
msg = LocaleController.formatString("NotificationInvitedToGroupByLink", R.string.NotificationInvitedToGroupByLink, name, chat.title);
|
||||
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatEditTitle) {
|
||||
msg = LocaleController.formatString("NotificationEditedGroupName", R.string.NotificationEditedGroupName, name, messageObject.messageOwner.action.title);
|
||||
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatEditPhoto || messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatDeletePhoto) {
|
||||
if (messageObject.messageOwner.to_id.channel_id != 0) {
|
||||
if (messageObject.messageOwner.to_id.channel_id != 0 && !messageObject.isMegagroup()) {
|
||||
msg = LocaleController.formatString("ChannelPhotoEditNotification", R.string.ChannelPhotoEditNotification, chat.title);
|
||||
} else {
|
||||
msg = LocaleController.formatString("NotificationEditedGroupPhoto", R.string.NotificationEditedGroupPhoto, name, chat.title);
|
||||
|
@ -739,9 +839,13 @@ public class NotificationsController {
|
|||
msg = messageObject.messageText.toString();
|
||||
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChannelCreate) {
|
||||
msg = messageObject.messageText.toString();
|
||||
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatMigrateTo) {
|
||||
msg = LocaleController.formatString("ActionMigrateFromGroupNotify", R.string.ActionMigrateFromGroupNotify, chat.title);
|
||||
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChannelMigrateFrom) {
|
||||
msg = LocaleController.formatString("ActionMigrateFromGroupNotify", R.string.ActionMigrateFromGroupNotify, messageObject.messageOwner.action.title);
|
||||
}
|
||||
} else {
|
||||
if (ChatObject.isChannel(chat)) {
|
||||
if (ChatObject.isChannel(chat) && !chat.megagroup) {
|
||||
if (from_id < 0) {
|
||||
if (messageObject.isMediaEmpty()) {
|
||||
if (!shortMessage && messageObject.messageOwner.message != null && messageObject.messageOwner.message.length() != 0) {
|
||||
|
@ -921,7 +1025,7 @@ public class NotificationsController {
|
|||
notificationsQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (lastSoundPlay > System.currentTimeMillis() - 500) {
|
||||
if (Math.abs(System.currentTimeMillis() - lastSoundPlay) <= 500) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
@ -992,7 +1096,7 @@ public class NotificationsController {
|
|||
|
||||
long dialog_id = lastMessageObject.getDialogId();
|
||||
long override_dialog_id = dialog_id;
|
||||
if ((lastMessageObject.messageOwner.flags & TLRPC.MESSAGE_FLAG_MENTION) != 0) {
|
||||
if (lastMessageObject.messageOwner.mentioned) {
|
||||
override_dialog_id = lastMessageObject.messageOwner.from_id;
|
||||
}
|
||||
int mid = lastMessageObject.getId();
|
||||
|
@ -1158,7 +1262,7 @@ public class NotificationsController {
|
|||
|
||||
String name;
|
||||
boolean replace = true;
|
||||
if ((int)dialog_id == 0 || pushDialogs.size() > 1 || AndroidUtilities.needShowPasscode(false) || UserConfig.isWaitingForPasscodeEnter) {
|
||||
if ((int) dialog_id == 0 || pushDialogs.size() > 1 || AndroidUtilities.needShowPasscode(false) || UserConfig.isWaitingForPasscodeEnter) {
|
||||
name = LocaleController.getString("AppName", R.string.AppName);
|
||||
replace = false;
|
||||
} else {
|
||||
|
@ -1348,10 +1452,24 @@ public class NotificationsController {
|
|||
continue;
|
||||
}
|
||||
}
|
||||
if (chat != null) {
|
||||
name = chat.title;
|
||||
TLRPC.FileLocation photoPath = null;
|
||||
if (AndroidUtilities.needShowPasscode(false) || UserConfig.isWaitingForPasscodeEnter) {
|
||||
name = LocaleController.getString("AppName", R.string.AppName);
|
||||
} else {
|
||||
name = UserObject.getUserName(user);
|
||||
if (chat != null) {
|
||||
name = chat.title;
|
||||
} else {
|
||||
name = UserObject.getUserName(user);
|
||||
}
|
||||
if (chat != null) {
|
||||
if (chat.photo != null && chat.photo.photo_small != null && chat.photo.photo_small.volume_id != 0 && chat.photo.photo_small.local_id != 0) {
|
||||
photoPath = chat.photo.photo_small;
|
||||
}
|
||||
} else {
|
||||
if (user.photo != null && user.photo.photo_small != null && user.photo.photo_small.volume_id != 0 && user.photo.photo_small.local_id != 0) {
|
||||
photoPath = user.photo.photo_small;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Integer notificationIdWear = oldIdsWear.get(dialog_id);
|
||||
|
@ -1380,7 +1498,7 @@ public class NotificationsController {
|
|||
|
||||
NotificationCompat.Action wearReplyAction = null;
|
||||
|
||||
if (!ChatObject.isChannel(chat)) {
|
||||
if (!ChatObject.isChannel(chat) && !AndroidUtilities.needShowPasscode(false) && !UserConfig.isWaitingForPasscodeEnter) {
|
||||
Intent msgReplyIntent = new Intent();
|
||||
msgReplyIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
||||
msgReplyIntent.setAction("org.telegram.messenger.ACTION_MESSAGE_REPLY");
|
||||
|
@ -1424,17 +1542,6 @@ public class NotificationsController {
|
|||
unreadConvBuilder.addMessage(message);
|
||||
}
|
||||
|
||||
TLRPC.FileLocation photoPath = null;
|
||||
if (chat != null) {
|
||||
if (chat.photo != null && chat.photo.photo_small != null && chat.photo.photo_small.volume_id != 0 && chat.photo.photo_small.local_id != 0) {
|
||||
photoPath = chat.photo.photo_small;
|
||||
}
|
||||
} else {
|
||||
if (user.photo != null && user.photo.photo_small != null && user.photo.photo_small.volume_id != 0 && user.photo.photo_small.local_id != 0) {
|
||||
photoPath = user.photo.photo_small;
|
||||
}
|
||||
}
|
||||
|
||||
Intent intent = new Intent(ApplicationLoader.applicationContext, LaunchActivity.class);
|
||||
intent.setAction("com.tmessages.openchat" + Math.random() + Integer.MAX_VALUE);
|
||||
intent.setFlags(32768);
|
||||
|
@ -1496,7 +1603,7 @@ public class NotificationsController {
|
|||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (lastSoundOutPlay > System.currentTimeMillis() - 100) {
|
||||
if (Math.abs(System.currentTimeMillis() - lastSoundOutPlay) <= 100) {
|
||||
return;
|
||||
}
|
||||
lastSoundOutPlay = System.currentTimeMillis();
|
||||
|
|
|
@ -80,7 +80,9 @@ public class SecretChatHelper {
|
|||
newMsg.action.encryptedAction = decryptedMessage;
|
||||
newMsg.local_id = newMsg.id = UserConfig.getNewMessageId();
|
||||
newMsg.from_id = UserConfig.getClientUserId();
|
||||
newMsg.flags = TLRPC.MESSAGE_FLAG_UNREAD | TLRPC.MESSAGE_FLAG_OUT | TLRPC.MESSAGE_FLAG_HAS_FROM_ID;
|
||||
newMsg.unread = true;
|
||||
newMsg.out = true;
|
||||
newMsg.flags = TLRPC.MESSAGE_FLAG_HAS_FROM_ID;
|
||||
newMsg.dialog_id = ((long) encryptedChat.id) << 32;
|
||||
newMsg.to_id = new TLRPC.TL_peerUser();
|
||||
newMsg.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING;
|
||||
|
@ -869,7 +871,8 @@ public class SecretChatHelper {
|
|||
newMessage.to_id = new TLRPC.TL_peerUser();
|
||||
newMessage.random_id = random_id;
|
||||
newMessage.to_id.user_id = UserConfig.getClientUserId();
|
||||
newMessage.flags = TLRPC.MESSAGE_FLAG_UNREAD | TLRPC.MESSAGE_FLAG_HAS_MEDIA | TLRPC.MESSAGE_FLAG_HAS_FROM_ID;
|
||||
newMessage.unread = true;
|
||||
newMessage.flags = TLRPC.MESSAGE_FLAG_HAS_MEDIA | TLRPC.MESSAGE_FLAG_HAS_FROM_ID;
|
||||
newMessage.dialog_id = ((long) chat.id) << 32;
|
||||
if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaEmpty) {
|
||||
newMessage.media = new TLRPC.TL_messageMediaEmpty();
|
||||
|
@ -1043,7 +1046,8 @@ public class SecretChatHelper {
|
|||
}
|
||||
newMessage.local_id = newMessage.id = UserConfig.getNewMessageId();
|
||||
UserConfig.saveConfig(false);
|
||||
newMessage.flags = TLRPC.MESSAGE_FLAG_UNREAD | TLRPC.MESSAGE_FLAG_HAS_FROM_ID;
|
||||
newMessage.unread = true;
|
||||
newMessage.flags = TLRPC.MESSAGE_FLAG_HAS_FROM_ID;
|
||||
newMessage.date = date;
|
||||
newMessage.from_id = from_id;
|
||||
newMessage.to_id = new TLRPC.TL_peerUser();
|
||||
|
|
|
@ -250,7 +250,8 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
String file = (String) args[1];
|
||||
ArrayList<DelayedMessage> arr = delayedMessages.get(path);
|
||||
if (arr != null) {
|
||||
for (final DelayedMessage message : arr) {
|
||||
for (int a = 0; a < arr.size(); a++) {
|
||||
final DelayedMessage message = arr.get(a);
|
||||
if (message.type == 0) {
|
||||
String md5 = Utilities.MD5(message.httpLocation) + ".jpg";
|
||||
final File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), md5);
|
||||
|
@ -525,7 +526,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
}
|
||||
|
||||
public void sendMessage(TLRPC.User user, long peer, MessageObject reply_to_msg, boolean asAdmin) {
|
||||
sendMessage(null, null, null, null, null, null, user, null, null, null, peer, false, null, reply_to_msg, null, true, asAdmin);
|
||||
sendMessage(null, null, null, null, null, user, null, null, null, peer, null, reply_to_msg, null, true, asAdmin, null);
|
||||
}
|
||||
|
||||
public void sendMessage(ArrayList<MessageObject> messages, final long peer, boolean asAdmin) {
|
||||
|
@ -534,11 +535,15 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
}
|
||||
int lower_id = (int) peer;
|
||||
final TLRPC.Peer to_id = MessagesController.getPeer((int) peer);
|
||||
boolean isMegagroup = false;
|
||||
if (lower_id > 0) {
|
||||
TLRPC.User sendToUser = MessagesController.getInstance().getUser(lower_id);
|
||||
if (sendToUser == null) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
TLRPC.Chat chat = MessagesController.getInstance().getChat(-lower_id);
|
||||
isMegagroup = ChatObject.isChannel(chat) && chat.megagroup;
|
||||
}
|
||||
|
||||
ArrayList<MessageObject> objArr = new ArrayList<>();
|
||||
|
@ -546,7 +551,8 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
ArrayList<Long> randomIds = new ArrayList<>();
|
||||
ArrayList<Integer> ids = new ArrayList<>();
|
||||
HashMap<Long, TLRPC.Message> messagesByRandomIds = new HashMap<>();
|
||||
TLRPC.InputPeer inputPeer = MessagesController.getInputPeer((int) peer);
|
||||
TLRPC.InputPeer inputPeer = MessagesController.getInputPeer(lower_id);
|
||||
long lastDialogId = 0;
|
||||
for (int a = 0; a < messages.size(); a++) {
|
||||
MessageObject msgObj = messages.get(a);
|
||||
if (msgObj.getId() <= 0) {
|
||||
|
@ -571,6 +577,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
if (newMsg.media != null) {
|
||||
newMsg.flags |= TLRPC.MESSAGE_FLAG_HAS_MEDIA;
|
||||
}
|
||||
if (isMegagroup) {
|
||||
newMsg.flags |= TLRPC.MESSAGE_FLAG_MEGAGROUP;
|
||||
}
|
||||
newMsg.message = msgObj.messageOwner.message;
|
||||
newMsg.fwd_msg_id = msgObj.getId();
|
||||
newMsg.attachPath = msgObj.messageOwner.attachPath;
|
||||
|
@ -582,8 +591,8 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
newMsg.attachPath = "";
|
||||
}
|
||||
newMsg.local_id = newMsg.id = UserConfig.getNewMessageId();
|
||||
newMsg.flags |= TLRPC.MESSAGE_FLAG_OUT;
|
||||
if (asAdmin && to_id.channel_id != 0) {
|
||||
newMsg.out = true;
|
||||
if (asAdmin && to_id.channel_id != 0 && !isMegagroup) {
|
||||
newMsg.from_id = -to_id.channel_id;
|
||||
} else {
|
||||
newMsg.from_id = UserConfig.getClientUserId();
|
||||
|
@ -597,10 +606,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
ids.add(newMsg.fwd_msg_id);
|
||||
newMsg.date = ConnectionsManager.getInstance().getCurrentTime();
|
||||
if (newMsg.media instanceof TLRPC.TL_messageMediaAudio) {
|
||||
newMsg.flags |= TLRPC.MESSAGE_FLAG_CONTENT_UNREAD;
|
||||
newMsg.media_unread = true;
|
||||
}
|
||||
if (inputPeer instanceof TLRPC.TL_inputPeerChannel) {
|
||||
if (asAdmin) {
|
||||
if (asAdmin && !isMegagroup) {
|
||||
newMsg.views = 1;
|
||||
newMsg.flags |= TLRPC.MESSAGE_FLAG_HAS_VIEWS;
|
||||
}
|
||||
|
@ -609,18 +618,22 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
newMsg.views = msgObj.messageOwner.views;
|
||||
newMsg.flags |= TLRPC.MESSAGE_FLAG_HAS_VIEWS;
|
||||
}
|
||||
newMsg.flags |= TLRPC.MESSAGE_FLAG_UNREAD;
|
||||
newMsg.unread = true;
|
||||
}
|
||||
newMsg.dialog_id = peer;
|
||||
newMsg.to_id = to_id;
|
||||
if (msgObj.messageOwner.to_id instanceof TLRPC.TL_peerChannel) {
|
||||
newMsg.ttl = -msgObj.messageOwner.to_id.channel_id;
|
||||
}
|
||||
MessageObject newMsgObj = new MessageObject(newMsg, null, true);
|
||||
newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING;
|
||||
objArr.add(newMsgObj);
|
||||
arr.add(newMsg);
|
||||
|
||||
putToSendingMessages(newMsg);
|
||||
boolean differentDialog = false;
|
||||
|
||||
if (arr.size() == 100 || a == messages.size() - 1) {
|
||||
if (arr.size() == 100 || a == messages.size() - 1 || a != messages.size() - 1 && messages.get(a + 1).getDialogId() != msgObj.getDialogId()) {
|
||||
MessagesStorage.getInstance().putMessages(new ArrayList<>(arr), false, true, false, 0);
|
||||
MessagesController.getInstance().updateInterfaceWithMessages(peer, objArr);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
|
||||
|
@ -635,12 +648,13 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
}
|
||||
req.random_id = randomIds;
|
||||
req.id = ids;
|
||||
if (asAdmin && req.to_peer.channel_id != 0) {
|
||||
req.flags |= 16;
|
||||
if (asAdmin && req.to_peer.channel_id != 0 && !isMegagroup) {
|
||||
req.broadcast = true;
|
||||
}
|
||||
|
||||
final ArrayList<TLRPC.Message> newMsgObjArr = arr;
|
||||
final HashMap<Long, TLRPC.Message> messagesByRandomIdsFinal = messagesByRandomIds;
|
||||
final boolean isMegagroupFinal = isMegagroup;
|
||||
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, final TLRPC.TL_error error) {
|
||||
|
@ -655,7 +669,8 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
a--;
|
||||
}
|
||||
}
|
||||
for (TLRPC.Update update : updates.updates) {
|
||||
for (int a = 0; a < updates.updates.size(); a++) {
|
||||
TLRPC.Update update = updates.updates.get(a);
|
||||
if (update instanceof TLRPC.TL_updateNewMessage || update instanceof TLRPC.TL_updateNewChannelMessage) {
|
||||
TLRPC.Message message;
|
||||
if (update instanceof TLRPC.TL_updateNewMessage) {
|
||||
|
@ -664,6 +679,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
} else {
|
||||
message = ((TLRPC.TL_updateNewChannelMessage) update).message;
|
||||
MessagesController.getInstance().processNewChannelDifferenceParams(update.pts, update.pts_count, message.to_id.channel_id);
|
||||
if (isMegagroupFinal) {
|
||||
message.flags |= TLRPC.MESSAGE_FLAG_MEGAGROUP;
|
||||
}
|
||||
}
|
||||
Long random_id = newMessagesByIds.get(message.id);
|
||||
if (random_id != null) {
|
||||
|
@ -738,35 +756,35 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
}
|
||||
}
|
||||
|
||||
public void sendMessage(MessageObject message, boolean asAdmin) {
|
||||
sendMessage(null, null, null, null, null, message, null, null, null, null, message.getDialogId(), true, message.messageOwner.attachPath, null, null, true, asAdmin);
|
||||
public void sendMessage(MessageObject retryMessageObject, boolean asAdmin) {
|
||||
sendMessage(null, null, null, null, null, null, null, null, null, retryMessageObject.getDialogId(), retryMessageObject.messageOwner.attachPath, null, null, true, asAdmin, retryMessageObject);
|
||||
}
|
||||
|
||||
public void sendMessage(TLRPC.TL_document document, String originalPath, String path, long peer, MessageObject reply_to_msg, boolean asAdmin) {
|
||||
sendMessage(null, null, null, null, null, null, null, document, null, originalPath, peer, false, path, reply_to_msg, null, true, asAdmin);
|
||||
sendMessage(null, null, null, null, null, null, document, null, originalPath, peer, path, reply_to_msg, null, true, asAdmin, null);
|
||||
}
|
||||
|
||||
public void sendMessage(String message, long peer, MessageObject reply_to_msg, TLRPC.WebPage webPage, boolean searchLinks, boolean asAdmin) {
|
||||
sendMessage(message, null, null, null, null, null, null, null, null, null, peer, false, null, reply_to_msg, webPage, searchLinks, asAdmin);
|
||||
sendMessage(message, null, null, null, null, null, null, null, null, peer, null, reply_to_msg, webPage, searchLinks, asAdmin, null);
|
||||
}
|
||||
|
||||
public void sendMessage(TLRPC.MessageMedia location, long peer, MessageObject reply_to_msg, boolean asAdmin) {
|
||||
sendMessage(null, location, null, null, null, null, null, null, null, null, peer, false, null, reply_to_msg, null, true, asAdmin);
|
||||
sendMessage(null, location, null, null, null, null, null, null, null, peer, null, reply_to_msg, null, true, asAdmin, null);
|
||||
}
|
||||
|
||||
public void sendMessage(TLRPC.TL_photo photo, String originalPath, String path, long peer, MessageObject reply_to_msg, boolean asAdmin) {
|
||||
sendMessage(null, null, photo, null, null, null, null, null, null, originalPath, peer, false, path, reply_to_msg, null, true, asAdmin);
|
||||
sendMessage(null, null, photo, null, null, null, null, null, originalPath, peer, path, reply_to_msg, null, true, asAdmin, null);
|
||||
}
|
||||
|
||||
public void sendMessage(TLRPC.TL_video video, VideoEditedInfo videoEditedInfo, String originalPath, String path, long peer, MessageObject reply_to_msg, boolean asAdmin) {
|
||||
sendMessage(null, null, null, video, videoEditedInfo, null, null, null, null, originalPath, peer, false, path, reply_to_msg, null, true, asAdmin);
|
||||
sendMessage(null, null, null, video, videoEditedInfo, null, null, null, originalPath, peer, path, reply_to_msg, null, true, asAdmin, null);
|
||||
}
|
||||
|
||||
public void sendMessage(TLRPC.TL_audio audio, String path, long peer, MessageObject reply_to_msg, boolean asAdmin) {
|
||||
sendMessage(null, null, null, null, null, null, null, null, audio, null, peer, false, path, reply_to_msg, null, true, asAdmin);
|
||||
sendMessage(null, null, null, null, null, null, null, audio, null, peer, path, reply_to_msg, null, true, asAdmin, null);
|
||||
}
|
||||
|
||||
private void sendMessage(String message, TLRPC.MessageMedia location, TLRPC.TL_photo photo, TLRPC.TL_video video, VideoEditedInfo videoEditedInfo, MessageObject msgObj, TLRPC.User user, TLRPC.TL_document document, TLRPC.TL_audio audio, String originalPath, long peer, boolean retry, String path, MessageObject reply_to_msg, TLRPC.WebPage webPage, boolean searchLinks, boolean asAdmin) {
|
||||
private void sendMessage(String message, TLRPC.MessageMedia location, TLRPC.TL_photo photo, TLRPC.TL_video video, VideoEditedInfo videoEditedInfo, TLRPC.User user, TLRPC.TL_document document, TLRPC.TL_audio audio, String originalPath, long peer, String path, MessageObject reply_to_msg, TLRPC.WebPage webPage, boolean searchLinks, boolean asAdmin, MessageObject retryMessageObject) {
|
||||
if (peer == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -782,57 +800,54 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
if (lower_id == 0) {
|
||||
encryptedChat = MessagesController.getInstance().getEncryptedChat(high_id);
|
||||
if (encryptedChat == null) {
|
||||
if (msgObj != null) {
|
||||
MessagesStorage.getInstance().markMessageAsSendError(msgObj.messageOwner);
|
||||
msgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR;
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, msgObj.getId());
|
||||
processSentMessage(msgObj.getId());
|
||||
if (retryMessageObject != null) {
|
||||
MessagesStorage.getInstance().markMessageAsSendError(retryMessageObject.messageOwner);
|
||||
retryMessageObject.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR;
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, retryMessageObject.getId());
|
||||
processSentMessage(retryMessageObject.getId());
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if (asAdmin && sendToPeer instanceof TLRPC.TL_inputPeerChannel) {
|
||||
TLRPC.Chat chat = MessagesController.getInstance().getChat(sendToPeer.channel_id);
|
||||
if (chat.megagroup) {
|
||||
asAdmin = false;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (retry) {
|
||||
newMsg = msgObj.messageOwner;
|
||||
if (retryMessageObject != null) {
|
||||
newMsg = retryMessageObject.messageOwner;
|
||||
|
||||
if (msgObj.type == 0) {
|
||||
if (msgObj.isForwarded()) {
|
||||
type = 4;
|
||||
} else {
|
||||
if (retryMessageObject.isForwarded()) {
|
||||
type = 4;
|
||||
} else {
|
||||
if (retryMessageObject.type == 0) {
|
||||
message = newMsg.message;
|
||||
type = 0;
|
||||
}
|
||||
} else if (msgObj.type == 4) {
|
||||
location = newMsg.media;
|
||||
type = 1;
|
||||
} else if (msgObj.type == 1) {
|
||||
if (msgObj.isForwarded()) {
|
||||
type = 4;
|
||||
} else {
|
||||
} else if (retryMessageObject.type == 4) {
|
||||
location = newMsg.media;
|
||||
type = 1;
|
||||
} else if (retryMessageObject.type == 1) {
|
||||
photo = (TLRPC.TL_photo) newMsg.media.photo;
|
||||
type = 2;
|
||||
}
|
||||
} else if (msgObj.type == 3) {
|
||||
if (msgObj.isForwarded()) {
|
||||
type = 4;
|
||||
} else {
|
||||
} else if (retryMessageObject.type == 3) {
|
||||
type = 3;
|
||||
video = (TLRPC.TL_video) newMsg.media.video;
|
||||
} else if (retryMessageObject.type == 12) {
|
||||
user = new TLRPC.TL_userRequest_old2();
|
||||
user.phone = newMsg.media.phone_number;
|
||||
user.first_name = newMsg.media.first_name;
|
||||
user.last_name = newMsg.media.last_name;
|
||||
user.id = newMsg.media.user_id;
|
||||
type = 6;
|
||||
} else if (retryMessageObject.type == 8 || retryMessageObject.type == 9 || retryMessageObject.type == 13) {
|
||||
document = (TLRPC.TL_document) newMsg.media.document;
|
||||
type = 7;
|
||||
} else if (retryMessageObject.type == 2) {
|
||||
audio = (TLRPC.TL_audio) newMsg.media.audio;
|
||||
type = 8;
|
||||
}
|
||||
} else if (msgObj.type == 12) {
|
||||
user = new TLRPC.TL_userRequest_old2();
|
||||
user.phone = newMsg.media.phone_number;
|
||||
user.first_name = newMsg.media.first_name;
|
||||
user.last_name = newMsg.media.last_name;
|
||||
user.id = newMsg.media.user_id;
|
||||
type = 6;
|
||||
} else if (msgObj.type == 8 || msgObj.type == 9 || msgObj.type == 13) {
|
||||
document = (TLRPC.TL_document) newMsg.media.document;
|
||||
type = 7;
|
||||
} else if (msgObj.type == 2) {
|
||||
audio = (TLRPC.TL_audio) newMsg.media.audio;
|
||||
type = 8;
|
||||
}
|
||||
} else {
|
||||
if (message != null) {
|
||||
|
@ -891,22 +906,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
newMsg.message = videoEditedInfo.getString();
|
||||
}
|
||||
newMsg.attachPath = path;
|
||||
} else if (msgObj != null) {
|
||||
newMsg = new TLRPC.TL_message();
|
||||
newMsg.flags |= TLRPC.MESSAGE_FLAG_FWD;
|
||||
if (msgObj.isForwarded()) {
|
||||
newMsg.fwd_from_id = msgObj.messageOwner.fwd_from_id;
|
||||
newMsg.fwd_date = msgObj.messageOwner.fwd_date;
|
||||
} else {
|
||||
newMsg.fwd_from_id = new TLRPC.TL_peerUser();
|
||||
newMsg.fwd_from_id.user_id = msgObj.messageOwner.from_id;
|
||||
newMsg.fwd_date = msgObj.messageOwner.date;
|
||||
}
|
||||
newMsg.media = msgObj.messageOwner.media;
|
||||
newMsg.message = msgObj.messageOwner.message;
|
||||
newMsg.fwd_msg_id = msgObj.getId();
|
||||
newMsg.attachPath = msgObj.messageOwner.attachPath;
|
||||
type = 4;
|
||||
} else if (user != null) {
|
||||
if (encryptedChat != null && AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
|
||||
newMsg = new TLRPC.TL_message_secret();
|
||||
|
@ -953,7 +952,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
newMsg.attachPath = "";
|
||||
}
|
||||
newMsg.local_id = newMsg.id = UserConfig.getNewMessageId();
|
||||
newMsg.flags |= TLRPC.MESSAGE_FLAG_OUT;
|
||||
newMsg.out = true;
|
||||
if (asAdmin && sendToPeer != null && sendToPeer.channel_id != 0) {
|
||||
newMsg.from_id = -sendToPeer.channel_id;
|
||||
} else {
|
||||
|
@ -968,15 +967,19 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
newMsg.date = ConnectionsManager.getInstance().getCurrentTime();
|
||||
newMsg.flags |= TLRPC.MESSAGE_FLAG_HAS_MEDIA;
|
||||
if (encryptedChat == null && high_id != 1 && newMsg.media instanceof TLRPC.TL_messageMediaAudio) {
|
||||
newMsg.flags |= TLRPC.MESSAGE_FLAG_CONTENT_UNREAD;
|
||||
newMsg.media_unread = true;
|
||||
}
|
||||
if (sendToPeer instanceof TLRPC.TL_inputPeerChannel) {
|
||||
if (asAdmin) {
|
||||
newMsg.views = 1;
|
||||
newMsg.flags |= TLRPC.MESSAGE_FLAG_HAS_VIEWS;
|
||||
}
|
||||
TLRPC.Chat chat = MessagesController.getInstance().getChat(sendToPeer.channel_id);
|
||||
if (chat != null && chat.megagroup) {
|
||||
newMsg.flags |= TLRPC.MESSAGE_FLAG_MEGAGROUP;
|
||||
}
|
||||
} else {
|
||||
newMsg.flags |= TLRPC.MESSAGE_FLAG_UNREAD;
|
||||
newMsg.unread = true;
|
||||
}
|
||||
newMsg.dialog_id = peer;
|
||||
if (reply_to_msg != null) {
|
||||
|
@ -992,7 +995,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
return;
|
||||
}
|
||||
sendToPeers = new ArrayList<>();
|
||||
for (TLRPC.TL_chatParticipant participant : currentChatInfo.participants.participants) {
|
||||
for (TLRPC.ChatParticipant participant : currentChatInfo.participants.participants) {
|
||||
TLRPC.User sendToUser = MessagesController.getInstance().getUser(participant.user_id);
|
||||
TLRPC.InputUser peerUser = MessagesController.getInputUser(sendToUser);
|
||||
if (peerUser != null) {
|
||||
|
@ -1009,8 +1012,8 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
processSentMessage(newMsg.id);
|
||||
return;
|
||||
}
|
||||
if ((sendToUser.flags & TLRPC.USER_FLAG_BOT) != 0) {
|
||||
newMsg.flags &= ~TLRPC.MESSAGE_FLAG_UNREAD;
|
||||
if (sendToUser.bot) {
|
||||
newMsg.unread = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1062,14 +1065,14 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
reqSend.peer = sendToPeer;
|
||||
reqSend.random_id = newMsg.random_id;
|
||||
if (asAdmin && sendToPeer instanceof TLRPC.TL_inputPeerChannel) {
|
||||
reqSend.flags |= 16;
|
||||
reqSend.broadcast = true;
|
||||
}
|
||||
if (reply_to_msg != null) {
|
||||
reqSend.flags |= 1;
|
||||
reqSend.reply_to_msg_id = reply_to_msg.getId();
|
||||
}
|
||||
if (!searchLinks) {
|
||||
reqSend.flags |= 2;
|
||||
reqSend.no_webpage = true;
|
||||
}
|
||||
performSendMessageRequest(reqSend, newMsgObj.messageOwner, null);
|
||||
}
|
||||
|
@ -1223,7 +1226,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
request.random_id = newMsg.random_id;
|
||||
request.media = inputMedia;
|
||||
if (asAdmin && sendToPeer instanceof TLRPC.TL_inputPeerChannel) {
|
||||
request.flags |= 16;
|
||||
request.broadcast = true;
|
||||
}
|
||||
if (reply_to_msg != null) {
|
||||
request.flags |= 1;
|
||||
|
@ -1444,13 +1447,21 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
}
|
||||
}
|
||||
} else if (type == 4) {
|
||||
TLRPC.TL_messages_forwardMessage reqSend = new TLRPC.TL_messages_forwardMessage(); //TODO remove
|
||||
reqSend.peer = sendToPeer;
|
||||
reqSend.random_id = newMsg.random_id;
|
||||
if (msgObj.getId() >= 0) {
|
||||
reqSend.id = msgObj.getId();
|
||||
TLRPC.TL_messages_forwardMessages reqSend = new TLRPC.TL_messages_forwardMessages();
|
||||
reqSend.to_peer = sendToPeer;
|
||||
if (retryMessageObject.messageOwner.ttl != 0) {
|
||||
reqSend.from_peer = MessagesController.getInputPeer(retryMessageObject.messageOwner.ttl);
|
||||
} else {
|
||||
reqSend.id = msgObj.messageOwner.fwd_msg_id;
|
||||
reqSend.from_peer = new TLRPC.TL_inputPeerEmpty();
|
||||
}
|
||||
reqSend.random_id.add(newMsg.random_id);
|
||||
if (retryMessageObject.getId() >= 0) {
|
||||
reqSend.id.add(retryMessageObject.getId());
|
||||
} else {
|
||||
reqSend.id.add(retryMessageObject.messageOwner.fwd_msg_id);
|
||||
}
|
||||
if (asAdmin && reqSend.to_peer.channel_id != 0) {
|
||||
reqSend.broadcast = true;
|
||||
}
|
||||
performSendMessageRequest(reqSend, newMsgObj.messageOwner, null);
|
||||
}
|
||||
|
@ -1608,6 +1619,8 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
newMsgObj.local_id = newMsgObj.id = res.id;
|
||||
newMsgObj.date = res.date;
|
||||
newMsgObj.entities = res.entities;
|
||||
newMsgObj.out = res.out;
|
||||
newMsgObj.unread = res.unread;
|
||||
if (res.media != null) {
|
||||
newMsgObj.media = res.media;
|
||||
newMsgObj.flags |= TLRPC.MESSAGE_FLAG_HAS_MEDIA;
|
||||
|
@ -1632,6 +1645,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
TLRPC.TL_updateNewChannelMessage newMessage = (TLRPC.TL_updateNewChannelMessage) update;
|
||||
sentMessages.add(newMessage.message);
|
||||
newMsgObj.id = newMessage.message.id;
|
||||
if ((newMsgObj.flags & TLRPC.MESSAGE_FLAG_MEGAGROUP) != 0) {
|
||||
newMessage.message.flags |= TLRPC.MESSAGE_FLAG_MEGAGROUP;
|
||||
}
|
||||
processSentMessage(newMsgObj, newMessage.message, originalPath);
|
||||
MessagesController.getInstance().processNewChannelDifferenceParams(newMessage.pts, newMessage.pts_count, newMessage.message.to_id.channel_id);
|
||||
ok = true;
|
||||
|
@ -1848,6 +1864,8 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
|||
}
|
||||
} else if (sentMessage.media instanceof TLRPC.TL_messageMediaContact && newMsg.media instanceof TLRPC.TL_messageMediaContact) {
|
||||
newMsg.media = sentMessage.media;
|
||||
} else if (sentMessage.media instanceof TLRPC.TL_messageMediaWebPage) {
|
||||
newMsg.media = sentMessage.media;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ public class TgChooserTargetService extends ChooserTargetService {
|
|||
ArrayList<Integer> usersToLoad = new ArrayList<>();
|
||||
usersToLoad.add(UserConfig.getClientUserId());
|
||||
ArrayList<Integer> chatsToLoad = new ArrayList<>();
|
||||
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT did FROM dialogs ORDER BY date DESC LIMIT %d,%d", 0, 20));
|
||||
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT did FROM dialogs ORDER BY date DESC LIMIT %d,%d", 0, 30));
|
||||
while (cursor.next()) {
|
||||
long id = cursor.longValue(0);
|
||||
|
||||
|
@ -109,11 +109,13 @@ public class TgChooserTargetService extends ChooserTargetService {
|
|||
for (int b = 0; b < users.size(); b++) {
|
||||
TLRPC.User user = users.get(b);
|
||||
if (user.id == id) {
|
||||
extras.putLong("dialogId", (long) id);
|
||||
if (user.photo != null && user.photo.photo_small != null) {
|
||||
icon = createRoundBitmap(FileLoader.getPathToAttach(user.photo.photo_small, true));
|
||||
if (!user.bot) {
|
||||
extras.putLong("dialogId", (long) id);
|
||||
if (user.photo != null && user.photo.photo_small != null) {
|
||||
icon = createRoundBitmap(FileLoader.getPathToAttach(user.photo.photo_small, true));
|
||||
}
|
||||
name = ContactsController.formatName(user.first_name, user.last_name);
|
||||
}
|
||||
name = ContactsController.formatName(user.first_name, user.last_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -121,11 +123,13 @@ public class TgChooserTargetService extends ChooserTargetService {
|
|||
for (int b = 0; b < chats.size(); b++) {
|
||||
TLRPC.Chat chat = chats.get(b);
|
||||
if (chat.id == -id) {
|
||||
extras.putLong("dialogId", (long) id);
|
||||
if (chat.photo != null && chat.photo.photo_small != null) {
|
||||
icon = createRoundBitmap(FileLoader.getPathToAttach(chat.photo.photo_small, true));
|
||||
if (!ChatObject.isNotInChat(chat) && (!ChatObject.isChannel(chat) || chat.megagroup)) {
|
||||
extras.putLong("dialogId", (long) id);
|
||||
if (chat.photo != null && chat.photo.photo_small != null) {
|
||||
icon = createRoundBitmap(FileLoader.getPathToAttach(chat.photo.photo_small, true));
|
||||
}
|
||||
name = chat.title;
|
||||
}
|
||||
name = chat.title;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,13 @@ public class UserConfig {
|
|||
public static boolean useFingerprint = true;
|
||||
public static int lastUpdateVersion;
|
||||
public static int lastContactsSyncTime;
|
||||
public static boolean channelsLoaded = false;
|
||||
|
||||
public static int migrateOffsetId = -1;
|
||||
public static int migrateOffsetDate = -1;
|
||||
public static int migrateOffsetUserId = -1;
|
||||
public static int migrateOffsetChatId = -1;
|
||||
public static int migrateOffsetChannelId = -1;
|
||||
public static long migrateOffsetAccess = -1;
|
||||
|
||||
public static int getNewMessageId() {
|
||||
int id;
|
||||
|
@ -79,9 +85,17 @@ public class UserConfig {
|
|||
editor.putInt("lastPauseTime", lastPauseTime);
|
||||
editor.putInt("lastUpdateVersion", lastUpdateVersion);
|
||||
editor.putInt("lastContactsSyncTime", lastContactsSyncTime);
|
||||
editor.putBoolean("channelsLoaded", channelsLoaded);
|
||||
editor.putBoolean("useFingerprint", useFingerprint);
|
||||
|
||||
editor.putInt("migrateOffsetId", migrateOffsetId);
|
||||
if (migrateOffsetId != -1) {
|
||||
editor.putInt("migrateOffsetDate", migrateOffsetDate);
|
||||
editor.putInt("migrateOffsetUserId", migrateOffsetUserId);
|
||||
editor.putInt("migrateOffsetChatId", migrateOffsetChatId);
|
||||
editor.putInt("migrateOffsetChannelId", migrateOffsetChannelId);
|
||||
editor.putLong("migrateOffsetAccess", migrateOffsetAccess);
|
||||
}
|
||||
|
||||
if (currentUser != null) {
|
||||
if (withFile) {
|
||||
SerializedData data = new SerializedData();
|
||||
|
@ -212,7 +226,16 @@ public class UserConfig {
|
|||
useFingerprint = preferences.getBoolean("useFingerprint", true);
|
||||
lastUpdateVersion = preferences.getInt("lastUpdateVersion", 511);
|
||||
lastContactsSyncTime = preferences.getInt("lastContactsSyncTime", (int) (System.currentTimeMillis() / 1000) - 23 * 60 * 60);
|
||||
channelsLoaded = preferences.getBoolean("channelsLoaded", false);
|
||||
|
||||
migrateOffsetId = preferences.getInt("migrateOffsetId", 0);
|
||||
if (migrateOffsetId != -1) {
|
||||
migrateOffsetDate = preferences.getInt("migrateOffsetDate", 0);
|
||||
migrateOffsetUserId = preferences.getInt("migrateOffsetUserId", 0);
|
||||
migrateOffsetChatId = preferences.getInt("migrateOffsetChatId", 0);
|
||||
migrateOffsetChannelId = preferences.getInt("migrateOffsetChannelId", 0);
|
||||
migrateOffsetAccess = preferences.getLong("migrateOffsetAccess", 0);
|
||||
}
|
||||
|
||||
String user = preferences.getString("user", null);
|
||||
if (user != null) {
|
||||
byte[] userBytes = Base64.decode(user, Base64.DEFAULT);
|
||||
|
@ -277,7 +300,12 @@ public class UserConfig {
|
|||
lastBroadcastId = -1;
|
||||
saveIncomingPhotos = false;
|
||||
blockedUsersLoaded = false;
|
||||
channelsLoaded = false;
|
||||
migrateOffsetId = -1;
|
||||
migrateOffsetDate = -1;
|
||||
migrateOffsetUserId = -1;
|
||||
migrateOffsetChatId = -1;
|
||||
migrateOffsetChannelId = -1;
|
||||
migrateOffsetAccess = -1;
|
||||
appLocked = false;
|
||||
passcodeType = 0;
|
||||
passcodeHash = "";
|
||||
|
|
|
@ -14,15 +14,15 @@ import org.telegram.tgnet.TLRPC;
|
|||
public class UserObject {
|
||||
|
||||
public static boolean isDeleted(TLRPC.User user) {
|
||||
return user == null || user instanceof TLRPC.TL_userDeleted_old2 || user instanceof TLRPC.TL_userEmpty || (user.flags & TLRPC.USER_FLAG_DELETED) != 0;
|
||||
return user == null || user instanceof TLRPC.TL_userDeleted_old2 || user instanceof TLRPC.TL_userEmpty || user.deleted;
|
||||
}
|
||||
|
||||
public static boolean isContact(TLRPC.User user) {
|
||||
return user instanceof TLRPC.TL_userContact_old2 || (user.flags & TLRPC.USER_FLAG_CONTACT) != 0 || (user.flags & TLRPC.USER_FLAG_MUTUAL_CONTACT) != 0;
|
||||
return user instanceof TLRPC.TL_userContact_old2 || user.contact || user.mutual_contact;
|
||||
}
|
||||
|
||||
public static boolean isUserSelf(TLRPC.User user) {
|
||||
return user instanceof TLRPC.TL_userSelf_old3 || (user.flags & TLRPC.USER_FLAG_SELF) != 0;
|
||||
return user instanceof TLRPC.TL_userSelf_old3 || user.self;
|
||||
}
|
||||
|
||||
public static String getUserName(TLRPC.User user) {
|
||||
|
|
|
@ -32,6 +32,6 @@ public class WearReplyReceiver extends BroadcastReceiver {
|
|||
return;
|
||||
}
|
||||
SendMessagesHelper.getInstance().sendMessage(text.toString(), dialog_id, null, null, true, false);
|
||||
MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, 0, true, false);
|
||||
MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, true, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,18 +20,19 @@ import org.telegram.tgnet.TLRPC;
|
|||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class MessagesSearchQuery {
|
||||
|
||||
private static int reqId;
|
||||
private static int lastReqId;
|
||||
private static boolean messagesSearchEndReached;
|
||||
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) {
|
||||
if (lastReturnedNum < searchResultMessages.size() - 1 || !messagesSearchEndReached[0] || !messagesSearchEndReached[1]) {
|
||||
mask |= 1;
|
||||
}
|
||||
if (lastReturnedNum > 0) {
|
||||
|
@ -40,25 +41,37 @@ public class MessagesSearchQuery {
|
|||
return mask;
|
||||
}
|
||||
|
||||
public static void searchMessagesInChat(String query, long dialog_id, final int guid, int direction) {
|
||||
public static void searchMessagesInChat(String query, final long dialog_id, final long mergeDialogId, final int guid, int direction) {
|
||||
if (reqId != 0) {
|
||||
ConnectionsManager.getInstance().cancelRequest(reqId, true);
|
||||
reqId = 0;
|
||||
}
|
||||
int max_id = 0;
|
||||
long queryWithDialog = dialog_id;
|
||||
if (query == null || query.length() == 0) {
|
||||
if (direction == 1) {
|
||||
lastReturnedNum++;
|
||||
if (lastReturnedNum < searchResultMessages.size()) {
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, searchResultMessages.get(lastReturnedNum).getId(), getMask());
|
||||
MessageObject messageObject = searchResultMessages.get(lastReturnedNum);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, messageObject.getId(), getMask(), messageObject.getDialogId());
|
||||
return;
|
||||
} else {
|
||||
if (messagesSearchEndReached) {
|
||||
if (messagesSearchEndReached[0] && mergeDialogId == 0 || messagesSearchEndReached[1]) {
|
||||
lastReturnedNum--;
|
||||
return;
|
||||
}
|
||||
query = lastSearchQuery;
|
||||
max_id = searchResultMessages.get(searchResultMessages.size() - 1).getId();
|
||||
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--;
|
||||
|
@ -66,15 +79,22 @@ public class MessagesSearchQuery {
|
|||
lastReturnedNum = 0;
|
||||
return;
|
||||
}
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, searchResultMessages.get(lastReturnedNum).getId(), getMask());
|
||||
if (lastReturnedNum >= searchResultMessages.size()) {
|
||||
lastReturnedNum = searchResultMessages.size() - 1;
|
||||
}
|
||||
MessageObject messageObject = searchResultMessages.get(lastReturnedNum);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, messageObject.getId(), getMask(), messageObject.getDialogId());
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (messagesSearchEndReached[0] && !messagesSearchEndReached[1] && mergeDialogId != 0) {
|
||||
queryWithDialog = mergeDialogId;
|
||||
}
|
||||
final TLRPC.TL_messages_search req = new TLRPC.TL_messages_search();
|
||||
req.limit = 21;
|
||||
int lower_part = (int) dialog_id;
|
||||
int lower_part = (int) queryWithDialog;
|
||||
req.peer = MessagesController.getInputPeer(lower_part);
|
||||
if (req.peer == null) {
|
||||
return;
|
||||
|
@ -84,19 +104,21 @@ public class MessagesSearchQuery {
|
|||
req.filter = new TLRPC.TL_inputMessagesFilterEmpty();
|
||||
final int currentReqId = ++lastReqId;
|
||||
lastSearchQuery = query;
|
||||
final long queryWithDialogFinal = queryWithDialog;
|
||||
reqId = 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() {
|
||||
reqId = 0;
|
||||
if (currentReqId == lastReqId) {
|
||||
if (error == 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) {
|
||||
if (req.max_id == 0 && queryWithDialogFinal == dialog_id) {
|
||||
lastReturnedNum = 0;
|
||||
searchResultMessages.clear();
|
||||
}
|
||||
|
@ -106,17 +128,27 @@ public class MessagesSearchQuery {
|
|||
added = true;
|
||||
searchResultMessages.add(new MessageObject(message, null, false));
|
||||
}
|
||||
messagesSearchEndReached = res.messages.size() != 21;
|
||||
messagesSearchEndReached[queryWithDialogFinal == dialog_id ? 0 : 1] = res.messages.size() != 21;
|
||||
if (mergeDialogId == 0) {
|
||||
messagesSearchEndReached[1] = messagesSearchEndReached[0];
|
||||
}
|
||||
if (searchResultMessages.isEmpty()) {
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, 0, getMask());
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, 0, getMask(), (long) 0);
|
||||
} else {
|
||||
if (added) {
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, searchResultMessages.get(lastReturnedNum).getId(), getMask());
|
||||
if (lastReturnedNum >= searchResultMessages.size()) {
|
||||
lastReturnedNum = searchResultMessages.size() - 1;
|
||||
}
|
||||
MessageObject messageObject = searchResultMessages.get(lastReturnedNum);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, messageObject.getId(), getMask(), messageObject.getDialogId());
|
||||
}
|
||||
}
|
||||
if (queryWithDialogFinal == dialog_id && messagesSearchEndReached[0] && mergeDialogId != 0) {
|
||||
messagesSearchEndReached[1] = false;
|
||||
searchMessagesInChat(lastSearchQuery, dialog_id, mergeDialogId, guid, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
reqId = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -82,39 +82,7 @@ public class ReplyMessageQuery {
|
|||
message.id = cursor.intValue(1);
|
||||
message.date = cursor.intValue(2);
|
||||
message.dialog_id = dialog_id;
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (message.action != null && message.action.user_id != 0) {
|
||||
if (!usersToLoad.contains(message.action.user_id)) {
|
||||
usersToLoad.add(message.action.user_id);
|
||||
}
|
||||
}
|
||||
if (message.media != null && message.media.user_id != 0) {
|
||||
if (!usersToLoad.contains(message.media.user_id)) {
|
||||
usersToLoad.add(message.media.user_id);
|
||||
}
|
||||
}
|
||||
if (message.media != null && message.media.audio != null && message.media.audio.user_id != 0) {
|
||||
if (!usersToLoad.contains(message.media.audio.user_id)) {
|
||||
usersToLoad.add(message.media.audio.user_id);
|
||||
}
|
||||
}
|
||||
if (message.fwd_from_id instanceof TLRPC.TL_peerUser) {
|
||||
if (!usersToLoad.contains(message.fwd_from_id.user_id)) {
|
||||
usersToLoad.add(message.fwd_from_id.user_id);
|
||||
}
|
||||
} else if (message.fwd_from_id instanceof TLRPC.TL_peerChannel) {
|
||||
if (!chatsToLoad.contains(message.fwd_from_id.channel_id)) {
|
||||
chatsToLoad.add(message.fwd_from_id.channel_id);
|
||||
}
|
||||
}
|
||||
MessagesStorage.addUsersAndChatsFromMessage(message, usersToLoad, chatsToLoad);
|
||||
result.add(message);
|
||||
replyMessages.remove((Integer) message.id);
|
||||
}
|
||||
|
@ -206,9 +174,15 @@ public class ReplyMessageQuery {
|
|||
}
|
||||
|
||||
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> usersHashMap = new HashMap<>();
|
||||
for (TLRPC.User user : users) {
|
||||
usersHashMap.put(user.id, user);
|
||||
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
|
||||
|
@ -216,11 +190,13 @@ public class ReplyMessageQuery {
|
|||
MessagesController.getInstance().putUsers(users, isCache);
|
||||
MessagesController.getInstance().putChats(chats, isCache);
|
||||
boolean changed = false;
|
||||
for (TLRPC.Message message : result) {
|
||||
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, usersHashMap, false);
|
||||
for (MessageObject m : arrayList) {
|
||||
MessageObject messageObject = new MessageObject(message, usersDict, chatsDict, false);
|
||||
for (int b = 0; b < arrayList.size(); b++) {
|
||||
MessageObject m = arrayList.get(b);
|
||||
m.replyMessageObject = messageObject;
|
||||
}
|
||||
changed = true;
|
||||
|
|
|
@ -197,13 +197,15 @@ public class SharedMediaQuery {
|
|||
putMediaDatabase(uid, type, res.messages, max_id, topReached);
|
||||
}
|
||||
|
||||
final HashMap<Integer, TLRPC.User> usersLocal = new HashMap<>();
|
||||
for (TLRPC.User u : res.users) {
|
||||
usersLocal.put(u.id, u);
|
||||
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 (TLRPC.Message message : res.messages) {
|
||||
objects.add(new MessageObject(message, usersLocal, true));
|
||||
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() {
|
||||
|
@ -273,37 +275,6 @@ public class SharedMediaQuery {
|
|||
}
|
||||
cursor.dispose();
|
||||
|
||||
/*cursor = MessagesStorage.getInstance().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, send_state, date FROM messages WHERE uid = %d ORDER BY mid ASC LIMIT %d", uid, 1000));
|
||||
ArrayList<TLRPC.Message> photos = new ArrayList<>();
|
||||
ArrayList<TLRPC.Message> docs = new ArrayList<>();
|
||||
while (cursor.next()) {
|
||||
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(1));
|
||||
if (data != null && cursor.byteBufferValue(1, data) != 0) {
|
||||
TLRPC.Message message = (TLRPC.Message) TLClassStore.Instance().TLdeserialize(data, data.readInt32());
|
||||
MessageObject.setIsUnread(message, cursor.intValue(0) != 1);
|
||||
message.date = cursor.intValue(2);
|
||||
message.send_state = cursor.intValue(1);
|
||||
message.dialog_id = uid;
|
||||
if (message.ttl > 60 && message.media instanceof TLRPC.TL_messageMediaPhoto || message.media instanceof TLRPC.TL_messageMediaVideo) {
|
||||
photos.add(message);
|
||||
} else if (message.media instanceof TLRPC.TL_messageMediaDocument) {
|
||||
docs.add(message);
|
||||
}
|
||||
}
|
||||
data.reuse();
|
||||
}
|
||||
cursor.dispose();
|
||||
if (!photos.isEmpty() || !docs.isEmpty()) {
|
||||
MessagesStorage.getInstance().getDatabase().beginTransaction();
|
||||
if (!photos.isEmpty()) {
|
||||
putMediaDatabaseInternal(uid, MEDIA_PHOTOVIDEO, photos);
|
||||
}
|
||||
if (docs.isEmpty()) {
|
||||
putMediaDatabaseInternal(uid, MEDIA_FILE, docs);
|
||||
}
|
||||
MessagesStorage.getInstance().getDatabase().commitTransaction();
|
||||
}*/
|
||||
|
||||
if (count != -1) {
|
||||
putMediaCountDatabase(uid, type, count);
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ public class StickersQuery {
|
|||
if (document != null) {
|
||||
long setId = getStickerSetId(document);
|
||||
TLRPC.TL_messages_stickerSet stickerSet = stickerSetsById.get(setId);
|
||||
if (stickerSet != null && (stickerSet.set.flags & 2) != 0) {
|
||||
if (stickerSet != null && stickerSet.set.disabled) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -156,7 +156,9 @@ public class StickersQuery {
|
|||
|
||||
TLRPC.TL_messages_stickerSet oldSet = stickerSetsById.get(stickerSet.id);
|
||||
if (oldSet != null && oldSet.set.hash == stickerSet.hash) {
|
||||
oldSet.set.flags = stickerSet.flags;
|
||||
oldSet.set.disabled = stickerSet.disabled;
|
||||
oldSet.set.installed = stickerSet.installed;
|
||||
oldSet.set.official = stickerSet.official;
|
||||
newStickerSets.put(oldSet.set.id, oldSet);
|
||||
newStickerArray.add(oldSet);
|
||||
|
||||
|
@ -206,24 +208,32 @@ public class StickersQuery {
|
|||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO stickers_v2 VALUES(?, ?, ?, ?)");
|
||||
state.requery();
|
||||
int size = 4;
|
||||
for (int a = 0; a < stickers.size(); a++) {
|
||||
size += stickers.get(a).getObjectSize();
|
||||
if (stickers != null) {
|
||||
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO stickers_v2 VALUES(?, ?, ?, ?)");
|
||||
state.requery();
|
||||
int size = 4;
|
||||
for (int a = 0; a < stickers.size(); a++) {
|
||||
size += stickers.get(a).getObjectSize();
|
||||
}
|
||||
NativeByteBuffer data = new NativeByteBuffer(size);
|
||||
data.writeInt32(stickers.size());
|
||||
for (int a = 0; a < stickers.size(); a++) {
|
||||
stickers.get(a).serializeToStream(data);
|
||||
}
|
||||
state.bindInteger(1, 1);
|
||||
state.bindByteBuffer(2, data);
|
||||
state.bindInteger(3, date);
|
||||
state.bindString(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();
|
||||
}
|
||||
NativeByteBuffer data = new NativeByteBuffer(size);
|
||||
data.writeInt32(stickers.size());
|
||||
for (int a = 0; a < stickers.size(); a++) {
|
||||
stickers.get(a).serializeToStream(data);
|
||||
}
|
||||
state.bindInteger(1, 1);
|
||||
state.bindByteBuffer(2, data);
|
||||
state.bindInteger(3, date);
|
||||
state.bindString(4, hash);
|
||||
state.step();
|
||||
data.reuse();
|
||||
state.dispose();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
|
@ -291,7 +301,7 @@ public class StickersQuery {
|
|||
}
|
||||
stickersByIdNew.put(document.id, document);
|
||||
}
|
||||
if ((stickerSet.set.flags & 2) == 0) {
|
||||
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) {
|
||||
|
@ -333,6 +343,14 @@ public class StickersQuery {
|
|||
} catch (Throwable e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
} else if (!cache) {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
loadDate = date;
|
||||
}
|
||||
});
|
||||
putStickersToCache(null, date, null);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -433,11 +451,7 @@ public class StickersQuery {
|
|||
stickerSetID.access_hash = stickerSet.access_hash;
|
||||
stickerSetID.id = stickerSet.id;
|
||||
if (hide != 0) {
|
||||
if (hide == 1) {
|
||||
stickerSet.flags |= 2;
|
||||
} else {
|
||||
stickerSet.flags &= ~2;
|
||||
}
|
||||
stickerSet.disabled = hide == 1;
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.stickersDidLoaded);
|
||||
TLRPC.TL_messages_installStickerSet req = new TLRPC.TL_messages_installStickerSet();
|
||||
req.stickerset = stickerSetID;
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.net.InterfaceAddress;
|
|||
import java.net.NetworkInterface;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class ConnectionsManager {
|
||||
|
||||
|
@ -57,7 +58,7 @@ public class ConnectionsManager {
|
|||
private int lastClassGuid = 1;
|
||||
private boolean isUpdating = false;
|
||||
private int connectionState = native_getConnectionState();
|
||||
private volatile int lastRequestToken = 1;
|
||||
private AtomicInteger lastRequestToken = new AtomicInteger(1);
|
||||
private PowerManager.WakeLock wakeLock = null;
|
||||
|
||||
private static volatile ConnectionsManager Instance = null;
|
||||
|
@ -114,11 +115,11 @@ public class ConnectionsManager {
|
|||
}
|
||||
|
||||
public int sendRequest(final TLObject object, final RequestDelegate onComplete, final QuickAckDelegate onQuickAck, final int flags, final int datacenterId, final int connetionType, final boolean immediate) {
|
||||
final int requestToken = lastRequestToken++;
|
||||
final int requestToken = lastRequestToken.getAndIncrement();
|
||||
Utilities.stageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
FileLog.d("tmessages", "send request " + object);
|
||||
FileLog.d("tmessages", "send request " + object + " with token = " + requestToken);
|
||||
NativeByteBuffer buffer = new NativeByteBuffer(object.getObjectSize());
|
||||
object.serializeToStream(buffer);
|
||||
object.freeResources();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -896,7 +896,7 @@ public class ActionBarLayout extends FrameLayout {
|
|||
onCloseAnimationEndRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
removeFragmentFromStack(currentFragment);
|
||||
removeFragmentFromStackInternal(currentFragment);
|
||||
setVisibility(GONE);
|
||||
if (backgroundView != null) {
|
||||
backgroundView.setVisibility(GONE);
|
||||
|
@ -935,7 +935,7 @@ public class ActionBarLayout extends FrameLayout {
|
|||
});
|
||||
currentAnimation.start();
|
||||
} else {
|
||||
removeFragmentFromStack(currentFragment);
|
||||
removeFragmentFromStackInternal(currentFragment);
|
||||
setVisibility(GONE);
|
||||
if (backgroundView != null) {
|
||||
backgroundView.setVisibility(GONE);
|
||||
|
@ -998,16 +998,24 @@ public class ActionBarLayout extends FrameLayout {
|
|||
}
|
||||
}
|
||||
|
||||
public void removeFragmentFromStack(BaseFragment fragment) {
|
||||
private void removeFragmentFromStackInternal(BaseFragment fragment) {
|
||||
fragment.onPause();
|
||||
fragment.onFragmentDestroy();
|
||||
fragment.setParentLayout(null);
|
||||
fragmentsStack.remove(fragment);
|
||||
}
|
||||
|
||||
public void removeFragmentFromStack(BaseFragment fragment) {
|
||||
if (useAlphaAnimations && fragmentsStack.size() == 1 && AndroidUtilities.isTablet()) {
|
||||
closeLastFragment(true);
|
||||
} else {
|
||||
removeFragmentFromStackInternal(fragment);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAllFragments() {
|
||||
for (int a = 0; a < fragmentsStack.size(); a++) {
|
||||
removeFragmentFromStack(fragmentsStack.get(a));
|
||||
removeFragmentFromStackInternal(fragmentsStack.get(a));
|
||||
a--;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -288,7 +288,6 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
|
|||
}
|
||||
if (popupWindow == null) {
|
||||
popupWindow = new ActionBarPopupWindow(popupLayout, LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT);
|
||||
//popupWindow.setBackgroundDrawable(new BitmapDrawable());
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
popupWindow.setAnimationStyle(0);
|
||||
} else {
|
||||
|
|
|
@ -90,13 +90,22 @@ public class ActionBarPopupWindow extends PopupWindow {
|
|||
setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(8), AndroidUtilities.dp(8), AndroidUtilities.dp(8));
|
||||
setWillNotDraw(false);
|
||||
|
||||
scrollView = new ScrollView(context);
|
||||
scrollView.setVerticalScrollBarEnabled(false);
|
||||
addView(scrollView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
|
||||
try {
|
||||
scrollView = new ScrollView(context);
|
||||
scrollView.setVerticalScrollBarEnabled(false);
|
||||
addView(scrollView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
|
||||
} catch (Throwable e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
|
||||
|
||||
linearLayout = new LinearLayout(context);
|
||||
linearLayout.setOrientation(LinearLayout.VERTICAL);
|
||||
scrollView.addView(linearLayout, new ScrollView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
if (scrollView != null) {
|
||||
scrollView.addView(linearLayout, new ScrollView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
} else {
|
||||
addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
|
||||
}
|
||||
}
|
||||
|
||||
public void setShowedFromBotton(boolean value) {
|
||||
|
@ -215,7 +224,9 @@ public class ActionBarPopupWindow extends PopupWindow {
|
|||
}
|
||||
|
||||
public void scrollToTop() {
|
||||
scrollView.scrollTo(0, 0);
|
||||
if (scrollView != null) {
|
||||
scrollView.scrollTo(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -374,6 +385,7 @@ public class ActionBarPopupWindow extends PopupWindow {
|
|||
}
|
||||
|
||||
public void dismiss(boolean animated) {
|
||||
setFocusable(false);
|
||||
if (animationEnabled && animated) {
|
||||
if (windowAnimatorSet != null) {
|
||||
windowAnimatorSet.cancel();
|
||||
|
@ -414,7 +426,6 @@ public class ActionBarPopupWindow extends PopupWindow {
|
|||
});
|
||||
windowAnimatorSet.start();
|
||||
} else {
|
||||
setFocusable(false);
|
||||
try {
|
||||
super.dismiss();
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -31,6 +31,7 @@ import android.view.View;
|
|||
import android.view.ViewAnimationUtils;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
|
@ -55,6 +56,7 @@ public class BottomSheet extends Dialog {
|
|||
|
||||
private LinearLayout containerView;
|
||||
private FrameLayout container;
|
||||
private Object lastInsets;
|
||||
|
||||
private boolean dismissed;
|
||||
private int tag;
|
||||
|
@ -70,6 +72,8 @@ public class BottomSheet extends Dialog {
|
|||
private ColorDrawable backgroundDrawable = new ColorDrawable(0xff000000);
|
||||
private static Drawable shadowDrawable;
|
||||
|
||||
private boolean focusable;
|
||||
|
||||
private Paint ciclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
|
||||
private static int backgroundPaddingTop;
|
||||
|
@ -193,10 +197,11 @@ public class BottomSheet extends Dialog {
|
|||
}
|
||||
}
|
||||
|
||||
public BottomSheet(Context context) {
|
||||
public BottomSheet(Context context, boolean needFocus) {
|
||||
super(context);
|
||||
|
||||
container = new FrameLayout(getContext()) {
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int width = MeasureSpec.getSize(widthMeasureSpec);
|
||||
|
@ -225,7 +230,12 @@ public class BottomSheet extends Dialog {
|
|||
if (child.getVisibility() == GONE || child == containerView) {
|
||||
continue;
|
||||
}
|
||||
measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
|
||||
if (lastInsets != null && Build.VERSION.SDK_INT >= 21) {
|
||||
WindowInsets wi = (WindowInsets) lastInsets;
|
||||
wi = wi.replaceSystemWindowInsets(wi.getSystemWindowInsetLeft(), wi.getSystemWindowInsetTop(), 0, wi.getSystemWindowInsetBottom());
|
||||
child.dispatchApplyWindowInsets(wi);
|
||||
}
|
||||
measureChildWithMargins(child, MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), 0, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY), 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -296,8 +306,18 @@ public class BottomSheet extends Dialog {
|
|||
}
|
||||
});
|
||||
container.setBackgroundDrawable(backgroundDrawable);
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
focusable = needFocus;
|
||||
if (Build.VERSION.SDK_INT >= 21 && !focusable) {
|
||||
container.setFitsSystemWindows(true);
|
||||
container.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
|
||||
lastInsets = insets;
|
||||
container.requestLayout();
|
||||
return insets.consumeSystemWindowInsets();
|
||||
}
|
||||
});
|
||||
container.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||
}
|
||||
}
|
||||
|
@ -424,9 +444,13 @@ public class BottomSheet extends Dialog {
|
|||
WindowManager.LayoutParams params = getWindow().getAttributes();
|
||||
params.width = ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
params.gravity = Gravity.TOP | Gravity.LEFT;
|
||||
params.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
|
||||
params.dimAmount = 0;
|
||||
params.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND;
|
||||
if (!focusable) {
|
||||
params.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
|
||||
params.dimAmount = 0;
|
||||
params.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND;
|
||||
} else {
|
||||
params.dimAmount = 0.2f;
|
||||
}
|
||||
if (Build.VERSION.SDK_INT < 21) {
|
||||
params.height = ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
}
|
||||
|
@ -436,6 +460,9 @@ public class BottomSheet extends Dialog {
|
|||
@Override
|
||||
public void show() {
|
||||
super.show();
|
||||
if (focusable) {
|
||||
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
|
||||
}
|
||||
dismissed = false;
|
||||
if (Build.VERSION.SDK_INT >= 21 || !useRevealAnimation) {
|
||||
containerView.setBackgroundDrawable(shadowDrawable);
|
||||
|
@ -592,7 +619,7 @@ public class BottomSheet extends Dialog {
|
|||
AnimatorSetProxy animatorSetProxy = new AnimatorSetProxy();
|
||||
animatorSetProxy.playTogether(
|
||||
ObjectAnimatorProxy.ofFloat(containerView, "translationY", 0),
|
||||
ObjectAnimatorProxy.ofInt(backgroundDrawable, "alpha", 51));
|
||||
ObjectAnimatorProxy.ofInt(backgroundDrawable, "alpha", focusable ? 0 : 51));
|
||||
animatorSetProxy.setDuration(200);
|
||||
animatorSetProxy.setStartDelay(20);
|
||||
animatorSetProxy.setInterpolator(new DecelerateInterpolator());
|
||||
|
@ -718,7 +745,11 @@ public class BottomSheet extends Dialog {
|
|||
private BottomSheet bottomSheet;
|
||||
|
||||
public Builder(Context context) {
|
||||
bottomSheet = new BottomSheet(context);
|
||||
bottomSheet = new BottomSheet(context, false);
|
||||
}
|
||||
|
||||
public Builder(Context context, boolean needFocus) {
|
||||
bottomSheet = new BottomSheet(context, needFocus);
|
||||
}
|
||||
|
||||
public Builder setItems(CharSequence[] items, final OnClickListener onClickListener) {
|
||||
|
|
|
@ -41,7 +41,7 @@ public class BaseSearchAdapter extends BaseFragmentAdapter {
|
|||
protected HashMap<String, HashtagObject> hashtagsByText;
|
||||
protected boolean hashtagsLoadedFromDb = false;
|
||||
|
||||
public void queryServerSearch(final String query, final boolean allowChats) {
|
||||
public void queryServerSearch(final String query, final boolean allowChats, final boolean allowBots) {
|
||||
if (reqId != 0) {
|
||||
ConnectionsManager.getInstance().cancelRequest(reqId, true);
|
||||
reqId = 0;
|
||||
|
@ -72,6 +72,9 @@ public class BaseSearchAdapter extends BaseFragmentAdapter {
|
|||
}
|
||||
}
|
||||
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;
|
||||
|
|
|
@ -238,7 +238,7 @@ public class ContactsAdapter extends BaseSectionsAdapter {
|
|||
}
|
||||
} else if (type == 0) {
|
||||
if (convertView == null) {
|
||||
convertView = new UserCell(mContext, 58);
|
||||
convertView = new UserCell(mContext, 58, 1);
|
||||
((UserCell) convertView).setStatusColors(0xffa8a8a8, 0xff3b84c0);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ public class DialogsAdapter extends RecyclerView.Adapter {
|
|||
|
||||
public boolean isDataSetChanged() {
|
||||
int current = currentCount;
|
||||
return current != getItemCount();
|
||||
return current != getItemCount() || current == 1;
|
||||
}
|
||||
|
||||
private ArrayList<TLRPC.Dialog> getDialogsArray() {
|
||||
|
|
|
@ -16,6 +16,7 @@ import android.view.ViewGroup;
|
|||
import org.telegram.SQLite.SQLiteCursor;
|
||||
import org.telegram.SQLite.SQLitePreparedStatement;
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.ChatObject;
|
||||
import org.telegram.messenger.ContactsController;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.MessageObject;
|
||||
|
@ -128,15 +129,29 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
|
|||
}
|
||||
return;
|
||||
}
|
||||
final TLRPC.TL_messages_search req = new TLRPC.TL_messages_search();
|
||||
|
||||
final TLRPC.TL_messages_searchGlobal req = new TLRPC.TL_messages_searchGlobal();
|
||||
req.limit = 20;
|
||||
req.peer = new TLRPC.TL_inputPeerEmpty();
|
||||
req.q = query;
|
||||
if (lastMessagesSearchString != null && query.equals(lastMessagesSearchString) && !searchResultMessages.isEmpty()) {
|
||||
req.max_id = searchResultMessages.get(searchResultMessages.size() - 1).getId();
|
||||
MessageObject lastMessage = searchResultMessages.get(searchResultMessages.size() - 1);
|
||||
req.offset_id = lastMessage.getId();
|
||||
req.offset_date = lastMessage.messageOwner.date;
|
||||
int id;
|
||||
if (lastMessage.messageOwner.to_id.channel_id != 0) {
|
||||
id = -lastMessage.messageOwner.to_id.channel_id;
|
||||
} else if (lastMessage.messageOwner.to_id.chat_id != 0) {
|
||||
id = -lastMessage.messageOwner.to_id.chat_id;
|
||||
} else {
|
||||
id = lastMessage.messageOwner.to_id.user_id;
|
||||
}
|
||||
req.offset_peer = MessagesController.getInputPeer(id);
|
||||
} else {
|
||||
req.offset_date = 0;
|
||||
req.offset_id = 0;
|
||||
req.offset_peer = new TLRPC.TL_inputPeerEmpty();
|
||||
}
|
||||
lastMessagesSearchString = query;
|
||||
req.filter = new TLRPC.TL_inputMessagesFilterEmpty();
|
||||
final int currentReqId = ++lastReqId;
|
||||
if (delegate != null) {
|
||||
delegate.searchStateChanged(true);
|
||||
|
@ -153,7 +168,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
|
|||
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) {
|
||||
if (req.offset_id == 0) {
|
||||
searchResultMessages.clear();
|
||||
}
|
||||
for (TLRPC.Message message : res.messages) {
|
||||
|
@ -258,7 +273,14 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
|
|||
} else {
|
||||
did = AndroidUtilities.makeBroadcastId(chat.id);
|
||||
}
|
||||
hashMap.get(did).object = chat;
|
||||
if (chat.migrated_to != null) {
|
||||
RecentSearchObject recentSearchObject = hashMap.remove(did);
|
||||
if (recentSearchObject != null) {
|
||||
arrayList.remove(recentSearchObject);
|
||||
}
|
||||
} else {
|
||||
hashMap.get(did).object = chat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -391,7 +413,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
|
|||
int resultCount = 0;
|
||||
|
||||
HashMap<Long, DialogSearchResult> dialogsResult = new HashMap<>();
|
||||
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT did, date FROM dialogs ORDER BY date DESC LIMIT 200");
|
||||
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT did, date FROM dialogs ORDER BY date DESC LIMIT 400");
|
||||
while (cursor.next()) {
|
||||
long id = cursor.longValue(0);
|
||||
DialogSearchResult dialogSearchResult = new DialogSearchResult();
|
||||
|
@ -481,16 +503,18 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
|
|||
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
|
||||
if (data != null && cursor.byteBufferValue(0, data) != 0) {
|
||||
TLRPC.Chat chat = TLRPC.Chat.TLdeserialize(data, data.readInt32(false), false);
|
||||
long dialog_id;
|
||||
if (chat.id > 0) {
|
||||
dialog_id = -chat.id;
|
||||
} else {
|
||||
dialog_id = AndroidUtilities.makeBroadcastId(chat.id);
|
||||
if (!(chat == null || chat.deactivated || ChatObject.isChannel(chat) && ChatObject.isNotInChat(chat))) {
|
||||
long dialog_id;
|
||||
if (chat.id > 0) {
|
||||
dialog_id = -chat.id;
|
||||
} else {
|
||||
dialog_id = AndroidUtilities.makeBroadcastId(chat.id);
|
||||
}
|
||||
DialogSearchResult dialogSearchResult = dialogsResult.get(dialog_id);
|
||||
dialogSearchResult.name = AndroidUtilities.generateSearchName(chat.title, null, q);
|
||||
dialogSearchResult.object = chat;
|
||||
resultCount++;
|
||||
}
|
||||
DialogSearchResult dialogSearchResult = dialogsResult.get(dialog_id);
|
||||
dialogSearchResult.name = AndroidUtilities.generateSearchName(chat.title, null, q);
|
||||
dialogSearchResult.object = chat;
|
||||
resultCount++;
|
||||
}
|
||||
data.reuse();
|
||||
break;
|
||||
|
@ -589,7 +613,8 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
|
|||
ArrayList<TLObject> resultArray = new ArrayList<>();
|
||||
ArrayList<CharSequence> resultArrayNames = new ArrayList<>();
|
||||
|
||||
for (DialogSearchResult dialogSearchResult : searchResults) {
|
||||
for (int a = 0; a < searchResults.size(); a++) {
|
||||
DialogSearchResult dialogSearchResult = searchResults.get(a);
|
||||
resultArray.add(dialogSearchResult.object);
|
||||
resultArrayNames.add(dialogSearchResult.name);
|
||||
}
|
||||
|
@ -797,7 +822,19 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
|
|||
public Object getItem(int i) {
|
||||
if (needMessagesSearch != 2 && (lastSearchText == null || lastSearchText.length() == 0) && !recentSearchObjects.isEmpty()) {
|
||||
if (i > 0 && i - 1 < recentSearchObjects.size()) {
|
||||
return recentSearchObjects.get(i - 1).object;
|
||||
TLObject object = recentSearchObjects.get(i - 1).object;
|
||||
if (object instanceof TLRPC.User) {
|
||||
TLRPC.User user = MessagesController.getInstance().getUser(((TLRPC.User) object).id);
|
||||
if (user != null) {
|
||||
object = user;
|
||||
}
|
||||
} else if (object instanceof TLRPC.Chat) {
|
||||
TLRPC.Chat chat = MessagesController.getInstance().getChat(((TLRPC.Chat) object).id);
|
||||
if (chat != null) {
|
||||
object = chat;
|
||||
}
|
||||
}
|
||||
return object;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -166,8 +166,9 @@ public class MentionsAdapter extends BaseSearchAdapter {
|
|||
}
|
||||
String usernameString = result.toString().toLowerCase();
|
||||
ArrayList<TLRPC.User> newResult = new ArrayList<>();
|
||||
if (info instanceof TLRPC.TL_chatFull) {
|
||||
for (TLRPC.TL_chatParticipant chatParticipant : info.participants.participants) {
|
||||
if (info.participants != null) {
|
||||
for (int a = 0; a < info.participants.participants.size(); a++) {
|
||||
TLRPC.ChatParticipant chatParticipant = info.participants.participants.get(a);
|
||||
TLRPC.User user = MessagesController.getInstance().getUser(chatParticipant.user_id);
|
||||
if (user == null || UserObject.isUserSelf(user)) {
|
||||
continue;
|
||||
|
@ -220,11 +221,13 @@ public class MentionsAdapter extends BaseSearchAdapter {
|
|||
ArrayList<TLRPC.User> newResultUsers = new ArrayList<>();
|
||||
String command = result.toString().toLowerCase();
|
||||
for (HashMap.Entry<Integer, TLRPC.BotInfo> entry : botInfo.entrySet()) {
|
||||
for (TLRPC.TL_botCommand botCommand : entry.getValue().commands) {
|
||||
TLRPC.BotInfo botInfo = entry.getValue();
|
||||
for (int a = 0; a < botInfo.commands.size(); a++) {
|
||||
TLRPC.TL_botCommand botCommand = botInfo.commands.get(a);
|
||||
if (botCommand != null && botCommand.command != null && botCommand.command.startsWith(command)) {
|
||||
newResult.add("/" + botCommand.command);
|
||||
newResultHelp.add(botCommand.description);
|
||||
newResultUsers.add(MessagesController.getInstance().getUser(entry.getValue().user_id));
|
||||
newResultUsers.add(MessagesController.getInstance().getUser(botInfo.user_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -311,8 +314,12 @@ public class MentionsAdapter extends BaseSearchAdapter {
|
|||
if (i < 0 || i >= searchResultCommands.size()) {
|
||||
return null;
|
||||
}
|
||||
if (searchResultCommandsUsers != null && botsCount != 1) {
|
||||
return String.format("%s@%s", searchResultCommands.get(i), searchResultCommandsUsers.get(i).username);
|
||||
if (searchResultCommandsUsers != null && (botsCount != 1 || info instanceof TLRPC.TL_channelFull)) {
|
||||
if (searchResultCommandsUsers.get(i) != null) {
|
||||
return String.format("%s@%s", searchResultCommands.get(i), searchResultCommandsUsers.get(i) != null ? searchResultCommandsUsers.get(i).username : "");
|
||||
} else {
|
||||
return String.format("%s", searchResultCommands.get(i));
|
||||
}
|
||||
}
|
||||
return searchResultCommands.get(i);
|
||||
}
|
||||
|
@ -338,7 +345,7 @@ public class MentionsAdapter extends BaseSearchAdapter {
|
|||
} else if (searchResultHashtags != null) {
|
||||
((MentionCell) view).setText(searchResultHashtags.get(i));
|
||||
} else if (searchResultCommands != null) {
|
||||
((MentionCell) view).setBotCommand(searchResultCommands.get(i), searchResultCommandsHelp.get(i), searchResultCommandsUsers.get(i));
|
||||
((MentionCell) view).setBotCommand(searchResultCommands.get(i), searchResultCommandsHelp.get(i), searchResultCommandsUsers != null ? searchResultCommandsUsers.get(i) : null);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
|
|
@ -74,20 +74,19 @@ public class PhotoAttachAdapter extends RecyclerView.Adapter {
|
|||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
PhotoAttachPhotoCell cell = new PhotoAttachPhotoCell(mContext);
|
||||
cell.setOnCheckClickLisnener(new View.OnClickListener() {
|
||||
cell.setDelegate(new PhotoAttachPhotoCell.PhotoAttachPhotoCellDelegate() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
PhotoAttachPhotoCell cell = (PhotoAttachPhotoCell) v.getParent();
|
||||
MediaController.PhotoEntry photoEntry = cell.getPhotoEntry();
|
||||
public void onCheckClick(PhotoAttachPhotoCell v) {
|
||||
MediaController.PhotoEntry photoEntry = v.getPhotoEntry();
|
||||
if (selectedPhotos.containsKey(photoEntry.imageId)) {
|
||||
selectedPhotos.remove(photoEntry.imageId);
|
||||
cell.setChecked(false, true);
|
||||
v.setChecked(false, true);
|
||||
photoEntry.imagePath = null;
|
||||
photoEntry.thumbPath = null;
|
||||
cell.setPhotoEntry(photoEntry, cell.getTag() == MediaController.allPhotosAlbumEntry.photos.size() - 1);
|
||||
v.setPhotoEntry(photoEntry, v.getTag() == MediaController.allPhotosAlbumEntry.photos.size() - 1);
|
||||
} else {
|
||||
selectedPhotos.put(photoEntry.imageId, photoEntry);
|
||||
cell.setChecked(true, true);
|
||||
v.setChecked(true, true);
|
||||
}
|
||||
delegate.selectedPhotosChanged();
|
||||
}
|
||||
|
|
|
@ -43,13 +43,15 @@ public class SearchAdapter extends BaseSearchAdapter {
|
|||
private boolean useUserCell;
|
||||
private boolean onlyMutual;
|
||||
private boolean allowChats;
|
||||
private boolean allowBots;
|
||||
|
||||
public SearchAdapter(Context context, HashMap<Integer, TLRPC.User> arg1, boolean usernameSearch, boolean mutual, boolean chats) {
|
||||
public SearchAdapter(Context context, HashMap<Integer, TLRPC.User> arg1, boolean usernameSearch, boolean mutual, boolean chats, boolean bots) {
|
||||
mContext = context;
|
||||
ignoreUsers = arg1;
|
||||
onlyMutual = mutual;
|
||||
allowUsernameSearch = usernameSearch;
|
||||
allowChats = chats;
|
||||
allowBots = bots;
|
||||
}
|
||||
|
||||
public void setCheckedMap(HashMap<Integer, ?> map) {
|
||||
|
@ -72,7 +74,7 @@ public class SearchAdapter extends BaseSearchAdapter {
|
|||
searchResult.clear();
|
||||
searchResultNames.clear();
|
||||
if (allowUsernameSearch) {
|
||||
queryServerSearch(null, allowChats);
|
||||
queryServerSearch(null, allowChats, allowBots);
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
} else {
|
||||
|
@ -97,7 +99,7 @@ public class SearchAdapter extends BaseSearchAdapter {
|
|||
@Override
|
||||
public void run() {
|
||||
if (allowUsernameSearch) {
|
||||
queryServerSearch(query, allowChats);
|
||||
queryServerSearch(query, allowChats, allowBots);
|
||||
}
|
||||
final ArrayList<TLRPC.TL_contact> contactsCopy = new ArrayList<>();
|
||||
contactsCopy.addAll(ContactsController.getInstance().contacts);
|
||||
|
@ -122,9 +124,10 @@ public class SearchAdapter extends BaseSearchAdapter {
|
|||
ArrayList<TLRPC.User> resultArray = new ArrayList<>();
|
||||
ArrayList<CharSequence> resultArrayNames = new ArrayList<>();
|
||||
|
||||
for (TLRPC.TL_contact contact : contactsCopy) {
|
||||
for (int a = 0; a < contactsCopy.size(); a++) {
|
||||
TLRPC.TL_contact contact = contactsCopy.get(a);
|
||||
TLRPC.User user = MessagesController.getInstance().getUser(contact.user_id);
|
||||
if (user.id == UserConfig.getClientUserId() || onlyMutual && (user.flags & TLRPC.USER_FLAG_MUTUAL_CONTACT) == 0) {
|
||||
if (user.id == UserConfig.getClientUserId() || onlyMutual && !user.mutual_contact) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -235,7 +238,7 @@ public class SearchAdapter extends BaseSearchAdapter {
|
|||
} else {
|
||||
if (view == null) {
|
||||
if (useUserCell) {
|
||||
view = new UserCell(mContext, 1);
|
||||
view = new UserCell(mContext, 1, 1);
|
||||
if (checkedMap != null) {
|
||||
((UserCell) view).setChecked(false, false);
|
||||
}
|
||||
|
|
|
@ -217,7 +217,7 @@ public class AudioSelectActivity extends BaseFragment implements NotificationCen
|
|||
File file = new File(audioEntry.path);
|
||||
|
||||
TLRPC.TL_message message = new TLRPC.TL_message();
|
||||
message.flags = TLRPC.MESSAGE_FLAG_OUT;
|
||||
message.out = true;
|
||||
message.id = id;
|
||||
message.to_id = new TLRPC.TL_peerUser();
|
||||
message.to_id.user_id = message.from_id = UserConfig.getClientUserId();
|
||||
|
|
|
@ -263,7 +263,7 @@ public class BlockedUsersActivity extends BaseFragment implements NotificationCe
|
|||
int type = getItemViewType(i);
|
||||
if (type == 0) {
|
||||
if (view == null) {
|
||||
view = new UserCell(mContext, 1);
|
||||
view = new UserCell(mContext, 1, 0);
|
||||
}
|
||||
TLRPC.User user = MessagesController.getInstance().getUser(MessagesController.getInstance().blockedUsers.get(i));
|
||||
if (user != null) {
|
||||
|
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* 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-2015.
|
||||
*/
|
||||
|
||||
package org.telegram.ui.Cells;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.text.Layout;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.StaticLayout;
|
||||
import android.text.TextPaint;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.Emoji;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.MessageObject;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
import org.telegram.ui.Components.LinkPath;
|
||||
import org.telegram.ui.Components.URLSpanNoUnderline;
|
||||
|
||||
public class AboutLinkCell extends FrameLayout {
|
||||
|
||||
private StaticLayout textLayout;
|
||||
private TextPaint textPaint;
|
||||
private Paint urlPaint;
|
||||
private String oldText;
|
||||
private int textX;
|
||||
private int textY;
|
||||
private SpannableStringBuilder stringBuilder;
|
||||
|
||||
private ImageView imageView;
|
||||
|
||||
private ClickableSpan pressedLink;
|
||||
private LinkPath urlPath = new LinkPath();
|
||||
|
||||
private AboutLinkCellDelegate delegate;
|
||||
|
||||
public interface AboutLinkCellDelegate {
|
||||
void didPressUrl(String url);
|
||||
}
|
||||
|
||||
public AboutLinkCell(Context context) {
|
||||
super(context);
|
||||
|
||||
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
|
||||
textPaint.setTextSize(AndroidUtilities.dp(16));
|
||||
textPaint.setColor(0xff000000);
|
||||
textPaint.linkColor = 0xff316f9f;
|
||||
|
||||
urlPaint = new Paint();
|
||||
urlPaint.setColor(0x33316f9f);
|
||||
|
||||
imageView = new ImageView(context);
|
||||
imageView.setScaleType(ImageView.ScaleType.CENTER);
|
||||
addView(imageView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 16, 5, LocaleController.isRTL ? 16 : 0, 0));
|
||||
setWillNotDraw(false);
|
||||
}
|
||||
|
||||
public void setDelegate(AboutLinkCellDelegate botHelpCellDelegate) {
|
||||
delegate = botHelpCellDelegate;
|
||||
}
|
||||
|
||||
private void resetPressedLink() {
|
||||
if (pressedLink != null) {
|
||||
pressedLink = null;
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setTextAndIcon(String text, int resId) {
|
||||
if (text == null || text.length() == 0) {
|
||||
setVisibility(GONE);
|
||||
return;
|
||||
}
|
||||
if (text != null && oldText != null && text.equals(oldText)) {
|
||||
return;
|
||||
}
|
||||
oldText = text;
|
||||
stringBuilder = new SpannableStringBuilder(oldText);
|
||||
MessageObject.addLinks(stringBuilder, false);
|
||||
Emoji.replaceEmoji(stringBuilder, textPaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
|
||||
requestLayout();
|
||||
if (resId == 0) {
|
||||
imageView.setImageDrawable(null);
|
||||
} else {
|
||||
imageView.setImageResource(resId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
float x = event.getX();
|
||||
float y = event.getY();
|
||||
|
||||
boolean result = false;
|
||||
if (textLayout != null) {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN || pressedLink != null && event.getAction() == MotionEvent.ACTION_UP) {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
resetPressedLink();
|
||||
try {
|
||||
int x2 = (int) (x - textX);
|
||||
int y2 = (int) (y - textY);
|
||||
final int line = textLayout.getLineForVertical(y2);
|
||||
final int off = textLayout.getOffsetForHorizontal(line, x2);
|
||||
|
||||
final float left = textLayout.getLineLeft(line);
|
||||
if (left <= x2 && left + textLayout.getLineWidth(line) >= x2) {
|
||||
Spannable buffer = (Spannable) textLayout.getText();
|
||||
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
|
||||
if (link.length != 0) {
|
||||
resetPressedLink();
|
||||
pressedLink = link[0];
|
||||
result = true;
|
||||
try {
|
||||
int start = buffer.getSpanStart(pressedLink);
|
||||
urlPath.setCurrentLayout(textLayout, start);
|
||||
textLayout.getSelectionPath(start, buffer.getSpanEnd(pressedLink), urlPath);
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
} else {
|
||||
resetPressedLink();
|
||||
}
|
||||
} else {
|
||||
resetPressedLink();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
resetPressedLink();
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
} else if (pressedLink != null) {
|
||||
try {
|
||||
if (pressedLink instanceof URLSpanNoUnderline) {
|
||||
String url = ((URLSpanNoUnderline) pressedLink).getURL();
|
||||
if (url.startsWith("@") || url.startsWith("#") || url.startsWith("/")) {
|
||||
if (delegate != null) {
|
||||
delegate.didPressUrl(url);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pressedLink.onClick(this);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
resetPressedLink();
|
||||
result = true;
|
||||
}
|
||||
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
|
||||
resetPressedLink();
|
||||
}
|
||||
}
|
||||
return result || super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@SuppressLint("DrawAllocation")
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
textLayout = new StaticLayout(stringBuilder, textPaint, MeasureSpec.getSize(widthMeasureSpec) - AndroidUtilities.dp(71 + 16), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
||||
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(textLayout.getHeight() + AndroidUtilities.dp(16), MeasureSpec.EXACTLY));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
canvas.save();
|
||||
canvas.translate(textX = AndroidUtilities.dp(LocaleController.isRTL ? 16 : 71), textY = AndroidUtilities.dp(8));
|
||||
if (pressedLink != null) {
|
||||
canvas.drawPath(urlPath, urlPaint);
|
||||
}
|
||||
textLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
|
@ -1,61 +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-2015.
|
||||
*/
|
||||
|
||||
package org.telegram.ui.Cells;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
import org.telegram.ui.Components.SimpleTextView;
|
||||
|
||||
public class AddMemberCell extends FrameLayout {
|
||||
|
||||
private SimpleTextView textView;
|
||||
|
||||
public AddMemberCell(Context context) {
|
||||
super(context);
|
||||
|
||||
ImageView imageView = new ImageView(context);
|
||||
imageView.setImageResource(R.drawable.addmember);
|
||||
imageView.setScaleType(ImageView.ScaleType.CENTER);
|
||||
addView(imageView, LayoutHelper.createFrame(48, 48, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 68, 8, LocaleController.isRTL ? 68 : 0, 0));
|
||||
|
||||
textView = new SimpleTextView(context);
|
||||
textView.setTextColor(0xff212121);
|
||||
textView.setTextSize(17);
|
||||
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
|
||||
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 20, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 28 : 129, 22.5f, LocaleController.isRTL ? 129 : 28, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (Build.VERSION.SDK_INT >= 21 && getBackground() != null) {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
getBackground().setHotspot(event.getX(), event.getY());
|
||||
}
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(64), MeasureSpec.EXACTLY));
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
textView.setText(text);
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ import android.view.MotionEvent;
|
|||
import android.view.View;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.Emoji;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.MessageObject;
|
||||
import org.telegram.messenger.FileLog;
|
||||
|
@ -97,6 +98,7 @@ public class BotHelpCell extends View {
|
|||
stringBuilder.append(text);
|
||||
MessageObject.addLinks(stringBuilder);
|
||||
stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), 0, help.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
Emoji.replaceEmoji(stringBuilder, textPaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
|
||||
textLayout = new StaticLayout(stringBuilder, textPaint, width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
||||
width = 0;
|
||||
height = textLayout.getHeight() + AndroidUtilities.dp(4 + 18);
|
||||
|
|
|
@ -51,6 +51,7 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
|
|||
void didPressUrl(MessageObject messageObject, ClickableSpan url, boolean longPress);
|
||||
void needOpenWebView(String url, String title, String originalUrl, int w, int h);
|
||||
void didClickedImage(ChatBaseCell cell);
|
||||
void didPressShare(ChatBaseCell cell);
|
||||
boolean canPerformActions();
|
||||
}
|
||||
|
||||
|
@ -104,6 +105,11 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
|
|||
private boolean replyPressed = false;
|
||||
private TLRPC.FileLocation currentReplyPhoto;
|
||||
|
||||
private boolean drawShareButton;
|
||||
private boolean sharePressed;
|
||||
private int shareStartX;
|
||||
private int shareStartY;
|
||||
|
||||
private StaticLayout nameLayout;
|
||||
protected int nameWidth;
|
||||
private float nameOffsetX = 0;
|
||||
|
@ -306,7 +312,7 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
|
|||
}
|
||||
|
||||
protected void measureTime(MessageObject messageObject) {
|
||||
currentTimeString = LocaleController.formatterDay.format((long) (messageObject.messageOwner.date) * 1000);
|
||||
currentTimeString = LocaleController.getInstance().formatterDay.format((long) (messageObject.messageOwner.date) * 1000);
|
||||
timeTextWidth = timeWidth = (int) Math.ceil(timeMediaPaint.measureText(currentTimeString));
|
||||
if ((messageObject.messageOwner.flags & TLRPC.MESSAGE_FLAG_HAS_VIEWS) != 0) {
|
||||
currentViewsString = String.format("%s", LocaleController.formatShortNumber(Math.max(1, messageObject.messageOwner.views), null));
|
||||
|
@ -323,6 +329,7 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
|
|||
isCheckPressed = true;
|
||||
isAvatarVisible = false;
|
||||
wasLayout = false;
|
||||
drawShareButton = false;
|
||||
replyNameLayout = null;
|
||||
replyTextLayout = null;
|
||||
replyNameWidth = 0;
|
||||
|
@ -345,6 +352,9 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
|
|||
currentUser = MessagesController.getInstance().getUser(messageObject.messageOwner.from_id);
|
||||
} else if (messageObject.messageOwner.from_id < 0) {
|
||||
currentChat = MessagesController.getInstance().getChat(-messageObject.messageOwner.from_id);
|
||||
if (messageObject.messageOwner.to_id.channel_id != 0 && (messageObject.messageOwner.reply_to_msg_id == 0 || messageObject.type != 13)) {
|
||||
drawShareButton = true;
|
||||
}
|
||||
}
|
||||
if (isChat && !messageObject.isOutOwner() && messageObject.messageOwner.from_id > 0) {
|
||||
isAvatarVisible = true;
|
||||
|
@ -379,7 +389,7 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
|
|||
currentTimePaint = timeMediaPaint;
|
||||
}
|
||||
|
||||
currentTimeString = LocaleController.formatterDay.format((long) (messageObject.messageOwner.date) * 1000);
|
||||
currentTimeString = LocaleController.getInstance().formatterDay.format((long) (messageObject.messageOwner.date) * 1000);
|
||||
timeTextWidth = timeWidth = (int)Math.ceil(currentTimePaint.measureText(currentTimeString));
|
||||
if ((messageObject.messageOwner.flags & TLRPC.MESSAGE_FLAG_HAS_VIEWS) != 0) {
|
||||
currentViewsString = String.format("%s", LocaleController.formatShortNumber(Math.max(1, messageObject.messageOwner.views), null));
|
||||
|
@ -398,15 +408,22 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
|
|||
currentNameString = "DELETED";
|
||||
}
|
||||
nameWidth = getMaxNameWidth();
|
||||
if (nameWidth < 0) {
|
||||
nameWidth = AndroidUtilities.dp(100);
|
||||
}
|
||||
|
||||
CharSequence nameStringFinal = TextUtils.ellipsize(currentNameString.replace("\n", " "), namePaint, nameWidth - AndroidUtilities.dp(12), TextUtils.TruncateAt.END);
|
||||
nameLayout = new StaticLayout(nameStringFinal, namePaint, nameWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
||||
if (nameLayout.getLineCount() > 0) {
|
||||
nameWidth = (int)Math.ceil(nameLayout.getLineWidth(0));
|
||||
namesOffset += AndroidUtilities.dp(19);
|
||||
nameOffsetX = nameLayout.getLineLeft(0);
|
||||
} else {
|
||||
nameWidth = 0;
|
||||
try {
|
||||
nameLayout = new StaticLayout(nameStringFinal, namePaint, nameWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
||||
if (nameLayout != null && nameLayout.getLineCount() > 0) {
|
||||
nameWidth = (int)Math.ceil(nameLayout.getLineWidth(0));
|
||||
namesOffset += AndroidUtilities.dp(19);
|
||||
nameOffsetX = nameLayout.getLineLeft(0);
|
||||
} else {
|
||||
nameWidth = 0;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
} else {
|
||||
currentNameString = null;
|
||||
|
@ -580,16 +597,16 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
|
|||
if (isAvatarVisible && avatarImage.isInsideImage(x, y)) {
|
||||
avatarPressed = true;
|
||||
result = true;
|
||||
} else if (drawForwardedName && forwardedNameLayout != null) {
|
||||
if (x >= forwardNameX && x <= forwardNameX + forwardedNameWidth && y >= forwardNameY && y <= forwardNameY + AndroidUtilities.dp(32)) {
|
||||
forwardNamePressed = true;
|
||||
result = true;
|
||||
}
|
||||
} else if (currentMessageObject.isReply()) {
|
||||
if (x >= replyStartX && x <= replyStartX + Math.max(replyNameWidth, replyTextWidth) && y >= replyStartY && y <= replyStartY + AndroidUtilities.dp(35)) {
|
||||
replyPressed = true;
|
||||
result = true;
|
||||
}
|
||||
} else if (drawForwardedName && forwardedNameLayout != null && x >= forwardNameX && x <= forwardNameX + forwardedNameWidth && y >= forwardNameY && y <= forwardNameY + AndroidUtilities.dp(32)) {
|
||||
forwardNamePressed = true;
|
||||
result = true;
|
||||
} else if (currentMessageObject.isReply() && x >= replyStartX && x <= replyStartX + Math.max(replyNameWidth, replyTextWidth) && y >= replyStartY && y <= replyStartY + AndroidUtilities.dp(35)) {
|
||||
replyPressed = true;
|
||||
result = true;
|
||||
} else if (drawShareButton && x >= shareStartX && x <= shareStartX + AndroidUtilities.dp(40) && y >= shareStartY && y <= shareStartY + AndroidUtilities.dp(32)) {
|
||||
sharePressed = true;
|
||||
result = true;
|
||||
invalidate();
|
||||
}
|
||||
if (result) {
|
||||
startCheckLongPress();
|
||||
|
@ -649,6 +666,21 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
|
|||
replyPressed = false;
|
||||
}
|
||||
}
|
||||
} else if (sharePressed) {
|
||||
if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||
sharePressed = false;
|
||||
playSoundEffect(SoundEffectConstants.CLICK);
|
||||
if (delegate != null) {
|
||||
delegate.didPressShare(this);
|
||||
}
|
||||
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
|
||||
sharePressed = false;
|
||||
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
if (!(x >= shareStartX && x <= shareStartX + AndroidUtilities.dp(40) && y >= shareStartY && y <= shareStartY + AndroidUtilities.dp(32))) {
|
||||
sharePressed = false;
|
||||
}
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -767,6 +799,11 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
|
|||
|
||||
onAfterBackgroundDraw(canvas);
|
||||
|
||||
if (drawShareButton) {
|
||||
ResourceLoader.shareDrawable[ApplicationLoader.isCustomTheme() ? 1 : 0][sharePressed ? 1 : 0].setBounds(shareStartX = currentBackgroundDrawable.getBounds().right + AndroidUtilities.dp(8), shareStartY = layoutHeight - AndroidUtilities.dp(41), currentBackgroundDrawable.getBounds().right + AndroidUtilities.dp(40), layoutHeight - AndroidUtilities.dp(9));
|
||||
ResourceLoader.shareDrawable[ApplicationLoader.isCustomTheme() ? 1 : 0][sharePressed ? 1 : 0].draw(canvas);
|
||||
}
|
||||
|
||||
if (drawName && nameLayout != null) {
|
||||
canvas.save();
|
||||
if (media) {
|
||||
|
|
|
@ -198,6 +198,9 @@ public class ChatContactCell extends ChatBaseCell {
|
|||
|
||||
String currentNameString = ContactsController.formatName(messageObject.messageOwner.media.first_name, messageObject.messageOwner.media.last_name);
|
||||
int nameWidth = Math.min((int) Math.ceil(namePaint.measureText(currentNameString)), maxWidth);
|
||||
if (maxWidth < 0) {
|
||||
maxWidth = AndroidUtilities.dp(100);
|
||||
}
|
||||
|
||||
CharSequence stringFinal = TextUtils.ellipsize(currentNameString.replace("\n", " "), namePaint, nameWidth, TextUtils.TruncateAt.END);
|
||||
nameLayout = new StaticLayout(stringFinal, namePaint, nameWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
||||
|
|
|
@ -498,7 +498,7 @@ public class ChatMediaCell extends ChatBaseCell {
|
|||
if (currentNameString == null || !currentNameString.equals(name)) {
|
||||
currentNameString = name;
|
||||
nameLayout = StaticLayoutEx.createStaticLayout(currentNameString, namePaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false, TextUtils.TruncateAt.END, maxWidth, 1);
|
||||
if (nameLayout.getLineCount() > 0) {
|
||||
if (nameLayout != null && nameLayout.getLineCount() > 0) {
|
||||
nameWidth = Math.min(maxWidth, (int) Math.ceil(nameLayout.getLineWidth(0)));
|
||||
nameOffsetX = (int) Math.ceil(-nameLayout.getLineLeft(0));
|
||||
} else {
|
||||
|
@ -746,14 +746,18 @@ public class ChatMediaCell extends ChatBaseCell {
|
|||
backgroundWidth += AndroidUtilities.dp(9);
|
||||
}
|
||||
if (messageObject.caption != null) {
|
||||
nameLayout = new StaticLayout(messageObject.caption, MessageObject.textPaint, photoWidth - AndroidUtilities.dp(10), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
||||
if (nameLayout.getLineCount() > 0) {
|
||||
captionHeight = nameLayout.getHeight();
|
||||
additionHeight += captionHeight + AndroidUtilities.dp(9);
|
||||
float lastLineWidth = nameLayout.getLineWidth(nameLayout.getLineCount() - 1) + nameLayout.getLineLeft(nameLayout.getLineCount() - 1);
|
||||
if (photoWidth - AndroidUtilities.dp(8) - lastLineWidth < timeWidthTotal) {
|
||||
additionHeight += AndroidUtilities.dp(14);
|
||||
try {
|
||||
nameLayout = new StaticLayout(messageObject.caption, MessageObject.textPaint, photoWidth - AndroidUtilities.dp(10), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
||||
if (nameLayout != null && nameLayout.getLineCount() > 0) {
|
||||
captionHeight = nameLayout.getHeight();
|
||||
additionHeight += captionHeight + AndroidUtilities.dp(9);
|
||||
float lastLineWidth = nameLayout.getLineWidth(nameLayout.getLineCount() - 1) + nameLayout.getLineLeft(nameLayout.getLineCount() - 1);
|
||||
if (photoWidth - AndroidUtilities.dp(8) - lastLineWidth < timeWidthTotal) {
|
||||
additionHeight += AndroidUtilities.dp(14);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -532,17 +532,18 @@ public class ChatMessageCell extends ChatBaseCell {
|
|||
}
|
||||
}
|
||||
|
||||
boolean authorIsRTL = false;
|
||||
if (webPage.author != null) {
|
||||
try {
|
||||
if (linkPreviewHeight != 0) {
|
||||
linkPreviewHeight += AndroidUtilities.dp(2);
|
||||
totalHeight += AndroidUtilities.dp(2);
|
||||
}
|
||||
int width = Math.min((int) Math.ceil(replyNamePaint.measureText(webPage.author)), linkPreviewMaxWidth);
|
||||
//int width = Math.min((int) Math.ceil(replyNamePaint.measureText(webPage.author)), linkPreviewMaxWidth);
|
||||
if (restLinesCount == 3 && (!isSmallImage || webPage.description == null)) {
|
||||
authorLayout = new StaticLayout(webPage.author, replyNamePaint, width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
||||
authorLayout = new StaticLayout(webPage.author, replyNamePaint, linkPreviewMaxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
||||
} else {
|
||||
authorLayout = generateStaticLayout(webPage.author, replyNamePaint, width, linkPreviewMaxWidth - AndroidUtilities.dp(48 + 2), restLinesCount, 1);
|
||||
authorLayout = generateStaticLayout(webPage.author, replyNamePaint, linkPreviewMaxWidth, linkPreviewMaxWidth - AndroidUtilities.dp(48 + 2), restLinesCount, 1);
|
||||
restLinesCount -= authorLayout.getLineCount();
|
||||
}
|
||||
int height = authorLayout.getLineBottom(authorLayout.getLineCount() - 1);
|
||||
|
@ -550,6 +551,13 @@ public class ChatMessageCell extends ChatBaseCell {
|
|||
totalHeight += height;
|
||||
int lineLeft = (int) authorLayout.getLineLeft(0);
|
||||
authorX = -lineLeft;
|
||||
int width;
|
||||
if (lineLeft != 0) {
|
||||
width = authorLayout.getWidth() - lineLeft;
|
||||
authorIsRTL = true;
|
||||
} else {
|
||||
width = (int) Math.ceil(authorLayout.getLineWidth(0));
|
||||
}
|
||||
maxChildWidth = Math.max(maxChildWidth, width + additinalWidth);
|
||||
maxWebWidth = Math.max(maxWebWidth, width + additinalWidth);
|
||||
} catch (Exception e) {
|
||||
|
@ -575,19 +583,31 @@ public class ChatMessageCell extends ChatBaseCell {
|
|||
int height = descriptionLayout.getLineBottom(descriptionLayout.getLineCount() - 1);
|
||||
linkPreviewHeight += height;
|
||||
totalHeight += height;
|
||||
|
||||
boolean hasRTL = false;
|
||||
for (int a = 0; a < descriptionLayout.getLineCount(); a++) {
|
||||
int lineLeft = (int) Math.ceil(descriptionLayout.getLineLeft(a));
|
||||
if (a == 0 && descriptionX == 0) {
|
||||
descriptionX = -lineLeft;
|
||||
} else {
|
||||
descriptionX = Math.max(descriptionX, -lineLeft);
|
||||
if (lineLeft != 0) {
|
||||
hasRTL = true;
|
||||
if (descriptionX == 0) {
|
||||
descriptionX = -lineLeft;
|
||||
} else {
|
||||
descriptionX = Math.max(descriptionX, -lineLeft);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int a = 0; a < descriptionLayout.getLineCount(); a++) {
|
||||
int lineLeft = (int) Math.ceil(descriptionLayout.getLineLeft(a));
|
||||
if (lineLeft == 0 && descriptionX != 0) {
|
||||
descriptionX = 0;
|
||||
}
|
||||
|
||||
int width;
|
||||
if (lineLeft != 0) {
|
||||
width = descriptionLayout.getWidth() - lineLeft;
|
||||
} else {
|
||||
width = (int) Math.ceil(descriptionLayout.getLineWidth(a));
|
||||
width = hasRTL ? descriptionLayout.getWidth() : (int) Math.ceil(descriptionLayout.getLineWidth(a));
|
||||
}
|
||||
if (a < restLines || lineLeft != 0 && isSmallImage) {
|
||||
width += AndroidUtilities.dp(48 + 2);
|
||||
|
@ -596,6 +616,9 @@ public class ChatMessageCell extends ChatBaseCell {
|
|||
if (titleIsRTL) {
|
||||
titleX += (width + additinalWidth - maxWebWidth);
|
||||
}
|
||||
if (authorIsRTL) {
|
||||
authorX += (width + additinalWidth - maxWebWidth);
|
||||
}
|
||||
maxWebWidth = width + additinalWidth;
|
||||
}
|
||||
maxChildWidth = Math.max(maxChildWidth, width + additinalWidth);
|
||||
|
|
|
@ -21,6 +21,7 @@ import android.view.MotionEvent;
|
|||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.PhoneFormat.PhoneFormat;
|
||||
import org.telegram.messenger.ChatObject;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.MessageObject;
|
||||
import org.telegram.messenger.UserObject;
|
||||
|
@ -40,7 +41,6 @@ public class DialogCell extends BaseCell {
|
|||
|
||||
private static TextPaint namePaint;
|
||||
private static TextPaint nameEncryptedPaint;
|
||||
private static TextPaint nameUnknownPaint;
|
||||
private static TextPaint messagePaint;
|
||||
private static TextPaint messagePrintingPaint;
|
||||
private static TextPaint timePaint;
|
||||
|
@ -55,6 +55,7 @@ public class DialogCell extends BaseCell {
|
|||
private static Drawable countDrawableGrey;
|
||||
private static Drawable groupDrawable;
|
||||
private static Drawable broadcastDrawable;
|
||||
private static Drawable botDrawable;
|
||||
private static Drawable muteDrawable;
|
||||
private static Drawable verifiedDrawable;
|
||||
|
||||
|
@ -87,6 +88,7 @@ public class DialogCell extends BaseCell {
|
|||
private boolean drawNameLock;
|
||||
private boolean drawNameGroup;
|
||||
private boolean drawNameBroadcast;
|
||||
private boolean drawNameBot;
|
||||
private int nameMuteLeft;
|
||||
private int nameLockLeft;
|
||||
private int nameLockTop;
|
||||
|
@ -136,11 +138,6 @@ public class DialogCell extends BaseCell {
|
|||
nameEncryptedPaint.setColor(0xff00a60e);
|
||||
nameEncryptedPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
|
||||
nameUnknownPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
|
||||
nameUnknownPaint.setTextSize(AndroidUtilities.dp(17));
|
||||
nameUnknownPaint.setColor(0xff4d83b3);
|
||||
nameUnknownPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
|
||||
messagePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
|
||||
messagePaint.setTextSize(AndroidUtilities.dp(16));
|
||||
messagePaint.setColor(0xff8f8f8f);
|
||||
|
@ -176,6 +173,7 @@ public class DialogCell extends BaseCell {
|
|||
broadcastDrawable = getResources().getDrawable(R.drawable.list_broadcast);
|
||||
muteDrawable = getResources().getDrawable(R.drawable.mute_grey);
|
||||
verifiedDrawable = getResources().getDrawable(R.drawable.check_list);
|
||||
botDrawable = getResources().getDrawable(R.drawable.bot_list);
|
||||
}
|
||||
|
||||
setBackgroundResource(R.drawable.list_selector);
|
||||
|
@ -264,6 +262,7 @@ public class DialogCell extends BaseCell {
|
|||
drawNameGroup = false;
|
||||
drawNameBroadcast = false;
|
||||
drawNameLock = false;
|
||||
drawNameBot = false;
|
||||
drawVerified = false;
|
||||
|
||||
if (encryptedChat != null) {
|
||||
|
@ -278,14 +277,14 @@ public class DialogCell extends BaseCell {
|
|||
}
|
||||
} else {
|
||||
if (chat != null) {
|
||||
if (chat.id < 0 || chat instanceof TLRPC.TL_channel || chat instanceof TLRPC.TL_channelForbidden) {
|
||||
if (chat.id < 0 || ChatObject.isChannel(chat) && !chat.megagroup) {
|
||||
drawNameBroadcast = true;
|
||||
nameLockTop = AndroidUtilities.dp(16.5f);
|
||||
} else {
|
||||
drawNameGroup = true;
|
||||
nameLockTop = AndroidUtilities.dp(17.5f);
|
||||
}
|
||||
drawVerified = (chat.flags & TLRPC.CHAT_FLAG_IS_VERIFIED) != 0;
|
||||
drawVerified = chat.verified;
|
||||
|
||||
if (!LocaleController.isRTL) {
|
||||
nameLockLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
|
||||
|
@ -300,6 +299,20 @@ public class DialogCell extends BaseCell {
|
|||
} else {
|
||||
nameLeft = AndroidUtilities.dp(14);
|
||||
}
|
||||
if (user != null) {
|
||||
if (user.bot) {
|
||||
drawNameBot = true;
|
||||
nameLockTop = AndroidUtilities.dp(16.5f);
|
||||
if (!LocaleController.isRTL) {
|
||||
nameLockLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
|
||||
nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline + 4) + botDrawable.getIntrinsicWidth();
|
||||
} else {
|
||||
nameLockLeft = getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline) - botDrawable.getIntrinsicWidth();
|
||||
nameLeft = AndroidUtilities.dp(14);
|
||||
}
|
||||
}
|
||||
drawVerified = user.verified;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -383,11 +396,11 @@ public class DialogCell extends BaseCell {
|
|||
mess = mess.substring(0, 150);
|
||||
}
|
||||
mess = mess.replace("\n", " ");
|
||||
messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("<c#ff4d83b3>%s:</c> <c#ff808080>%s</c>", name, mess), AndroidUtilities.FLAG_TAG_COLOR), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
|
||||
messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("<c#ff4d83b3>%s:</c> <c#ff808080>%s</c>", name.replace("\n", ""), mess), AndroidUtilities.FLAG_TAG_COLOR), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
|
||||
} else {
|
||||
if (message.messageOwner.media != null && !message.isMediaEmpty()) {
|
||||
currentMessagePaint = messagePrintingPaint;
|
||||
messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("<c#ff4d83b3>%s:</c> <c#ff4d83b3>%s</c>", name, message.messageText), AndroidUtilities.FLAG_TAG_COLOR), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
|
||||
messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("<c#ff4d83b3>%s:</c> <c#ff4d83b3>%s</c>", name.replace("\n", ""), message.messageText), AndroidUtilities.FLAG_TAG_COLOR), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
|
||||
} else {
|
||||
if (message.messageOwner.message != null) {
|
||||
String mess = message.messageOwner.message;
|
||||
|
@ -395,7 +408,7 @@ public class DialogCell extends BaseCell {
|
|||
mess = mess.substring(0, 150);
|
||||
}
|
||||
mess = mess.replace("\n", " ");
|
||||
messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("<c#ff4d83b3>%s:</c> <c#ff808080>%s</c>", name, mess), AndroidUtilities.FLAG_TAG_COLOR), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
|
||||
messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("<c#ff4d83b3>%s:</c> <c#ff808080>%s</c>", name.replace("\n", ""), mess), AndroidUtilities.FLAG_TAG_COLOR), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -468,7 +481,6 @@ public class DialogCell extends BaseCell {
|
|||
if (user.phone != null && user.phone.length() != 0) {
|
||||
nameString = PhoneFormat.getInstance().format("+" + user.phone);
|
||||
} else {
|
||||
currentNamePaint = nameUnknownPaint;
|
||||
nameString = UserObject.getUserName(user);
|
||||
}
|
||||
}
|
||||
|
@ -497,6 +509,8 @@ public class DialogCell extends BaseCell {
|
|||
nameWidth -= AndroidUtilities.dp(4) + groupDrawable.getIntrinsicWidth();
|
||||
} else if (drawNameBroadcast) {
|
||||
nameWidth -= AndroidUtilities.dp(4) + broadcastDrawable.getIntrinsicWidth();
|
||||
} else if (drawNameBot) {
|
||||
nameWidth -= AndroidUtilities.dp(4) + botDrawable.getIntrinsicWidth();
|
||||
}
|
||||
if (drawClock) {
|
||||
int w = clockDrawable.getIntrinsicWidth() + AndroidUtilities.dp(5);
|
||||
|
@ -678,7 +692,7 @@ public class DialogCell extends BaseCell {
|
|||
public void checkCurrentDialogIndex() {
|
||||
if (index < getDialogsArray().size()) {
|
||||
TLRPC.Dialog dialog = getDialogsArray().get(index);
|
||||
if (currentDialogId != dialog.id || message != null && message.getId() != dialog.top_message || unreadCount != dialog.unread_count) {
|
||||
if (currentDialogId != dialog.id || message != null && message.getId() != dialog.top_message || unreadCount != dialog.unread_count || message == null && MessagesController.getInstance().dialogMessage.get(dialog.id) != null) {
|
||||
currentDialogId = dialog.id;
|
||||
update(0);
|
||||
}
|
||||
|
@ -766,6 +780,12 @@ public class DialogCell extends BaseCell {
|
|||
} else {
|
||||
if (lower_id < 0) {
|
||||
chat = MessagesController.getInstance().getChat(-lower_id);
|
||||
if (!isDialogCell && chat != null && chat.migrated_to != null) {
|
||||
TLRPC.Chat chat2 = MessagesController.getInstance().getChat(chat.migrated_to.channel_id);
|
||||
if (chat2 != null) {
|
||||
chat = chat2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
user = MessagesController.getInstance().getUser(lower_id);
|
||||
}
|
||||
|
@ -819,6 +839,9 @@ public class DialogCell extends BaseCell {
|
|||
} else if (drawNameBroadcast) {
|
||||
setDrawableBounds(broadcastDrawable, nameLockLeft, nameLockTop);
|
||||
broadcastDrawable.draw(canvas);
|
||||
} else if (drawNameBot) {
|
||||
setDrawableBounds(botDrawable, nameLockLeft, nameLockTop);
|
||||
botDrawable.draw(canvas);
|
||||
}
|
||||
|
||||
if (nameLayout != null) {
|
||||
|
|
|
@ -15,6 +15,7 @@ import android.widget.FrameLayout;
|
|||
import android.widget.TextView;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
|
||||
public class DrawerActionCell extends FrameLayout {
|
||||
|
@ -42,7 +43,11 @@ public class DrawerActionCell extends FrameLayout {
|
|||
}
|
||||
|
||||
public void setTextAndIcon(String text, int resId) {
|
||||
textView.setText(text);
|
||||
textView.setCompoundDrawablesWithIntrinsicBounds(resId, 0, 0, 0);
|
||||
try {
|
||||
textView.setText(text);
|
||||
textView.setCompoundDrawablesWithIntrinsicBounds(resId, 0, 0, 0);
|
||||
} catch (Throwable e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,10 @@
|
|||
package org.telegram.ui.Cells;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SoundEffectConstants;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
|
@ -28,6 +30,13 @@ public class PhotoAttachPhotoCell extends FrameLayout {
|
|||
private FrameLayout checkFrame;
|
||||
private CheckBox checkBox;
|
||||
private boolean isLast;
|
||||
private boolean pressed;
|
||||
private static Rect rect = new Rect();
|
||||
private PhotoAttachPhotoCellDelegate delegate;
|
||||
|
||||
public interface PhotoAttachPhotoCellDelegate {
|
||||
void onCheckClick(PhotoAttachPhotoCell v);
|
||||
}
|
||||
|
||||
private MediaController.PhotoEntry photoEntry;
|
||||
|
||||
|
@ -36,13 +45,7 @@ public class PhotoAttachPhotoCell extends FrameLayout {
|
|||
|
||||
imageView = new BackupImageView(context);
|
||||
addView(imageView, LayoutHelper.createFrame(80, 80));
|
||||
checkFrame = new FrameLayout(context) {
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
getParent().requestDisallowInterceptTouchEvent(true);
|
||||
return super.onInterceptTouchEvent(ev);
|
||||
}
|
||||
};
|
||||
checkFrame = new FrameLayout(context);
|
||||
addView(checkFrame, LayoutHelper.createFrame(42, 42, Gravity.LEFT | Gravity.TOP, 38, 0, 0, 0));
|
||||
|
||||
checkBox = new CheckBox(context, R.drawable.checkbig);
|
||||
|
@ -72,6 +75,7 @@ public class PhotoAttachPhotoCell extends FrameLayout {
|
|||
}
|
||||
|
||||
public void setPhotoEntry(MediaController.PhotoEntry entry, boolean last) {
|
||||
pressed = false;
|
||||
photoEntry = entry;
|
||||
isLast = last;
|
||||
if (photoEntry.thumbPath != null) {
|
||||
|
@ -95,4 +99,43 @@ public class PhotoAttachPhotoCell extends FrameLayout {
|
|||
public void setOnCheckClickLisnener(OnClickListener onCheckClickLisnener) {
|
||||
checkFrame.setOnClickListener(onCheckClickLisnener);
|
||||
}
|
||||
|
||||
public void setDelegate(PhotoAttachPhotoCellDelegate delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
boolean result = false;
|
||||
|
||||
checkFrame.getHitRect(rect);
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
if (rect.contains((int) event.getX(), (int) event.getY())) {
|
||||
pressed = true;
|
||||
invalidate();
|
||||
result = true;
|
||||
}
|
||||
} else if (pressed) {
|
||||
if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||
getParent().requestDisallowInterceptTouchEvent(true);
|
||||
pressed = false;
|
||||
playSoundEffect(SoundEffectConstants.CLICK);
|
||||
delegate.onCheckClick(this);
|
||||
invalidate();
|
||||
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
|
||||
pressed = false;
|
||||
invalidate();
|
||||
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
if (!(rect.contains((int) event.getX(), (int) event.getY()))) {
|
||||
pressed = false;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!result) {
|
||||
result = super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,9 +41,11 @@ public class ProfileSearchCell extends BaseCell {
|
|||
private static TextPaint offlinePaint;
|
||||
private static TextPaint countPaint;
|
||||
private static Drawable lockDrawable;
|
||||
private static Drawable botDrawable;
|
||||
private static Drawable broadcastDrawable;
|
||||
private static Drawable groupDrawable;
|
||||
private static Drawable countDrawable;
|
||||
private static Drawable countDrawableGrey;
|
||||
private static Drawable checkDrawable;
|
||||
private static Paint linePaint;
|
||||
|
||||
|
@ -55,7 +57,7 @@ public class ProfileSearchCell extends BaseCell {
|
|||
private TLRPC.User user = null;
|
||||
private TLRPC.Chat chat = null;
|
||||
private TLRPC.EncryptedChat encryptedChat = null;
|
||||
long dialog_id;
|
||||
private long dialog_id;
|
||||
|
||||
private String lastName = null;
|
||||
private int lastStatus = 0;
|
||||
|
@ -70,6 +72,7 @@ public class ProfileSearchCell extends BaseCell {
|
|||
private boolean drawNameLock;
|
||||
private boolean drawNameBroadcast;
|
||||
private boolean drawNameGroup;
|
||||
private boolean drawNameBot;
|
||||
private int nameLockLeft;
|
||||
private int nameLockTop;
|
||||
|
||||
|
@ -119,7 +122,9 @@ public class ProfileSearchCell extends BaseCell {
|
|||
lockDrawable = getResources().getDrawable(R.drawable.list_secret);
|
||||
groupDrawable = getResources().getDrawable(R.drawable.list_group);
|
||||
countDrawable = getResources().getDrawable(R.drawable.dialogs_badge);
|
||||
countDrawableGrey = getResources().getDrawable(R.drawable.dialogs_badge2);
|
||||
checkDrawable = getResources().getDrawable(R.drawable.check_list);
|
||||
botDrawable = getResources().getDrawable(R.drawable.bot_list);
|
||||
}
|
||||
|
||||
avatarImage = new ImageReceiver(this);
|
||||
|
@ -188,6 +193,7 @@ public class ProfileSearchCell extends BaseCell {
|
|||
drawNameLock = false;
|
||||
drawNameGroup = false;
|
||||
drawCheck = false;
|
||||
drawNameBot = false;
|
||||
|
||||
if (encryptedChat != null) {
|
||||
drawNameLock = true;
|
||||
|
@ -208,7 +214,7 @@ public class ProfileSearchCell extends BaseCell {
|
|||
nameLockTop = AndroidUtilities.dp(28.5f);
|
||||
} else {
|
||||
dialog_id = -chat.id;
|
||||
if (ChatObject.isChannel(chat)) {
|
||||
if (ChatObject.isChannel(chat) && !chat.megagroup) {
|
||||
drawNameBroadcast = true;
|
||||
nameLockTop = AndroidUtilities.dp(28.5f);
|
||||
} else {
|
||||
|
@ -216,7 +222,7 @@ public class ProfileSearchCell extends BaseCell {
|
|||
nameLockTop = AndroidUtilities.dp(30);
|
||||
}
|
||||
}
|
||||
drawCheck = (chat.flags & TLRPC.CHAT_FLAG_IS_VERIFIED) != 0;
|
||||
drawCheck = chat.verified;
|
||||
if (!LocaleController.isRTL) {
|
||||
nameLockLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
|
||||
nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline + 4) + (drawNameGroup ? groupDrawable.getIntrinsicWidth() : broadcastDrawable.getIntrinsicWidth());
|
||||
|
@ -231,6 +237,20 @@ public class ProfileSearchCell extends BaseCell {
|
|||
} else {
|
||||
nameLeft = AndroidUtilities.dp(11);
|
||||
}
|
||||
if (user.bot) {
|
||||
drawNameBot = true;
|
||||
if (!LocaleController.isRTL) {
|
||||
nameLockLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
|
||||
nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline + 4) + botDrawable.getIntrinsicWidth();
|
||||
} else {
|
||||
nameLockLeft = getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline + 2) - botDrawable.getIntrinsicWidth();
|
||||
nameLeft = AndroidUtilities.dp(11);
|
||||
}
|
||||
nameLockTop = AndroidUtilities.dp(16.5f);
|
||||
} else {
|
||||
nameLockTop = AndroidUtilities.dp(17);
|
||||
}
|
||||
drawCheck = user.verified;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,6 +291,8 @@ public class ProfileSearchCell extends BaseCell {
|
|||
nameWidth -= AndroidUtilities.dp(6) + broadcastDrawable.getIntrinsicWidth();
|
||||
} else if (drawNameGroup) {
|
||||
nameWidth -= AndroidUtilities.dp(6) + groupDrawable.getIntrinsicWidth();
|
||||
} else if (drawNameBot) {
|
||||
nameWidth -= AndroidUtilities.dp(6) + botDrawable.getIntrinsicWidth();
|
||||
}
|
||||
|
||||
if (drawCount) {
|
||||
|
@ -313,7 +335,7 @@ public class ProfileSearchCell extends BaseCell {
|
|||
if (subLabel != null) {
|
||||
onlineString = subLabel;
|
||||
} else if (user != null) {
|
||||
if ((user.flags & TLRPC.USER_FLAG_BOT) != 0) {
|
||||
if (user.bot) {
|
||||
onlineString = LocaleController.getString("Bot", R.string.Bot);
|
||||
} else {
|
||||
onlineString = LocaleController.formatUserStatus(user);
|
||||
|
@ -327,7 +349,7 @@ public class ProfileSearchCell extends BaseCell {
|
|||
CharSequence onlineStringFinal = TextUtils.ellipsize(onlineString, currentOnlinePaint, onlineWidth - AndroidUtilities.dp(12), TextUtils.TruncateAt.END);
|
||||
onlineLayout = new StaticLayout(onlineStringFinal, currentOnlinePaint, onlineWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
||||
nameTop = AndroidUtilities.dp(13);
|
||||
if (subLabel != null) {
|
||||
if (subLabel != null && !drawNameBot) {
|
||||
nameLockTop -= AndroidUtilities.dp(12);
|
||||
}
|
||||
} else {
|
||||
|
@ -492,6 +514,9 @@ public class ProfileSearchCell extends BaseCell {
|
|||
} else if (drawNameBroadcast) {
|
||||
setDrawableBounds(broadcastDrawable, nameLockLeft, nameLockTop);
|
||||
broadcastDrawable.draw(canvas);
|
||||
} else if (drawNameBot) {
|
||||
setDrawableBounds(botDrawable, nameLockLeft, nameLockTop);
|
||||
botDrawable.draw(canvas);
|
||||
}
|
||||
|
||||
if (nameLayout != null) {
|
||||
|
@ -517,8 +542,13 @@ public class ProfileSearchCell extends BaseCell {
|
|||
}
|
||||
|
||||
if (countLayout != null) {
|
||||
setDrawableBounds(countDrawable, countLeft - AndroidUtilities.dp(5.5f), countTop, countWidth + AndroidUtilities.dp(11), countDrawable.getIntrinsicHeight());
|
||||
countDrawable.draw(canvas);
|
||||
if (MessagesController.getInstance().isDialogMuted(dialog_id)) {
|
||||
setDrawableBounds(countDrawableGrey, countLeft - AndroidUtilities.dp(5.5f), countTop, countWidth + AndroidUtilities.dp(11), countDrawableGrey.getIntrinsicHeight());
|
||||
countDrawableGrey.draw(canvas);
|
||||
} else {
|
||||
setDrawableBounds(countDrawable, countLeft - AndroidUtilities.dp(5.5f), countTop, countWidth + AndroidUtilities.dp(11), countDrawable.getIntrinsicHeight());
|
||||
countDrawable.draw(canvas);
|
||||
}
|
||||
canvas.save();
|
||||
canvas.translate(countLeft, countTop + AndroidUtilities.dp(4));
|
||||
countLayout.draw(canvas);
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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-2015.
|
||||
*/
|
||||
|
||||
package org.telegram.ui.Cells;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.ContactsController;
|
||||
import org.telegram.messenger.MessagesController;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
import org.telegram.ui.Components.AvatarDrawable;
|
||||
import org.telegram.ui.Components.BackupImageView;
|
||||
import org.telegram.ui.Components.CheckBox;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
|
||||
public class ShareDialogCell extends FrameLayout {
|
||||
|
||||
private BackupImageView imageView;
|
||||
private TextView nameTextView;
|
||||
private CheckBox checkBox;
|
||||
private AvatarDrawable avatarDrawable = new AvatarDrawable();
|
||||
|
||||
public ShareDialogCell(Context context) {
|
||||
super(context);
|
||||
|
||||
imageView = new BackupImageView(context);
|
||||
imageView.setRoundRadius(AndroidUtilities.dp(27));
|
||||
addView(imageView, LayoutHelper.createFrame(54, 54, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 7, 0, 0));
|
||||
|
||||
nameTextView = new TextView(context);
|
||||
nameTextView.setTextColor(0xff212121);
|
||||
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
|
||||
nameTextView.setMaxLines(2);
|
||||
nameTextView.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL);
|
||||
nameTextView.setLines(2);
|
||||
nameTextView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 6, 64, 6, 0));
|
||||
|
||||
checkBox = new CheckBox(context, R.drawable.round_check2);
|
||||
checkBox.setSize(24);
|
||||
checkBox.setCheckOffset(AndroidUtilities.dp(1));
|
||||
checkBox.setVisibility(VISIBLE);
|
||||
checkBox.setColor(0xff3ec1f9);
|
||||
addView(checkBox, LayoutHelper.createFrame(24, 24, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 17, 39, 0, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(100), MeasureSpec.EXACTLY));
|
||||
}
|
||||
|
||||
public void setDialog(TLRPC.Dialog dialog, boolean checked, CharSequence name) {
|
||||
int lower_id = (int) dialog.id;
|
||||
TLRPC.FileLocation photo = null;
|
||||
if (lower_id > 0) {
|
||||
TLRPC.User user = MessagesController.getInstance().getUser(lower_id);
|
||||
if (name != null) {
|
||||
nameTextView.setText(name);
|
||||
} else if (user != null) {
|
||||
nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name));
|
||||
} else {
|
||||
nameTextView.setText("");
|
||||
}
|
||||
avatarDrawable.setInfo(user);
|
||||
if (user != null && user.photo != null) {
|
||||
photo = user.photo.photo_small;
|
||||
}
|
||||
} else {
|
||||
TLRPC.Chat chat = MessagesController.getInstance().getChat(-lower_id);
|
||||
if (name != null) {
|
||||
nameTextView.setText(name);
|
||||
} else if (chat != null) {
|
||||
nameTextView.setText(chat.title);
|
||||
} else {
|
||||
nameTextView.setText("");
|
||||
}
|
||||
avatarDrawable.setInfo(chat);
|
||||
if (chat != null && chat.photo != null) {
|
||||
photo = chat.photo.photo_small;
|
||||
}
|
||||
}
|
||||
imageView.setImage(photo, "50_50", avatarDrawable);
|
||||
checkBox.setChecked(checked, false);
|
||||
}
|
||||
|
||||
public void setChecked(boolean checked, boolean animated) {
|
||||
checkBox.setChecked(checked, animated);
|
||||
}
|
||||
}
|
|
@ -220,7 +220,7 @@ public class SharedDocumentCell extends FrameLayout implements MediaController.F
|
|||
thumbImageView.setImage(document.messageOwner.media.document.thumb.location, "40_40", (Drawable) null);
|
||||
}
|
||||
long date = (long) document.messageOwner.date * 1000;
|
||||
dateTextView.setText(String.format("%s, %s", AndroidUtilities.formatFileSize(document.messageOwner.media.document.size), LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, LocaleController.formatterYear.format(new Date(date)), LocaleController.formatterDay.format(new Date(date)))));
|
||||
dateTextView.setText(String.format("%s, %s", AndroidUtilities.formatFileSize(document.messageOwner.media.document.size), LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, LocaleController.getInstance().formatterYear.format(new Date(date)), LocaleController.getInstance().formatterDay.format(new Date(date)))));
|
||||
} else {
|
||||
nameTextView.setText("");
|
||||
extTextView.setText("");
|
||||
|
|
|
@ -98,7 +98,7 @@ public class StickerSetCell extends FrameLayout {
|
|||
stickersSet = set;
|
||||
|
||||
textView.setText(stickersSet.set.title);
|
||||
if ((stickersSet.set.flags & 2) != 0) {
|
||||
if (stickersSet.set.disabled) {
|
||||
ViewProxy.setAlpha(textView, 0.5f);
|
||||
ViewProxy.setAlpha(valueTextView, 0.5f);
|
||||
ViewProxy.setAlpha(imageView, 0.5f);
|
||||
|
|
|
@ -28,8 +28,6 @@ public class TextCell extends FrameLayout {
|
|||
private ImageView imageView;
|
||||
private ImageView valueImageView;
|
||||
|
||||
private boolean multiline;
|
||||
|
||||
public TextCell(Context context) {
|
||||
super(context);
|
||||
|
||||
|
@ -63,7 +61,7 @@ public class TextCell extends FrameLayout {
|
|||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), multiline ? MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED) : MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(48), MeasureSpec.EXACTLY));
|
||||
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(48), MeasureSpec.EXACTLY));
|
||||
}
|
||||
|
||||
public void setTextColor(int color) {
|
||||
|
@ -83,27 +81,7 @@ public class TextCell extends FrameLayout {
|
|||
imageView.setVisibility(VISIBLE);
|
||||
valueTextView.setVisibility(INVISIBLE);
|
||||
valueImageView.setVisibility(INVISIBLE);
|
||||
if (multiline) {
|
||||
imageView.setPadding(0, 0, 0, 0);
|
||||
} else {
|
||||
imageView.setPadding(0, AndroidUtilities.dp(7), 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void setMultiline(boolean value) {
|
||||
if (multiline == value) {
|
||||
return;
|
||||
}
|
||||
multiline = value;
|
||||
if (value) {
|
||||
textView.setSingleLine(false);
|
||||
textView.setPadding(0, AndroidUtilities.dp(6), 0, AndroidUtilities.dp(6));
|
||||
} else {
|
||||
textView.setLines(1);
|
||||
textView.setMaxLines(1);
|
||||
textView.setSingleLine(true);
|
||||
}
|
||||
requestLayout();
|
||||
imageView.setPadding(0, AndroidUtilities.dp(7), 0, 0);
|
||||
}
|
||||
|
||||
public void setTextAndValue(String text, String value) {
|
||||
|
@ -120,10 +98,6 @@ public class TextCell extends FrameLayout {
|
|||
valueImageView.setImageDrawable(drawable);
|
||||
valueTextView.setVisibility(INVISIBLE);
|
||||
imageView.setVisibility(INVISIBLE);
|
||||
if (multiline) {
|
||||
imageView.setPadding(0, 0, 0, 0);
|
||||
} else {
|
||||
imageView.setPadding(0, AndroidUtilities.dp(7), 0, 0);
|
||||
}
|
||||
imageView.setPadding(0, AndroidUtilities.dp(7), 0, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.telegram.messenger.UserConfig;
|
|||
import org.telegram.ui.Components.AvatarDrawable;
|
||||
import org.telegram.ui.Components.BackupImageView;
|
||||
import org.telegram.ui.Components.CheckBox;
|
||||
import org.telegram.ui.Components.CheckBoxSquare;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
import org.telegram.ui.Components.SimpleTextView;
|
||||
|
||||
|
@ -35,6 +36,7 @@ public class UserCell extends FrameLayout {
|
|||
private SimpleTextView statusTextView;
|
||||
private ImageView imageView;
|
||||
private CheckBox checkBox;
|
||||
private CheckBoxSquare checkBoxBig;
|
||||
|
||||
private AvatarDrawable avatarDrawable;
|
||||
private TLObject currentObject = null;
|
||||
|
@ -50,7 +52,7 @@ public class UserCell extends FrameLayout {
|
|||
private int statusColor = 0xffa8a8a8;
|
||||
private int statusOnlineColor = 0xff3b84c0;
|
||||
|
||||
public UserCell(Context context, int padding) {
|
||||
public UserCell(Context context, int padding, int checkbox) {
|
||||
super(context);
|
||||
|
||||
avatarDrawable = new AvatarDrawable();
|
||||
|
@ -75,9 +77,14 @@ public class UserCell extends FrameLayout {
|
|||
imageView.setVisibility(GONE);
|
||||
addView(imageView, LayoutHelper.createFrame(LayoutParams.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL, LocaleController.isRTL ? 0 : 16, 0, LocaleController.isRTL ? 16 : 0, 0));
|
||||
|
||||
checkBox = new CheckBox(context, R.drawable.round_check2);
|
||||
checkBox.setVisibility(INVISIBLE);
|
||||
addView(checkBox, LayoutHelper.createFrame(22, 22, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 37 + padding, 38, LocaleController.isRTL ? 37 + padding : 0, 0));
|
||||
if (checkbox == 2) {
|
||||
checkBoxBig = new CheckBoxSquare(context);
|
||||
addView(checkBoxBig, LayoutHelper.createFrame(18, 18, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.CENTER_VERTICAL, LocaleController.isRTL ? 19 : 0, 0, LocaleController.isRTL ? 0 : 19, 0));
|
||||
} else if (checkbox == 1) {
|
||||
checkBox = new CheckBox(context, R.drawable.round_check2);
|
||||
checkBox.setVisibility(INVISIBLE);
|
||||
addView(checkBox, LayoutHelper.createFrame(22, 22, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 37 + padding, 38, LocaleController.isRTL ? 37 + padding : 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
public void setData(TLObject user, CharSequence name, CharSequence status, int resId) {
|
||||
|
@ -98,10 +105,23 @@ public class UserCell extends FrameLayout {
|
|||
}
|
||||
|
||||
public void setChecked(boolean checked, boolean animated) {
|
||||
if (checkBox.getVisibility() != VISIBLE) {
|
||||
checkBox.setVisibility(VISIBLE);
|
||||
if (checkBox != null) {
|
||||
if (checkBox.getVisibility() != VISIBLE) {
|
||||
checkBox.setVisibility(VISIBLE);
|
||||
}
|
||||
checkBox.setChecked(checked, animated);
|
||||
} else if (checkBoxBig != null) {
|
||||
if (checkBoxBig.getVisibility() != VISIBLE) {
|
||||
checkBoxBig.setVisibility(VISIBLE);
|
||||
}
|
||||
checkBoxBig.setChecked(checked, animated);
|
||||
}
|
||||
}
|
||||
|
||||
public void setCheckDisabled(boolean disabled) {
|
||||
if (checkBoxBig != null) {
|
||||
checkBoxBig.setDisabled(disabled);
|
||||
}
|
||||
checkBox.setChecked(checked, animated);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -191,9 +211,9 @@ public class UserCell extends FrameLayout {
|
|||
statusTextView.setTextColor(statusColor);
|
||||
statusTextView.setText(currrntStatus);
|
||||
} else if (currentUser != null) {
|
||||
if ((currentUser.flags & TLRPC.USER_FLAG_BOT) != 0) {
|
||||
if (currentUser.bot) {
|
||||
statusTextView.setTextColor(statusColor);
|
||||
if ((currentUser.flags & TLRPC.USER_FLAG_BOT_READING_HISTORY) != 0) {
|
||||
if (currentUser.bot_chat_history) {
|
||||
statusTextView.setText(LocaleController.getString("BotStatusRead", R.string.BotStatusRead));
|
||||
} else {
|
||||
statusTextView.setText(LocaleController.getString("BotStatusCantRead", R.string.BotStatusCantRead));
|
||||
|
|
|
@ -139,8 +139,15 @@ public class ChangeChatNameActivity extends BaseFragment {
|
|||
@Override
|
||||
public void onTransitionAnimationEnd(boolean isOpen, boolean backward) {
|
||||
if (isOpen) {
|
||||
firstNameField.requestFocus();
|
||||
AndroidUtilities.showKeyboard(firstNameField);
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (firstNameField != null) {
|
||||
firstNameField.requestFocus();
|
||||
AndroidUtilities.showKeyboard(firstNameField);
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -187,8 +187,15 @@ public class ChangeNameActivity extends BaseFragment {
|
|||
@Override
|
||||
public void onTransitionAnimationEnd(boolean isOpen, boolean backward) {
|
||||
if (isOpen) {
|
||||
firstNameField.requestFocus();
|
||||
AndroidUtilities.showKeyboard(firstNameField);
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (firstNameField != null) {
|
||||
firstNameField.requestFocus();
|
||||
AndroidUtilities.showKeyboard(firstNameField);
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ import org.telegram.messenger.AnimationCompat.AnimatorListenerAdapterProxy;
|
|||
import org.telegram.messenger.AnimationCompat.AnimatorSetProxy;
|
||||
import org.telegram.messenger.AnimationCompat.ObjectAnimatorProxy;
|
||||
import org.telegram.messenger.AnimationCompat.ViewProxy;
|
||||
import org.telegram.ui.Components.HintEditText;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
import org.telegram.ui.Components.SlideView;
|
||||
import org.telegram.ui.Components.TypefaceSpan;
|
||||
|
@ -259,7 +260,7 @@ public class ChangePhoneActivity extends BaseFragment {
|
|||
public class PhoneView extends SlideView implements AdapterView.OnItemSelectedListener {
|
||||
|
||||
private EditText codeField;
|
||||
private EditText phoneField;
|
||||
private HintEditText phoneField;
|
||||
private TextView countryButton;
|
||||
|
||||
private int countryState = 0;
|
||||
|
@ -267,6 +268,7 @@ public class ChangePhoneActivity extends BaseFragment {
|
|||
private ArrayList<String> countriesArray = new ArrayList<>();
|
||||
private HashMap<String, String> countriesMap = new HashMap<>();
|
||||
private HashMap<String, String> codesMap = new HashMap<>();
|
||||
private HashMap<String, String> phoneFormatMap = new HashMap<>();
|
||||
|
||||
private boolean ignoreSelection = false;
|
||||
private boolean ignoreOnTextChange = false;
|
||||
|
@ -287,14 +289,7 @@ public class ChangePhoneActivity extends BaseFragment {
|
|||
countryButton.setEllipsize(TextUtils.TruncateAt.END);
|
||||
countryButton.setGravity(Gravity.LEFT | Gravity.CENTER_HORIZONTAL);
|
||||
countryButton.setBackgroundResource(R.drawable.spinner_states);
|
||||
addView(countryButton);
|
||||
LayoutParams layoutParams = (LayoutParams) countryButton.getLayoutParams();
|
||||
layoutParams.width = LayoutHelper.MATCH_PARENT;
|
||||
layoutParams.height = AndroidUtilities.dp(36);
|
||||
layoutParams.leftMargin = AndroidUtilities.dp(20);
|
||||
layoutParams.rightMargin = AndroidUtilities.dp(20);
|
||||
layoutParams.bottomMargin = AndroidUtilities.dp(14);
|
||||
countryButton.setLayoutParams(layoutParams);
|
||||
addView(countryButton, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 36, 20, 0, 20, 14));
|
||||
countryButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
|
@ -303,7 +298,14 @@ public class ChangePhoneActivity extends BaseFragment {
|
|||
@Override
|
||||
public void didSelectCountry(String name) {
|
||||
selectCountry(name);
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
AndroidUtilities.showKeyboard(phoneField);
|
||||
}
|
||||
}, 300);
|
||||
phoneField.requestFocus();
|
||||
phoneField.setSelection(phoneField.length());
|
||||
}
|
||||
});
|
||||
presentFragment(fragment);
|
||||
|
@ -313,34 +315,17 @@ public class ChangePhoneActivity extends BaseFragment {
|
|||
View view = new View(context);
|
||||
view.setPadding(AndroidUtilities.dp(12), 0, AndroidUtilities.dp(12), 0);
|
||||
view.setBackgroundColor(0xffdbdbdb);
|
||||
addView(view);
|
||||
layoutParams = (LayoutParams) view.getLayoutParams();
|
||||
layoutParams.width = LayoutHelper.MATCH_PARENT;
|
||||
layoutParams.height = 1;
|
||||
layoutParams.leftMargin = AndroidUtilities.dp(24);
|
||||
layoutParams.rightMargin = AndroidUtilities.dp(24);
|
||||
layoutParams.topMargin = AndroidUtilities.dp(-17.5f);
|
||||
view.setLayoutParams(layoutParams);
|
||||
addView(view, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 1, 24, -17.5f, 24, 0));
|
||||
|
||||
LinearLayout linearLayout = new LinearLayout(context);
|
||||
linearLayout.setOrientation(HORIZONTAL);
|
||||
addView(linearLayout);
|
||||
layoutParams = (LayoutParams) linearLayout.getLayoutParams();
|
||||
layoutParams.width = LayoutHelper.MATCH_PARENT;
|
||||
layoutParams.height = LayoutHelper.WRAP_CONTENT;
|
||||
layoutParams.topMargin = AndroidUtilities.dp(20);
|
||||
linearLayout.setLayoutParams(layoutParams);
|
||||
addView(linearLayout, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 20, 0, 0));
|
||||
|
||||
TextView textView = new TextView(context);
|
||||
textView.setText("+");
|
||||
textView.setTextColor(0xff212121);
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18);
|
||||
linearLayout.addView(textView);
|
||||
layoutParams = (LayoutParams) textView.getLayoutParams();
|
||||
layoutParams.width = LayoutHelper.WRAP_CONTENT;
|
||||
layoutParams.height = LayoutHelper.WRAP_CONTENT;
|
||||
layoutParams.leftMargin = AndroidUtilities.dp(24);
|
||||
textView.setLayoutParams(layoutParams);
|
||||
linearLayout.addView(textView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, 24, 0, 0, 0));
|
||||
|
||||
codeField = new EditText(context);
|
||||
codeField.setInputType(InputType.TYPE_CLASS_PHONE);
|
||||
|
@ -352,15 +337,9 @@ public class ChangePhoneActivity extends BaseFragment {
|
|||
codeField.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
|
||||
codeField.setImeOptions(EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
|
||||
InputFilter[] inputFilters = new InputFilter[1];
|
||||
inputFilters[0] = new InputFilter.LengthFilter(4);
|
||||
inputFilters[0] = new InputFilter.LengthFilter(5);
|
||||
codeField.setFilters(inputFilters);
|
||||
linearLayout.addView(codeField);
|
||||
layoutParams = (LayoutParams) codeField.getLayoutParams();
|
||||
layoutParams.width = AndroidUtilities.dp(55);
|
||||
layoutParams.height = AndroidUtilities.dp(36);
|
||||
layoutParams.rightMargin = AndroidUtilities.dp(16);
|
||||
layoutParams.leftMargin = AndroidUtilities.dp(-9);
|
||||
codeField.setLayoutParams(layoutParams);
|
||||
linearLayout.addView(codeField, LayoutHelper.createLinear(55, 36, -9, 0, 16, 0));
|
||||
codeField.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
|
||||
|
@ -383,26 +362,57 @@ public class ChangePhoneActivity extends BaseFragment {
|
|||
codeField.setText(text);
|
||||
if (text.length() == 0) {
|
||||
countryButton.setText(LocaleController.getString("ChooseCountry", R.string.ChooseCountry));
|
||||
phoneField.setHintText(null);
|
||||
countryState = 1;
|
||||
} else {
|
||||
String country = codesMap.get(text);
|
||||
String country;
|
||||
boolean ok = false;
|
||||
String textToSet = null;
|
||||
if (text.length() > 4) {
|
||||
ignoreOnTextChange = true;
|
||||
for (int a = 4; a >= 1; a--) {
|
||||
String sub = text.substring(0, a);
|
||||
country = codesMap.get(sub);
|
||||
if (country != null) {
|
||||
ok = true;
|
||||
textToSet = text.substring(a, text.length()) + phoneField.getText().toString();
|
||||
codeField.setText(text = sub);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
ignoreOnTextChange = true;
|
||||
textToSet = text.substring(1, text.length()) + phoneField.getText().toString();
|
||||
codeField.setText(text = text.substring(0, 1));
|
||||
}
|
||||
}
|
||||
country = codesMap.get(text);
|
||||
if (country != null) {
|
||||
int index = countriesArray.indexOf(country);
|
||||
if (index != -1) {
|
||||
ignoreSelection = true;
|
||||
countryButton.setText(countriesArray.get(index));
|
||||
|
||||
updatePhoneField();
|
||||
String hint = phoneFormatMap.get(text);
|
||||
phoneField.setHintText(hint != null ? hint.replace('X', '–') : null);
|
||||
countryState = 0;
|
||||
} else {
|
||||
countryButton.setText(LocaleController.getString("WrongCountry", R.string.WrongCountry));
|
||||
phoneField.setHintText(null);
|
||||
countryState = 2;
|
||||
}
|
||||
} else {
|
||||
countryButton.setText(LocaleController.getString("WrongCountry", R.string.WrongCountry));
|
||||
phoneField.setHintText(null);
|
||||
countryState = 2;
|
||||
}
|
||||
codeField.setSelection(codeField.getText().length());
|
||||
if (!ok) {
|
||||
codeField.setSelection(codeField.getText().length());
|
||||
}
|
||||
if (textToSet != null) {
|
||||
phoneField.requestFocus();
|
||||
phoneField.setText(textToSet);
|
||||
phoneField.setSelection(phoneField.length());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -411,13 +421,14 @@ public class ChangePhoneActivity extends BaseFragment {
|
|||
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
|
||||
if (i == EditorInfo.IME_ACTION_NEXT) {
|
||||
phoneField.requestFocus();
|
||||
phoneField.setSelection(phoneField.length());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
phoneField = new EditText(context);
|
||||
phoneField = new HintEditText(context);
|
||||
phoneField.setInputType(InputType.TYPE_CLASS_PHONE);
|
||||
phoneField.setTextColor(0xff212121);
|
||||
phoneField.setHintTextColor(0xff979797);
|
||||
|
@ -427,43 +438,25 @@ public class ChangePhoneActivity extends BaseFragment {
|
|||
phoneField.setMaxLines(1);
|
||||
phoneField.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
|
||||
phoneField.setImeOptions(EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
|
||||
linearLayout.addView(phoneField);
|
||||
layoutParams = (LayoutParams) phoneField.getLayoutParams();
|
||||
layoutParams.width = LayoutHelper.MATCH_PARENT;
|
||||
layoutParams.height = AndroidUtilities.dp(36);
|
||||
layoutParams.rightMargin = AndroidUtilities.dp(24);
|
||||
phoneField.setLayoutParams(layoutParams);
|
||||
linearLayout.addView(phoneField, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 36, 0, 0, 24, 0));
|
||||
phoneField.addTextChangedListener(new TextWatcher() {
|
||||
|
||||
private int characterAction = -1;
|
||||
private int actionPosition;
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
if (ignoreOnPhoneChange) {
|
||||
return;
|
||||
}
|
||||
if (count == 1 && after == 0 && s.length() > 1) {
|
||||
String phoneChars = "0123456789";
|
||||
String str = s.toString();
|
||||
String substr = str.substring(start, start + 1);
|
||||
if (!phoneChars.contains(substr)) {
|
||||
ignoreOnPhoneChange = true;
|
||||
StringBuilder builder = new StringBuilder(str);
|
||||
int toDelete = 0;
|
||||
for (int a = start; a >= 0; a--) {
|
||||
substr = str.substring(a, a + 1);
|
||||
if(phoneChars.contains(substr)) {
|
||||
break;
|
||||
}
|
||||
toDelete++;
|
||||
}
|
||||
builder.delete(Math.max(0, start - toDelete), start + 1);
|
||||
str = builder.toString();
|
||||
if (PhoneFormat.strip(str).length() == 0) {
|
||||
phoneField.setText("");
|
||||
} else {
|
||||
phoneField.setText(str);
|
||||
updatePhoneField();
|
||||
}
|
||||
ignoreOnPhoneChange = false;
|
||||
if (count == 0 && after == 1) {
|
||||
characterAction = 1;
|
||||
} else if (count == 1 && after == 0) {
|
||||
if (s.charAt(start) == ' ' && start > 0) {
|
||||
characterAction = 3;
|
||||
actionPosition = start - 1;
|
||||
} else {
|
||||
characterAction = 2;
|
||||
}
|
||||
} else {
|
||||
characterAction = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -477,7 +470,47 @@ public class ChangePhoneActivity extends BaseFragment {
|
|||
if (ignoreOnPhoneChange) {
|
||||
return;
|
||||
}
|
||||
updatePhoneField();
|
||||
int start = phoneField.getSelectionStart();
|
||||
String phoneChars = "0123456789";
|
||||
String str = phoneField.getText().toString();
|
||||
if (characterAction == 3) {
|
||||
str = str.substring(0, actionPosition) + str.substring(actionPosition + 1, str.length());
|
||||
start--;
|
||||
}
|
||||
StringBuilder builder = new StringBuilder(str.length());
|
||||
for (int a = 0; a < str.length(); a++) {
|
||||
String ch = str.substring(a, a + 1);
|
||||
if (phoneChars.contains(ch)) {
|
||||
builder.append(ch);
|
||||
}
|
||||
}
|
||||
ignoreOnPhoneChange = true;
|
||||
String hint = phoneField.getHintText();
|
||||
if (hint != null) {
|
||||
for (int a = 0; a < builder.length(); a++) {
|
||||
if (a < hint.length()) {
|
||||
if (hint.charAt(a) == ' ') {
|
||||
builder.insert(a, ' ');
|
||||
a++;
|
||||
if (start == a && characterAction != 2 && characterAction != 3) {
|
||||
start++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
builder.insert(a, ' ');
|
||||
if (start == a + 1 && characterAction != 2 && characterAction != 3) {
|
||||
start++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
phoneField.setText(builder);
|
||||
if (start >= 0) {
|
||||
phoneField.setSelection(start <= phoneField.length() ? start : phoneField.length());
|
||||
}
|
||||
phoneField.onTextChange();
|
||||
ignoreOnPhoneChange = false;
|
||||
}
|
||||
});
|
||||
phoneField.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
|
@ -497,16 +530,7 @@ public class ChangePhoneActivity extends BaseFragment {
|
|||
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
textView.setGravity(Gravity.LEFT);
|
||||
textView.setLineSpacing(AndroidUtilities.dp(2), 1.0f);
|
||||
addView(textView);
|
||||
layoutParams = (LayoutParams) textView.getLayoutParams();
|
||||
layoutParams.width = LayoutHelper.WRAP_CONTENT;
|
||||
layoutParams.height = LayoutHelper.WRAP_CONTENT;
|
||||
layoutParams.leftMargin = AndroidUtilities.dp(24);
|
||||
layoutParams.rightMargin = AndroidUtilities.dp(24);
|
||||
layoutParams.topMargin = AndroidUtilities.dp(28);
|
||||
layoutParams.bottomMargin = AndroidUtilities.dp(10);
|
||||
layoutParams.gravity = Gravity.LEFT;
|
||||
textView.setLayoutParams(layoutParams);
|
||||
addView(textView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT, 24, 28, 24, 10));
|
||||
|
||||
HashMap<String, String> languageMap = new HashMap<>();
|
||||
try {
|
||||
|
@ -517,6 +541,9 @@ public class ChangePhoneActivity extends BaseFragment {
|
|||
countriesArray.add(0, args[2]);
|
||||
countriesMap.put(args[2], args[0]);
|
||||
codesMap.put(args[0], args[2]);
|
||||
if (args.length > 3) {
|
||||
phoneFormatMap.put(args[0], args[3]);
|
||||
}
|
||||
languageMap.put(args[1], args[2]);
|
||||
}
|
||||
reader.close();
|
||||
|
@ -554,12 +581,14 @@ public class ChangePhoneActivity extends BaseFragment {
|
|||
}
|
||||
if (codeField.length() == 0) {
|
||||
countryButton.setText(LocaleController.getString("ChooseCountry", R.string.ChooseCountry));
|
||||
phoneField.setHintText(null);
|
||||
countryState = 1;
|
||||
}
|
||||
|
||||
if (codeField.length() != 0) {
|
||||
AndroidUtilities.showKeyboard(phoneField);
|
||||
phoneField.requestFocus();
|
||||
phoneField.setSelection(phoneField.length());
|
||||
} else {
|
||||
AndroidUtilities.showKeyboard(codeField);
|
||||
codeField.requestFocus();
|
||||
|
@ -570,39 +599,15 @@ public class ChangePhoneActivity extends BaseFragment {
|
|||
int index = countriesArray.indexOf(name);
|
||||
if (index != -1) {
|
||||
ignoreOnTextChange = true;
|
||||
codeField.setText(countriesMap.get(name));
|
||||
String code = countriesMap.get(name);
|
||||
codeField.setText(code);
|
||||
countryButton.setText(name);
|
||||
String hint = phoneFormatMap.get(code);
|
||||
phoneField.setHintText(hint != null ? hint.replace('X', '–') : null);
|
||||
countryState = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePhoneField() {
|
||||
ignoreOnPhoneChange = true;
|
||||
try {
|
||||
String codeText = codeField.getText().toString();
|
||||
String phone = PhoneFormat.getInstance().format("+" + codeText + phoneField.getText().toString());
|
||||
int idx = phone.indexOf(" ");
|
||||
if (idx != -1) {
|
||||
String resultCode = PhoneFormat.stripExceptNumbers(phone.substring(0, idx));
|
||||
if (!codeText.equals(resultCode)) {
|
||||
phone = PhoneFormat.getInstance().format(phoneField.getText().toString()).trim();
|
||||
phoneField.setText(phone);
|
||||
int len = phoneField.length();
|
||||
phoneField.setSelection(phoneField.length());
|
||||
} else {
|
||||
phoneField.setText(phone.substring(idx).trim());
|
||||
int len = phoneField.length();
|
||||
phoneField.setSelection(phoneField.length());
|
||||
}
|
||||
} else {
|
||||
phoneField.setSelection(phoneField.length());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
ignoreOnPhoneChange = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
|
||||
if (ignoreSelection) {
|
||||
|
@ -612,7 +617,6 @@ public class ChangePhoneActivity extends BaseFragment {
|
|||
ignoreOnTextChange = true;
|
||||
String str = countriesArray.get(i);
|
||||
codeField.setText(countriesMap.get(str));
|
||||
updatePhoneField();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -686,8 +690,14 @@ public class ChangePhoneActivity extends BaseFragment {
|
|||
public void onShow() {
|
||||
super.onShow();
|
||||
if (phoneField != null) {
|
||||
AndroidUtilities.showKeyboard(phoneField);
|
||||
phoneField.setSelection(phoneField.length());
|
||||
if (codeField.length() != 0) {
|
||||
AndroidUtilities.showKeyboard(phoneField);
|
||||
phoneField.requestFocus();
|
||||
phoneField.setSelection(phoneField.length());
|
||||
} else {
|
||||
AndroidUtilities.showKeyboard(codeField);
|
||||
codeField.requestFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -713,6 +723,7 @@ public class ChangePhoneActivity extends BaseFragment {
|
|||
private volatile int codeTime = 15000;
|
||||
private double lastCurrentTime;
|
||||
private double lastCodeTime;
|
||||
private boolean ignoreOnTextChange;
|
||||
private boolean waitingForSms = false;
|
||||
private boolean nextPressed = false;
|
||||
private String lastError = "";
|
||||
|
@ -755,6 +766,27 @@ public class ChangePhoneActivity extends BaseFragment {
|
|||
layoutParams.leftMargin = AndroidUtilities.dp(24);
|
||||
layoutParams.rightMargin = AndroidUtilities.dp(24);
|
||||
codeField.setLayoutParams(layoutParams);
|
||||
codeField.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
if (ignoreOnTextChange) {
|
||||
return;
|
||||
}
|
||||
if (codeField.length() == 5) {
|
||||
onNextPressed();
|
||||
}
|
||||
}
|
||||
});
|
||||
codeField.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
@Override
|
||||
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
|
||||
|
@ -1051,6 +1083,7 @@ public class ChangePhoneActivity extends BaseFragment {
|
|||
return;
|
||||
}
|
||||
if (codeField != null) {
|
||||
ignoreOnTextChange = true;
|
||||
codeField.setText("" + args[0]);
|
||||
onNextPressed();
|
||||
}
|
||||
|
|
|
@ -307,7 +307,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
|
|||
result.add(user);
|
||||
}
|
||||
}
|
||||
MessagesController.getInstance().addUsersToChannel(chatId, result);
|
||||
MessagesController.getInstance().addUsersToChannel(chatId, result, null);
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats);
|
||||
Bundle args2 = new Bundle();
|
||||
args2.putInt("chat_id", chatId);
|
||||
|
@ -655,7 +655,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
|
|||
actionBar.setTitle(LocaleController.getString("ChannelAddMembers", R.string.ChannelAddMembers));
|
||||
actionBar.setSubtitle(LocaleController.formatPluralString("Members", selectedContacts.size()));
|
||||
|
||||
searchListViewAdapter = new SearchAdapter(context, null, false, false, false);
|
||||
searchListViewAdapter = new SearchAdapter(context, null, false, false, false, false);
|
||||
searchListViewAdapter.setCheckedMap(selectedContacts);
|
||||
searchListViewAdapter.setUseUserCell(true);
|
||||
listViewAdapter = new ContactsAdapter(context, 1, false, null, false);
|
||||
|
|
|
@ -118,7 +118,7 @@ public class ChannelEditActivity extends BaseFragment implements AvatarUpdater.A
|
|||
return false;
|
||||
}
|
||||
if (info == null) {
|
||||
MessagesStorage.getInstance().loadChatInfo(chatId, semaphore, false);
|
||||
MessagesStorage.getInstance().loadChatInfo(chatId, semaphore, false, false);
|
||||
try {
|
||||
semaphore.acquire();
|
||||
} catch (Exception e) {
|
||||
|
@ -132,7 +132,7 @@ public class ChannelEditActivity extends BaseFragment implements AvatarUpdater.A
|
|||
wasPrivate = currentChat.username == null || currentChat.username.length() == 0;
|
||||
avatarUpdater.parentFragment = this;
|
||||
avatarUpdater.delegate = this;
|
||||
allowComments = (currentChat.flags & TLRPC.CHAT_FLAG_IS_BROADCAST) == 0;
|
||||
allowComments = !currentChat.broadcast;
|
||||
return super.onFragmentCreate();
|
||||
}
|
||||
|
||||
|
@ -178,14 +178,16 @@ public class ChannelEditActivity extends BaseFragment implements AvatarUpdater.A
|
|||
AndroidUtilities.shakeView(nameTextView, 2, 0);
|
||||
return;
|
||||
}
|
||||
if ((currentChat.username == null && userNameTextView.length() != 0) || (currentChat.username != null && !currentChat.username.equalsIgnoreCase(userNameTextView.getText().toString()))) {
|
||||
if (userNameTextView.length() != 0 && !lastNameAvailable) {
|
||||
Vibrator v = (Vibrator) getParentActivity().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
if (v != null) {
|
||||
v.vibrate(200);
|
||||
if (userNameTextView != null) {
|
||||
if ((currentChat.username == null && userNameTextView.length() != 0) || (currentChat.username != null && !currentChat.username.equalsIgnoreCase(userNameTextView.getText().toString()))) {
|
||||
if (userNameTextView.length() != 0 && !lastNameAvailable) {
|
||||
Vibrator v = (Vibrator) getParentActivity().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
if (v != null) {
|
||||
v.vibrate(200);
|
||||
}
|
||||
AndroidUtilities.shakeView(checkTextView, 2, 0);
|
||||
return;
|
||||
}
|
||||
AndroidUtilities.shakeView(checkTextView, 2, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -211,7 +213,7 @@ public class ChannelEditActivity extends BaseFragment implements AvatarUpdater.A
|
|||
progressDialog.show();
|
||||
return;
|
||||
}
|
||||
boolean currentAllowComments = (currentChat.flags & TLRPC.CHAT_FLAG_IS_BROADCAST) == 0;
|
||||
boolean currentAllowComments = !currentChat.broadcast;
|
||||
if (allowComments != currentAllowComments) {
|
||||
MessagesController.getInstance().toogleChannelComments(chatId, allowComments);
|
||||
}
|
||||
|
@ -221,9 +223,11 @@ public class ChannelEditActivity extends BaseFragment implements AvatarUpdater.A
|
|||
if (info != null && !info.about.equals(descriptionTextView.getText().toString())) {
|
||||
MessagesController.getInstance().updateChannelAbout(chatId, descriptionTextView.getText().toString(), info);
|
||||
}
|
||||
String oldUserName = currentChat.username != null ? currentChat.username : "";
|
||||
if (!oldUserName.equals(userNameTextView.getText().toString())) {
|
||||
MessagesController.getInstance().updateChannelUserName(chatId, userNameTextView.getText().toString());
|
||||
if (userNameTextView != null) {
|
||||
String oldUserName = currentChat.username != null ? currentChat.username : "";
|
||||
if (!oldUserName.equals(userNameTextView.getText().toString())) {
|
||||
MessagesController.getInstance().updateChannelUserName(chatId, userNameTextView.getText().toString());
|
||||
}
|
||||
}
|
||||
if (uploadedAvatar != null) {
|
||||
MessagesController.getInstance().changeChatAvatar(chatId, uploadedAvatar);
|
||||
|
@ -299,7 +303,11 @@ public class ChannelEditActivity extends BaseFragment implements AvatarUpdater.A
|
|||
});
|
||||
|
||||
nameTextView = new EditText(context);
|
||||
nameTextView.setHint(LocaleController.getString("EnterChannelName", R.string.EnterChannelName));
|
||||
if (currentChat.megagroup) {
|
||||
nameTextView.setHint(LocaleController.getString("GroupName", R.string.GroupName));
|
||||
} else {
|
||||
nameTextView.setHint(LocaleController.getString("EnterChannelName", R.string.EnterChannelName));
|
||||
}
|
||||
nameTextView.setMaxLines(4);
|
||||
nameTextView.setGravity(Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT));
|
||||
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
|
||||
|
@ -382,90 +390,95 @@ public class ChannelEditActivity extends BaseFragment implements AvatarUpdater.A
|
|||
});
|
||||
|
||||
TextInfoPrivacyCell infoCell = new TextInfoPrivacyCell(context);
|
||||
infoCell.setText(LocaleController.getString("DescriptionInfo", R.string.DescriptionInfo));
|
||||
if (currentChat.megagroup) {
|
||||
infoCell.setText(LocaleController.getString("DescriptionInfoMega", R.string.DescriptionInfoMega));
|
||||
} else {
|
||||
infoCell.setText(LocaleController.getString("DescriptionInfo", R.string.DescriptionInfo));
|
||||
}
|
||||
infoCell.setBackgroundResource(R.drawable.greydivider);
|
||||
linearLayout.addView(infoCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
|
||||
if (!currentChat.megagroup) {
|
||||
linearLayout2 = new LinearLayout(context);
|
||||
linearLayout2.setOrientation(LinearLayout.VERTICAL);
|
||||
linearLayout2.setBackgroundColor(0xffffffff);
|
||||
linearLayout2.setPadding(0, 0, 0, AndroidUtilities.dp(7));
|
||||
linearLayout.addView(linearLayout2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
|
||||
linearLayout2 = new LinearLayout(context);
|
||||
linearLayout2.setOrientation(LinearLayout.VERTICAL);
|
||||
linearLayout2.setBackgroundColor(0xffffffff);
|
||||
linearLayout2.setPadding(0, 0, 0, AndroidUtilities.dp(7));
|
||||
linearLayout.addView(linearLayout2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
LinearLayout publicContainer = new LinearLayout(context);
|
||||
publicContainer.setOrientation(LinearLayout.HORIZONTAL);
|
||||
linearLayout2.addView(publicContainer, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 36, 17, 7, 17, 0));
|
||||
|
||||
LinearLayout publicContainer = new LinearLayout(context);
|
||||
publicContainer.setOrientation(LinearLayout.HORIZONTAL);
|
||||
linearLayout2.addView(publicContainer, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 36, 17, 7, 17, 0));
|
||||
EditText editText = new EditText(context);
|
||||
editText.setText("telegram.me/");
|
||||
editText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18);
|
||||
editText.setHintTextColor(0xff979797);
|
||||
editText.setTextColor(0xff212121);
|
||||
editText.setMaxLines(1);
|
||||
editText.setLines(1);
|
||||
editText.setEnabled(false);
|
||||
editText.setBackgroundDrawable(null);
|
||||
editText.setPadding(0, 0, 0, 0);
|
||||
editText.setSingleLine(true);
|
||||
editText.setInputType(InputType.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT);
|
||||
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
|
||||
publicContainer.addView(editText, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 36));
|
||||
|
||||
EditText editText = new EditText(context);
|
||||
editText.setText("telegram.me/");
|
||||
editText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18);
|
||||
editText.setHintTextColor(0xff979797);
|
||||
editText.setTextColor(0xff212121);
|
||||
editText.setMaxLines(1);
|
||||
editText.setLines(1);
|
||||
editText.setEnabled(false);
|
||||
editText.setBackgroundDrawable(null);
|
||||
editText.setPadding(0, 0, 0, 0);
|
||||
editText.setSingleLine(true);
|
||||
editText.setInputType(InputType.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT);
|
||||
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
|
||||
publicContainer.addView(editText, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 36));
|
||||
|
||||
userNameTextView = new EditText(context);
|
||||
userNameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18);
|
||||
userNameTextView.setHintTextColor(0xff979797);
|
||||
userNameTextView.setTextColor(0xff212121);
|
||||
userNameTextView.setMaxLines(1);
|
||||
userNameTextView.setLines(1);
|
||||
userNameTextView.setBackgroundDrawable(null);
|
||||
userNameTextView.setPadding(0, 0, 0, 0);
|
||||
userNameTextView.setSingleLine(true);
|
||||
userNameTextView.setText(currentChat.username);
|
||||
userNameTextView.setInputType(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS | InputType.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT);
|
||||
userNameTextView.setImeOptions(EditorInfo.IME_ACTION_DONE);
|
||||
userNameTextView.setHint(LocaleController.getString("ChannelUsernamePlaceholder", R.string.ChannelUsernamePlaceholder));
|
||||
userNameTextView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (wasPrivate && hasFocus && !privateAlertShown) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
|
||||
builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
|
||||
builder.setMessage(LocaleController.getString("ChannelWasPrivateAlert", R.string.ChannelWasPrivateAlert));
|
||||
builder.setPositiveButton(LocaleController.getString("Close", R.string.Close), null);
|
||||
showDialog(builder.create());
|
||||
userNameTextView = new EditText(context);
|
||||
userNameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18);
|
||||
userNameTextView.setHintTextColor(0xff979797);
|
||||
userNameTextView.setTextColor(0xff212121);
|
||||
userNameTextView.setMaxLines(1);
|
||||
userNameTextView.setLines(1);
|
||||
userNameTextView.setBackgroundDrawable(null);
|
||||
userNameTextView.setPadding(0, 0, 0, 0);
|
||||
userNameTextView.setSingleLine(true);
|
||||
userNameTextView.setText(currentChat.username);
|
||||
userNameTextView.setInputType(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS | InputType.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT);
|
||||
userNameTextView.setImeOptions(EditorInfo.IME_ACTION_DONE);
|
||||
userNameTextView.setHint(LocaleController.getString("ChannelUsernamePlaceholder", R.string.ChannelUsernamePlaceholder));
|
||||
userNameTextView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (wasPrivate && hasFocus && !privateAlertShown) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
|
||||
builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
|
||||
builder.setMessage(LocaleController.getString("ChannelWasPrivateAlert", R.string.ChannelWasPrivateAlert));
|
||||
builder.setPositiveButton(LocaleController.getString("Close", R.string.Close), null);
|
||||
showDialog(builder.create());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
AndroidUtilities.clearCursorDrawable(userNameTextView);
|
||||
publicContainer.addView(userNameTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 36));
|
||||
userNameTextView.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
|
||||
});
|
||||
AndroidUtilities.clearCursorDrawable(userNameTextView);
|
||||
publicContainer.addView(userNameTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 36));
|
||||
userNameTextView.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
|
||||
checkUserName(userNameTextView.getText().toString(), false);
|
||||
}
|
||||
@Override
|
||||
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
|
||||
checkUserName(userNameTextView.getText().toString(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
checkTextView = new TextView(context);
|
||||
checkTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
|
||||
checkTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
|
||||
checkTextView.setVisibility(View.GONE);
|
||||
linearLayout2.addView(checkTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT, 17, 3, 17, 7));
|
||||
checkTextView = new TextView(context);
|
||||
checkTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
|
||||
checkTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
|
||||
checkTextView.setVisibility(View.GONE);
|
||||
linearLayout2.addView(checkTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT, 17, 3, 17, 7));
|
||||
|
||||
infoCell = new TextInfoPrivacyCell(context);
|
||||
infoCell.setBackgroundResource(R.drawable.greydivider);
|
||||
infoCell.setText(LocaleController.getString("ChannelUsernameHelp", R.string.ChannelUsernameHelp));
|
||||
linearLayout.addView(infoCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
infoCell = new TextInfoPrivacyCell(context);
|
||||
infoCell.setBackgroundResource(R.drawable.greydivider);
|
||||
infoCell.setText(LocaleController.getString("ChannelUsernameHelp", R.string.ChannelUsernameHelp));
|
||||
linearLayout.addView(infoCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
}
|
||||
|
||||
|
||||
/*frameLayout = new FrameLayoutFixed(context);
|
||||
|
@ -496,13 +509,21 @@ public class ChannelEditActivity extends BaseFragment implements AvatarUpdater.A
|
|||
TextSettingsCell textCell = new TextSettingsCell(context);
|
||||
textCell.setTextColor(0xffed3d39);
|
||||
textCell.setBackgroundResource(R.drawable.list_selector);
|
||||
textCell.setText(LocaleController.getString("ChannelDelete", R.string.ChannelDelete), false);
|
||||
if (currentChat.megagroup) {
|
||||
textCell.setText(LocaleController.getString("DeleteMega", R.string.DeleteMega), false);
|
||||
} else {
|
||||
textCell.setText(LocaleController.getString("ChannelDelete", R.string.ChannelDelete), false);
|
||||
}
|
||||
frameLayout.addView(textCell, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
textCell.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
|
||||
builder.setMessage(LocaleController.getString("ChannelDeleteAlert", R.string.ChannelDeleteAlert));
|
||||
if (currentChat.megagroup) {
|
||||
builder.setMessage(LocaleController.getString("MegaDeleteAlert", R.string.MegaDeleteAlert));
|
||||
} else {
|
||||
builder.setMessage(LocaleController.getString("ChannelDeleteAlert", R.string.ChannelDeleteAlert));
|
||||
}
|
||||
builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
|
||||
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
|
@ -524,7 +545,11 @@ public class ChannelEditActivity extends BaseFragment implements AvatarUpdater.A
|
|||
|
||||
infoCell = new TextInfoPrivacyCell(context);
|
||||
infoCell.setBackgroundResource(R.drawable.greydivider_bottom);
|
||||
infoCell.setText(LocaleController.getString("ChannelDeleteInfo", R.string.ChannelDeleteInfo));
|
||||
if (currentChat.megagroup) {
|
||||
infoCell.setText(LocaleController.getString("MegaDeleteInfo", R.string.MegaDeleteInfo));
|
||||
} else {
|
||||
infoCell.setText(LocaleController.getString("ChannelDeleteInfo", R.string.ChannelDeleteInfo));
|
||||
}
|
||||
linearLayout.addView(infoCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
|
||||
nameTextView.setText(currentChat.title);
|
||||
|
|
|
@ -57,8 +57,10 @@ public class ChannelUsersActivity extends BaseFragment implements NotificationCe
|
|||
private int chatId;
|
||||
private int type;
|
||||
private boolean loadingUsers;
|
||||
private boolean firstLoaded;
|
||||
private boolean isAdmin;
|
||||
private boolean isPublic;
|
||||
private boolean isMegagroup;
|
||||
private int participantsStartRow;
|
||||
|
||||
public ChannelUsersActivity(Bundle args) {
|
||||
|
@ -66,9 +68,12 @@ public class ChannelUsersActivity extends BaseFragment implements NotificationCe
|
|||
chatId = arguments.getInt("chat_id");
|
||||
type = arguments.getInt("type");
|
||||
TLRPC.Chat chat = MessagesController.getInstance().getChat(chatId);
|
||||
if (chat != null && (chat.flags & TLRPC.CHAT_FLAG_ADMIN) != 0) {
|
||||
isAdmin = true;
|
||||
isPublic = (chat.flags & TLRPC.CHAT_FLAG_IS_PUBLIC) != 0;
|
||||
if (chat != null) {
|
||||
if (chat.creator) {
|
||||
isAdmin = true;
|
||||
isPublic = (chat.flags & TLRPC.CHAT_FLAG_IS_PUBLIC) != 0;
|
||||
}
|
||||
isMegagroup = chat.megagroup;
|
||||
}
|
||||
if (type == 0) {
|
||||
participantsStartRow = 0;
|
||||
|
@ -121,7 +126,11 @@ public class ChannelUsersActivity extends BaseFragment implements NotificationCe
|
|||
|
||||
emptyView = new EmptyTextProgressView(context);
|
||||
if (type == 0) {
|
||||
emptyView.setText(LocaleController.getString("NoBlocked", R.string.NoBlocked));
|
||||
if (isMegagroup) {
|
||||
emptyView.setText(LocaleController.getString("NoBlockedGroup", R.string.NoBlockedGroup));
|
||||
} else {
|
||||
emptyView.setText(LocaleController.getString("NoBlocked", R.string.NoBlocked));
|
||||
}
|
||||
}
|
||||
frameLayout.addView(emptyView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
|
||||
|
||||
|
@ -171,6 +180,9 @@ public class ChannelUsersActivity extends BaseFragment implements NotificationCe
|
|||
args.putBoolean("returnAsResult", true);
|
||||
args.putBoolean("needForwardCount", false);
|
||||
args.putBoolean("allowUsernameSearch", true);
|
||||
if (isMegagroup) {
|
||||
args.putBoolean("allowBots", false);
|
||||
}
|
||||
args.putString("selectAlertString", LocaleController.getString("ChannelAddUserAdminAlert", R.string.ChannelAddUserAdminAlert));
|
||||
ContactsActivity fragment = new ContactsActivity(args);
|
||||
fragment.setDelegate(new ContactsActivity.ContactsActivityDelegate() {
|
||||
|
@ -195,7 +207,7 @@ public class ChannelUsersActivity extends BaseFragment implements NotificationCe
|
|||
}
|
||||
});
|
||||
|
||||
if (isAdmin) {
|
||||
if (isAdmin || isMegagroup && type == 0) {
|
||||
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
|
||||
|
@ -280,18 +292,19 @@ public class ChannelUsersActivity extends BaseFragment implements NotificationCe
|
|||
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, final TLRPC.TL_error error) {
|
||||
if (response instanceof TLRPC.TL_boolTrue) {
|
||||
if (error == null) {
|
||||
MessagesController.getInstance().processUpdates((TLRPC.Updates) response, false);
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
MessagesController.getInstance().loadFullChat(chatId, 0, true);
|
||||
}
|
||||
}, 1000);
|
||||
} else if (error != null) {
|
||||
} else {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
AlertsCreator.showAddUserAlert(error.text, ChannelUsersActivity.this);
|
||||
AlertsCreator.showAddUserAlert(error.text, ChannelUsersActivity.this, !isMegagroup);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -329,7 +342,7 @@ public class ChannelUsersActivity extends BaseFragment implements NotificationCe
|
|||
return;
|
||||
}
|
||||
loadingUsers = true;
|
||||
if (emptyView != null) {
|
||||
if (emptyView != null && !firstLoaded) {
|
||||
emptyView.showProgress();
|
||||
}
|
||||
if (listViewAdapter != null) {
|
||||
|
@ -421,6 +434,7 @@ public class ChannelUsersActivity extends BaseFragment implements NotificationCe
|
|||
}
|
||||
}
|
||||
loadingUsers = false;
|
||||
firstLoaded = true;
|
||||
if (emptyView != null) {
|
||||
emptyView.showTextView();
|
||||
}
|
||||
|
@ -486,7 +500,7 @@ public class ChannelUsersActivity extends BaseFragment implements NotificationCe
|
|||
|
||||
@Override
|
||||
public int getCount() {
|
||||
if (participants.isEmpty() && type == 0 || loadingUsers) {
|
||||
if (participants.isEmpty() && type == 0 || loadingUsers && !firstLoaded) {
|
||||
return 0;
|
||||
}
|
||||
return participants.size() + participantsStartRow + 1;
|
||||
|
@ -512,7 +526,7 @@ public class ChannelUsersActivity extends BaseFragment implements NotificationCe
|
|||
int viewType = getItemViewType(i);
|
||||
if (viewType == 0) {
|
||||
if (view == null) {
|
||||
view = new UserCell(mContext, 1);
|
||||
view = new UserCell(mContext, 1, 0);
|
||||
view.setBackgroundColor(0xffffffff);
|
||||
}
|
||||
UserCell userCell = (UserCell) view;
|
||||
|
@ -540,19 +554,27 @@ public class ChannelUsersActivity extends BaseFragment implements NotificationCe
|
|||
view = new TextInfoPrivacyCell(mContext);
|
||||
}
|
||||
if (type == 0) {
|
||||
((TextInfoPrivacyCell) view).setText(LocaleController.getString("UnblockText", R.string.UnblockText));
|
||||
((TextInfoPrivacyCell) view).setText(String.format("%1$s\n\n%2$s", LocaleController.getString("NoBlockedGroup", R.string.NoBlockedGroup), LocaleController.getString("UnblockText", R.string.UnblockText)));
|
||||
view.setBackgroundResource(R.drawable.greydivider_bottom);
|
||||
} else if (type == 1) {
|
||||
if (i == 1 && isAdmin) {
|
||||
((TextInfoPrivacyCell) view).setText(LocaleController.getString("ChannelAdminsInfo", R.string.ChannelAdminsInfo));
|
||||
if (isMegagroup) {
|
||||
((TextInfoPrivacyCell) view).setText(LocaleController.getString("MegaAdminsInfo", R.string.MegaAdminsInfo));
|
||||
} else {
|
||||
((TextInfoPrivacyCell) view).setText(LocaleController.getString("ChannelAdminsInfo", R.string.ChannelAdminsInfo));
|
||||
}
|
||||
view.setBackgroundResource(R.drawable.greydivider);
|
||||
} else {
|
||||
((TextInfoPrivacyCell) view).setText("");
|
||||
view.setBackgroundResource(R.drawable.greydivider_bottom);
|
||||
}
|
||||
} else if (type == 2) {
|
||||
if ((!isPublic && i == 2 || i == 1) &&isAdmin) {
|
||||
((TextInfoPrivacyCell) view).setText(LocaleController.getString("ChannelMembersInfo", R.string.ChannelMembersInfo));
|
||||
if ((!isPublic && i == 2 || i == 1) && isAdmin) {
|
||||
if (isMegagroup) {
|
||||
((TextInfoPrivacyCell) view).setText("");
|
||||
} else {
|
||||
((TextInfoPrivacyCell) view).setText(LocaleController.getString("ChannelMembersInfo", R.string.ChannelMembersInfo));
|
||||
}
|
||||
view.setBackgroundResource(R.drawable.greydivider);
|
||||
} else {
|
||||
((TextInfoPrivacyCell) view).setText("");
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -70,6 +70,7 @@ public class AlertsCreator {
|
|||
editor.putInt("notifyuntil_" + dialog_id, untilTime);
|
||||
flags = ((long) untilTime << 32) | 1;
|
||||
}
|
||||
NotificationsController.getInstance().removeNotificationsForDialog(dialog_id);
|
||||
MessagesStorage.getInstance().setDialogFlags(dialog_id, flags);
|
||||
editor.commit();
|
||||
TLRPC.Dialog dialog = MessagesController.getInstance().dialogs_dict.get(dialog_id);
|
||||
|
@ -84,7 +85,7 @@ public class AlertsCreator {
|
|||
return builder.create();
|
||||
}
|
||||
|
||||
public static void showAddUserAlert(String error, final BaseFragment fragment) {
|
||||
public static void showAddUserAlert(String error, final BaseFragment fragment, boolean isChannel) {
|
||||
if (error == null || fragment == null || fragment.getParentActivity() == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -109,16 +110,39 @@ public class AlertsCreator {
|
|||
case "USER_BLOCKED":
|
||||
case "USER_BOT":
|
||||
case "USER_ID_INVALID":
|
||||
builder.setMessage(LocaleController.getString("ChannelUserCantAdd", R.string.ChannelUserCantAdd));
|
||||
if (isChannel) {
|
||||
builder.setMessage(LocaleController.getString("ChannelUserCantAdd", R.string.ChannelUserCantAdd));
|
||||
} else {
|
||||
builder.setMessage(LocaleController.getString("GroupUserCantAdd", R.string.GroupUserCantAdd));
|
||||
}
|
||||
break;
|
||||
case "USERS_TOO_MUCH":
|
||||
builder.setMessage(LocaleController.getString("ChannelUserAddLimit", R.string.ChannelUserAddLimit));
|
||||
if (isChannel) {
|
||||
builder.setMessage(LocaleController.getString("ChannelUserAddLimit", R.string.ChannelUserAddLimit));
|
||||
} else {
|
||||
builder.setMessage(LocaleController.getString("GroupUserAddLimit", R.string.GroupUserAddLimit));
|
||||
}
|
||||
break;
|
||||
case "USER_NOT_MUTUAL_CONTACT":
|
||||
builder.setMessage(LocaleController.getString("ChannelUserLeftError", R.string.ChannelUserLeftError));
|
||||
if (isChannel) {
|
||||
builder.setMessage(LocaleController.getString("ChannelUserLeftError", R.string.ChannelUserLeftError));
|
||||
} else {
|
||||
builder.setMessage(LocaleController.getString("GroupUserLeftError", R.string.GroupUserLeftError));
|
||||
}
|
||||
break;
|
||||
case "ADMINS_TOO_MUCH":
|
||||
builder.setMessage(LocaleController.getString("ChannelUserCantAdmin", R.string.ChannelUserCantAdmin));
|
||||
if (isChannel) {
|
||||
builder.setMessage(LocaleController.getString("ChannelUserCantAdmin", R.string.ChannelUserCantAdmin));
|
||||
} else {
|
||||
builder.setMessage(LocaleController.getString("GroupUserCantAdmin", R.string.GroupUserCantAdmin));
|
||||
}
|
||||
break;
|
||||
case "BOTS_TOO_MUCH":
|
||||
if (isChannel) {
|
||||
builder.setMessage(LocaleController.getString("ChannelUserCantBot", R.string.ChannelUserCantBot));
|
||||
} else {
|
||||
builder.setMessage(LocaleController.getString("GroupUserCantBot", R.string.GroupUserCantBot));
|
||||
}
|
||||
break;
|
||||
}
|
||||
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null);
|
||||
|
|
|
@ -30,7 +30,7 @@ public class AvatarDrawable extends Drawable {
|
|||
private static Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private static TextPaint namePaint;
|
||||
private static TextPaint namePaintSmall;
|
||||
private static int[] arrColors = {0xffe56555, 0xfff28c48, 0xff549cdd, 0xff76c84d, 0xff5fbed5, 0xff549cdd, 0xff8e85ee, 0xfff2749a};
|
||||
private static int[] arrColors = {0xffe56555, 0xfff28c48, 0xff8e85ee, 0xff76c84d, 0xff5fbed5, 0xff549cdd, 0xff8e85ee, 0xfff2749a};
|
||||
private static int[] arrColorsProfiles = {0xffd86f65, 0xfff69d61, 0xff8c79d2, 0xff67b35d, 0xff56a2bb, 0xff5c98cd, 0xff8c79d2, 0xfff37fa6};
|
||||
private static int[] arrColorsProfilesBack = {0xffca6056, 0xfff18944, 0xff7d6ac4, 0xff56a14c, 0xff4492ac, 0xff4c84b6, 0xff7d6ac4, 0xff4c84b6};
|
||||
private static int[] arrColorsProfilesText = {0xfff9cbc5, 0xfffdddc8, 0xffcdc4ed, 0xffc0edba, 0xffb8e2f0, 0xffb3d7f7, 0xffcdc4ed, 0xffb3d7f7};
|
||||
|
@ -92,6 +92,10 @@ public class AvatarDrawable extends Drawable {
|
|||
}
|
||||
}
|
||||
|
||||
public void setProfile(boolean value) {
|
||||
isProfile = value;
|
||||
}
|
||||
|
||||
public void setSmallStyle(boolean value) {
|
||||
smallStyle = value;
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ public class BotKeyboardView extends LinearLayout {
|
|||
buttonViews.clear();
|
||||
|
||||
if (buttons != null && botButtons.rows.size() != 0) {
|
||||
isFullSize = (buttons.flags & 1) == 0;
|
||||
isFullSize = !buttons.resize;
|
||||
buttonHeight = !isFullSize ? 42 : (int) Math.max(42, (panelHeight - AndroidUtilities.dp(30) - (botButtons.rows.size() - 1) * AndroidUtilities.dp(10)) / botButtons.rows.size() / AndroidUtilities.density);
|
||||
for (int a = 0; a < buttons.rows.size(); a++) {
|
||||
TLRPC.TL_keyboardButtonRow row = buttons.rows.get(a);
|
||||
|
|
|
@ -690,7 +690,7 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat
|
|||
return isAsAdmin;
|
||||
}
|
||||
|
||||
public void showTopView(boolean animated) {
|
||||
public void showTopView(boolean animated, final boolean openKeyboard) {
|
||||
if (topView == null || topViewShowed || getVisibility() != VISIBLE) {
|
||||
return;
|
||||
}
|
||||
|
@ -713,7 +713,7 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat
|
|||
public void onAnimationEnd(Object animation) {
|
||||
if (currentTopViewAnimation != null && currentTopViewAnimation.equals(animation)) {
|
||||
setTopViewAnimation(1.0f);
|
||||
if (!forceShowSendButton) {
|
||||
if (!forceShowSendButton || openKeyboard) {
|
||||
openKeyboard();
|
||||
}
|
||||
currentTopViewAnimation = null;
|
||||
|
@ -724,7 +724,7 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat
|
|||
currentTopViewAnimation.start();
|
||||
} else {
|
||||
setTopViewAnimation(1.0f);
|
||||
if (!forceShowSendButton) {
|
||||
if (!forceShowSendButton || openKeyboard) {
|
||||
openKeyboard();
|
||||
}
|
||||
}
|
||||
|
@ -829,6 +829,7 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat
|
|||
|
||||
public void onPause() {
|
||||
isPaused = true;
|
||||
closeKeyboard();
|
||||
}
|
||||
|
||||
public void onResume() {
|
||||
|
@ -849,8 +850,8 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat
|
|||
dialog_id = id;
|
||||
if ((int) dialog_id < 0) {
|
||||
TLRPC.Chat currentChat = MessagesController.getInstance().getChat(-(int) dialog_id);
|
||||
isAsAdmin = ChatObject.isChannel(currentChat) && ((currentChat.flags & TLRPC.CHAT_FLAG_ADMIN) != 0 || (currentChat.flags & TLRPC.CHAT_FLAG_USER_IS_EDITOR) != 0);
|
||||
adminModeAvailable = isAsAdmin && (currentChat.flags & TLRPC.CHAT_FLAG_IS_BROADCAST) == 0;
|
||||
isAsAdmin = ChatObject.isChannel(currentChat) && (currentChat.creator || currentChat.editor) && !currentChat.megagroup;
|
||||
adminModeAvailable = isAsAdmin && !currentChat.broadcast;
|
||||
if (adminModeAvailable) {
|
||||
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
|
||||
isAsAdmin = preferences.getBoolean("asadmin_" + dialog_id, true);
|
||||
|
@ -865,8 +866,9 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat
|
|||
|
||||
private void updateFieldHint() {
|
||||
boolean isChannel = false;
|
||||
if ((int) dialog_id < 0 && ChatObject.isChannel(MessagesController.getInstance().getChat(-(int) dialog_id))) {
|
||||
isChannel = true;
|
||||
if ((int) dialog_id < 0) {
|
||||
TLRPC.Chat chat = MessagesController.getInstance().getChat(-(int) dialog_id);
|
||||
isChannel = ChatObject.isChannel(chat) && !chat.megagroup;
|
||||
}
|
||||
if (isChannel) {
|
||||
messageEditText.setHint(isAsAdmin ? LocaleController.getString("ChannelBroadcast", R.string.ChannelBroadcast) : LocaleController.getString("ChannelComment", R.string.ChannelComment));
|
||||
|
@ -946,9 +948,9 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat
|
|||
}
|
||||
|
||||
private String getTrimmedString(String src) {
|
||||
String result = src.trim();
|
||||
if (result.length() == 0) {
|
||||
return result;
|
||||
src = src.trim();
|
||||
if (src.length() == 0) {
|
||||
return src;
|
||||
}
|
||||
while (src.startsWith("\n")) {
|
||||
src = src.substring(1);
|
||||
|
@ -1240,13 +1242,18 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat
|
|||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
public void setCommand(MessageObject messageObject, String command, boolean longPress) {
|
||||
public void setCommand(MessageObject messageObject, String command, boolean longPress, boolean username) {
|
||||
if (command == null || getVisibility() != VISIBLE) {
|
||||
return;
|
||||
}
|
||||
if (longPress) {
|
||||
String text = messageEditText.getText().toString();
|
||||
text = command + " " + text.replaceFirst("^/[a-zA-Z@\\d_]{1,255}(\\s|$)", "");
|
||||
TLRPC.User user = messageObject != null && (int) dialog_id < 0 ? MessagesController.getInstance().getUser(messageObject.messageOwner.from_id) : null;
|
||||
if ((botCount != 1 || username) && user != null && user.bot && !command.contains("@")) {
|
||||
text = String.format(Locale.US, "%s@%s", command, user.username) + " " + text.replaceFirst("^/[a-zA-Z@\\d_]{1,255}(\\s|$)", "");
|
||||
} else {
|
||||
text = command + " " + text.replaceFirst("^/[a-zA-Z@\\d_]{1,255}(\\s|$)", "");
|
||||
}
|
||||
ignoreTextChange = true;
|
||||
messageEditText.setText(text);
|
||||
messageEditText.setSelection(messageEditText.getText().length());
|
||||
|
@ -1256,7 +1263,7 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat
|
|||
}
|
||||
} else {
|
||||
TLRPC.User user = messageObject != null && (int) dialog_id < 0 ? MessagesController.getInstance().getUser(messageObject.messageOwner.from_id) : null;
|
||||
if (botCount != 1 && user != null && (user.flags & TLRPC.USER_FLAG_BOT) != 0 && !command.contains("@")) {
|
||||
if ((botCount != 1 || username) && user != null && user.bot && !command.contains("@")) {
|
||||
SendMessagesHelper.getInstance().sendMessage(String.format(Locale.US, "%s@%s", command, user.username), dialog_id, null, null, false, asAdmin());
|
||||
} else {
|
||||
SendMessagesHelper.getInstance().sendMessage(command, dialog_id, null, null, false, asAdmin());
|
||||
|
@ -1406,7 +1413,7 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat
|
|||
if (replyingMessageObject != null) {
|
||||
openKeyboardInternal();
|
||||
setButtons(botMessageObject, false);
|
||||
} else if ((botButtonsMessageObject.messageOwner.reply_markup.flags & 2) != 0) {
|
||||
} else if (botButtonsMessageObject.messageOwner.reply_markup.single_use) {
|
||||
openKeyboardInternal();
|
||||
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
|
||||
preferences.edit().putInt("answered_" + dialog_id, botButtonsMessageObject.getId()).commit();
|
||||
|
@ -1426,7 +1433,7 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat
|
|||
if (botReplyMarkup != null) {
|
||||
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
|
||||
boolean keyboardHidden = preferences.getInt("hidekeyboard_" + dialog_id, 0) == messageObject.getId();
|
||||
if (botButtonsMessageObject != replyingMessageObject && (botReplyMarkup.flags & 2) != 0) {
|
||||
if (botButtonsMessageObject != replyingMessageObject && botReplyMarkup.single_use) {
|
||||
if (preferences.getInt("answered_" + dialog_id, 0) == messageObject.getId()) {
|
||||
return;
|
||||
}
|
||||
|
@ -1594,6 +1601,10 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat
|
|||
AndroidUtilities.showKeyboard(messageEditText);
|
||||
}
|
||||
|
||||
public void closeKeyboard() {
|
||||
AndroidUtilities.hideKeyboard(messageEditText);
|
||||
}
|
||||
|
||||
public boolean isPopupShowing() {
|
||||
return emojiView != null && emojiView.getVisibility() == VISIBLE || botKeyboardView != null && botKeyboardView.getVisibility() == VISIBLE;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
* 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-2015.
|
||||
*/
|
||||
|
||||
package org.telegram.ui.Components;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.RectF;
|
||||
import android.view.View;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.AnimationCompat.ObjectAnimatorProxy;
|
||||
|
||||
public class CheckBoxSquare extends View {
|
||||
|
||||
private static Paint eraser;
|
||||
private static Paint checkPaint;
|
||||
private static Paint backgroundPaint;
|
||||
private static RectF rectF;
|
||||
|
||||
private Bitmap drawBitmap;
|
||||
private Canvas drawCanvas;
|
||||
|
||||
private float progress;
|
||||
private ObjectAnimatorProxy checkAnimator;
|
||||
private boolean isCheckAnimation = true;
|
||||
|
||||
private boolean attachedToWindow;
|
||||
private boolean isChecked;
|
||||
private boolean isDisabled;
|
||||
|
||||
private int color = 0xff43a0df;
|
||||
|
||||
private final static float progressBounceDiff = 0.2f;
|
||||
|
||||
public CheckBoxSquare(Context context) {
|
||||
super(context);
|
||||
if (checkPaint == null) {
|
||||
checkPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
checkPaint.setColor(0xffffffff);
|
||||
checkPaint.setStyle(Paint.Style.STROKE);
|
||||
checkPaint.setStrokeWidth(AndroidUtilities.dp(2));
|
||||
eraser = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
eraser.setColor(0);
|
||||
eraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
|
||||
backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
rectF = new RectF();
|
||||
}
|
||||
|
||||
drawBitmap = Bitmap.createBitmap(AndroidUtilities.dp(18), AndroidUtilities.dp(18), Bitmap.Config.ARGB_4444);
|
||||
drawCanvas = new Canvas(drawBitmap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisibility(int visibility) {
|
||||
super.setVisibility(visibility);
|
||||
if (visibility == VISIBLE && drawBitmap == null) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void setProgress(float value) {
|
||||
if (progress == value) {
|
||||
return;
|
||||
}
|
||||
progress = value;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public float getProgress() {
|
||||
return progress;
|
||||
}
|
||||
|
||||
public void setColor(int value) {
|
||||
color = value;
|
||||
}
|
||||
|
||||
private void cancelCheckAnimator() {
|
||||
if (checkAnimator != null) {
|
||||
checkAnimator.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private void animateToCheckedState(boolean newCheckedState) {
|
||||
isCheckAnimation = newCheckedState;
|
||||
checkAnimator = ObjectAnimatorProxy.ofFloatProxy(this, "progress", newCheckedState ? 1 : 0);
|
||||
checkAnimator.setDuration(300);
|
||||
checkAnimator.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
attachedToWindow = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
attachedToWindow = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
}
|
||||
|
||||
public void setChecked(boolean checked, boolean animated) {
|
||||
if (checked == isChecked) {
|
||||
return;
|
||||
}
|
||||
isChecked = checked;
|
||||
if (attachedToWindow && animated) {
|
||||
animateToCheckedState(checked);
|
||||
} else {
|
||||
cancelCheckAnimator();
|
||||
setProgress(checked ? 1.0f : 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDisabled(boolean disabled) {
|
||||
isDisabled = disabled;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public boolean isChecked() {
|
||||
return isChecked;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
if (getVisibility() != VISIBLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
float checkProgress;
|
||||
float bounceProgress;
|
||||
if (progress <= 0.5f) {
|
||||
bounceProgress = checkProgress = progress / 0.5f;
|
||||
int rD = (int) ((Color.red(color) - 0x73) * checkProgress);
|
||||
int gD = (int) ((Color.green(color) - 0x73) * checkProgress);
|
||||
int bD = (int) ((Color.blue(color) - 0x73) * checkProgress);
|
||||
int c = Color.rgb(0x73 + rD, 0x73 + gD, 0x73 + bD);
|
||||
backgroundPaint.setColor(c);
|
||||
} else {
|
||||
bounceProgress = 2.0f - progress / 0.5f;
|
||||
checkProgress = 1.0f;
|
||||
backgroundPaint.setColor(color);
|
||||
}
|
||||
if (isDisabled) {
|
||||
backgroundPaint.setColor(0xffb0b0b0);
|
||||
}
|
||||
float bounce = AndroidUtilities.dp(1) * bounceProgress;
|
||||
rectF.set(bounce, bounce, AndroidUtilities.dp(18) - bounce, AndroidUtilities.dp(18) - bounce);
|
||||
|
||||
drawBitmap.eraseColor(0);
|
||||
drawCanvas.drawRoundRect(rectF, AndroidUtilities.dp(2), AndroidUtilities.dp(2), backgroundPaint);
|
||||
|
||||
if (checkProgress != 1) {
|
||||
float rad = Math.min(AndroidUtilities.dp(7), AndroidUtilities.dp(7) * checkProgress + bounce);
|
||||
rectF.set(AndroidUtilities.dp(2) + rad, AndroidUtilities.dp(2) + rad, AndroidUtilities.dp(16) - rad, AndroidUtilities.dp(16) - rad);
|
||||
drawCanvas.drawRect(rectF, eraser);
|
||||
}
|
||||
|
||||
if (progress > 0.5f) {
|
||||
int endX = (int) (AndroidUtilities.dp(7.5f) - AndroidUtilities.dp(5) * (1.0f - bounceProgress)); //dp 2.5f
|
||||
int endY = (int) (AndroidUtilities.dpf2(13.5f) - AndroidUtilities.dp(5) * (1.0f - bounceProgress)); //dpf2 8.5f
|
||||
drawCanvas.drawLine(AndroidUtilities.dp(7.5f), (int) AndroidUtilities.dpf2(13.5f), endX, endY, checkPaint);
|
||||
endX = (int) (AndroidUtilities.dpf2(6.5f) + AndroidUtilities.dp(9) * (1.0f - bounceProgress)); //dpf2 15.5f
|
||||
endY = (int) (AndroidUtilities.dpf2(13.5f) - AndroidUtilities.dp(9) * (1.0f - bounceProgress)); //dpf2 4.5f
|
||||
drawCanvas.drawLine((int) AndroidUtilities.dpf2(6.5f), (int) AndroidUtilities.dpf2(13.5f), endX, endY, checkPaint);
|
||||
}
|
||||
canvas.drawBitmap(drawBitmap, 0, 0, null);
|
||||
/*eraser2.setStrokeWidth(AndroidUtilities.dp(size + 6));
|
||||
|
||||
drawBitmap.eraseColor(0);
|
||||
float rad = getMeasuredWidth() / 2;
|
||||
|
||||
float roundProgress = progress >= 0.5f ? 1.0f : progress / 0.5f;
|
||||
float checkProgress = progress < 0.5f ? 0.0f : (progress - 0.5f) / 0.5f;
|
||||
|
||||
float roundProgressCheckState = isCheckAnimation ? progress : (1.0f - progress);
|
||||
if (roundProgressCheckState < progressBounceDiff) {
|
||||
rad -= AndroidUtilities.dp(2) * roundProgressCheckState / progressBounceDiff;
|
||||
} else if (roundProgressCheckState < progressBounceDiff * 2) {
|
||||
rad -= AndroidUtilities.dp(2) - AndroidUtilities.dp(2) * (roundProgressCheckState - progressBounceDiff) / progressBounceDiff;
|
||||
}
|
||||
if (drawBackground) {
|
||||
paint.setColor(0x44000000);
|
||||
canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, rad - AndroidUtilities.dp(1), paint);
|
||||
canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, rad - AndroidUtilities.dp(1), backgroundPaint);
|
||||
}
|
||||
|
||||
paint.setColor(color);
|
||||
|
||||
bitmapCanvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, rad, paint);
|
||||
bitmapCanvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, rad * (1 - roundProgress), eraser);
|
||||
canvas.drawBitmap(drawBitmap, 0, 0, null);
|
||||
|
||||
checkBitmap.eraseColor(0);
|
||||
int w = checkDrawable.getIntrinsicWidth();
|
||||
int h = checkDrawable.getIntrinsicHeight();
|
||||
int x = (getMeasuredWidth() - w) / 2;
|
||||
int y = (getMeasuredHeight() - h) / 2;
|
||||
|
||||
checkDrawable.setBounds(x, y + checkOffset, x + w, y + h + checkOffset);
|
||||
checkDrawable.draw(checkCanvas);
|
||||
checkCanvas.drawCircle(getMeasuredWidth() / 2 - AndroidUtilities.dp(2.5f), getMeasuredHeight() / 2 + AndroidUtilities.dp(4), ((getMeasuredWidth() + AndroidUtilities.dp(6)) / 2) * (1 - checkProgress), eraser2);
|
||||
|
||||
canvas.drawBitmap(checkBitmap, 0, 0, null);*/
|
||||
}
|
||||
}
|
|
@ -1166,7 +1166,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
|
|||
ArrayList<TLRPC.TL_messages_stickerSet> packs = StickersQuery.getStickerSets();
|
||||
for (int a = 0; a < packs.size(); a++) {
|
||||
TLRPC.TL_messages_stickerSet pack = packs.get(a);
|
||||
if ((pack.set.flags & 2) != 0 || pack.documents == null || pack.documents.isEmpty()) {
|
||||
if (pack.set.disabled || pack.documents == null || pack.documents.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
stickerSets.add(pack);
|
||||
|
|
|
@ -151,7 +151,11 @@ public class FrameLayoutFixed extends FrameLayout {
|
|||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
try {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
} catch (Exception e2) {
|
||||
FileLog.e("tmessages", e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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-2015.
|
||||
*/
|
||||
|
||||
package org.telegram.ui.Components;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.widget.EditText;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
|
||||
public class HintEditText extends EditText {
|
||||
|
||||
private String hintText;
|
||||
private float textOffset;
|
||||
private float spaceSize;
|
||||
private float numberSize;
|
||||
private Paint paint = new Paint();
|
||||
private Rect rect = new Rect();
|
||||
|
||||
public HintEditText(Context context) {
|
||||
super(context);
|
||||
paint.setColor(0xff979797);
|
||||
}
|
||||
|
||||
public String getHintText() {
|
||||
return hintText;
|
||||
}
|
||||
|
||||
public void setHintText(String value) {
|
||||
hintText = value;
|
||||
onTextChange();
|
||||
setText(getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
onTextChange();
|
||||
}
|
||||
|
||||
public void onTextChange() {
|
||||
textOffset = (length() > 0 ? getPaint().measureText(getText(), 0, length()) : 0);
|
||||
spaceSize = getPaint().measureText(" ");
|
||||
numberSize = getPaint().measureText("1");
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
if (hintText != null && length() < hintText.length()) {
|
||||
int top = getMeasuredHeight() / 2;
|
||||
float offsetX = textOffset;
|
||||
for (int a = length(); a < hintText.length(); a++) {
|
||||
if (hintText.charAt(a) == ' ') {
|
||||
offsetX += spaceSize;
|
||||
} else {
|
||||
rect.set((int) offsetX + AndroidUtilities.dp(1), top, (int) (offsetX + numberSize) - AndroidUtilities.dp(1), top + AndroidUtilities.dp(2));
|
||||
canvas.drawRect(rect, paint);
|
||||
offsetX += numberSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ package org.telegram.ui.Components;
|
|||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.ScrollView;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
|
||||
|
@ -23,6 +24,10 @@ public class LayoutHelper {
|
|||
return (int) (size < 0 ? size : AndroidUtilities.dp(size));
|
||||
}
|
||||
|
||||
public static FrameLayout.LayoutParams createScroll(int width, int height, int gravity) {
|
||||
return new ScrollView.LayoutParams(getSize(width), getSize(height), gravity);
|
||||
}
|
||||
|
||||
public static FrameLayout.LayoutParams createFrame(int width, float height, int gravity, float leftMargin, float topMargin, float rightMargin, float bottomMargin) {
|
||||
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(getSize(width), getSize(height), gravity);
|
||||
layoutParams.setMargins(AndroidUtilities.dp(leftMargin), AndroidUtilities.dp(topMargin), AndroidUtilities.dp(rightMargin), AndroidUtilities.dp(bottomMargin));
|
||||
|
@ -100,7 +105,7 @@ public class LayoutHelper {
|
|||
return layoutParams;
|
||||
}
|
||||
|
||||
public static LinearLayout.LayoutParams createLinear(int width, int height, int leftMargin, int topMargin, int rightMargin, int bottomMargin) {
|
||||
public static LinearLayout.LayoutParams createLinear(int width, int height, float leftMargin, float topMargin, float rightMargin, float bottomMargin) {
|
||||
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(getSize(width), getSize(height));
|
||||
layoutParams.setMargins(AndroidUtilities.dp(leftMargin), AndroidUtilities.dp(topMargin), AndroidUtilities.dp(rightMargin), AndroidUtilities.dp(bottomMargin));
|
||||
return layoutParams;
|
||||
|
|
|
@ -47,23 +47,13 @@ public class PickerBottomLayout extends FrameLayout {
|
|||
cancelButton.setPadding(AndroidUtilities.dp(29), 0, AndroidUtilities.dp(29), 0);
|
||||
cancelButton.setText(LocaleController.getString("Cancel", R.string.Cancel).toUpperCase());
|
||||
cancelButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
addView(cancelButton);
|
||||
LayoutParams layoutParams = (LayoutParams) cancelButton.getLayoutParams();
|
||||
layoutParams.width = LayoutHelper.WRAP_CONTENT;
|
||||
layoutParams.height = LayoutHelper.MATCH_PARENT;
|
||||
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
|
||||
cancelButton.setLayoutParams(layoutParams);
|
||||
addView(cancelButton, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT));
|
||||
|
||||
doneButton = new LinearLayout(context);
|
||||
doneButton.setOrientation(LinearLayout.HORIZONTAL);
|
||||
doneButton.setBackgroundResource(isDarkTheme ? R.drawable.bar_selector_picker : R.drawable.bar_selector_audio);
|
||||
doneButton.setPadding(AndroidUtilities.dp(29), 0, AndroidUtilities.dp(29), 0);
|
||||
addView(doneButton);
|
||||
layoutParams = (LayoutParams) doneButton.getLayoutParams();
|
||||
layoutParams.width = LayoutHelper.WRAP_CONTENT;
|
||||
layoutParams.height = LayoutHelper.MATCH_PARENT;
|
||||
layoutParams.gravity = Gravity.TOP | Gravity.RIGHT;
|
||||
doneButton.setLayoutParams(layoutParams);
|
||||
addView(doneButton, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.RIGHT));
|
||||
|
||||
doneButtonBadgeTextView = new TextView(context);
|
||||
doneButtonBadgeTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
|
@ -73,13 +63,7 @@ public class PickerBottomLayout extends FrameLayout {
|
|||
doneButtonBadgeTextView.setBackgroundResource(isDarkTheme ? R.drawable.photobadge : R.drawable.bluecounter);
|
||||
doneButtonBadgeTextView.setMinWidth(AndroidUtilities.dp(23));
|
||||
doneButtonBadgeTextView.setPadding(AndroidUtilities.dp(8), 0, AndroidUtilities.dp(8), AndroidUtilities.dp(1));
|
||||
doneButton.addView(doneButtonBadgeTextView);
|
||||
LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams) doneButtonBadgeTextView.getLayoutParams();
|
||||
layoutParams1.width = LayoutHelper.WRAP_CONTENT;
|
||||
layoutParams1.height = AndroidUtilities.dp(23);
|
||||
layoutParams1.rightMargin = AndroidUtilities.dp(10);
|
||||
layoutParams1.gravity = Gravity.CENTER_VERTICAL;
|
||||
doneButtonBadgeTextView.setLayoutParams(layoutParams1);
|
||||
doneButton.addView(doneButtonBadgeTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 23, Gravity.CENTER_VERTICAL, 0, 0, 10, 0));
|
||||
|
||||
doneButtonTextView = new TextView(context);
|
||||
doneButtonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
|
@ -88,12 +72,7 @@ public class PickerBottomLayout extends FrameLayout {
|
|||
doneButtonTextView.setCompoundDrawablePadding(AndroidUtilities.dp(8));
|
||||
doneButtonTextView.setText(LocaleController.getString("Send", R.string.Send).toUpperCase());
|
||||
doneButtonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
doneButton.addView(doneButtonTextView);
|
||||
layoutParams1 = (LinearLayout.LayoutParams) doneButtonTextView.getLayoutParams();
|
||||
layoutParams1.width = LayoutHelper.WRAP_CONTENT;
|
||||
layoutParams1.gravity = Gravity.CENTER_VERTICAL;
|
||||
layoutParams1.height = LayoutHelper.WRAP_CONTENT;
|
||||
doneButtonTextView.setLayoutParams(layoutParams1);
|
||||
doneButton.addView(doneButtonTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL));
|
||||
}
|
||||
|
||||
public void updateSelectedCount(int count, boolean disable) {
|
||||
|
|
|
@ -19,6 +19,8 @@ import android.view.View;
|
|||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.AnimationCompat.ObjectAnimatorProxy;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.ImageLoader;
|
||||
|
||||
public class RadioButton extends View {
|
||||
|
||||
|
@ -50,8 +52,15 @@ public class RadioButton extends View {
|
|||
eraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
|
||||
}
|
||||
|
||||
bitmap = Bitmap.createBitmap(AndroidUtilities.dp(size), AndroidUtilities.dp(size), Bitmap.Config.ARGB_4444);
|
||||
bitmapCanvas = new Canvas(bitmap);
|
||||
try {
|
||||
bitmap = Bitmap.createBitmap(AndroidUtilities.dp(size), AndroidUtilities.dp(size), Bitmap.Config.ARGB_4444);
|
||||
if (ImageLoader.getInstance().runtimeHack != null) {
|
||||
ImageLoader.getInstance().runtimeHack.trackFree(bitmap.getRowBytes() * bitmap.getHeight());
|
||||
}
|
||||
bitmapCanvas = new Canvas(bitmap);
|
||||
} catch (Throwable e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setProgress(float value) {
|
||||
|
@ -86,7 +95,7 @@ public class RadioButton extends View {
|
|||
|
||||
private void animateToCheckedState(boolean newCheckedState) {
|
||||
checkAnimator = ObjectAnimatorProxy.ofFloatProxy(this, "progress", newCheckedState ? 1 : 0);
|
||||
checkAnimator.setDuration(300);
|
||||
checkAnimator.setDuration(200);
|
||||
checkAnimator.start();
|
||||
}
|
||||
|
||||
|
@ -100,6 +109,11 @@ public class RadioButton extends View {
|
|||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
attachedToWindow = false;
|
||||
if (bitmap != null && ImageLoader.getInstance().runtimeHack != null) {
|
||||
ImageLoader.getInstance().runtimeHack.trackAlloc(bitmap.getRowBytes() * bitmap.getHeight());
|
||||
bitmap.recycle();
|
||||
bitmap = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setChecked(boolean checked, boolean animated) {
|
||||
|
@ -124,10 +138,20 @@ public class RadioButton extends View {
|
|||
protected void onDraw(Canvas canvas) {
|
||||
if (bitmap == null || bitmap.getWidth() != getMeasuredWidth()) {
|
||||
if (bitmap != null) {
|
||||
if (ImageLoader.getInstance().runtimeHack != null) {
|
||||
ImageLoader.getInstance().runtimeHack.trackAlloc(bitmap.getRowBytes() * bitmap.getHeight());
|
||||
}
|
||||
bitmap.recycle();
|
||||
}
|
||||
bitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
|
||||
bitmapCanvas = new Canvas(bitmap);
|
||||
try {
|
||||
bitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
|
||||
if (ImageLoader.getInstance().runtimeHack != null) {
|
||||
ImageLoader.getInstance().runtimeHack.trackFree(bitmap.getRowBytes() * bitmap.getHeight());
|
||||
}
|
||||
bitmapCanvas = new Canvas(bitmap);
|
||||
} catch (Throwable e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
float circleProgress;
|
||||
float innerRad;
|
||||
|
@ -147,16 +171,18 @@ public class RadioButton extends View {
|
|||
paint.setColor(c);
|
||||
checkedPaint.setColor(c);
|
||||
}
|
||||
bitmap.eraseColor(0);
|
||||
float rad = size / 2 - (1 + circleProgress) * AndroidUtilities.density;
|
||||
bitmapCanvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, rad, paint);
|
||||
if (progress <= 0.5f) {
|
||||
bitmapCanvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, (rad - AndroidUtilities.dp(1)), checkedPaint);
|
||||
bitmapCanvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, (rad - AndroidUtilities.dp(1)) * (1.0f - circleProgress), eraser);
|
||||
} else {
|
||||
bitmapCanvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, size / 4 + (rad - AndroidUtilities.dp(1) - size / 4) * circleProgress, checkedPaint);
|
||||
}
|
||||
if (bitmap != null) {
|
||||
bitmap.eraseColor(0);
|
||||
float rad = size / 2 - (1 + circleProgress) * AndroidUtilities.density;
|
||||
bitmapCanvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, rad, paint);
|
||||
if (progress <= 0.5f) {
|
||||
bitmapCanvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, (rad - AndroidUtilities.dp(1)), checkedPaint);
|
||||
bitmapCanvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, (rad - AndroidUtilities.dp(1)) * (1.0f - circleProgress), eraser);
|
||||
} else {
|
||||
bitmapCanvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, size / 4 + (rad - AndroidUtilities.dp(1) - size / 4) * circleProgress, checkedPaint);
|
||||
}
|
||||
|
||||
canvas.drawBitmap(bitmap, 0, 0, null);
|
||||
canvas.drawBitmap(bitmap, 0, 0, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user