Refactoring / revert reaction module to package in main module

This commit is contained in:
Valere 2019-05-09 18:26:32 +02:00
parent 64216f74ae
commit dcc430f91b
31 changed files with 65 additions and 216353 deletions

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
/build

View File

@ -1,55 +0,0 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
compileSdkVersion 28



defaultConfig {
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
multiDexEnabled true

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}

}

dependencies {

def coroutines_version = "1.0.1"

implementation fileTree(dir: 'libs', include: ['*.jar'])


implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"

// Log
implementation 'com.jakewharton.timber:timber:4.7.1'

implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.0.0-beta01'
implementation 'androidx.legacy:legacy-support-v4:1.0.0-beta01'
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0-beta01'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

View File

@ -1,21 +0,0 @@
# 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

View File

@ -1,26 +0,0 @@
package im.vector.reactions;

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();

assertEquals("im.vector.reactions.test", appContext.getPackageName());
}
}

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="im.vector.reactions">

<application>
<meta-data
android:name="fontProviderRequests"
android:value="Noto Color Emoji Compat" />

<activity
android:name=".EmojiReactionPickerActivity"
android:label="@string/title_activity_emoji_reaction_picker"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
android:exported="true"
>
</activity>
</application>

</manifest>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="pale_grey">#f2f5f8</color>
<color name="light_blue_grey">#4ac1c9d6</color>
</resources>

View File

@ -1,3 +0,0 @@
<resources>
<dimen name="fab_margin">16dp</dimen>
</resources>

View File

@ -1,4 +0,0 @@
<resources>
<string name="app_name">reactions</string>
<string name="title_activity_emoji_reaction_picker">Reactions</string>
</resources>

View File

@ -1,13 +0,0 @@
<resources>

<style name="AppTheme" parent="Theme.MaterialComponents.Light" />

<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>

<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />

<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources>

View File

@ -1,17 +0,0 @@
package im.vector.reactions;

import org.junit.Test;

import static org.junit.Assert.*;

/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}

View File

@ -1 +1 @@
include ':vector', ':matrix-sdk-android', ':matrix-sdk-android-rx', ':reactions' include ':vector', ':matrix-sdk-android', ':matrix-sdk-android-rx'

View File

@ -124,10 +124,10 @@ dependencies {
def markwon_version = '3.0.0-SNAPSHOT' def markwon_version = '3.0.0-SNAPSHOT'
def big_image_viewer_version = '1.5.6' def big_image_viewer_version = '1.5.6'
def glide_version = '4.9.0' def glide_version = '4.9.0'
def moshi_version = '1.8.0'


implementation project(":matrix-sdk-android") implementation project(":matrix-sdk-android")
implementation project(":matrix-sdk-android-rx") implementation project(":matrix-sdk-android-rx")
implementation project(":reactions")
implementation 'com.android.support:multidex:1.0.3' implementation 'com.android.support:multidex:1.0.3'


implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
@ -139,6 +139,8 @@ dependencies {
implementation 'androidx.core:core-ktx:1.0.1' implementation 'androidx.core:core-ktx:1.0.1'


implementation 'com.jakewharton.threetenabp:threetenabp:1.1.1' implementation 'com.jakewharton.threetenabp:threetenabp:1.1.1'
implementation "com.squareup.moshi:moshi-adapters:$moshi_version"
kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi_version"


// Log // Log
implementation 'com.jakewharton.timber:timber:4.7.1' implementation 'com.jakewharton.timber:timber:4.7.1'

View File

@ -39,6 +39,10 @@
android:windowSoftInputMode="adjustResize" /> android:windowSoftInputMode="adjustResize" />
<activity android:name=".features.media.VideoMediaViewerActivity" /> <activity android:name=".features.media.VideoMediaViewerActivity" />


<activity
android:name="im.vector.riotredesign.features.reactions.EmojiReactionPickerActivity"
android:label="@string/title_activity_emoji_reaction_picker" />

<service <service
android:name=".core.services.CallService" android:name=".core.services.CallService"
android:exported="false" /> android:exported="false" />

View File

@ -199,7 +199,7 @@ abstract class VectorBaseActivity : BaseMvRxActivity() {
* MENU MANAGEMENT * MENU MANAGEMENT
* ========================================================================================== */ * ========================================================================================== */


final override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {
val menuRes = getMenuRes() val menuRes = getMenuRes()


if (menuRes != -1) { if (menuRes != -1) {

View File

@ -52,7 +52,7 @@ import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.room.model.message.* import im.vector.matrix.android.api.session.room.model.message.*
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.api.session.user.model.User import im.vector.matrix.android.api.session.user.model.User
import im.vector.reactions.EmojiReactionPickerActivity import im.vector.riotredesign.features.reactions.EmojiReactionPickerActivity
import im.vector.riotredesign.R import im.vector.riotredesign.R
import im.vector.riotredesign.core.dialogs.DialogListItem import im.vector.riotredesign.core.dialogs.DialogListItem
import im.vector.riotredesign.core.epoxy.LayoutManagerStateRestorer import im.vector.riotredesign.core.epoxy.LayoutManagerStateRestorer

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package im.vector.reactions package im.vector.riotredesign.features.reactions


import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProviders
import android.os.Bundle import android.os.Bundle
@ -22,8 +22,8 @@ import androidx.fragment.app.Fragment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import im.vector.riotredesign.R




class EmojiChooserFragment : Fragment() { class EmojiChooserFragment : Fragment() {
@ -50,9 +50,7 @@ class EmojiChooserFragment : Fragment() {
it.adapter?.notifyDataSetChanged() it.adapter?.notifyDataSetChanged()
} }


val ds = EmojiDataSource(this.context!!) // val ds = EmojiDataSource(this.context!!)

Log.d("YO","trtrt")
} }


override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package im.vector.reactions package im.vector.riotredesign.features.reactions


import android.content.Context import android.content.Context
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
@ -27,6 +27,7 @@ class EmojiChooserViewModel : ViewModel() {
val currentSection: MutableLiveData<Int> = MutableLiveData() val currentSection: MutableLiveData<Int> = MutableLiveData()


fun initWithContect(context: Context) { fun initWithContect(context: Context) {
//TODO load async
val emojiDataSource = EmojiDataSource(context) val emojiDataSource = EmojiDataSource(context)
emojiSourceLiveData.value = emojiDataSource emojiSourceLiveData.value = emojiDataSource
adapter = EmojiRecyclerAdapter(emojiDataSource) adapter = EmojiRecyclerAdapter(emojiDataSource)

View File

@ -13,35 +13,45 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package im.vector.reactions package im.vector.riotredesign.features.reactions


import android.content.Context import android.content.Context
import com.google.gson.Gson import com.squareup.moshi.Json
import com.google.gson.annotations.SerializedName import com.squareup.moshi.JsonClass
import com.squareup.moshi.Moshi
import im.vector.riotredesign.R
import java.io.InputStreamReader import java.io.InputStreamReader
import com.squareup.moshi.JsonAdapter




class EmojiDataSource(val context: Context) { class EmojiDataSource(val context: Context) {


var rawData: EmojiData? = null var rawData: EmojiData? = null


init { init {
context.resources.openRawResource(R.raw.emoji_picker_datasource).use { context.resources.openRawResource(R.raw.emoji_picker_datasource).use { input ->
var gson = Gson() val moshi = Moshi.Builder().build()
this.rawData = gson.fromJson(InputStreamReader(it), EmojiData::class.java) val jsonAdapter = moshi.adapter(EmojiData::class.java)
val inputAsString = input.bufferedReader().use { it.readText() }
this.rawData = jsonAdapter.fromJson(inputAsString)
// this.rawData = mb.fr(InputStreamReader(it), EmojiData::class.java)
} }
} }
@JsonClass(generateAdapter = true)
data class EmojiData(val categories: List<EmojiCategory>,
val emojis: Map<String, EmojiItem>,
val aliases: Map<String, String>)


data class EmojiData(val categories: ArrayList<EmojiCategory>, @JsonClass(generateAdapter = true)
val name: String, data class EmojiCategory(val id: String, val name: String, val emojis: List<String>)
val emojis: HashMap<String, EmojiItem>,
val aliases: HashMap<String, String>)


data class EmojiCategory(val id: String, val name: String, val emojis: ArrayList<String>) @JsonClass(generateAdapter = true)
data class EmojiItem( data class EmojiItem(
@SerializedName("a") val name: String, @Json(name = "a") val name: String,
@SerializedName("b") val unicode: String, @Json(name = "b") val unicode: String,
@SerializedName("j") val keywords: ArrayList<String>?, @Json(name = "j") val keywords: List<String>?,
val k: ArrayList<String>?) { val k: List<String>?) {


var _emojiText: String? = null var _emojiText: String? = null


View File

@ -1,15 +1,13 @@
package im.vector.reactions package im.vector.riotredesign.features.reactions


import android.content.Context import android.content.Context
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Color import android.graphics.Color
import android.graphics.Typeface import android.graphics.Typeface
import android.text.Layout
import android.text.StaticLayout import android.text.StaticLayout
import android.text.TextPaint import android.text.TextPaint
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.View
import java.lang.Exception
import kotlin.math.abs import kotlin.math.abs




View File

@ -13,12 +13,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package im.vector.reactions package im.vector.riotredesign.features.reactions


import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Typeface import android.graphics.Typeface
import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.HandlerThread import android.os.HandlerThread
import android.util.TypedValue import android.util.TypedValue
@ -26,22 +25,24 @@ import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.widget.SearchView import android.widget.SearchView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.core.provider.FontRequest import androidx.core.provider.FontRequest
import androidx.core.provider.FontsContractCompat import androidx.core.provider.FontsContractCompat
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProviders
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import im.vector.riotredesign.R
import im.vector.riotredesign.core.platform.VectorBaseActivity
import timber.log.Timber import timber.log.Timber



/** /**
* *
* TODO: Loading indicator while getting emoji data source? * TODO: Loading indicator while getting emoji data source?
* TODO: migrate to maverick * TODO: migrate to maverick
* TODO: Finish Refactor to vector base activity
* TODO: Move font request to app
*/ */
class EmojiReactionPickerActivity : AppCompatActivity() { class EmojiReactionPickerActivity : VectorBaseActivity() {


private lateinit var tabLayout: TabLayout private lateinit var tabLayout: TabLayout


@ -49,6 +50,12 @@ class EmojiReactionPickerActivity : AppCompatActivity() {


private var mHandler: Handler? = null private var mHandler: Handler? = null


override fun getMenuRes(): Int = R.menu.menu_emoji_reaction_picker

override fun getLayoutRes(): Int = R.layout.activity_emoji_reaction_picker

override fun getTitleRes(): Int = R.string.title_activity_emoji_reaction_picker

private var tabLayoutSelectionListener = object : TabLayout.BaseOnTabSelectedListener<TabLayout.Tab> { private var tabLayoutSelectionListener = object : TabLayout.BaseOnTabSelectedListener<TabLayout.Tab> {
override fun onTabReselected(p0: TabLayout.Tab) { override fun onTabReselected(p0: TabLayout.Tab) {
} }
@ -71,19 +78,14 @@ class EmojiReactionPickerActivity : AppCompatActivity() {
return mHandler!! return mHandler!!
} }


override fun onCreate(savedInstanceState: Bundle?) { override fun initUiAndData() {
super.onCreate(savedInstanceState)
configureToolbar()


requestEmojivUnicode10CompatibleFont() requestEmojivUnicode10CompatibleFont()



setContentView(R.layout.activity_emoji_reaction_picker)
setSupportActionBar(findViewById(R.id.toolbar))

tabLayout = findViewById(R.id.tabs) tabLayout = findViewById(R.id.tabs)




viewModel = ViewModelProviders.of(this).get(EmojiChooserViewModel::class.java) viewModel = ViewModelProviders.of(this).get(EmojiChooserViewModel::class.java)


viewModel.emojiSourceLiveData.observe(this, Observer { viewModel.emojiSourceLiveData.observe(this, Observer {
@ -104,7 +106,6 @@ class EmojiReactionPickerActivity : AppCompatActivity() {
tabLayout.addOnTabSelectedListener(tabLayoutSelectionListener) tabLayout.addOnTabSelectedListener(tabLayoutSelectionListener)
} }
}) })
supportActionBar?.title = getString(R.string.title_activity_emoji_reaction_picker)
} }


private fun requestEmojivUnicode10CompatibleFont() { private fun requestEmojivUnicode10CompatibleFont() {
@ -132,7 +133,7 @@ class EmojiReactionPickerActivity : AppCompatActivity() {


override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {
val inflater: MenuInflater = menuInflater val inflater: MenuInflater = menuInflater
inflater.inflate(R.menu.menu_emoji_reaction_picker, menu) inflater.inflate(getMenuRes(), menu)


val searchItem = menu.findItem(R.id.search) val searchItem = menu.findItem(R.id.search)
(searchItem.actionView as? SearchView)?.let { (searchItem.actionView as? SearchView)?.let {

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package im.vector.reactions package im.vector.riotredesign.features.reactions


import android.os.Build import android.os.Build
import android.os.Trace import android.os.Trace
@ -29,6 +29,7 @@ import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.transition.AutoTransition import androidx.transition.AutoTransition
import androidx.transition.TransitionManager import androidx.transition.TransitionManager
import im.vector.riotredesign.R
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch

View File

@ -4,45 +4,20 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".EmojiReactionPickerActivity"> tools:context="im.vector.riotredesign.features.reactions.EmojiReactionPickerActivity">



<fragment <fragment
android:id="@+id/fragment" android:id="@+id/fragment"
android:name="im.vector.reactions.EmojiChooserFragment" android:name="im.vector.riotredesign.features.reactions.EmojiChooserFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:layout="@layout/emoji_chooser_fragment" /> tools:layout="@layout/emoji_chooser_fragment" />
<!--<androidx.core.widget.NestedScrollView-->
<!--android:id="@+id/nestedScrollView"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:fillViewport="true"-->
<!--android:fitsSystemWindows="true"-->
<!--app:layout_behavior="@string/appbar_scrolling_view_behavior">-->

<!--<fragment-->
<!--android:id="@+id/fragment"-->
<!--android:name="im.vector.reactions.EmojiChooserFragment"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--tools:layout="@layout/emoji_chooser_fragment" />-->

<!--</androidx.core.widget.NestedScrollView>-->


<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">


<!--<com.google.android.material.appbar.CollapsingToolbarLayout-->
<!--android:id="@+id/collapsingToolbarLayout"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--app:contentScrim="?attr/colorPrimary"-->
<!--app:expandedTitleGravity="top"-->
<!--app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">-->

<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -61,7 +36,6 @@
android:background="?attr/colorPrimary" android:background="?attr/colorPrimary"
android:elevation="4dp" /> android:elevation="4dp" />


<!--</com.google.android.material.appbar.CollapsingToolbarLayout>-->
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>




View File

@ -5,7 +5,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:scrollbars="vertical" android:scrollbars="vertical"
tools:context=".EmojiChooserFragment" tools:context="im.vector.riotredesign.features.reactions.EmojiChooserFragment"
tools:itemCount="100" tools:itemCount="100"
tools:layoutManager="androidx.recyclerview.widget.GridLayoutManager" tools:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
tools:listitem="@layout/grid_item_emoji" tools:listitem="@layout/grid_item_emoji"

View File

@ -15,7 +15,7 @@
tools:visibility="visible" tools:visibility="visible"
android:background="@drawable/circle" /> android:background="@drawable/circle" />


<im.vector.reactions.EmojiDrawView <im.vector.riotredesign.features.reactions.EmojiDrawView
android:id="@+id/grid_item_emoji_text" android:id="@+id/grid_item_emoji_text"
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="40dp" android:layout_height="40dp"

View File

@ -1402,6 +1402,8 @@ Why choose Riot.im?
<string name="autodiscover_well_known_autofill_dialog_message">Riot detected a custom server configuration for your userId domain \"%s\":\n%s</string> <string name="autodiscover_well_known_autofill_dialog_message">Riot detected a custom server configuration for your userId domain \"%s\":\n%s</string>
<string name="autodiscover_well_known_autofill_confirm">Use Config</string> <string name="autodiscover_well_known_autofill_confirm">Use Config</string>



<string name="title_activity_emoji_reaction_picker">Reactions</string>
<string name="reactions_agree">Agree</string> <string name="reactions_agree">Agree</string>
<string name="reactions_like">Like</string> <string name="reactions_like">Like</string>
<string name="message_add_reaction">Add Reaction</string> <string name="message_add_reaction">Add Reaction</string>