commit 6ce9456c26c2b67d511cf4afc977edcefb454bc7
Author: wlh <646507849@qq.com>
Date: Thu Dec 14 20:59:56 2023 +0800
中健 365 im
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..36b401f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,12 @@
+# OS X Files
+.DS_Store
+**/.DS_Store
+
+
+# Gradle files
+*/Android/.gradle/
+
+# IDEA Files
+*/Android/.idea/
+
+*/Android/local.properties
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/TUIKit.iml b/.idea/TUIKit.iml
new file mode 100644
index 0000000..d6ebd48
--- /dev/null
+++ b/.idea/TUIKit.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..bb0683a
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..fd0dea8
--- /dev/null
+++ b/README.md
@@ -0,0 +1,30 @@
+English | [简体中文](./README_ZH.md)
+
+# TUIKit (Android)
+
+## Download Links
+
+[Latest TUIChat download](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUIChat.zip)
+
+[Latest TUIConversation download](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUIConversation.zip)
+
+[Latest TUIContact download](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUIContact.zip)
+
+[Latest TUIGroup download](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUIGroup.zip)
+
+[Latest TUISearch download](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUISearch.zip)
+
+[Latest TUICallKit download](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUICallKit.zip)
+
+[Latest TUIOfflinePush download](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUIOfflinePush.zip)
+
+[Latest TUICommunity download](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUICommunity.zip)
+
+[Latest TUITranslation download](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUITranslation.zip)
+
+[Latest TUICore download](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUICore.zip)
+
+[Latest TIMCommon download](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TIMCommon.zip)
+
+
+If you encounter a TUIKit bug, please submit a pull request. After successful merging, we will update the TUIKit library in time.
diff --git a/README_ZH.md b/README_ZH.md
new file mode 100644
index 0000000..bb67ce8
--- /dev/null
+++ b/README_ZH.md
@@ -0,0 +1,35 @@
+[English](./README.md) | 简体中文
+
+# TUIKit(Android)
+
+## 下载地址
+
+[最新 TUIChat 下载](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUIChat.zip)
+
+[最新 TUIConversation 下载](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUIConversation.zip)
+
+[最新 TUIContact 下载](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUIContact.zip)
+
+[最新 TUIGroup 下载](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUIGroup.zip)
+
+[最新 TUISearch 下载](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUISearch.zip)
+
+[最新 TUICallKit 下载](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUICallKit.zip)
+
+[最新 TUIOfflinePush 下载](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUIOfflinePush.zip)
+
+[最新 TUICommunity 下载](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUICommunity.zip)
+
+[最新 TUITranslation 下载](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUITranslation.zip)
+
+[最新 TUICore 下载](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TUICore.zip)
+
+[最新 TIMCommon 下载](https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/android/TIMCommon.zip)
+
+## 交流&反馈
+
+如果您遇到 TUIKit 的 Bug,欢迎提交 Pull Request,Merge 成功后我们会及时更新 pod 集成的 TUIKit 库 。
+
+欢迎加入 QQ 群进行技术交流和反馈问题。
+
+
diff --git a/TIMCommon/.gitignore b/TIMCommon/.gitignore
new file mode 100644
index 0000000..aa724b7
--- /dev/null
+++ b/TIMCommon/.gitignore
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/TIMCommon/build.gradle b/TIMCommon/build.gradle
new file mode 100644
index 0000000..0114b27
--- /dev/null
+++ b/TIMCommon/build.gradle
@@ -0,0 +1,5 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ id 'com.android.application' version '7.4.1' apply false
+ id 'com.android.library' version '7.4.1' apply false
+}
\ No newline at end of file
diff --git a/TIMCommon/gradle.properties b/TIMCommon/gradle.properties
new file mode 100644
index 0000000..3e927b1
--- /dev/null
+++ b/TIMCommon/gradle.properties
@@ -0,0 +1,21 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/TIMCommon/gradle/wrapper/gradle-wrapper.jar b/TIMCommon/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
Binary files /dev/null and b/TIMCommon/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/TIMCommon/gradle/wrapper/gradle-wrapper.properties b/TIMCommon/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..ecf7412
--- /dev/null
+++ b/TIMCommon/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Mar 10 11:10:42 CST 2023
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/TIMCommon/gradlew b/TIMCommon/gradlew
new file mode 100644
index 0000000..4f906e0
--- /dev/null
+++ b/TIMCommon/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/TIMCommon/gradlew.bat b/TIMCommon/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/TIMCommon/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/TIMCommon/settings.gradle b/TIMCommon/settings.gradle
new file mode 100644
index 0000000..15f8361
--- /dev/null
+++ b/TIMCommon/settings.gradle
@@ -0,0 +1,16 @@
+pluginManagement {
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+rootProject.name = "TIMCommon"
+include ':timcommon'
diff --git a/TIMCommon/timcommon/.gitignore b/TIMCommon/timcommon/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/TIMCommon/timcommon/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/TIMCommon/timcommon/build.gradle b/TIMCommon/timcommon/build.gradle
new file mode 100644
index 0000000..08b5679
--- /dev/null
+++ b/TIMCommon/timcommon/build.gradle
@@ -0,0 +1,51 @@
+plugins {
+ id 'com.android.library'
+}
+
+android {
+ compileSdkVersion 30
+ buildToolsVersion "30.0.3"
+
+ defaultConfig {
+ minSdkVersion 19
+ targetSdkVersion 30
+ versionCode 1
+ versionName "1.0"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ // 主题资源文件夹
+ sourceSets {
+ main {
+ res.srcDirs += "src/main/res-light"
+ res.srcDirs += "src/main/res-lively"
+ res.srcDirs += "src/main/res-serious"
+ }
+ }
+}
+
+afterEvaluate{
+ generateReleaseBuildConfig.enabled =false
+ generateDebugBuildConfig.enabled =false
+}
+
+dependencies {
+
+ api project(':tuicore')
+ implementation 'com.google.code.gson:gson:2.9.1'
+ implementation 'androidx.appcompat:appcompat:1.3.1'
+ implementation 'com.github.bumptech.glide:glide:4.12.0'
+ implementation 'androidx.recyclerview:recyclerview:1.2.1'
+ implementation 'androidx.viewpager2:viewpager2:1.0.0'
+ implementation 'androidx.cardview:cardview:1.0.0'
+}
+
diff --git a/TIMCommon/timcommon/consumer-rules.pro b/TIMCommon/timcommon/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
diff --git a/TIMCommon/timcommon/proguard-rules.pro b/TIMCommon/timcommon/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/TIMCommon/timcommon/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/TIMCommon/timcommon/src/main/AndroidManifest.xml b/TIMCommon/timcommon/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..197c852
--- /dev/null
+++ b/TIMCommon/timcommon/src/main/AndroidManifest.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[NO]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[NO]@2x.png
new file mode 100644
index 0000000..b7ae6d7
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[NO]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[OK]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[OK]@2x.png
new file mode 100644
index 0000000..e723cb6
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[OK]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[下雨]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[下雨]@2x.png
new file mode 100644
index 0000000..d049b49
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[下雨]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[么么哒]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[么么哒]@2x.png
new file mode 100644
index 0000000..f47fa56
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[么么哒]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[乒乓]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[乒乓]@2x.png
new file mode 100644
index 0000000..56f307d
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[乒乓]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[便便]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[便便]@2x.png
new file mode 100644
index 0000000..adf4cc2
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[便便]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[信封]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[信封]@2x.png
new file mode 100644
index 0000000..c571ad2
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[信封]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[偷笑]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[偷笑]@2x.png
new file mode 100644
index 0000000..a303375
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[偷笑]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[傲慢]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[傲慢]@2x.png
new file mode 100644
index 0000000..34fa967
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[傲慢]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[再见]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[再见]@2x.png
new file mode 100644
index 0000000..497e464
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[再见]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[冷汗]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[冷汗]@2x.png
new file mode 100644
index 0000000..137ec0f
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[冷汗]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[凋谢]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[凋谢]@2x.png
new file mode 100644
index 0000000..dd05090
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[凋谢]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[刀]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[刀]@2x.png
new file mode 100644
index 0000000..ab4fc8d
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[刀]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[删除]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[删除]@2x.png
new file mode 100644
index 0000000..113e20f
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[删除]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[勾引]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[勾引]@2x.png
new file mode 100644
index 0000000..04060f5
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[勾引]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[发呆]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[发呆]@2x.png
new file mode 100644
index 0000000..d8393d9
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[发呆]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[发抖]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[发抖]@2x.png
new file mode 100644
index 0000000..094ed1d
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[发抖]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[可怜]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[可怜]@2x.png
new file mode 100644
index 0000000..73963b7
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[可怜]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[可爱]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[可爱]@2x.png
new file mode 100644
index 0000000..a235324
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[可爱]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[右哼哼]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[右哼哼]@2x.png
new file mode 100644
index 0000000..e1ca267
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[右哼哼]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[右太极]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[右太极]@2x.png
new file mode 100644
index 0000000..6b55dfb
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[右太极]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[右车头]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[右车头]@2x.png
new file mode 100644
index 0000000..85fdb86
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[右车头]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[吐]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[吐]@2x.png
new file mode 100644
index 0000000..0265a28
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[吐]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[吓]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[吓]@2x.png
new file mode 100644
index 0000000..b03f3b6
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[吓]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[咒骂]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[咒骂]@2x.png
new file mode 100644
index 0000000..c65faa6
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[咒骂]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[咖啡]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[咖啡]@2x.png
new file mode 100644
index 0000000..dd595d3
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[咖啡]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[啤酒]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[啤酒]@2x.png
new file mode 100644
index 0000000..52289b0
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[啤酒]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[嘘]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[嘘]@2x.png
new file mode 100644
index 0000000..e011a35
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[嘘]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[回头]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[回头]@2x.png
new file mode 100644
index 0000000..84660e2
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[回头]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[困]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[困]@2x.png
new file mode 100644
index 0000000..cc0447f
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[困]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[坏笑]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[坏笑]@2x.png
new file mode 100644
index 0000000..36f3c32
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[坏笑]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[多云]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[多云]@2x.png
new file mode 100644
index 0000000..71d23d6
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[多云]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[大兵]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[大兵]@2x.png
new file mode 100644
index 0000000..94b0d52
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[大兵]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[大哭]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[大哭]@2x.png
new file mode 100644
index 0000000..e816c56
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[大哭]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[太阳]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[太阳]@2x.png
new file mode 100644
index 0000000..a0d229a
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[太阳]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[奋斗]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[奋斗]@2x.png
new file mode 100644
index 0000000..3347c97
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[奋斗]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[奶瓶]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[奶瓶]@2x.png
new file mode 100644
index 0000000..0d4b8d9
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[奶瓶]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[委屈]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[委屈]@2x.png
new file mode 100644
index 0000000..3f136dd
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[委屈]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[害羞]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[害羞]@2x.png
new file mode 100644
index 0000000..30a9341
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[害羞]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[尴尬]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[尴尬]@2x.png
new file mode 100644
index 0000000..62afd7e
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[尴尬]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[左哼哼]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[左哼哼]@2x.png
new file mode 100644
index 0000000..e6f64df
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[左哼哼]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[左太极]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[左太极]@2x.png
new file mode 100644
index 0000000..5a88a56
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[左太极]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[左车头]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[左车头]@2x.png
new file mode 100644
index 0000000..e05c11c
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[左车头]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[差劲]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[差劲]@2x.png
new file mode 100644
index 0000000..455365a
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[差劲]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[弱]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[弱]@2x.png
new file mode 100644
index 0000000..fe5fbf9
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[弱]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[强]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[强]@2x.png
new file mode 100644
index 0000000..f4f7a5b
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[强]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[彩带]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[彩带]@2x.png
new file mode 100644
index 0000000..88cd3f0
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[彩带]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[彩球]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[彩球]@2x.png
new file mode 100644
index 0000000..8a60eed
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[彩球]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[得意]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[得意]@2x.png
new file mode 100644
index 0000000..4027f8c
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[得意]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[微笑]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[微笑]@2x.png
new file mode 100644
index 0000000..bb57a0a
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[微笑]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[心碎了]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[心碎了]@2x.png
new file mode 100644
index 0000000..a11ed0f
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[心碎了]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[快哭了]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[快哭了]@2x.png
new file mode 100644
index 0000000..8f49f69
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[快哭了]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[怄火]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[怄火]@2x.png
new file mode 100644
index 0000000..7277dae
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[怄火]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[怒]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[怒]@2x.png
new file mode 100644
index 0000000..a4e4a69
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[怒]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[惊恐]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[惊恐]@2x.png
new file mode 100644
index 0000000..617810a
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[惊恐]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[惊讶]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[惊讶]@2x.png
new file mode 100644
index 0000000..df93544
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[惊讶]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[憨笑]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[憨笑]@2x.png
new file mode 100644
index 0000000..4c5b4ba
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[憨笑]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[手枪]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[手枪]@2x.png
new file mode 100644
index 0000000..58af826
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[手枪]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[打哈欠]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[打哈欠]@2x.png
new file mode 100644
index 0000000..14490ce
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[打哈欠]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[抓狂]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[抓狂]@2x.png
new file mode 100644
index 0000000..0556a4d
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[抓狂]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[折磨]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[折磨]@2x.png
new file mode 100644
index 0000000..d9dfd53
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[折磨]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[抠鼻]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[抠鼻]@2x.png
new file mode 100644
index 0000000..cbc61e8
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[抠鼻]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[抱抱]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[抱抱]@2x.png
new file mode 100644
index 0000000..828971e
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[抱抱]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[抱拳]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[抱拳]@2x.png
new file mode 100644
index 0000000..95b5ee0
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[抱拳]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[拳头]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[拳头]@2x.png
new file mode 100644
index 0000000..6d501d3
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[拳头]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[挥手]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[挥手]@2x.png
new file mode 100644
index 0000000..ad5d3e0
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[挥手]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[握手]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[握手]@2x.png
new file mode 100644
index 0000000..10a615b
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[握手]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[撇嘴]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[撇嘴]@2x.png
new file mode 100644
index 0000000..d8839f4
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[撇嘴]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[擦汗]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[擦汗]@2x.png
new file mode 100644
index 0000000..8804e98
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[擦汗]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[敲打]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[敲打]@2x.png
new file mode 100644
index 0000000..3dfff7b
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[敲打]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[晕]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[晕]@2x.png
new file mode 100644
index 0000000..2bd83a4
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[晕]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[月亮]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[月亮]@2x.png
new file mode 100644
index 0000000..eb37fb9
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[月亮]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[棒棒糖]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[棒棒糖]@2x.png
new file mode 100644
index 0000000..4f58458
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[棒棒糖]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[汽车]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[汽车]@2x.png
new file mode 100644
index 0000000..14363af
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[汽车]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[沙发]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[沙发]@2x.png
new file mode 100644
index 0000000..87d233a
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[沙发]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[流汗]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[流汗]@2x.png
new file mode 100644
index 0000000..d835eeb
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[流汗]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[流泪]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[流泪]@2x.png
new file mode 100644
index 0000000..61dab0a
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[流泪]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[激动]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[激动]@2x.png
new file mode 100644
index 0000000..262b317
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[激动]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[灯泡]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[灯泡]@2x.png
new file mode 100644
index 0000000..b61a829
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[灯泡]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[炸弹]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[炸弹]@2x.png
new file mode 100644
index 0000000..62b5736
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[炸弹]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[熊猫]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[熊猫]@2x.png
new file mode 100644
index 0000000..e4088f8
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[熊猫]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[爆筋]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[爆筋]@2x.png
new file mode 100644
index 0000000..af054a7
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[爆筋]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[爱你]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[爱你]@2x.png
new file mode 100644
index 0000000..5be2bd0
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[爱你]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[爱心]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[爱心]@2x.png
new file mode 100644
index 0000000..4474769
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[爱心]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[爱情]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[爱情]@2x.png
new file mode 100644
index 0000000..4f2263d
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[爱情]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[猪头]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[猪头]@2x.png
new file mode 100644
index 0000000..535548b
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[猪头]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[猫咪]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[猫咪]@2x.png
new file mode 100644
index 0000000..c0b1a89
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[猫咪]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[献吻]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[献吻]@2x.png
new file mode 100644
index 0000000..33da041
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[献吻]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[玫瑰]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[玫瑰]@2x.png
new file mode 100644
index 0000000..faac04b
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[玫瑰]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[瓢虫]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[瓢虫]@2x.png
new file mode 100644
index 0000000..8fcd467
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[瓢虫]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[疑问]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[疑问]@2x.png
new file mode 100644
index 0000000..72376dd
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[疑问]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[白眼]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[白眼]@2x.png
new file mode 100644
index 0000000..0a8a259
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[白眼]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[皮球]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[皮球]@2x.png
new file mode 100644
index 0000000..6dcf45e
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[皮球]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[睡觉]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[睡觉]@2x.png
new file mode 100644
index 0000000..aafb55f
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[睡觉]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[磕头]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[磕头]@2x.png
new file mode 100644
index 0000000..817923a
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[磕头]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[示爱]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[示爱]@2x.png
new file mode 100644
index 0000000..7be52ca
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[示爱]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[礼品袋]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[礼品袋]@2x.png
new file mode 100644
index 0000000..5d017c8
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[礼品袋]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[礼物]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[礼物]@2x.png
new file mode 100644
index 0000000..5b606ff
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[礼物]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[篮球]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[篮球]@2x.png
new file mode 100644
index 0000000..aee5674
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[篮球]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[米饭]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[米饭]@2x.png
new file mode 100644
index 0000000..2c469a9
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[米饭]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[糗大了]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[糗大了]@2x.png
new file mode 100644
index 0000000..4373f1b
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[糗大了]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[红双喜]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[红双喜]@2x.png
new file mode 100644
index 0000000..b37d964
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[红双喜]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[红灯笼]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[红灯笼]@2x.png
new file mode 100644
index 0000000..bb432af
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[红灯笼]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[纸巾]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[纸巾]@2x.png
new file mode 100644
index 0000000..10469fe
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[纸巾]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[胜利]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[胜利]@2x.png
new file mode 100644
index 0000000..ac5cefa
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[胜利]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[色]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[色]@2x.png
new file mode 100644
index 0000000..a45e109
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[色]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[药]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[药]@2x.png
new file mode 100644
index 0000000..1588f9e
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[药]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[菜刀]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[菜刀]@2x.png
new file mode 100644
index 0000000..69072bb
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[菜刀]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[蛋糕]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[蛋糕]@2x.png
new file mode 100644
index 0000000..279eb79
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[蛋糕]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[蜡烛]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[蜡烛]@2x.png
new file mode 100644
index 0000000..9f06f3e
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[蜡烛]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[街舞]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[街舞]@2x.png
new file mode 100644
index 0000000..c8045d8
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[街舞]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[衰]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[衰]@2x.png
new file mode 100644
index 0000000..b055d46
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[衰]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[西瓜]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[西瓜]@2x.png
new file mode 100644
index 0000000..0d79d2a
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[西瓜]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[调皮]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[调皮]@2x.png
new file mode 100644
index 0000000..11f0646
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[调皮]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[象棋]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[象棋]@2x.png
new file mode 100644
index 0000000..cf35cad
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[象棋]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[跳绳]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[跳绳]@2x.png
new file mode 100644
index 0000000..17cffd3
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[跳绳]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[跳跳]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[跳跳]@2x.png
new file mode 100644
index 0000000..b5646c6
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[跳跳]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[车厢]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[车厢]@2x.png
new file mode 100644
index 0000000..a1276eb
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[车厢]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[转圈]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[转圈]@2x.png
new file mode 100644
index 0000000..2c15311
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[转圈]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[鄙视]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[鄙视]@2x.png
new file mode 100644
index 0000000..65b1aec
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[鄙视]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[酷]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[酷]@2x.png
new file mode 100644
index 0000000..06d8163
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[酷]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[钞票]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[钞票]@2x.png
new file mode 100644
index 0000000..7218532
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[钞票]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[钻戒]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[钻戒]@2x.png
new file mode 100644
index 0000000..787cb6a
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[钻戒]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[闪电]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[闪电]@2x.png
new file mode 100644
index 0000000..84f1526
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[闪电]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[闭嘴]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[闭嘴]@2x.png
new file mode 100644
index 0000000..d1d3d3b
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[闭嘴]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[闹钟]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[闹钟]@2x.png
new file mode 100644
index 0000000..daade80
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[闹钟]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[阴险]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[阴险]@2x.png
new file mode 100644
index 0000000..e277198
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[阴险]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[难过]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[难过]@2x.png
new file mode 100644
index 0000000..35bd8ec
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[难过]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[雨伞]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[雨伞]@2x.png
new file mode 100644
index 0000000..5011da4
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[雨伞]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[青蛙]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[青蛙]@2x.png
new file mode 100644
index 0000000..4b69277
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[青蛙]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[面条]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[面条]@2x.png
new file mode 100644
index 0000000..78e8e71
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[面条]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[鞭炮]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[鞭炮]@2x.png
new file mode 100644
index 0000000..ec12c3e
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[鞭炮]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[风车]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[风车]@2x.png
new file mode 100644
index 0000000..02321c3
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[风车]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[飞吻]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[飞吻]@2x.png
new file mode 100644
index 0000000..a9a4e16
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[飞吻]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[飞机]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[飞机]@2x.png
new file mode 100644
index 0000000..f407930
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[飞机]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[饥饿]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[饥饿]@2x.png
new file mode 100644
index 0000000..5bbd805
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[饥饿]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[香蕉]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[香蕉]@2x.png
new file mode 100644
index 0000000..b3bde3c
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[香蕉]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[骷髅]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[骷髅]@2x.png
new file mode 100644
index 0000000..c4ee653
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[骷髅]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[麦克风]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[麦克风]@2x.png
new file mode 100644
index 0000000..0e0ae99
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[麦克风]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[麻将]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[麻将]@2x.png
new file mode 100644
index 0000000..011d8e2
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[麻将]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[鼓掌]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[鼓掌]@2x.png
new file mode 100644
index 0000000..18cd1d2
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[鼓掌]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/assets/emoji/[龇牙]@2x.png b/TIMCommon/timcommon/src/main/assets/emoji/[龇牙]@2x.png
new file mode 100644
index 0000000..4fed0fc
Binary files /dev/null and b/TIMCommon/timcommon/src/main/assets/emoji/[龇牙]@2x.png differ
diff --git a/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/TIMCommonConfig.java b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/TIMCommonConfig.java
new file mode 100644
index 0000000..f380165
--- /dev/null
+++ b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/TIMCommonConfig.java
@@ -0,0 +1,68 @@
+package com.tencent.qcloud.tuikit.timcommon;
+
+public class TIMCommonConfig {
+ private static boolean enableGroupGridAvatar = true;
+ private static int defaultAvatarImage;
+ private static int defaultGroupAvatarImage;
+
+ /**
+ * 获取群组会话否展示九宫格样式的头像,默认为 true
+ * Gets whether to display the avatar in the nine-square grid style in the group conversation, the default is true
+ */
+ public static boolean isEnableGroupGridAvatar() {
+ return enableGroupGridAvatar;
+ }
+
+ /**
+ * 设置群组会话是否展示九宫格样式的头像
+ * Set whether to display the avatar in the nine-square grid style in group conversations
+ */
+ public static void setEnableGroupGridAvatar(boolean enableGroupGridAvatar) {
+ TIMCommonConfig.enableGroupGridAvatar = enableGroupGridAvatar;
+ }
+
+ /**
+ * 获取 c2c 会话的默认头像
+ *
+ * Get the default avatar for c2c conversation
+ *
+ * @return
+ */
+ public static int getDefaultAvatarImage() {
+ return defaultAvatarImage;
+ }
+
+ /**
+ * 设置 c2c 会话的默认头像
+ *
+ *Set the default avatar for c2c conversation
+ *
+ * @return
+ */
+ public static void setDefaultAvatarImage(int defaultAvatarImage) {
+ TIMCommonConfig.defaultAvatarImage = defaultAvatarImage;
+ }
+
+ /**
+ * 获取 group 会话的默认头像
+ *
+ * Get the default avatar for group conversation
+ *
+ * @return
+ */
+ public static int getDefaultGroupAvatarImage() {
+ return defaultGroupAvatarImage;
+ }
+
+ /**
+ * 设置 group 会话的默认头像
+ *
+ *Set the default avatar for group conversation
+ *
+ * @return
+ */
+ public static void setDefaultGroupAvatarImage(int defaultGroupAvatarImage) {
+ TIMCommonConfig.defaultGroupAvatarImage = defaultGroupAvatarImage;
+ }
+
+}
diff --git a/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/TIMCommonService.java b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/TIMCommonService.java
new file mode 100644
index 0000000..636ff0e
--- /dev/null
+++ b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/TIMCommonService.java
@@ -0,0 +1,28 @@
+package com.tencent.qcloud.tuikit.timcommon;
+
+import android.content.Context;
+
+import com.tencent.qcloud.tuicore.ServiceInitializer;
+
+public class TIMCommonService extends ServiceInitializer {
+
+ @Override
+ public void init(Context context) {
+ super.init(context);
+ }
+
+ @Override
+ public int getLightThemeResId() {
+ return R.style.TIMCommonLightTheme;
+ }
+
+ @Override
+ public int getLivelyThemeResId() {
+ return R.style.TIMCommonLivelyTheme;
+ }
+
+ @Override
+ public int getSeriousThemeResId() {
+ return R.style.TIMCommonSeriousTheme;
+ }
+}
diff --git a/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/MessageFeature.java b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/MessageFeature.java
new file mode 100644
index 0000000..e446579
--- /dev/null
+++ b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/MessageFeature.java
@@ -0,0 +1,33 @@
+package com.tencent.qcloud.tuikit.timcommon.bean;
+
+import java.io.Serializable;
+
+/*
+ * 通过消息携带功能宏,主要用于新老版本兼容,使用 cloudCustomData 字段。
+ * 像对方输入中功能。
+ *
+ * Carrying function macros through messages,Mainly used to be compatible with old and new versions,Use the cloudCustomData field.
+ * Such as Typing function.
+ */
+public class MessageFeature implements Serializable {
+ public static final int VERSION = 1;
+
+ private int needTyping = 1; // message typing feature ...
+ private int version = VERSION;
+
+ public int getVersion() {
+ return version;
+ }
+
+ public void setVersion(int version) {
+ this.version = version;
+ }
+
+ public int getNeedTyping() {
+ return needTyping;
+ }
+
+ public void setNeedTyping(int needTyping) {
+ this.needTyping = needTyping;
+ }
+}
diff --git a/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/MessageReactBean.java b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/MessageReactBean.java
new file mode 100644
index 0000000..9bd3d53
--- /dev/null
+++ b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/MessageReactBean.java
@@ -0,0 +1,66 @@
+package com.tencent.qcloud.tuikit.timcommon.bean;
+
+import java.io.Serializable;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class MessageReactBean implements Serializable {
+ public static final int VERSION = 1;
+
+ private Map> reacts;
+ private int version = VERSION;
+
+ private transient Map reactUserBeanMap;
+
+ public void operateUser(String emojiId, String userId) {
+ if (reacts == null) {
+ reacts = new LinkedHashMap<>();
+ }
+ Set userList = reacts.get(emojiId);
+ if (userList == null) {
+ userList = new LinkedHashSet<>();
+ reacts.put(emojiId, userList);
+ }
+ if (userList.contains(userId)) {
+ userList.remove(userId);
+ } else {
+ userList.add(userId);
+ }
+ if (userList.isEmpty()) {
+ reacts.remove(emojiId);
+ }
+ }
+
+ public Map> getReacts() {
+ return reacts;
+ }
+
+ public void setReacts(Map> reacts) {
+ this.reacts = reacts;
+ }
+
+ public int getReactSize() {
+ if (reacts != null) {
+ return reacts.size();
+ }
+ return 0;
+ }
+
+ public void setReactUserBeanMap(Map reactUserBeanMap) {
+ this.reactUserBeanMap = reactUserBeanMap;
+ }
+
+ public Map getReactUserBeanMap() {
+ return reactUserBeanMap;
+ }
+
+ public int getVersion() {
+ return version;
+ }
+
+ public void setVersion(int version) {
+ this.version = version;
+ }
+}
diff --git a/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/MessageReceiptInfo.java b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/MessageReceiptInfo.java
new file mode 100644
index 0000000..069db17
--- /dev/null
+++ b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/MessageReceiptInfo.java
@@ -0,0 +1,55 @@
+package com.tencent.qcloud.tuikit.timcommon.bean;
+
+import com.tencent.imsdk.v2.V2TIMMessageReceipt;
+
+import java.io.Serializable;
+
+public class MessageReceiptInfo implements Serializable {
+ private V2TIMMessageReceipt messageReceipt;
+
+ public void setMessageReceipt(V2TIMMessageReceipt messageReceipt) {
+ this.messageReceipt = messageReceipt;
+ }
+
+ public String getUserID() {
+ if (messageReceipt != null) {
+ return messageReceipt.getUserID();
+ }
+ return null;
+ }
+
+ public boolean isPeerRead() {
+ if (messageReceipt != null) {
+ return messageReceipt.isPeerRead();
+ }
+ return false;
+ }
+
+ public String getGroupID() {
+ if (messageReceipt != null) {
+ return messageReceipt.getGroupID();
+ }
+ return null;
+ }
+
+ public long getReadCount() {
+ if (messageReceipt != null) {
+ return messageReceipt.getReadCount();
+ }
+ return 0;
+ }
+
+ public long getUnreadCount() {
+ if (messageReceipt != null) {
+ return messageReceipt.getUnreadCount();
+ }
+ return 0;
+ }
+
+ public String getMsgID() {
+ if (messageReceipt != null) {
+ return messageReceipt.getMsgID();
+ }
+ return null;
+ }
+}
diff --git a/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/MessageRepliesBean.java b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/MessageRepliesBean.java
new file mode 100644
index 0000000..53d7bbe
--- /dev/null
+++ b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/MessageRepliesBean.java
@@ -0,0 +1,115 @@
+package com.tencent.qcloud.tuikit.timcommon.bean;
+
+import android.text.TextUtils;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public class MessageRepliesBean implements Serializable {
+ public static final int VERSION = 1;
+
+ public static class ReplyBean implements Serializable {
+ private String messageID;
+ private String messageAbstract;
+ private String messageSender;
+ transient private String senderFaceUrl;
+ transient private String senderShowName;
+ public String getMessageID() {
+ return messageID;
+ }
+
+ public void setMessageID(String messageID) {
+ this.messageID = messageID;
+ }
+
+ public String getMessageAbstract() {
+ return messageAbstract;
+ }
+
+ public void setMessageAbstract(String messageAbstract) {
+ this.messageAbstract = messageAbstract;
+ }
+
+ public String getMessageSender() {
+ return messageSender;
+ }
+
+ public void setMessageSender(String messageSender) {
+ this.messageSender = messageSender;
+ }
+
+ public void setSenderFaceUrl(String senderFaceUrl) {
+ this.senderFaceUrl = senderFaceUrl;
+ }
+
+ public String getSenderFaceUrl() {
+ return senderFaceUrl;
+ }
+
+ public void setSenderShowName(String senderShowName) {
+ this.senderShowName = senderShowName;
+ }
+
+ public String getSenderShowName() {
+ if (TextUtils.isEmpty(senderShowName)) {
+ return messageSender;
+ }
+ return senderShowName;
+ }
+ }
+
+ private List replies;
+ private int version = VERSION;
+
+ public void addReplyMessage(String messageId, String messageAbstract, String sender) {
+ if (replies == null) {
+ replies = new ArrayList<>();
+ }
+ for (ReplyBean replyBean : replies) {
+ if (TextUtils.equals(replyBean.messageID, messageId)) {
+ return;
+ }
+ }
+ ReplyBean replyBean = new ReplyBean();
+ replyBean.messageID = messageId;
+ replyBean.messageAbstract = messageAbstract;
+ replyBean.messageSender = sender;
+ replies.add(replyBean);
+ }
+
+ public void removeReplyMessage(String messageID) {
+ if (replies == null) {
+ return;
+ }
+ for (ReplyBean replyBean : replies) {
+ if (TextUtils.equals(replyBean.messageID, messageID)) {
+ replies.remove(replyBean);
+ return;
+ }
+ }
+ }
+
+ public void setVersion(int version) {
+ this.version = version;
+ }
+
+ public int getVersion() {
+ return version;
+ }
+
+ public List getReplies() {
+ return replies;
+ }
+
+ public void setReplies(List replies) {
+ this.replies = replies;
+ }
+
+ public int getRepliesSize() {
+ if (replies != null) {
+ return replies.size();
+ }
+ return 0;
+ }
+}
diff --git a/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/ReactUserBean.java b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/ReactUserBean.java
new file mode 100644
index 0000000..16622ab
--- /dev/null
+++ b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/ReactUserBean.java
@@ -0,0 +1,65 @@
+package com.tencent.qcloud.tuikit.timcommon.bean;
+
+import android.text.TextUtils;
+
+import java.io.Serializable;
+
+public class ReactUserBean implements Serializable {
+ private String userId;
+ private String nikeName;
+ private String nameCard;
+ private String friendRemark;
+ private String faceUrl;
+
+ public String getUserId() {
+ return userId;
+ }
+
+ public void setUserId(String userId) {
+ this.userId = userId;
+ }
+
+ public String getNikeName() {
+ return nikeName;
+ }
+
+ public void setNikeName(String nikeName) {
+ this.nikeName = nikeName;
+ }
+
+ public String getFriendRemark() {
+ return friendRemark;
+ }
+
+ public void setFriendRemark(String friendRemark) {
+ this.friendRemark = friendRemark;
+ }
+
+ public void setNameCard(String nameCard) {
+ this.nameCard = nameCard;
+ }
+
+ public String getNameCard() {
+ return nameCard;
+ }
+
+ public String getDisplayString() {
+ if (!TextUtils.isEmpty(nameCard)) {
+ return nameCard;
+ } else if (!TextUtils.isEmpty(friendRemark)) {
+ return friendRemark;
+ } else if (!TextUtils.isEmpty(nikeName)) {
+ return nikeName;
+ } else {
+ return userId;
+ }
+ }
+
+ public String getFaceUrl() {
+ return faceUrl;
+ }
+
+ public void setFaceUrl(String faceUrl) {
+ this.faceUrl = faceUrl;
+ }
+}
diff --git a/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/TUIMessageBean.java b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/TUIMessageBean.java
new file mode 100644
index 0000000..41aa82f
--- /dev/null
+++ b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/TUIMessageBean.java
@@ -0,0 +1,528 @@
+package com.tencent.qcloud.tuikit.timcommon.bean;
+
+import android.text.TextUtils;
+
+import com.tencent.imsdk.v2.V2TIMManager;
+import com.tencent.imsdk.v2.V2TIMMessage;
+import com.tencent.qcloud.tuikit.timcommon.R;
+import com.tencent.qcloud.tuikit.timcommon.TIMCommonService;
+import com.tencent.qcloud.tuikit.timcommon.util.MessageBuilder;
+import com.tencent.qcloud.tuikit.timcommon.util.MessageParser;
+import com.tencent.qcloud.tuikit.timcommon.util.TIMCommonConstants;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.Serializable;
+
+public abstract class TUIMessageBean implements Serializable {
+ /**
+ * 消息正常状态
+ *
+ * message normal
+ */
+ public static final int MSG_STATUS_NORMAL = 0;
+ /**
+ * 消息发送中状态
+ *
+ * message sending
+ */
+ public static final int MSG_STATUS_SENDING = 1;
+ /**
+ * 消息发送成功状态
+ *
+ * message send success
+ */
+ public static final int MSG_STATUS_SEND_SUCCESS = 2;
+ /**
+ * 消息发送失败状态
+ *
+ * message send failed
+ */
+ public static final int MSG_STATUS_SEND_FAIL = 3;
+
+ /**
+ * 消息未读状态
+ *
+ * message unread
+ */
+ public static final int MSG_STATUS_READ = 0x111;
+ /**
+ * 消息删除状态
+ *
+ * message deleted
+ */
+ public static final int MSG_STATUS_DELETE = 0x112;
+ /**
+ * 消息撤回状态
+ *
+ * messaage revoked
+ */
+ public static final int MSG_STATUS_REVOKE = 0x113;
+
+ /**
+ * 消息内容下载中状态
+ *
+ * message downloading
+ */
+ public static final int MSG_STATUS_DOWNLOADING = 4;
+ /**
+ * 消息内容未下载状态
+ *
+ * message undownloaded
+ */
+ public static final int MSG_STATUS_UN_DOWNLOAD = 5;
+ /**
+ * 消息内容已下载状态
+ *
+ * message downloaded
+ */
+ public static final int MSG_STATUS_DOWNLOADED = 6;
+ /**
+ * 消息翻译初始化状态
+ *
+ * message translation unknown
+ */
+ public static final int MSG_TRANSLATE_STATUS_UNKNOWN = 0;
+ /**
+ * 消息翻译隐藏状态
+ *
+ * message translation hidden
+ */
+ public static final int MSG_TRANSLATE_STATUS_HIDDEN = 1;
+ /**
+ * 消息翻译进行中状态
+ *
+ * message translation loading
+ */
+ public static final int MSG_TRANSLATE_STATUS_LOADING = 2;
+ /**
+ * 消息翻译展示状态
+ *
+ * message translation shown
+ */
+ public static final int MSG_TRANSLATE_STATUS_SHOWN = 3;
+
+ public static final String TRANSLATION_KEY = "translation";
+ public static final String TRANSLATION_VIEW_STATUS_KEY = "translation_view_status";
+
+ private V2TIMMessage v2TIMMessage;
+ private long msgTime;
+ private String extra;
+ private String id;
+ private boolean isGroup;
+ private int status;
+ private int downloadStatus;
+ private String selectText;
+ private int translationStatus = MSG_TRANSLATE_STATUS_UNKNOWN;
+ private boolean excludeFromHistory;
+ private boolean isUseMsgReceiverAvatar = false;
+ private boolean isEnableForward = true;
+
+ public void setExcludeFromHistory(boolean excludeFromHistory) {
+ this.excludeFromHistory = excludeFromHistory;
+ }
+
+ public boolean isExcludeFromHistory() {
+ return excludeFromHistory;
+ }
+
+ public void setUseMsgReceiverAvatar(boolean useMsgReceiverAvatar) {
+ isUseMsgReceiverAvatar = useMsgReceiverAvatar;
+ }
+
+ public boolean isUseMsgReceiverAvatar() {
+ return isUseMsgReceiverAvatar;
+ }
+
+ public boolean isEnableForward() {
+ return isEnableForward;
+ }
+
+ public void setEnableForward(boolean enableForward) {
+ isEnableForward = enableForward;
+ }
+
+ private MessageReceiptInfo messageReceiptInfo;
+ private MessageRepliesBean messageRepliesBean;
+ private MessageReactBean messageReactBean;
+
+ public MessageReactBean getMessageReactBean() {
+ return messageReactBean;
+ }
+
+ public MessageRepliesBean getMessageRepliesBean() {
+ return messageRepliesBean;
+ }
+
+ public void setMessageReactBean(MessageReactBean messageReactBean) {
+ this.messageReactBean = messageReactBean;
+ MessageBuilder.mergeCloudCustomData(this, TIMCommonConstants.MESSAGE_REACT_KEY, messageReactBean);
+ }
+
+ public void setMessageRepliesBean(MessageRepliesBean messageRepliesBean) {
+ this.messageRepliesBean = messageRepliesBean;
+ MessageBuilder.mergeCloudCustomData(this, TIMCommonConstants.MESSAGE_REPLIES_KEY, messageRepliesBean);
+ }
+
+ public void setMessageReceiptInfo(MessageReceiptInfo messageReceiptInfo) {
+ this.messageReceiptInfo = messageReceiptInfo;
+ }
+
+ public long getReadCount() {
+ if (messageReceiptInfo != null) {
+ return messageReceiptInfo.getReadCount();
+ }
+ return 0;
+ }
+
+ public long getUnreadCount() {
+ if (messageReceiptInfo != null) {
+ return messageReceiptInfo.getUnreadCount();
+ }
+ return 0;
+ }
+
+ public void setCommonAttribute(V2TIMMessage v2TIMMessage) {
+ msgTime = System.currentTimeMillis() / 1000;
+ this.v2TIMMessage = v2TIMMessage;
+
+ if (v2TIMMessage == null) {
+ return;
+ }
+
+ id = v2TIMMessage.getMsgID();
+ isGroup = !TextUtils.isEmpty(v2TIMMessage.getGroupID());
+
+ if (v2TIMMessage.getStatus() == V2TIMMessage.V2TIM_MSG_STATUS_LOCAL_REVOKED) {
+ status = MSG_STATUS_REVOKE;
+ if (isSelf()) {
+ extra = TIMCommonService.getAppContext().getString(R.string.revoke_tips_you);
+ } else if (isGroup) {
+ String message = TIMCommonConstants.covert2HTMLString(getSender());
+ extra = message + TIMCommonService.getAppContext().getString(R.string.revoke_tips);
+ } else {
+ extra = TIMCommonService.getAppContext().getString(R.string.revoke_tips_other);
+ }
+ } else {
+ if (isSelf()) {
+ if (v2TIMMessage.getStatus() == V2TIMMessage.V2TIM_MSG_STATUS_SEND_FAIL) {
+ status = MSG_STATUS_SEND_FAIL;
+ } else if (v2TIMMessage.getStatus() == V2TIMMessage.V2TIM_MSG_STATUS_SEND_SUCC) {
+ status = MSG_STATUS_SEND_SUCCESS;
+ } else if (v2TIMMessage.getStatus() == V2TIMMessage.V2TIM_MSG_STATUS_SENDING) {
+ status = MSG_STATUS_SENDING;
+ }
+ }
+ }
+
+ messageReactBean = MessageParser.parseMessageReact(this);
+ messageRepliesBean = MessageParser.parseMessageReplies(this);
+ }
+
+ public boolean isPeerRead() {
+ if (messageReceiptInfo != null) {
+ return messageReceiptInfo.isPeerRead();
+ }
+ return false;
+ }
+
+ public boolean isAllRead() {
+ return getUnreadCount() == 0 && getReadCount() > 0;
+ }
+
+ public boolean isUnread() {
+ return getReadCount() == 0;
+ }
+
+ /**
+ * 获取要显示在会话列表的消息摘要
+ *
+ * Get a summary of messages to display in the conversation list
+ * @return
+ */
+ public abstract String onGetDisplayString();
+
+ public abstract void onProcessMessage(V2TIMMessage v2TIMMessage);
+
+ public final long getMessageTime() {
+ if (v2TIMMessage != null) {
+ long timestamp = v2TIMMessage.getTimestamp();
+ if (timestamp != 0) {
+ return timestamp;
+ }
+ }
+ return msgTime;
+ }
+
+ public long getMsgSeq() {
+ if (v2TIMMessage != null) {
+ return v2TIMMessage.getSeq();
+ }
+ return 0;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+
+ public String getUserId() {
+ if (v2TIMMessage != null) {
+ return v2TIMMessage.getUserID();
+ }
+ return "";
+ }
+
+ public boolean isSelf() {
+ if (v2TIMMessage != null) {
+ return v2TIMMessage.isSelf();
+ }
+ return true;
+ }
+
+ public String getSender() {
+ String sender = null;
+ if (v2TIMMessage != null) {
+ sender = v2TIMMessage.getSender();
+ }
+ if (TextUtils.isEmpty(sender)) {
+ sender = V2TIMManager.getInstance().getLoginUser();
+ }
+ return sender;
+ }
+
+ public V2TIMMessage getV2TIMMessage() {
+ return v2TIMMessage;
+ }
+
+ public boolean isGroup() {
+ return isGroup;
+ }
+
+ public void setGroup(boolean group) {
+ isGroup = group;
+ }
+
+ public String getGroupId() {
+ if (v2TIMMessage != null) {
+ return v2TIMMessage.getGroupID();
+ }
+ return "";
+ }
+
+ public String getNameCard() {
+ if (v2TIMMessage != null) {
+ return v2TIMMessage.getNameCard();
+ }
+ return "";
+ }
+
+ public String getNickName() {
+ if (v2TIMMessage != null) {
+ return v2TIMMessage.getNickName();
+ }
+ return "";
+ }
+
+ public String getFriendRemark() {
+ if (v2TIMMessage != null) {
+ return v2TIMMessage.getFriendRemark();
+ }
+ return "";
+ }
+
+ public String getUserDisplayName() {
+ String displayName;
+ if (!TextUtils.isEmpty(getNameCard())) {
+ displayName = getNameCard();
+ } else if (!TextUtils.isEmpty(getFriendRemark())) {
+ displayName = getFriendRemark();
+ } else if (!TextUtils.isEmpty(getNickName())) {
+ displayName = getNickName();
+ } else {
+ displayName = getSender();
+ }
+ return displayName;
+ }
+
+ public String getFaceUrl() {
+ if (v2TIMMessage != null) {
+ return v2TIMMessage.getFaceUrl();
+ }
+ return "";
+ }
+
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+
+ public void setExtra(String extra) {
+ this.extra = extra;
+ }
+
+ public String getExtra() {
+ return extra;
+ }
+
+ public void setDownloadStatus(int downloadStatus) {
+ this.downloadStatus = downloadStatus;
+ }
+
+ public int getDownloadStatus() {
+ return downloadStatus;
+ }
+
+ public int getMsgType() {
+ if (v2TIMMessage != null) {
+ return v2TIMMessage.getElemType();
+ } else {
+ return V2TIMMessage.V2TIM_ELEM_TYPE_NONE;
+ }
+ }
+
+ public boolean isNeedReadReceipt() {
+ if (v2TIMMessage != null) {
+ return v2TIMMessage.isNeedReadReceipt();
+ }
+ return false;
+ }
+
+ public void setNeedReadReceipt(boolean isNeedReceipt) {
+ if (v2TIMMessage != null) {
+ v2TIMMessage.setNeedReadReceipt(isNeedReceipt);
+ }
+ }
+
+ public void setTranslationStatus(int status) {
+ if (status != MSG_TRANSLATE_STATUS_UNKNOWN &&
+ status != MSG_TRANSLATE_STATUS_HIDDEN &&
+ status != MSG_TRANSLATE_STATUS_SHOWN &&
+ status != MSG_TRANSLATE_STATUS_LOADING) {
+ return;
+ }
+
+ if (status == translationStatus) {
+ return;
+ }
+
+ if (status == MSG_TRANSLATE_STATUS_LOADING) {
+ translationStatus = MSG_TRANSLATE_STATUS_LOADING;
+ return;
+ }
+
+ translationStatus = status;
+
+ if (v2TIMMessage != null) {
+ String localCustomData = v2TIMMessage.getLocalCustomData();
+ JSONObject customJson = new JSONObject();
+ try {
+ if (!TextUtils.isEmpty(localCustomData)) {
+ customJson = new JSONObject(localCustomData);
+ }
+ customJson.put(TRANSLATION_VIEW_STATUS_KEY, status);
+ v2TIMMessage.setLocalCustomData(customJson.toString());
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public int getTranslationStatus() {
+ if (translationStatus != MSG_TRANSLATE_STATUS_UNKNOWN) {
+ return translationStatus;
+ }
+
+ if (v2TIMMessage != null) {
+ String localCustomData = v2TIMMessage.getLocalCustomData();
+ if (TextUtils.isEmpty(localCustomData)) {
+ return translationStatus;
+ }
+ try {
+ JSONObject customJson = new JSONObject(localCustomData);
+ if (customJson.has(TRANSLATION_VIEW_STATUS_KEY)) {
+ translationStatus = customJson.getInt(TRANSLATION_VIEW_STATUS_KEY);
+ }
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ return translationStatus;
+ }
+
+ public void setTranslation(String translation) {
+ if (v2TIMMessage != null) {
+ String localCustomData = v2TIMMessage.getLocalCustomData();
+ JSONObject customJson = new JSONObject();
+ try {
+ if (!TextUtils.isEmpty(localCustomData)) {
+ customJson = new JSONObject(localCustomData);
+ }
+ customJson.put(TRANSLATION_KEY, translation);
+ customJson.put(TRANSLATION_VIEW_STATUS_KEY, MSG_TRANSLATE_STATUS_SHOWN);
+ v2TIMMessage.setLocalCustomData(customJson.toString());
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ translationStatus = MSG_TRANSLATE_STATUS_SHOWN;
+ }
+ }
+
+ public String getTranslation() {
+ String translation = "";
+ if (v2TIMMessage != null) {
+ String localCustomData = v2TIMMessage.getLocalCustomData();
+ if (TextUtils.isEmpty(localCustomData)) {
+ return translation;
+ }
+ try {
+ JSONObject customJson = new JSONObject(localCustomData);
+ if (customJson.has(TRANSLATION_KEY)) {
+ translation = customJson.getString(TRANSLATION_KEY);
+ }
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ return translation;
+ }
+
+ public void setV2TIMMessage(V2TIMMessage v2TIMMessage) {
+ this.v2TIMMessage = v2TIMMessage;
+ setCommonAttribute(v2TIMMessage);
+ onProcessMessage(v2TIMMessage);
+ }
+
+ public void update(TUIMessageBean messageBean) {
+ setV2TIMMessage(messageBean.getV2TIMMessage());
+ }
+
+ public String getSelectText() {
+ return selectText;
+ }
+
+ public void setSelectText(String text) {
+ this.selectText = text;
+ }
+
+ public MessageFeature isSupportTyping() {
+ return MessageParser.isSupportTyping(this);
+ }
+
+ public void setMessageTypingFeature(MessageFeature messageFeature) {
+ MessageBuilder.mergeCloudCustomData(this, TIMCommonConstants.MESSAGE_FEATURE_KEY, messageFeature);
+ }
+
+ public Class extends TUIReplyQuoteBean> getReplyQuoteBeanClass() {
+ return null;
+ }
+
+}
diff --git a/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/TUIReplyQuoteBean.java b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/TUIReplyQuoteBean.java
new file mode 100644
index 0000000..a26d697
--- /dev/null
+++ b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/bean/TUIReplyQuoteBean.java
@@ -0,0 +1,36 @@
+package com.tencent.qcloud.tuikit.timcommon.bean;
+
+import java.io.Serializable;
+
+public abstract class TUIReplyQuoteBean implements Serializable {
+ private T messageBean;
+ protected String defaultAbstract;
+ protected int messageType;
+
+ public abstract void onProcessReplyQuoteBean(T messageBean);
+
+ public void setMessageBean(T messageBean) {
+ this.messageBean = messageBean;
+ }
+
+ public void setDefaultAbstract(String defaultAbstract) {
+ this.defaultAbstract = defaultAbstract;
+ }
+
+ public void setMessageType(int messageType) {
+ this.messageType = messageType;
+ }
+
+ public int getMessageType() {
+ return messageType;
+ }
+
+ public T getMessageBean() {
+ return messageBean;
+ }
+
+ public String getDefaultAbstract() {
+ return defaultAbstract;
+ }
+
+}
diff --git a/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/classicui/component/BeginnerGuidePage.java b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/classicui/component/BeginnerGuidePage.java
new file mode 100644
index 0000000..b86daca
--- /dev/null
+++ b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/classicui/component/BeginnerGuidePage.java
@@ -0,0 +1,182 @@
+package com.tencent.qcloud.tuikit.timcommon.classicui.component;
+
+import android.animation.ValueAnimator;
+import android.app.Activity;
+import android.graphics.drawable.ColorDrawable;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.view.animation.LinearInterpolator;
+import android.widget.ImageView;
+import android.widget.PopupWindow;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.viewpager2.widget.ViewPager2;
+
+import com.tencent.qcloud.tuicore.util.SPUtils;
+import com.tencent.qcloud.tuikit.timcommon.R;
+import com.tencent.qcloud.tuikit.timcommon.component.impl.GlideEngine;
+import com.tencent.qcloud.tuikit.timcommon.util.ScreenUtil;
+import com.tencent.qcloud.tuikit.timcommon.util.SoftKeyBoardUtil;
+import com.tencent.qcloud.tuikit.timcommon.util.TIMCommonConstants;
+
+public class BeginnerGuidePage {
+
+ private PopupWindow popupWindow;
+ private ViewPager2 viewPager;
+ private OnFinishListener onFinishListener;
+ private int[] resIDs;
+ public BeginnerGuidePage(Activity activity) {
+ View popupView = LayoutInflater.from(activity).inflate(R.layout.layout_beginner_guide, null);
+ viewPager = popupView.findViewById(R.id.view_pager);
+
+ popupWindow = new PopupWindow(popupView, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, true) {
+ @Override
+ public void showAtLocation(View anchor, int gravity, int x, int y) {
+ if (activity != null && !activity.isFinishing()) {
+ Window dialogWindow = activity.getWindow();
+ startAnimation(dialogWindow, true);
+ }
+ super.showAtLocation(anchor, gravity, x, y);
+ }
+
+ @Override
+ public void dismiss() {
+ if (activity != null && !activity.isFinishing()) {
+ Window dialogWindow = activity.getWindow();
+ startAnimation(dialogWindow, false);
+ }
+
+ super.dismiss();
+ }
+ };
+ popupWindow.setBackgroundDrawable(new ColorDrawable());
+ popupWindow.setTouchable(true);
+ popupWindow.setOutsideTouchable(false);
+ popupWindow.setAnimationStyle(R.style.BeginnerGuidePopupAnimation);
+ viewPager.setUserInputEnabled(false);
+ viewPager.setAdapter(new GuideAdapter());
+ }
+
+ private void startAnimation(Window window, boolean isShow) {
+ LinearInterpolator interpolator = new LinearInterpolator();
+ ValueAnimator animator;
+ if (isShow) {
+ animator = ValueAnimator.ofFloat(1.0f, 0.5f);
+ } else {
+ animator = ValueAnimator.ofFloat(0.5f, 1.0f);
+ }
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ WindowManager.LayoutParams lp = window.getAttributes();
+ lp.alpha = (float) animation.getAnimatedValue();
+ window.setAttributes(lp);
+ }
+ });
+
+ animator.setDuration(200);
+ animator.setInterpolator(interpolator);
+ animator.start();
+ }
+
+ public void setPagesResIDs(int... imageResIDs) {
+ resIDs = imageResIDs;
+ viewPager.setOffscreenPageLimit(resIDs.length);
+ viewPager.getAdapter().notifyDataSetChanged();
+ viewPager.setCurrentItem(0, false);
+ }
+
+ public void setOnFinishListener(OnFinishListener onFinishListener) {
+ this.onFinishListener = onFinishListener;
+ }
+
+ public void show(View rootView, int gravity) {
+ if (popupWindow != null) {
+ popupWindow.showAtLocation(rootView, gravity, 0, 0);
+ }
+ }
+
+ class GuideAdapter extends RecyclerView.Adapter {
+ @NonNull
+ @Override
+ public GuideViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ return new GuideViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_beginner_guide_item, parent ,false));
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull GuideViewHolder holder, int position) {
+ ViewGroup.LayoutParams params = holder.image.getLayoutParams();
+ if (params != null) {
+ params.width = ScreenUtil.getScreenWidth(holder.image.getContext());
+ params.height = ScreenUtil.getScreenHeight(holder.image.getContext());
+ holder.image.setLayoutParams(params);
+ }
+ GlideEngine.loadImage(holder.image, resIDs[position]);
+ holder.itemView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (viewPager != null) {
+ int currentPos = holder.getBindingAdapterPosition();
+ if (currentPos < getItemCount() - 1) {
+ viewPager.setCurrentItem(currentPos + 1, true);
+ } else {
+ if (onFinishListener != null) {
+ onFinishListener.onFinish();
+ }
+ if (popupWindow != null && popupWindow.isShowing()) {
+ popupWindow.dismiss();
+ }
+ }
+ }
+ }
+ });
+ }
+
+ @Override
+ public int getItemCount() {
+ if (resIDs == null) {
+ return 0;
+ }
+ return resIDs.length;
+ }
+
+ class GuideViewHolder extends RecyclerView.ViewHolder {
+ private final ImageView image;
+ public GuideViewHolder(@NonNull View itemView) {
+ super(itemView);
+ image = itemView.findViewById(R.id.center_image);
+ }
+ }
+ }
+
+
+ public static void showBeginnerGuideThen(View view, Runnable runnable) {
+ boolean isShowGuide = SPUtils.getInstance(TIMCommonConstants.CHAT_SETTINGS_SP_NAME).getBoolean(TIMCommonConstants.CHAT_REPLY_GUIDE_SHOW_SP_KEY, true);
+ if (isShowGuide) {
+ SoftKeyBoardUtil.hideKeyBoard(view.getWindowToken());
+ SPUtils.getInstance(TIMCommonConstants.CHAT_SETTINGS_SP_NAME).put(TIMCommonConstants.CHAT_REPLY_GUIDE_SHOW_SP_KEY, false);
+
+ BeginnerGuidePage guidePage = new BeginnerGuidePage((Activity) view.getContext());
+ guidePage.setPagesResIDs(R.drawable.chat_reply_guide, R.drawable.chat_quote_guide);
+ guidePage.setOnFinishListener(new BeginnerGuidePage.OnFinishListener() {
+ @Override
+ public void onFinish() {
+ runnable.run();
+ }
+ });
+ guidePage.show(view, Gravity.NO_GRAVITY);
+ } else {
+ runnable.run();
+ }
+ }
+
+ @FunctionalInterface
+ public interface OnFinishListener {
+ void onFinish();
+ }
+}
diff --git a/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/classicui/widget/message/ChatFlowReactView.java b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/classicui/widget/message/ChatFlowReactView.java
new file mode 100644
index 0000000..9d0efae
--- /dev/null
+++ b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/classicui/widget/message/ChatFlowReactView.java
@@ -0,0 +1,256 @@
+package com.tencent.qcloud.tuikit.timcommon.classicui.widget.message;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.tencent.qcloud.tuicore.TUIThemeManager;
+import com.tencent.qcloud.tuikit.timcommon.R;
+import com.tencent.qcloud.tuikit.timcommon.bean.MessageReactBean;
+import com.tencent.qcloud.tuikit.timcommon.bean.ReactUserBean;
+import com.tencent.qcloud.tuikit.timcommon.component.face.FaceManager;
+
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Set;
+
+public class ChatFlowReactView extends RecyclerView {
+ private ChatFlowReactLayoutManager layoutManager;
+ private ChatFlowReactAdapter adapter;
+ private int themeColorId;
+ public ChatFlowReactView(@NonNull Context context) {
+ super(context);
+ initView();
+ }
+
+ public ChatFlowReactView(@NonNull Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ initView();
+ }
+
+ public ChatFlowReactView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ initView();
+ }
+
+ private void initView() {
+
+ DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
+ float spacingVertical = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 7.68f, displayMetrics);
+ float spacingHorizontal = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5.76f, displayMetrics);
+
+ layoutManager = new ChatFlowReactLayoutManager(spacingHorizontal, spacingVertical);
+ setLayoutManager(layoutManager);
+ adapter = new ChatFlowReactAdapter();
+ setAdapter(adapter);
+ }
+
+ public void setThemeColorId(int themeColorId) {
+ this.themeColorId = themeColorId;
+ adapter.setThemeColorId(themeColorId);
+ }
+
+ public void setReactOnClickListener(ReactOnClickListener reactOnClickListener) {
+ if (adapter != null) {
+ adapter.setReactOnClickListener(reactOnClickListener);
+ }
+ }
+
+ public void setData(MessageReactBean reactBean) {
+ if (adapter != null) {
+ adapter.setData(reactBean);
+ adapter.notifyDataSetChanged();
+ }
+ }
+
+ static class ChatFlowReactAdapter extends Adapter {
+ private MessageReactBean data;
+ private ReactOnClickListener reactOnClickListener;
+ private int themeColorId;
+ public void setReactOnClickListener(ReactOnClickListener reactOnClickListener) {
+ this.reactOnClickListener = reactOnClickListener;
+ }
+
+ public void setThemeColorId(int themeColorId) {
+ this.themeColorId = themeColorId;
+ }
+
+ public void setData(MessageReactBean data) {
+ this.data = data;
+ }
+
+ @NonNull
+ @Override
+ public ChatFlowReactViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_flow_react_item_layout, parent, false);
+ return new ChatFlowReactViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull ChatFlowReactViewHolder holder, int position) {
+ Map.Entry> entry = new ArrayList<>(data.getReacts().entrySet()).get(position);
+ String emojiId = entry.getKey();
+ Set userIds = entry.getValue();
+
+ Bitmap bitmap = FaceManager.getEmoji(emojiId);
+ holder.faceImageView.setImageBitmap(bitmap);
+
+ holder.faceImageView.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (reactOnClickListener != null) {
+ reactOnClickListener.onClick(emojiId);
+ }
+ }
+ });
+ if (themeColorId != 0) {
+ holder.userTextView.setTextColor(holder.userTextView.getResources().getColor(themeColorId));
+ holder.userTextView.setTextColor(holder.userTextView.getResources().getColor(themeColorId));
+ } else {
+ holder.userTextView.setTextColor(holder.userTextView.getResources().getColor(
+ TUIThemeManager.getAttrResId(holder.userTextView.getContext(), R.attr.chat_react_text_color)));
+ holder.userTextView.setTextColor(holder.userTextView.getResources().getColor(
+ TUIThemeManager.getAttrResId(holder.userTextView.getContext(), R.attr.chat_react_text_color)));
+ }
+ holder.userTextView.setText(formatDisplayUserName(userIds));
+ }
+
+ private String getUserDisplayName(String id) {
+ if (data.getReactUserBeanMap() == null) {
+ return id;
+ } else {
+ ReactUserBean reactUserBean = data.getReactUserBeanMap().get(id);
+ if (reactUserBean == null) {
+ return id;
+ } else {
+ return reactUserBean.getDisplayString();
+ }
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ if (data != null) {
+ return data.getReactSize();
+ }
+ return 0;
+ }
+
+ private String formatDisplayUserName(Set userIds) {
+ StringBuilder stringBuilder = new StringBuilder();
+ int index = 0;
+ for (String userId : userIds) {
+ stringBuilder.append(getUserDisplayName(userId));
+ index++;
+ if (index != userIds.size()) {
+ stringBuilder.append("、");
+ }
+ }
+ return stringBuilder.toString();
+ }
+ }
+
+ public interface ReactOnClickListener {
+ void onClick(String emojiId);
+ }
+
+ static class ChatFlowReactViewHolder extends ViewHolder {
+ public TextView userTextView;
+ public ImageView faceImageView;
+ public ChatFlowReactViewHolder(@NonNull View itemView) {
+ super(itemView);
+ userTextView = itemView.findViewById(R.id.users_tv);
+ faceImageView = itemView.findViewById(R.id.face_iv);
+ }
+ }
+
+
+ // ChatReactView is just a simple flowLayout
+ static class ChatFlowReactLayoutManager extends LayoutManager {
+ private int verticalSpacing = 0;
+ private int horizontalSpacing = 0;
+
+ public ChatFlowReactLayoutManager() {}
+
+ public ChatFlowReactLayoutManager(float horizontalSpacing, float verticalSpacing) {
+ this.verticalSpacing = Math.round(verticalSpacing);
+ this.horizontalSpacing = Math.round(horizontalSpacing);
+ }
+
+ @Override
+ public LayoutParams generateDefaultLayoutParams() {
+ return new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+ }
+
+ @Override
+ public void onLayoutChildren(Recycler recycler, State state) {
+ detachAndScrapAttachedViews(recycler);
+ int itemCount = getItemCount();
+ if (itemCount == 0) {
+ return;
+ }
+
+ int offsetTop;
+ int offsetBottom;
+ int offsetLeft;
+ int offsetRight = getPaddingStart();
+
+ boolean isLineFirstItem = true;
+ boolean isFirstLine = true;
+
+ int currentMaxBottom = 0;
+ int nextMaxBottom = 0;
+ for (int i = 0; i < itemCount; i++) {
+ View childView = recycler.getViewForPosition(i);
+ addView(childView);
+ measureChildWithMargins(childView, 0, 0);
+ int childMeasuredWidth = getDecoratedMeasuredWidth(childView);
+ int childMeasuredHeight = getDecoratedMeasuredHeight(childView);
+
+ if (i != 0 && offsetRight + horizontalSpacing + childMeasuredWidth >
+ getWidth() - getPaddingStart() - getPaddingEnd()) {
+ // switch a new line
+ isLineFirstItem = true;
+ isFirstLine = false;
+ currentMaxBottom = nextMaxBottom;
+ }
+
+ if (isLineFirstItem) {
+ offsetLeft = getPaddingStart();
+ } else {
+ offsetLeft = offsetRight + horizontalSpacing;
+ }
+
+ if (isFirstLine) {
+ offsetTop = getPaddingTop();
+ } else {
+ offsetTop = currentMaxBottom + verticalSpacing;
+ }
+
+ offsetRight = offsetLeft + childMeasuredWidth;
+ offsetBottom = offsetTop + childMeasuredHeight;
+ nextMaxBottom = Math.max(nextMaxBottom, offsetBottom);
+
+ layoutDecoratedWithMargins(childView, offsetLeft, offsetTop, offsetRight, offsetBottom);
+
+ isLineFirstItem = false;
+ }
+ }
+
+ @Override
+ public boolean isAutoMeasureEnabled() {
+ return true;
+ }
+ }
+}
diff --git a/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/classicui/widget/message/MessageBaseHolder.java b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/classicui/widget/message/MessageBaseHolder.java
new file mode 100644
index 0000000..7d116a4
--- /dev/null
+++ b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/classicui/widget/message/MessageBaseHolder.java
@@ -0,0 +1,190 @@
+package com.tencent.qcloud.tuikit.timcommon.classicui.widget.message;
+
+import android.animation.Animator;
+import android.animation.ArgbEvaluator;
+import android.animation.ValueAnimator;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import androidx.cardview.widget.CardView;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.tencent.qcloud.tuikit.timcommon.R;
+import com.tencent.qcloud.tuikit.timcommon.bean.TUIMessageBean;
+import com.tencent.qcloud.tuikit.timcommon.component.MessageProperties;
+import com.tencent.qcloud.tuikit.timcommon.interfaces.ICommonMessageAdapter;
+import com.tencent.qcloud.tuikit.timcommon.interfaces.OnItemClickListener;
+import com.tencent.qcloud.tuikit.timcommon.util.DateTimeUtil;
+
+import java.util.Date;
+
+public abstract class MessageBaseHolder extends RecyclerView.ViewHolder {
+ public static final int MSG_TYPE_HEADER_VIEW = -99;
+
+ public ICommonMessageAdapter mAdapter;
+ public MessageProperties properties = MessageProperties.getInstance();
+ protected OnItemClickListener onItemClickListener;
+
+ public TextView chatTimeText;
+ public FrameLayout msgContentFrame;
+ public LinearLayout msgReplyDetailLayout;
+ public LinearLayout msgArea;
+ public CardView cardView;
+ public LinearLayout msgAreaAndReply;
+ public ChatFlowReactView reactView;
+ public CheckBox mMutiSelectCheckBox;
+ public RelativeLayout rightGroupLayout;
+ public RelativeLayout mContentLayout;
+
+ private ValueAnimator highLightAnimator;
+
+ public MessageBaseHolder(View itemView) {
+ super(itemView);
+ chatTimeText = itemView.findViewById(R.id.message_top_time_tv);
+ msgContentFrame = itemView.findViewById(R.id.msg_content_fl);
+ msgReplyDetailLayout = itemView.findViewById(R.id.msg_reply_detail_fl);
+ reactView = itemView.findViewById(R.id.reacts_view);
+ msgArea = itemView.findViewById(R.id.msg_area);
+ cardView = itemView.findViewById(R.id.cardView);
+ msgAreaAndReply = itemView.findViewById(R.id.msg_area_and_reply);
+ mMutiSelectCheckBox = itemView.findViewById(R.id.select_checkbox);
+ rightGroupLayout = itemView.findViewById(R.id.right_group_layout);
+ mContentLayout = itemView.findViewById(R.id.message_content_layout);
+ initVariableLayout();
+ }
+
+ public abstract int getVariableLayout();
+
+ private void setVariableLayout(int resId) {
+ if (msgContentFrame.getChildCount() == 0) {
+ View.inflate(itemView.getContext(), resId, msgContentFrame);
+ }
+ }
+
+ private void initVariableLayout() {
+ if (getVariableLayout() != 0) {
+ setVariableLayout(getVariableLayout());
+ }
+ }
+
+ public void setAdapter(ICommonMessageAdapter adapter) {
+ mAdapter = adapter;
+ }
+
+ public void setOnItemClickListener(OnItemClickListener listener) {
+ this.onItemClickListener = listener;
+ }
+
+ public OnItemClickListener getOnItemClickListener() {
+ return this.onItemClickListener;
+ }
+
+ public void layoutViews(final TUIMessageBean msg, final int position) {
+ if (properties.getChatTimeBubble() != null) {
+ chatTimeText.setBackground(properties.getChatTimeBubble());
+ }
+ if (properties.getChatTimeFontColor() != 0) {
+ chatTimeText.setTextColor(properties.getChatTimeFontColor());
+ }
+ if (properties.getChatTimeFontSize() != 0) {
+ chatTimeText.setTextSize(properties.getChatTimeFontSize());
+ }
+
+ if (position > 1) {
+ TUIMessageBean last = mAdapter.getItem(position - 1);
+ if (last != null) {
+ if (msg.getMessageTime() - last.getMessageTime() >= 5 * 60) {
+ chatTimeText.setVisibility(View.VISIBLE);
+ chatTimeText.setText(DateTimeUtil.getTimeFormatText(new Date(msg.getMessageTime() * 1000)));
+ } else {
+ chatTimeText.setVisibility(View.GONE);
+ }
+ }
+ } else {
+ chatTimeText.setVisibility(View.VISIBLE);
+ chatTimeText.setText(DateTimeUtil.getTimeFormatText(new Date(msg.getMessageTime() * 1000)));
+ }
+
+ if (cardView != null) {
+ cardView.setRadius(0);
+ cardView.setCardElevation(0);
+ cardView.setMaxCardElevation(0);
+ }
+ }
+
+ public void stopHighLight() {
+ if (highLightAnimator != null) {
+ highLightAnimator.cancel();
+ }
+ clearHighLightBackground();
+ }
+
+ public void startHighLight() {
+ int highLightColorDark = itemView.getResources().getColor(com.tencent.qcloud.tuikit.timcommon.R.color.chat_message_bubble_high_light_dark_color);
+ int highLightColorLight = itemView.getResources().getColor(com.tencent.qcloud.tuikit.timcommon.R.color.chat_message_bubble_high_light_light_color);
+
+ if (highLightAnimator == null) {
+ ArgbEvaluator argbEvaluator = new ArgbEvaluator();
+ highLightAnimator = new ValueAnimator();
+ highLightAnimator.setIntValues(highLightColorDark, highLightColorLight);
+ highLightAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ Integer color = (Integer) animation.getAnimatedValue();
+ setHighLightBackground(color);
+ }
+ });
+ highLightAnimator.addListener(new Animator.AnimatorListener() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ clearHighLightBackground();
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ clearHighLightBackground();
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+
+ }
+ });
+ highLightAnimator.setEvaluator(argbEvaluator);
+ highLightAnimator.setRepeatCount(3);
+ highLightAnimator.setDuration(250);
+ highLightAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ }
+ highLightAnimator.start();
+ }
+
+ public void setHighLightBackground(int color) {
+ Drawable drawable = msgArea.getBackground();
+ if (drawable != null) {
+ drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
+ }
+ }
+
+ public void clearHighLightBackground() {
+ Drawable drawable = msgArea.getBackground();
+ if (drawable != null) {
+ drawable.setColorFilter(null);
+ }
+ }
+
+ public CardView getCardView() {
+ return cardView;
+ }
+}
diff --git a/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/classicui/widget/message/MessageContentHolder.java b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/classicui/widget/message/MessageContentHolder.java
new file mode 100644
index 0000000..ed0c7f7
--- /dev/null
+++ b/TIMCommon/timcommon/src/main/java/com/tencent/qcloud/tuikit/timcommon/classicui/widget/message/MessageContentHolder.java
@@ -0,0 +1,626 @@
+package com.tencent.qcloud.tuikit.timcommon.classicui.widget.message;
+
+import android.text.TextUtils;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.tencent.imsdk.v2.V2TIMManager;
+import com.tencent.imsdk.v2.V2TIMMessage;
+import com.tencent.imsdk.v2.V2TIMUserFullInfo;
+import com.tencent.imsdk.v2.V2TIMValueCallback;
+import com.tencent.qcloud.tuicore.TUIConstants;
+import com.tencent.qcloud.tuicore.TUICore;
+import com.tencent.qcloud.tuicore.TUIThemeManager;
+import com.tencent.qcloud.tuikit.timcommon.R;
+import com.tencent.qcloud.tuikit.timcommon.TIMCommonService;
+import com.tencent.qcloud.tuikit.timcommon.bean.MessageReactBean;
+import com.tencent.qcloud.tuikit.timcommon.bean.MessageRepliesBean;
+import com.tencent.qcloud.tuikit.timcommon.bean.TUIMessageBean;
+import com.tencent.qcloud.tuikit.timcommon.component.fragments.BaseFragment;
+import com.tencent.qcloud.tuikit.timcommon.component.gatherimage.UserIconView;
+import com.tencent.qcloud.tuikit.timcommon.util.DateTimeUtil;
+import com.tencent.qcloud.tuikit.timcommon.util.ScreenUtil;
+import com.tencent.qcloud.tuikit.timcommon.util.TIMCommonLog;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+
+public abstract class MessageContentHolder extends MessageBaseHolder {
+
+ public UserIconView leftUserIcon;
+ public UserIconView rightUserIcon;
+ public TextView usernameText;
+ public LinearLayout msgContentLinear;
+ public ProgressBar sendingProgress;
+ public ImageView statusImage;
+ public TextView isReadText;
+ public TextView unreadAudioText;
+ public TextView messageDetailsTimeTv;
+ private FrameLayout translationContentFrameLayout;
+
+ public boolean isForwardMode = false;
+ public boolean isReplyDetailMode = false;
+ public boolean isMultiSelectMode = false;
+
+ private List mDataSource = new ArrayList<>();
+ protected SelectTextHelper selectableTextHelper;
+ // 是否显示翻译的内容。合并转发的消息详情界面不用展示翻译内容。
+ // Whether to display the translated content. The merged-forwarded message details activity does not display the translated content.
+ protected boolean isNeedShowTranslation = true;
+ protected boolean isShowRead = false;
+ private BaseFragment fragment;
+ private RecyclerView recyclerView;
+
+ public MessageContentHolder(View itemView) {
+ super(itemView);
+ leftUserIcon = itemView.findViewById(R.id.left_user_icon_view);
+ rightUserIcon = itemView.findViewById(R.id.right_user_icon_view);
+ usernameText = itemView.findViewById(R.id.user_name_tv);
+ msgContentLinear = itemView.findViewById(R.id.msg_content_ll);
+ statusImage = itemView.findViewById(R.id.message_status_iv);
+ sendingProgress = itemView.findViewById(R.id.message_sending_pb);
+ isReadText = itemView.findViewById(R.id.is_read_tv);
+ unreadAudioText = itemView.findViewById(R.id.audio_unread);
+ messageDetailsTimeTv = itemView.findViewById(R.id.msg_detail_time_tv);
+ translationContentFrameLayout = itemView.findViewById(R.id.translate_content_fl);
+ }
+
+ public void setFragment(BaseFragment fragment) {
+ this.fragment = fragment;
+ }
+
+ public void setRecyclerView(RecyclerView recyclerView) {
+ this.recyclerView = recyclerView;
+ }
+
+ public void setDataSource(List dataSource) {
+ if (dataSource == null || dataSource.isEmpty()) {
+ mDataSource = null;
+ }
+
+ List mediaSource = new ArrayList<>();
+ for(TUIMessageBean messageBean : dataSource) {
+ int type = messageBean.getMsgType();
+ if (type == V2TIMMessage.V2TIM_ELEM_TYPE_IMAGE || type == V2TIMMessage.V2TIM_ELEM_TYPE_VIDEO) {
+ mediaSource.add(messageBean);
+ }
+ }
+ mDataSource = mediaSource;
+ }
+
+ public List getDataSource() {
+ return mDataSource;
+ }
+
+ public void resetSelectableText() {
+ if (selectableTextHelper != null) {
+ selectableTextHelper.reset();
+ }
+ }
+
+ @Override
+ public void layoutViews(final TUIMessageBean msg, final int position) {
+ super.layoutViews(msg, position);
+
+ if (isForwardMode || isReplyDetailMode) {
+ leftUserIcon.setVisibility(View.VISIBLE);
+ rightUserIcon.setVisibility(View.GONE);
+ } else {
+ if (msg.isSelf()) {
+ leftUserIcon.setVisibility(View.GONE);
+ rightUserIcon.setVisibility(View.VISIBLE);
+ } else {
+ leftUserIcon.setVisibility(View.VISIBLE);
+ rightUserIcon.setVisibility(View.GONE);
+ }
+ }
+ if (properties.getAvatar() != 0) {
+ leftUserIcon.setDefaultImageResId(properties.getAvatar());
+ rightUserIcon.setDefaultImageResId(properties.getAvatar());
+ } else {
+ leftUserIcon.setDefaultImageResId(TUIThemeManager.getAttrResId(leftUserIcon.getContext(), com.tencent.qcloud.tuikit.timcommon.R.attr.core_default_user_icon));
+ rightUserIcon.setDefaultImageResId(TUIThemeManager.getAttrResId(rightUserIcon.getContext(), com.tencent.qcloud.tuikit.timcommon.R.attr.core_default_user_icon));
+ }
+ if (properties.getAvatarRadius() != 0) {
+ leftUserIcon.setRadius(properties.getAvatarRadius());
+ rightUserIcon.setRadius(properties.getAvatarRadius());
+ } else {
+ int radius = ScreenUtil.dip2px(25);
+ leftUserIcon.setRadius(radius);
+ rightUserIcon.setRadius(radius);
+ }
+ if (properties.getAvatarSize() != null && properties.getAvatarSize().length == 2) {
+ ViewGroup.LayoutParams params = leftUserIcon.getLayoutParams();
+ params.width = properties.getAvatarSize()[0];
+ params.height = properties.getAvatarSize()[1];
+ leftUserIcon.setLayoutParams(params);
+
+ params = rightUserIcon.getLayoutParams();
+ params.width = properties.getAvatarSize()[0];
+ params.height = properties.getAvatarSize()[1];
+ rightUserIcon.setLayoutParams(params);
+ }
+
+ if (isForwardMode || isReplyDetailMode) {
+ usernameText.setVisibility(View.VISIBLE);
+ } else {
+ if (msg.isSelf()) {
+ if (properties.getRightNameVisibility() == 0) {
+ usernameText.setVisibility(View.GONE);
+ } else {
+ usernameText.setVisibility(properties.getRightNameVisibility());
+ }
+ } else {
+ if (properties.getLeftNameVisibility() == 0) {
+ if (msg.isGroup()) {
+ usernameText.setVisibility(View.VISIBLE);
+ } else {
+ usernameText.setVisibility(View.GONE);
+ }
+ } else {
+ usernameText.setVisibility(properties.getLeftNameVisibility());
+ }
+ }
+ }
+ if (properties.getNameFontColor() != 0) {
+ usernameText.setTextColor(properties.getNameFontColor());
+ }
+ if (properties.getNameFontSize() != 0) {
+ usernameText.setTextSize(properties.getNameFontSize());
+ }
+
+ if (!TextUtils.isEmpty(msg.getNameCard())) {
+ usernameText.setText(msg.getNameCard());
+ } else if (!TextUtils.isEmpty(msg.getFriendRemark())) {
+ usernameText.setText(msg.getFriendRemark());
+ } else if (!TextUtils.isEmpty(msg.getNickName())) {
+ usernameText.setText(msg.getNickName());
+ } else {
+ usernameText.setText(msg.getSender());
+ }
+
+ loadAvatar(msg);
+
+ if (isForwardMode || isReplyDetailMode) {
+ sendingProgress.setVisibility(View.GONE);
+ } else {
+ if (msg.isSelf()) {
+ if (msg.getStatus() == TUIMessageBean.MSG_STATUS_SEND_FAIL
+ || msg.getStatus() == TUIMessageBean.MSG_STATUS_SEND_SUCCESS
+ || msg.isPeerRead()) {
+ sendingProgress.setVisibility(View.GONE);
+ } else {
+ sendingProgress.setVisibility(View.VISIBLE);
+ }
+ } else {
+ sendingProgress.setVisibility(View.GONE);
+ }
+ }
+
+ if (isForwardMode || isReplyDetailMode) {
+ msgArea.setBackgroundResource(TUIThemeManager.getAttrResId(itemView.getContext(), R.attr.chat_bubble_other_bg));
+ statusImage.setVisibility(View.GONE);
+ } else {
+ if (msg.isSelf()) {
+ if (properties.getRightBubble() != null && properties.getRightBubble().getConstantState() != null) {
+ msgArea.setBackground(properties.getRightBubble().getConstantState().newDrawable());
+ } else {
+ msgArea.setBackgroundResource(TUIThemeManager.getAttrResId(itemView.getContext(), R.attr.chat_bubble_self_bg));
+ }
+ } else {
+ if (properties.getLeftBubble() != null && properties.getLeftBubble().getConstantState() != null) {
+ msgArea.setBackground(properties.getLeftBubble().getConstantState().newDrawable());
+ } else {
+ msgArea.setBackgroundResource(TUIThemeManager.getAttrResId(itemView.getContext(), R.attr.chat_bubble_other_bg));
+ }
+ }
+
+ if (onItemClickListener != null) {
+ msgContentFrame.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ onItemClickListener.onMessageLongClick(v, position, msg);
+ return true;
+ }
+ });
+
+ msgArea.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ onItemClickListener.onMessageLongClick(msgArea, position, msg);
+ return true;
+ }
+ });
+
+ leftUserIcon.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ onItemClickListener.onUserIconClick(view, position, msg);
+ }
+ });
+ leftUserIcon.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View view) {
+ onItemClickListener.onUserIconLongClick(view, position, msg);
+ return true;
+ }
+ });
+ rightUserIcon.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ onItemClickListener.onUserIconClick(view, position, msg);
+ }
+ });
+ }
+
+ if (msg.getStatus() == TUIMessageBean.MSG_STATUS_SEND_FAIL) {
+ statusImage.setVisibility(View.VISIBLE);
+ msgContentFrame.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (onItemClickListener != null) {
+ onItemClickListener.onMessageLongClick(msgContentFrame, position, msg);
+ }
+ }
+ });
+ statusImage.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (onItemClickListener != null) {
+ onItemClickListener.onSendFailBtnClick(statusImage, position, msg);
+ }
+ }
+ });
+ } else {
+ msgContentFrame.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (onItemClickListener != null) {
+ onItemClickListener.onMessageClick(msgContentFrame, position, msg);
+ }
+ }
+ });
+ statusImage.setVisibility(View.GONE);
+ }
+ }
+
+ if (isForwardMode || isReplyDetailMode) {
+ setGravity(true);
+ msgContentLinear.removeView(msgAreaAndReply);
+ msgContentLinear.addView(msgAreaAndReply);
+ } else {
+ if (msg.isSelf()) {
+ setGravity(false);
+ msgContentLinear.removeView(msgAreaAndReply);
+ msgContentLinear.addView(msgAreaAndReply);
+ } else {
+ setGravity(true);
+ msgContentLinear.removeView(msgAreaAndReply);
+ msgContentLinear.addView(msgAreaAndReply, 0);
+ }
+ }
+
+ if (rightGroupLayout != null) {
+ rightGroupLayout.setVisibility(View.VISIBLE);
+ }
+ msgContentLinear.setVisibility(View.VISIBLE);
+
+ // clear isReadText status
+ isReadText.setTextColor(isReadText.getResources().getColor(R.color.text_gray1));
+ isReadText.setOnClickListener(null);
+
+ if (isForwardMode || isReplyDetailMode) {
+ isReadText.setVisibility(View.GONE);
+ unreadAudioText.setVisibility(View.GONE);
+ } else {
+ if (isShowRead) {
+ if (msg.isSelf() && TUIMessageBean.MSG_STATUS_SEND_SUCCESS == msg.getStatus()) {
+ if (!msg.isNeedReadReceipt()) {
+ isReadText.setVisibility(View.GONE);
+ } else {
+ showReadText(msg);
+ }
+ } else {
+ isReadText.setVisibility(View.GONE);
+ }
+ }
+ unreadAudioText.setVisibility(View.GONE);
+ }
+
+ if (isReplyDetailMode) {
+ chatTimeText.setVisibility(View.GONE);
+ }
+
+ setReplyContent(msg);
+ setReactContent(msg);
+ if (isNeedShowTranslation) {
+ setTranslationContent(msg);
+ }
+
+ setMessageAreaPadding();
+
+ layoutVariableViews(msg, position);
+ }
+
+ private void setTranslationContent(TUIMessageBean msg) {
+ HashMap param = new HashMap<>();
+ param.put(TUIConstants.TUIChat.MESSAGE_BEAN, msg);
+ param.put(TUIConstants.TUIChat.CHAT_RECYCLER_VIEW, recyclerView);
+ param.put(TUIConstants.TUIChat.FRAGMENT, fragment);
+
+ TUICore.raiseExtension(TUIConstants.TUITranslation.Extension.TranslationView.CLASSIC_EXTENSION_ID, translationContentFrameLayout, param);
+ }
+
+ private void loadAvatar(TUIMessageBean msg) {
+ if (msg.isUseMsgReceiverAvatar()) {
+ String userId = "";
+ if (TextUtils.equals(msg.getSender(), V2TIMManager.getInstance().getLoginUser())) {
+ userId = msg.getUserId();
+ } else {
+ userId = V2TIMManager.getInstance().getLoginUser();
+ }
+ List idList = new ArrayList<>();
+ idList.add(userId);
+ V2TIMManager.getInstance().getUsersInfo(idList, new V2TIMValueCallback>() {
+ @Override
+ public void onSuccess(List v2TIMUserFullInfos) {
+ V2TIMUserFullInfo userInfo = v2TIMUserFullInfos.get(0);
+ if (userInfo == null) {
+ setupAvatar("", msg.isSelf());
+ } else {
+ setupAvatar(userInfo.getFaceUrl(), msg.isSelf());
+ }
+ }
+
+ @Override
+ public void onError(int code, String desc) {
+ setupAvatar("", msg.isSelf());
+ }
+ });
+ } else {
+ setupAvatar(msg.getFaceUrl(), msg.isSelf());
+ }
+ }
+
+ private void setupAvatar(String faceUrl, boolean right) {
+ if (!TextUtils.isEmpty(faceUrl)) {
+ List