Unverified Commit cca7645c authored by Lucio Maciel's avatar Lucio Maciel Committed by GitHub

Merge branch 'develop' into basicauth

parents 0e1d03e7 f4ee4bec
version: 2 version: 2
build:
machine:
java: oraclejdk8
jobs: jobs:
build-kotlin-sdk: build-kotlin-sdk:
docker: docker:
- image: circleci/android:api-27-alpha - image: circleci/android:api-28-alpha
environment: environment:
JVM_OPTS: -Xmx3200m JAVA_TOOL_OPTIONS: -Xmx5024m
steps: steps:
- checkout - checkout
- run: - run:
...@@ -18,8 +21,9 @@ jobs: ...@@ -18,8 +21,9 @@ jobs:
command: pushd app/ ; ./build-sdk.sh ; popd command: pushd app/ ; ./build-sdk.sh ; popd
- save_cache: - save_cache:
paths: paths:
- ~/.gradle - ~/.gradle/caches
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "player/build.gradle" }} - ~/.gradle/wrapper
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "player/build.gradle" }}-{{ checksum "core/build.gradle" }}-{{ checksum "util/build.gradle" }}-{{ checksum "draw/build.gradle" }}-{{ checksum "emoji/build.gradle" }}-{{ checksum "suggestions/build.gradle" }}
- save_cache: - save_cache:
paths: paths:
- app/libs/ - app/libs/
...@@ -30,9 +34,9 @@ jobs: ...@@ -30,9 +34,9 @@ jobs:
destination: libs destination: libs
code-analysis: code-analysis:
docker: docker:
- image: circleci/android:api-27-alpha - image: circleci/android:api-28-alpha
environment: environment:
JVM_OPTS: -Xmx3200m JAVA_TOOL_OPTIONS: -Xmx5024m
steps: steps:
- checkout - checkout
- run: - run:
...@@ -44,33 +48,37 @@ jobs: ...@@ -44,33 +48,37 @@ jobs:
- restore_cache: - restore_cache:
key: kotlin-sdk-{{ .Revision }} key: kotlin-sdk-{{ .Revision }}
- restore_cache: - restore_cache:
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "player/build.gradle" }} key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "player/build.gradle" }}-{{ checksum "core/build.gradle" }}-{{ checksum "util/build.gradle" }}-{{ checksum "draw/build.gradle" }}-{{ checksum "emoji/build.gradle" }}-{{ checksum "suggestions/build.gradle" }}
- run: - run:
name: Download Dependencies name: Download Dependencies
command: ./gradlew androidDependencies --quiet --console=plain command: ./gradlew --no-daemon androidDependencies --quiet --console=plain
- save_cache: - save_cache:
paths: paths:
- ~/.gradle - ~/.gradle/caches
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "player/build.gradle" }} - ~/.gradle/wrapper
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "player/build.gradle" }}-{{ checksum "core/build.gradle" }}-{{ checksum "util/build.gradle" }}-{{ checksum "draw/build.gradle" }}-{{ checksum "emoji/build.gradle" }}-{{ checksum "suggestions/build.gradle" }}
- run: - run:
name: Run Lint #, Checkstyles, PMD, Findbugs... name: Run Lint #, Checkstyles, PMD, Findbugs...
command: ./gradlew lint command: ./gradlew --no-daemon lint
- run: - run:
name: Run Unit test name: Run Unit test
command: ./gradlew test command: ./gradlew --no-daemon test
- run: - run:
name: Compile Instrumentation test name: Compile Instrumentation test
command: ./gradlew assembleAndroidTest command: ./gradlew --no-daemon assembleAndroidTest
- store_artifacts: - store_artifacts:
path: app/build/reports/ path: app/build/reports/
destination: reports destination: reports
build-play-apk: build-play-apk:
docker: docker:
- image: circleci/android:api-27-alpha - image: circleci/android:api-28-alpha
environment: environment:
JVM_OPTS: -Xmx3200m JAVA_TOOL_OPTIONS: -Xmx5024m
steps: steps:
- checkout - checkout
- run:
name: ANDROID_HOME
command: echo "sdk.dir="$ANDROID_HOME > local.properties
- run: - run:
name: restore files from ENV name: restore files from ENV
command: | command: |
...@@ -82,28 +90,32 @@ jobs: ...@@ -82,28 +90,32 @@ jobs:
- restore_cache: - restore_cache:
key: kotlin-sdk-{{ .Revision }} key: kotlin-sdk-{{ .Revision }}
- restore_cache: - restore_cache:
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "player/build.gradle" }} key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "player/build.gradle" }}-{{ checksum "core/build.gradle" }}-{{ checksum "util/build.gradle" }}-{{ checksum "draw/build.gradle" }}-{{ checksum "emoji/build.gradle" }}-{{ checksum "suggestions/build.gradle" }}
- run: - run:
name: Download Dependencies name: Download Dependencies
command: ./gradlew androidDependencies --quiet --console=plain command: ./gradlew --no-daemon androidDependencies --quiet --console=plain
- save_cache: - save_cache:
paths: paths:
- ~/.gradle - ~/.gradle/caches
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "player/build.gradle" }} - ~/.gradle/wrapper
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "player/build.gradle" }}-{{ checksum "core/build.gradle" }}-{{ checksum "util/build.gradle" }}-{{ checksum "draw/build.gradle" }}-{{ checksum "emoji/build.gradle" }}-{{ checksum "suggestions/build.gradle" }}
- run: - run:
name: Build APK name: Build APK
command: | command: |
./gradlew assemblePlayRelease --info --console=plain --stacktrace ./gradlew --no-daemon assemblePlayRelease --info --console=plain --stacktrace
- store_artifacts: - store_artifacts:
path: app/build/outputs/apk path: app/build/outputs/apk
destination: apks destination: apks
build-foss-apk: build-foss-apk:
docker: docker:
- image: circleci/android:api-27-alpha - image: circleci/android:api-28-alpha
environment: environment:
JVM_OPTS: -Xmx3200m JAVA_TOOL_OPTIONS: -Xmx5024m
steps: steps:
- checkout - checkout
- run:
name: ANDROID_HOME
command: echo "sdk.dir="$ANDROID_HOME > local.properties
- run: - run:
name: restore files from ENV name: restore files from ENV
command: | command: |
...@@ -115,18 +127,19 @@ jobs: ...@@ -115,18 +127,19 @@ jobs:
- restore_cache: - restore_cache:
key: kotlin-sdk-{{ .Revision }} key: kotlin-sdk-{{ .Revision }}
- restore_cache: - restore_cache:
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "player/build.gradle" }} key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "player/build.gradle" }}-{{ checksum "core/build.gradle" }}-{{ checksum "util/build.gradle" }}-{{ checksum "draw/build.gradle" }}-{{ checksum "emoji/build.gradle" }}-{{ checksum "suggestions/build.gradle" }}
- run: - run:
name: Download Dependencies name: Download Dependencies
command: ./gradlew androidDependencies --quiet --console=plain command: ./gradlew --no-daemon androidDependencies --quiet --console=plain
- save_cache: - save_cache:
paths: paths:
- ~/.gradle - ~/.gradle/caches
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "player/build.gradle" }} - ~/.gradle/wrapper
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "player/build.gradle" }}-{{ checksum "core/build.gradle" }}-{{ checksum "util/build.gradle" }}-{{ checksum "draw/build.gradle" }}-{{ checksum "emoji/build.gradle" }}-{{ checksum "suggestions/build.gradle" }}
- run: - run:
name: Build APK name: Build APK
command: | command: |
./gradlew assembleFossRelease --info --console=plain --stacktrace ./gradlew --no-daemon assembleFossRelease --info --console=plain --stacktrace
- store_artifacts: - store_artifacts:
path: app/build/outputs/apk path: app/build/outputs/apk
destination: apks destination: apks
......
...@@ -11,7 +11,7 @@ This repository contains all the code related to the Android native application ...@@ -11,7 +11,7 @@ This repository contains all the code related to the Android native application
## How to build ## How to build
- You need to download the latest [Android Studio Preview](https://developer.android.com/studio/preview/) version since the stable IDE version does not support the [JetPack](https://developer.android.com/jetpack/) that is beeing used on this application. - You need to download the latest [Android Studio Preview](https://developer.android.com/studio/preview/) version since the stable IDE version does not support the [JetPack](https://developer.android.com/jetpack/) that is being used on this application.
- Make sure that you have the latest **gradle** and the **android plugin** versions installed. Go to `File > Project Structure > Project` and make sure that you have the latest versions installed. Refer [this](https://developer.android.com/studio/releases/gradle-plugin.html#updating-gradle) to see the compatible versions. - Make sure that you have the latest **gradle** and the **android plugin** versions installed. Go to `File > Project Structure > Project` and make sure that you have the latest versions installed. Refer [this](https://developer.android.com/studio/releases/gradle-plugin.html#updating-gradle) to see the compatible versions.
- Kotlin is already configured in the project. To check, go to `Tools > Kotlin > Configure Kotlin in project`. A message saying kotlin is already configured in the project pops up. You can update kotlin to the latest version by going to `Tools > Kotlin > Configure Kotlin updates` and download the latest version of kotlin. - Kotlin is already configured in the project. To check, go to `Tools > Kotlin > Configure Kotlin in project`. A message saying kotlin is already configured in the project pops up. You can update kotlin to the latest version by going to `Tools > Kotlin > Configure Kotlin updates` and download the latest version of kotlin.
......
...@@ -94,8 +94,8 @@ if ! check_git_dirty && ! check_last_commit && [ -f "${CURRENT_DIR}"/libs/common ...@@ -94,8 +94,8 @@ if ! check_git_dirty && ! check_last_commit && [ -f "${CURRENT_DIR}"/libs/common
exit 0 exit 0
fi fi
cd "${SDK_DIR}" && ./gradlew common:assemble && cd "${CURRENT_DIR}" cd "${SDK_DIR}" && ./gradlew --no-daemon common:assemble && cd "${CURRENT_DIR}"
cd "${SDK_DIR}" && ./gradlew core:assemble && cd "${CURRENT_DIR}" cd "${SDK_DIR}" && ./gradlew --no-daemon core:assemble && cd "${CURRENT_DIR}"
rm "${CURRENT_DIR}"/libs/common* "${CURRENT_DIR}"/libs/core* rm "${CURRENT_DIR}"/libs/common* "${CURRENT_DIR}"/libs/core*
......
...@@ -18,7 +18,9 @@ import chat.rocket.android.util.extensions.toList ...@@ -18,7 +18,9 @@ import chat.rocket.android.util.extensions.toList
import chat.rocket.core.model.Message import chat.rocket.core.model.Message
import chat.rocket.core.model.isSystemMessage import chat.rocket.core.model.isSystemMessage
import com.google.android.flexbox.FlexDirection import com.google.android.flexbox.FlexDirection
import com.google.android.flexbox.FlexWrap
import com.google.android.flexbox.FlexboxLayoutManager import com.google.android.flexbox.FlexboxLayoutManager
import com.google.android.flexbox.JustifyContent
abstract class BaseViewHolder<T : BaseUiModel<*>>( abstract class BaseViewHolder<T : BaseUiModel<*>>(
itemView: View, itemView: View,
...@@ -41,13 +43,12 @@ abstract class BaseViewHolder<T : BaseUiModel<*>>( ...@@ -41,13 +43,12 @@ abstract class BaseViewHolder<T : BaseUiModel<*>>(
private fun bindReactions() { private fun bindReactions() {
data?.let { data?.let {
val recyclerView = itemView.findViewById(R.id.recycler_view_reactions) as RecyclerView val recyclerView = itemView.findViewById(R.id.recycler_view_reactions) as RecyclerView
val adapter: MessageReactionsAdapter val adapter: MessageReactionsAdapter = if (recyclerView.adapter == null) {
if (recyclerView.adapter == null) { MessageReactionsAdapter()
adapter = MessageReactionsAdapter()
} else { } else {
adapter = recyclerView.adapter as MessageReactionsAdapter recyclerView.adapter as MessageReactionsAdapter
adapter.clear()
} }
adapter.clear()
if (it.nextDownStreamMessage == null) { if (it.nextDownStreamMessage == null) {
adapter.listener = object : EmojiReactionListener { adapter.listener = object : EmojiReactionListener {
...@@ -61,13 +62,16 @@ abstract class BaseViewHolder<T : BaseUiModel<*>>( ...@@ -61,13 +62,16 @@ abstract class BaseViewHolder<T : BaseUiModel<*>>(
} }
} }
} }
val context = itemView.context val context = itemView.context
val manager = FlexboxLayoutManager(context, FlexDirection.ROW) val manager = FlexboxLayoutManager(context, FlexDirection.ROW)
manager.justifyContent = JustifyContent.FLEX_START
recyclerView.layoutManager = manager recyclerView.layoutManager = manager
recyclerView.adapter = adapter recyclerView.adapter = adapter
adapter.addReactions(it.reactions.filterNot { reactionUiModel ->
reactionUiModel.unicode.startsWith(":") && reactionUiModel.url.isNullOrEmpty() if (it.reactions.isNotEmpty()) {
}) itemView.post { adapter.addReactions(it.reactions) }
}
} }
} }
} }
......
...@@ -4,7 +4,6 @@ import android.view.LayoutInflater ...@@ -4,7 +4,6 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R import chat.rocket.android.R
...@@ -35,17 +34,17 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() ...@@ -35,17 +34,17 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>()
} }
else -> { else -> {
view = inflater.inflate(R.layout.item_reaction, parent, false) view = inflater.inflate(R.layout.item_reaction, parent, false)
SingleReactionViewHolder(view, listener) ReactionViewHolder(view, listener)
} }
} }
} }
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is SingleReactionViewHolder) { if (holder is ReactionViewHolder) {
holder.bind(reactions[position]) holder.bind(reactions[position])
} else { } else {
holder as AddReactionViewHolder holder as AddReactionViewHolder
holder.bind(reactions[0].messageId) holder.bind(reactions.first().messageId)
} }
} }
...@@ -73,7 +72,7 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() ...@@ -73,7 +72,7 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>()
fun contains(reactionShortname: String) = fun contains(reactionShortname: String) =
reactions.firstOrNull { it.shortname == reactionShortname } != null reactions.firstOrNull { it.shortname == reactionShortname } != null
class SingleReactionViewHolder( class ReactionViewHolder(
view: View, view: View,
private val listener: EmojiReactionListener? private val listener: EmojiReactionListener?
) : RecyclerView.ViewHolder(view), View.OnClickListener { ) : RecyclerView.ViewHolder(view), View.OnClickListener {
...@@ -97,9 +96,11 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() ...@@ -97,9 +96,11 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>()
this.reaction = reaction this.reaction = reaction
with(itemView) { with(itemView) {
if (reaction.url.isNullOrEmpty()) { if (reaction.url.isNullOrEmpty()) {
text_emoji.text = reaction.unicode // The view at index 0 corresponds to the one to display unicode text emoji.
view_flipper_reaction.displayedChild = 0 view_flipper_reaction.displayedChild = 0
text_emoji.text = reaction.unicode
} else { } else {
// The view at index 1 corresponds to the one to display custom emojis which are images.
view_flipper_reaction.displayedChild = 1 view_flipper_reaction.displayedChild = 1
val glideRequest = if (reaction.url!!.endsWith("gif", true)) { val glideRequest = if (reaction.url!!.endsWith("gif", true)) {
GlideApp.with(context).asGif() GlideApp.with(context).asGif()
...@@ -110,15 +111,16 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() ...@@ -110,15 +111,16 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>()
glideRequest.load(reaction.url).into(image_emoji) glideRequest.load(reaction.url).into(image_emoji)
} }
text_count.text = reaction.count.toString()
val myself = localRepository.get(LocalRepository.CURRENT_USERNAME_KEY) val myself = localRepository.get(LocalRepository.CURRENT_USERNAME_KEY)
if (reaction.usernames.contains(myself)) { if (reaction.usernames.contains(myself)) {
val context = itemView.context val context = itemView.context
text_count.setTextColor(ContextCompat.getColor(context, R.color.colorAccent)) text_count.setTextColor(ContextCompat.getColor(context, R.color.colorAccent))
} }
view_flipper_reaction.setOnClickListener(this@SingleReactionViewHolder) text_count.text = reaction.count.toString()
text_count.setOnClickListener(this@SingleReactionViewHolder)
view_flipper_reaction.setOnClickListener(this@ReactionViewHolder)
text_count.setOnClickListener(this@ReactionViewHolder)
} }
} }
......
...@@ -19,7 +19,7 @@ interface LocalComponent { ...@@ -19,7 +19,7 @@ interface LocalComponent {
fun build(): LocalComponent fun build(): LocalComponent
} }
fun inject(adapter: MessageReactionsAdapter.SingleReactionViewHolder) fun inject(adapter: MessageReactionsAdapter.ReactionViewHolder)
fun inject(adapter: MessageReactionsAdapter.AddReactionViewHolder) fun inject(adapter: MessageReactionsAdapter.AddReactionViewHolder)
/*@Component.Builder /*@Component.Builder
......
...@@ -40,7 +40,7 @@ abstract class MessageDao { ...@@ -40,7 +40,7 @@ abstract class MessageDao {
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun insert(field: AttachmentFieldEntity) abstract fun insert(field: AttachmentFieldEntity)
@Insert(onConflict = OnConflictStrategy.IGNORE) @Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun insert(reaction: ReactionEntity) abstract fun insert(reaction: ReactionEntity)
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
......
...@@ -12,7 +12,7 @@ import android.text.style.ImageSpan ...@@ -12,7 +12,7 @@ import android.text.style.ImageSpan
import android.text.style.ReplacementSpan import android.text.style.ReplacementSpan
import android.view.View import android.view.View
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.core.util.PatternsCompat import chat.rocket.android.R
import chat.rocket.android.chatroom.ui.StrikethroughDelimiterProcessor import chat.rocket.android.chatroom.ui.StrikethroughDelimiterProcessor
import chat.rocket.android.emoji.EmojiParser import chat.rocket.android.emoji.EmojiParser
import chat.rocket.android.emoji.EmojiRepository import chat.rocket.android.emoji.EmojiRepository
...@@ -39,6 +39,7 @@ import ru.noties.markwon.SpannableConfiguration ...@@ -39,6 +39,7 @@ import ru.noties.markwon.SpannableConfiguration
import ru.noties.markwon.renderer.SpannableMarkdownVisitor import ru.noties.markwon.renderer.SpannableMarkdownVisitor
import ru.noties.markwon.tasklist.TaskListExtension import ru.noties.markwon.tasklist.TaskListExtension
import java.util.* import java.util.*
import java.util.regex.Pattern
import javax.inject.Inject import javax.inject.Inject
class MessageParser @Inject constructor( class MessageParser @Inject constructor(
...@@ -46,7 +47,6 @@ class MessageParser @Inject constructor( ...@@ -46,7 +47,6 @@ class MessageParser @Inject constructor(
private val configuration: SpannableConfiguration, private val configuration: SpannableConfiguration,
private val settings: PublicSettings private val settings: PublicSettings
) { ) {
/** /**
* Render markdown and other rules on message to rich text with spans. * Render markdown and other rules on message to rich text with spans.
* *
...@@ -230,7 +230,7 @@ class MessageParser @Inject constructor( ...@@ -230,7 +230,7 @@ class MessageParser @Inject constructor(
override fun visit(document: Document) { override fun visit(document: Document) {
// Replace all url links to markdown url syntax. // Replace all url links to markdown url syntax.
val matcher = PatternsCompat.AUTOLINK_WEB_URL.matcher(builder.text()) val matcher = MessageParser.WEB_URL.matcher(builder.text())
val consumed = mutableListOf<String>() val consumed = mutableListOf<String>()
while (matcher.find()) { while (matcher.find()) {
...@@ -283,4 +283,249 @@ class MessageParser @Inject constructor( ...@@ -283,4 +283,249 @@ class MessageParser @Inject constructor(
canvas.drawText(text, start, end, x + padding, y.toFloat(), paint) canvas.drawText(text, start, end, x + padding, y.toFloat(), paint)
} }
} }
companion object {
/**
* Regular expression to match all IANA top-level domains.
*
* List accurate as of 2015/11/24. List taken from:
* http://data.iana.org/TLD/tlds-alpha-by-domain.txt
* This pattern is auto-generated by frameworks/ex/common/tools/make-iana-tld-pattern.py
*/
private val IANA_TOP_LEVEL_DOMAINS = (
"(?:"
+ "(?:aaa|aarp|abb|abbott|abogado|academy|accenture|accountant|accountants|aco|active"
+ "|actor|ads|adult|aeg|aero|afl|agency|aig|airforce|airtel|allfinanz|alsace|amica|amsterdam"
+ "|android|apartments|app|apple|aquarelle|aramco|archi|army|arpa|arte|asia|associates"
+ "|attorney|auction|audio|auto|autos|axa|azure|a[cdefgilmoqrstuwxz])"
+ "|(?:band|bank|bar|barcelona|barclaycard|barclays|bargains|bauhaus|bayern|bbc|bbva"
+ "|bcn|beats|beer|bentley|berlin|best|bet|bharti|bible|bid|bike|bing|bingo|bio|biz|black"
+ "|blackfriday|bloomberg|blue|bms|bmw|bnl|bnpparibas|boats|bom|bond|boo|boots|boutique"
+ "|bradesco|bridgestone|broadway|broker|brother|brussels|budapest|build|builders|business"
+ "|buzz|bzh|b[abdefghijmnorstvwyz])"
+ "|(?:cab|cafe|cal|camera|camp|cancerresearch|canon|capetown|capital|car|caravan|cards"
+ "|care|career|careers|cars|cartier|casa|cash|casino|cat|catering|cba|cbn|ceb|center|ceo"
+ "|cern|cfa|cfd|chanel|channel|chat|cheap|chloe|christmas|chrome|church|cipriani|cisco"
+ "|citic|city|cityeats|claims|cleaning|click|clinic|clothing|cloud|club|clubmed|coach"
+ "|codes|coffee|college|cologne|com|commbank|community|company|computer|comsec|condos"
+ "|construction|consulting|contractors|cooking|cool|coop|corsica|country|coupons|courses"
+ "|credit|creditcard|creditunion|cricket|crown|crs|cruises|csc|cuisinella|cymru|cyou|c[acdfghiklmnoruvwxyz])"
+ "|(?:dabur|dad|dance|date|dating|datsun|day|dclk|deals|degree|delivery|dell|delta"
+ "|democrat|dental|dentist|desi|design|dev|diamonds|diet|digital|direct|directory|discount"
+ "|dnp|docs|dog|doha|domains|doosan|download|drive|durban|dvag|d[ejkmoz])"
+ "|(?:earth|eat|edu|education|email|emerck|energy|engineer|engineering|enterprises"
+ "|epson|equipment|erni|esq|estate|eurovision|eus|events|everbank|exchange|expert|exposed"
+ "|express|e[cegrstu])"
+ "|(?:fage|fail|fairwinds|faith|family|fan|fans|farm|fashion|feedback|ferrero|film"
+ "|final|finance|financial|firmdale|fish|fishing|fit|fitness|flights|florist|flowers|flsmidth"
+ "|fly|foo|football|forex|forsale|forum|foundation|frl|frogans|fund|furniture|futbol|fyi"
+ "|f[ijkmor])"
+ "|(?:gal|gallery|game|garden|gbiz|gdn|gea|gent|genting|ggee|gift|gifts|gives|giving"
+ "|glass|gle|global|globo|gmail|gmo|gmx|gold|goldpoint|golf|goo|goog|google|gop|gov|grainger"
+ "|graphics|gratis|green|gripe|group|gucci|guge|guide|guitars|guru|g[abdefghilmnpqrstuwy])"
+ "|(?:hamburg|hangout|haus|healthcare|help|here|hermes|hiphop|hitachi|hiv|hockey|holdings"
+ "|holiday|homedepot|homes|honda|horse|host|hosting|hoteles|hotmail|house|how|hsbc|hyundai"
+ "|h[kmnrtu])"
+ "|(?:ibm|icbc|ice|icu|ifm|iinet|immo|immobilien|industries|infiniti|info|ing|ink|institute"
+ "|insure|int|international|investments|ipiranga|irish|ist|istanbul|itau|iwc|i[delmnoqrst])"
+ "|(?:jaguar|java|jcb|jetzt|jewelry|jlc|jll|jobs|joburg|jprs|juegos|j[emop])"
+ "|(?:kaufen|kddi|kia|kim|kinder|kitchen|kiwi|koeln|komatsu|krd|kred|kyoto|k[eghimnprwyz])"
+ "|(?:lacaixa|lancaster|land|landrover|lasalle|lat|latrobe|law|lawyer|lds|lease|leclerc"
+ "|legal|lexus|lgbt|liaison|lidl|life|lifestyle|lighting|limited|limo|linde|link|live"
+ "|lixil|loan|loans|lol|london|lotte|lotto|love|ltd|ltda|lupin|luxe|luxury|l[abcikrstuvy])"
+ "|(?:madrid|maif|maison|man|management|mango|market|marketing|markets|marriott|mba"
+ "|media|meet|melbourne|meme|memorial|men|menu|meo|miami|microsoft|mil|mini|mma|mobi|moda"
+ "|moe|moi|mom|monash|money|montblanc|mormon|mortgage|moscow|motorcycles|mov|movie|movistar"
+ "|mtn|mtpc|mtr|museum|mutuelle|m[acdeghklmnopqrstuvwxyz])"
+ "|(?:nadex|nagoya|name|navy|nec|net|netbank|network|neustar|new|news|nexus|ngo|nhk"
+ "|nico|ninja|nissan|nokia|nra|nrw|ntt|nyc|n[acefgilopruz])"
+ "|(?:obi|office|okinawa|omega|one|ong|onl|online|ooo|oracle|orange|org|organic|osaka"
+ "|otsuka|ovh|om)"
+ "|(?:page|panerai|paris|partners|parts|party|pet|pharmacy|philips|photo|photography"
+ "|photos|physio|piaget|pics|pictet|pictures|ping|pink|pizza|place|play|playstation|plumbing"
+ "|plus|pohl|poker|porn|post|praxi|press|pro|prod|productions|prof|properties|property"
+ "|protection|pub|p[aefghklmnrstwy])"
+ "|(?:qpon|quebec|qa)"
+ "|(?:racing|realtor|realty|recipes|red|redstone|rehab|reise|reisen|reit|ren|rent|rentals"
+ "|repair|report|republican|rest|restaurant|review|reviews|rich|ricoh|rio|rip|rocher|rocks"
+ "|rodeo|rsvp|ruhr|run|rwe|ryukyu|r[eosuw])"
+ "|(?:saarland|sakura|sale|samsung|sandvik|sandvikcoromant|sanofi|sap|sapo|sarl|saxo"
+ "|sbs|sca|scb|schmidt|scholarships|school|schule|schwarz|science|scor|scot|seat|security"
+ "|seek|sener|services|seven|sew|sex|sexy|shiksha|shoes|show|shriram|singles|site|ski"
+ "|sky|skype|sncf|soccer|social|software|sohu|solar|solutions|sony|soy|space|spiegel|spreadbetting"
+ "|srl|stada|starhub|statoil|stc|stcgroup|stockholm|studio|study|style|sucks|supplies"
+ "|supply|support|surf|surgery|suzuki|swatch|swiss|sydney|systems|s[abcdeghijklmnortuvxyz])"
+ "|(?:tab|taipei|tatamotors|tatar|tattoo|tax|taxi|team|tech|technology|tel|telefonica"
+ "|temasek|tennis|thd|theater|theatre|tickets|tienda|tips|tires|tirol|today|tokyo|tools"
+ "|top|toray|toshiba|tours|town|toyota|toys|trade|trading|training|travel|trust|tui|t[cdfghjklmnortvwz])"
+ "|(?:ubs|university|uno|uol|u[agksyz])"
+ "|(?:vacations|vana|vegas|ventures|versicherung|vet|viajes|video|villas|vin|virgin"
+ "|vision|vista|vistaprint|viva|vlaanderen|vodka|vote|voting|voto|voyage|v[aceginu])"
+ "|(?:wales|walter|wang|watch|webcam|website|wed|wedding|weir|whoswho|wien|wiki|williamhill"
+ "|win|windows|wine|wme|work|works|world|wtc|wtf|w[fs])"
+ "|(?:\u03b5\u03bb|\u0431\u0435\u043b|\u0434\u0435\u0442\u0438|\u043a\u043e\u043c|\u043c\u043a\u0434"
+ "|\u043c\u043e\u043d|\u043c\u043e\u0441\u043a\u0432\u0430|\u043e\u043d\u043b\u0430\u0439\u043d"
+ "|\u043e\u0440\u0433|\u0440\u0443\u0441|\u0440\u0444|\u0441\u0430\u0439\u0442|\u0441\u0440\u0431"
+ "|\u0443\u043a\u0440|\u049b\u0430\u0437|\u0570\u0561\u0575|\u05e7\u05d5\u05dd|\u0627\u0631\u0627\u0645\u0643\u0648"
+ "|\u0627\u0644\u0627\u0631\u062f\u0646|\u0627\u0644\u062c\u0632\u0627\u0626\u0631|\u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629"
+ "|\u0627\u0644\u0645\u063a\u0631\u0628|\u0627\u0645\u0627\u0631\u0627\u062a|\u0627\u06cc\u0631\u0627\u0646"
+ "|\u0628\u0627\u0632\u0627\u0631|\u0628\u06be\u0627\u0631\u062a|\u062a\u0648\u0646\u0633"
+ "|\u0633\u0648\u062f\u0627\u0646|\u0633\u0648\u0631\u064a\u0629|\u0634\u0628\u0643\u0629"
+ "|\u0639\u0631\u0627\u0642|\u0639\u0645\u0627\u0646|\u0641\u0644\u0633\u0637\u064a\u0646"
+ "|\u0642\u0637\u0631|\u0643\u0648\u0645|\u0645\u0635\u0631|\u0645\u0644\u064a\u0633\u064a\u0627"
+ "|\u0645\u0648\u0642\u0639|\u0915\u0949\u092e|\u0928\u0947\u091f|\u092d\u093e\u0930\u0924"
+ "|\u0938\u0902\u0917\u0920\u0928|\u09ad\u09be\u09b0\u09a4|\u0a2d\u0a3e\u0a30\u0a24|\u0aad\u0abe\u0ab0\u0aa4"
+ "|\u0b87\u0ba8\u0bcd\u0ba4\u0bbf\u0baf\u0bbe|\u0b87\u0bb2\u0b99\u0bcd\u0b95\u0bc8|\u0b9a\u0bbf\u0b99\u0bcd\u0b95\u0baa\u0bcd\u0baa\u0bc2\u0bb0\u0bcd"
+ "|\u0c2d\u0c3e\u0c30\u0c24\u0c4d|\u0dbd\u0d82\u0d9a\u0dcf|\u0e04\u0e2d\u0e21|\u0e44\u0e17\u0e22"
+ "|\u10d2\u10d4|\u307f\u3093\u306a|\u30b0\u30fc\u30b0\u30eb|\u30b3\u30e0|\u4e16\u754c"
+ "|\u4e2d\u4fe1|\u4e2d\u56fd|\u4e2d\u570b|\u4e2d\u6587\u7f51|\u4f01\u4e1a|\u4f5b\u5c71"
+ "|\u4fe1\u606f|\u5065\u5eb7|\u516b\u5366|\u516c\u53f8|\u516c\u76ca|\u53f0\u6e7e|\u53f0\u7063"
+ "|\u5546\u57ce|\u5546\u5e97|\u5546\u6807|\u5728\u7ebf|\u5927\u62ff|\u5a31\u4e50|\u5de5\u884c"
+ "|\u5e7f\u4e1c|\u6148\u5584|\u6211\u7231\u4f60|\u624b\u673a|\u653f\u52a1|\u653f\u5e9c"
+ "|\u65b0\u52a0\u5761|\u65b0\u95fb|\u65f6\u5c1a|\u673a\u6784|\u6de1\u9a6c\u9521|\u6e38\u620f"
+ "|\u70b9\u770b|\u79fb\u52a8|\u7ec4\u7ec7\u673a\u6784|\u7f51\u5740|\u7f51\u5e97|\u7f51\u7edc"
+ "|\u8c37\u6b4c|\u96c6\u56e2|\u98de\u5229\u6d66|\u9910\u5385|\u9999\u6e2f|\ub2f7\ub137"
+ "|\ub2f7\ucef4|\uc0bc\uc131|\ud55c\uad6d|xbox"
+ "|xerox|xin|xn\\-\\-11b4c3d|xn\\-\\-1qqw23a|xn\\-\\-30rr7y|xn\\-\\-3bst00m|xn\\-\\-3ds443g"
+ "|xn\\-\\-3e0b707e|xn\\-\\-3pxu8k|xn\\-\\-42c2d9a|xn\\-\\-45brj9c|xn\\-\\-45q11c|xn\\-\\-4gbrim"
+ "|xn\\-\\-55qw42g|xn\\-\\-55qx5d|xn\\-\\-6frz82g|xn\\-\\-6qq986b3xl|xn\\-\\-80adxhks"
+ "|xn\\-\\-80ao21a|xn\\-\\-80asehdb|xn\\-\\-80aswg|xn\\-\\-90a3ac|xn\\-\\-90ais|xn\\-\\-9dbq2a"
+ "|xn\\-\\-9et52u|xn\\-\\-b4w605ferd|xn\\-\\-c1avg|xn\\-\\-c2br7g|xn\\-\\-cg4bki|xn\\-\\-clchc0ea0b2g2a9gcd"
+ "|xn\\-\\-czr694b|xn\\-\\-czrs0t|xn\\-\\-czru2d|xn\\-\\-d1acj3b|xn\\-\\-d1alf|xn\\-\\-efvy88h"
+ "|xn\\-\\-estv75g|xn\\-\\-fhbei|xn\\-\\-fiq228c5hs|xn\\-\\-fiq64b|xn\\-\\-fiqs8s|xn\\-\\-fiqz9s"
+ "|xn\\-\\-fjq720a|xn\\-\\-flw351e|xn\\-\\-fpcrj9c3d|xn\\-\\-fzc2c9e2c|xn\\-\\-gecrj9c"
+ "|xn\\-\\-h2brj9c|xn\\-\\-hxt814e|xn\\-\\-i1b6b1a6a2e|xn\\-\\-imr513n|xn\\-\\-io0a7i"
+ "|xn\\-\\-j1aef|xn\\-\\-j1amh|xn\\-\\-j6w193g|xn\\-\\-kcrx77d1x4a|xn\\-\\-kprw13d|xn\\-\\-kpry57d"
+ "|xn\\-\\-kput3i|xn\\-\\-l1acc|xn\\-\\-lgbbat1ad8j|xn\\-\\-mgb9awbf|xn\\-\\-mgba3a3ejt"
+ "|xn\\-\\-mgba3a4f16a|xn\\-\\-mgbaam7a8h|xn\\-\\-mgbab2bd|xn\\-\\-mgbayh7gpa|xn\\-\\-mgbbh1a71e"
+ "|xn\\-\\-mgbc0a9azcg|xn\\-\\-mgberp4a5d4ar|xn\\-\\-mgbpl2fh|xn\\-\\-mgbtx2b|xn\\-\\-mgbx4cd0ab"
+ "|xn\\-\\-mk1bu44c|xn\\-\\-mxtq1m|xn\\-\\-ngbc5azd|xn\\-\\-node|xn\\-\\-nqv7f|xn\\-\\-nqv7fs00ema"
+ "|xn\\-\\-nyqy26a|xn\\-\\-o3cw4h|xn\\-\\-ogbpf8fl|xn\\-\\-p1acf|xn\\-\\-p1ai|xn\\-\\-pgbs0dh"
+ "|xn\\-\\-pssy2u|xn\\-\\-q9jyb4c|xn\\-\\-qcka1pmc|xn\\-\\-qxam|xn\\-\\-rhqv96g|xn\\-\\-s9brj9c"
+ "|xn\\-\\-ses554g|xn\\-\\-t60b56a|xn\\-\\-tckwe|xn\\-\\-unup4y|xn\\-\\-vermgensberater\\-ctb"
+ "|xn\\-\\-vermgensberatung\\-pwb|xn\\-\\-vhquv|xn\\-\\-vuq861b|xn\\-\\-wgbh1c|xn\\-\\-wgbl6a"
+ "|xn\\-\\-xhq521b|xn\\-\\-xkc2al3hye2a|xn\\-\\-xkc2dl3a5ee0h|xn\\-\\-y9a3aq|xn\\-\\-yfro4i67o"
+ "|xn\\-\\-ygbi2ammx|xn\\-\\-zfr164b|xperia|xxx|xyz)"
+ "|(?:yachts|yamaxun|yandex|yodobashi|yoga|yokohama|youtube|y[et])"
+ "|(?:zara|zip|zone|zuerich|z[amw]))")
/**
* RFC 3492 references RFC 1034 and limits Punycode algorithm output to 63 characters.
*/
private val PUNYCODE_TLD = "xn\\-\\-[\\w\\-]{0,58}\\w"
/**
* Valid UCS characters defined in RFC 3987. Excludes space characters.
*/
private val UCS_CHAR = "[" +
"\u00A0-\uD7FF" +
"\uF900-\uFDCF" +
"\uFDF0-\uFFEF" +
"\uD800\uDC00-\uD83F\uDFFD" +
"\uD840\uDC00-\uD87F\uDFFD" +
"\uD880\uDC00-\uD8BF\uDFFD" +
"\uD8C0\uDC00-\uD8FF\uDFFD" +
"\uD900\uDC00-\uD93F\uDFFD" +
"\uD940\uDC00-\uD97F\uDFFD" +
"\uD980\uDC00-\uD9BF\uDFFD" +
"\uD9C0\uDC00-\uD9FF\uDFFD" +
"\uDA00\uDC00-\uDA3F\uDFFD" +
"\uDA40\uDC00-\uDA7F\uDFFD" +
"\uDA80\uDC00-\uDABF\uDFFD" +
"\uDAC0\uDC00-\uDAFF\uDFFD" +
"\uDB00\uDC00-\uDB3F\uDFFD" +
"\uDB44\uDC00-\uDB7F\uDFFD" +
"&&[^\u00A0[\u2000-\u200A]\u2028\u2029\u202F\u3000]]"
/**
* Valid characters for IRI label defined in RFC 3987.
*/
private val LABEL_CHAR = "a-zA-Z0-9$UCS_CHAR"
/**
* RFC 1035 Section 2.3.4 limits the labels to a maximum 63 octets.
*/
private val IRI_LABEL =
"[" + LABEL_CHAR + "](?:[" + LABEL_CHAR + "_\\-]{0,61}[" + LABEL_CHAR + "]){0,1}"
private val IP_ADDRESS = Pattern.compile(
"((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]"
+ "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]"
+ "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
+ "|[1-9][0-9]|[0-9]))")
/**
* Regular expression that matches domain names without a TLD
*/
private val RELAXED_DOMAIN_NAME =
"(?:(?:$IRI_LABEL(?:\\.(?=\\S))?)+|$IP_ADDRESS)"
private val PROTOCOL = "(?i:http|https|rtsp)://"
/* A word boundary or end of input. This is to stop foo.sure from matching as foo.su */
private val WORD_BOUNDARY = "(?:\\b|$|^)"
private val PORT_NUMBER = "\\:\\d{1,5}"
private val PATH_AND_QUERY = ("[/\\?](?:(?:[" + LABEL_CHAR
+ ";/\\?:@&=#~" // plus optional query params
+ "\\-\\.\\+!\\*'\\(\\),_\\$])|(?:%[a-fA-F0-9]{2}))*")
private val USER_INFO = ("(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
+ "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
+ "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@")
/**
* Regular expression to match strings that start with a supported protocol. Rules for domain
* names and TLDs are more relaxed. TLDs are optional.
*/
private val WEB_URL_WITH_PROTOCOL = ("("
+ WORD_BOUNDARY
+ "(?:"
+ "(?:" + PROTOCOL + "(?:" + USER_INFO + ")?" + ")"
+ "(?:" + RELAXED_DOMAIN_NAME + ")?"
+ "(?:" + PORT_NUMBER + ")?"
+ ")"
+ "(?:" + PATH_AND_QUERY + ")?"
+ WORD_BOUNDARY
+ ")")
/**
* Regular expression that matches known TLDs and punycode TLDs
*/
private val STRICT_TLD = "(?:" +
IANA_TOP_LEVEL_DOMAINS + "|" + PUNYCODE_TLD + ")"
private val STRICT_HOST_NAME = ("(?:(?:" + IRI_LABEL + "\\.)+"
+ STRICT_TLD + ")")
private val STRICT_DOMAIN_NAME = Pattern.compile("(?:$STRICT_HOST_NAME|$IP_ADDRESS)")
/**
* Regular expression to match strings that do not start with a supported protocol. The TLDs
* are expected to be one of the known TLDs.
*/
private val WEB_URL_WITHOUT_PROTOCOL = ("("
+ WORD_BOUNDARY
+ "(?<!:\\/\\/)"
+ "("
+ "(?:" + STRICT_DOMAIN_NAME + ")"
+ "(?:" + PORT_NUMBER + ")?"
+ ")"
+ "(?:" + PATH_AND_QUERY + ")?"
+ WORD_BOUNDARY
+ ")")
/**
* Regular expression pattern to match IRIs. If a string starts with http(s):// the expression
* tries to match the URL structure with a relaxed rule for TLDs. If the string does not start
* with http(s):// the TLDs are expected to be one of the known TLDs.
*
* Borrowed from the [androidx.core.util.PatternsCompat] since this regex is restricted to
* library and thus, breaks the lint.
*/
private val WEB_URL = Pattern.compile(
"($WEB_URL_WITH_PROTOCOL|$WEB_URL_WITHOUT_PROTOCOL)")
}
} }
package chat.rocket.android.main.presentation package chat.rocket.android.main.presentation
import android.content.Context import android.content.Context
import chat.rocket.android.R
import chat.rocket.android.core.lifecycle.CancelStrategy import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.db.DatabaseManagerFactory import chat.rocket.android.db.DatabaseManagerFactory
import chat.rocket.android.emoji.Emoji import chat.rocket.android.emoji.Emoji
......
...@@ -232,6 +232,15 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, ...@@ -232,6 +232,15 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
toolbar.setNavigationOnClickListener { openDrawer() } toolbar.setNavigationOnClickListener { openDrawer() }
} }
fun showLogoutDialog() {
val builder = AlertDialog.Builder(this)
builder.setTitle(R.string.action_logout)
builder.setMessage(R.string.title_confirmation)
builder.setPositiveButton(R.string.action_logout) { _, _ -> presenter.logout()}
.setNegativeButton(R.string.action_stay) { dialog, _ -> dialog.cancel() }
builder.create().show()
}
fun setAvatar(avatarUrl: String) { fun setAvatar(avatarUrl: String) {
headerLayout.image_avatar.setImageURI(avatarUrl) headerLayout.image_avatar.setImageURI(avatarUrl)
} }
......
...@@ -64,6 +64,6 @@ internal fun MainActivity.onNavDrawerItemSelected(menuItem: MenuItem) { ...@@ -64,6 +64,6 @@ internal fun MainActivity.onNavDrawerItemSelected(menuItem: MenuItem) {
R.id.menu_action_profile -> presenter.toUserProfile() R.id.menu_action_profile -> presenter.toUserProfile()
R.id.menu_action_settings -> presenter.toSettings() R.id.menu_action_settings -> presenter.toSettings()
R.id.menu_action_admin_panel -> presenter.toAdminPanel() R.id.menu_action_admin_panel -> presenter.toAdminPanel()
R.id.menu_action_logout -> presenter.logout() R.id.menu_action_logout -> showLogoutDialog()
} }
} }
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="2dp" android:layout_marginEnd="2dp"
...@@ -10,7 +11,7 @@ ...@@ -10,7 +11,7 @@
<ViewFlipper <ViewFlipper
android:id="@+id/view_flipper_reaction" android:id="@+id/view_flipper_reaction"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/text_count" app:layout_constraintEnd_toStartOf="@+id/text_count"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
...@@ -19,12 +20,13 @@ ...@@ -19,12 +20,13 @@
<TextView <TextView
android:id="@+id/text_emoji" android:id="@+id/text_emoji"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:ellipsize="end" android:ellipsize="end"
android:gravity="center"
android:maxLines="1" android:maxLines="1"
android:paddingStart="4dp" android:paddingStart="4dp"
android:paddingLeft="4dp" android:paddingLeft="4dp"
android:textColor="#868585" android:textColor="@color/reaction_text"
android:textSize="16sp" android:textSize="16sp"
tools:text=":)" /> tools:text=":)" />
...@@ -48,13 +50,12 @@ ...@@ -48,13 +50,12 @@
android:paddingEnd="4dp" android:paddingEnd="4dp"
android:paddingRight="4dp" android:paddingRight="4dp"
android:paddingBottom="4dp" android:paddingBottom="4dp"
android:textColor="#868585" android:textColor="@color/reaction_text"
android:textSize="16sp" android:textSize="16sp"
android:textStyle="bold" android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/view_flipper_reaction"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:text="12" /> tools:text="12" />
</androidx.constraintlayout.widget.ConstraintLayout> </LinearLayout>
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
<string name="title_update_profile">Update Profil</string> <string name="title_update_profile">Update Profil</string>
<string name="title_about">Über</string> <string name="title_about">Über</string>
<string name="title_create_channel">Erstelle Raum</string> <string name="title_create_channel">Erstelle Raum</string>
<string name="title_confirmation">Are You Sure you want to logout?</string><!-- TODO Add translation -->
<!-- Actions --> <!-- Actions -->
<string name="action_connect">Verbinde</string> <string name="action_connect">Verbinde</string>
...@@ -33,6 +34,7 @@ ...@@ -33,6 +34,7 @@
<string name="action_create_channel">Erstelle Raum</string> <string name="action_create_channel">Erstelle Raum</string>
<string name="action_create">Erstelle</string> <string name="action_create">Erstelle</string>
<string name="action_logout">Abmelden</string> <string name="action_logout">Abmelden</string>
<string name="action_stay">Stay</string> <!-- TODO Add translation -->
<string name="action_files">Dateien</string> <string name="action_files">Dateien</string>
<string name="action_confirm_password">Bestätige Passwort Änderung</string> <string name="action_confirm_password">Bestätige Passwort Änderung</string>
<string name="action_join_chat">Trete Chat bei</string> <string name="action_join_chat">Trete Chat bei</string>
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<string name="title_update_profile">Actualización del perfil</string> <string name="title_update_profile">Actualización del perfil</string>
<string name="title_about">Acerca de</string> <string name="title_about">Acerca de</string>
<string name="title_create_channel">Crear canal</string> <string name="title_create_channel">Crear canal</string>
<string name="title_confirmation">Are You Sure you want to logout?</string> <!-- TODO Add translation -->
<!-- Actions --> <!-- Actions -->
<string name="action_connect">Conectar</string> <string name="action_connect">Conectar</string>
<string name="action_use_this_username">Usa este nombre de usuario</string> <string name="action_use_this_username">Usa este nombre de usuario</string>
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
<string name="action_create_channel">Crear canal</string> <string name="action_create_channel">Crear canal</string>
<string name="action_create">Create</string> <string name="action_create">Create</string>
<string name="action_logout">Cerrar sesión</string> <string name="action_logout">Cerrar sesión</string>
<string name="action_stay">Stay</string> <!-- TODO Add translation -->
<string name="action_files">Archivos</string> <string name="action_files">Archivos</string>
<string name="action_confirm_password">Confirmar cambio de contraseña</string> <string name="action_confirm_password">Confirmar cambio de contraseña</string>
<string name="action_join_chat">Unirse al chat</string> <string name="action_join_chat">Unirse al chat</string>
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
<string name="title_update_profile">Mettre à jour le profil</string> <string name="title_update_profile">Mettre à jour le profil</string>
<string name="title_about">À propos</string> <string name="title_about">À propos</string>
<string name="title_create_channel">Créer salon</string> <string name="title_create_channel">Créer salon</string>
<string name="title_confirmation">Are You Sure you want to logout?</string> <!-- TODO Add translation -->
<!-- Actions --> <!-- Actions -->
...@@ -34,6 +36,7 @@ ...@@ -34,6 +36,7 @@
<string name="action_create_channel">Créer salon</string> <string name="action_create_channel">Créer salon</string>
<string name="action_create">Créer</string> <string name="action_create">Créer</string>
<string name="action_logout">Se déconnecter</string> <string name="action_logout">Se déconnecter</string>
<string name="action_stay">Stay</string> <!-- TODO Add translation -->
<string name="action_files">Fichiers</string> <string name="action_files">Fichiers</string>
<string name="action_confirm_password">Confirmer le mot de passe</string> <string name="action_confirm_password">Confirmer le mot de passe</string>
<string name="action_join_chat">Rejoignez le chat</string> <string name="action_join_chat">Rejoignez le chat</string>
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
<string name="title_update_profile">प्रोफ़ाइल अपडेट करें</string> <string name="title_update_profile">प्रोफ़ाइल अपडेट करें</string>
<string name="title_about">परिचय</string> <string name="title_about">परिचय</string>
<string name="title_create_channel">चैनल बनाएं</string> <string name="title_create_channel">चैनल बनाएं</string>
<string name="title_confirmation">Are You Sure you want to logout?</string> <!-- TODO Add translation -->
<!-- Actions --> <!-- Actions -->
<string name="action_connect">जुडिये</string> <string name="action_connect">जुडिये</string>
...@@ -33,6 +35,7 @@ ...@@ -33,6 +35,7 @@
<string name="action_create_channel">चैनल बनाएं</string> <string name="action_create_channel">चैनल बनाएं</string>
<string name="action_create">बनाएं</string> <string name="action_create">बनाएं</string>
<string name="action_logout">लोग आउट करें</string> <string name="action_logout">लोग आउट करें</string>
<string name="action_stay">Stay</string> <!-- TODO Add translation -->
<string name="action_files">फ़ाइलें</string> <string name="action_files">फ़ाइलें</string>
<string name="action_confirm_password">पासवर्ड परिवर्तन की पुष्टि करें</string> <string name="action_confirm_password">पासवर्ड परिवर्तन की पुष्टि करें</string>
<string name="action_join_chat">चैट में शामिल हों</string> <string name="action_join_chat">चैट में शामिल हों</string>
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
<string name="title_update_profile">プロフィールの更新</string> <string name="title_update_profile">プロフィールの更新</string>
<string name="title_about">About</string> <string name="title_about">About</string>
<string name="title_create_channel">新しいチャネルを作成します</string> <string name="title_create_channel">新しいチャネルを作成します</string>
<string name="title_confirmation">Are You Sure you want to logout?</string> <!-- TODO Add translation -->
<!-- Actions --> <!-- Actions -->
<string name="action_connect">接続</string> <string name="action_connect">接続</string>
...@@ -35,6 +37,7 @@ ...@@ -35,6 +37,7 @@
<string name="action_create_channel">チャンネル作成</string> <string name="action_create_channel">チャンネル作成</string>
<string name="action_create">作ります</string> <string name="action_create">作ります</string>
<string name="action_logout">ログアウト</string> <string name="action_logout">ログアウト</string>
<string name="action_stay">Stay</string> <!-- TODO Add translation -->
<string name="action_files">ファイル</string> <string name="action_files">ファイル</string>
<string name="action_confirm_password">変更したパスワードの確認</string> <string name="action_confirm_password">変更したパスワードの確認</string>
<string name="action_join_chat">チャットに参加</string> <string name="action_join_chat">チャットに参加</string>
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
<string name="title_update_profile">Editar perfil</string> <string name="title_update_profile">Editar perfil</string>
<string name="title_about">Sobre</string> <string name="title_about">Sobre</string>
<string name="title_create_channel">Criar chat</string> <string name="title_create_channel">Criar chat</string>
<string name="title_confirmation">Are You Sure you want to logout?</string> <!-- TODO Add translation -->
<!-- Actions --> <!-- Actions -->
<string name="action_connect">Conectar</string> <string name="action_connect">Conectar</string>
...@@ -33,6 +35,7 @@ ...@@ -33,6 +35,7 @@
<string name="action_create_channel">Criar chat</string> <string name="action_create_channel">Criar chat</string>
<string name="action_create">Criar</string> <string name="action_create">Criar</string>
<string name="action_logout">Sair</string> <string name="action_logout">Sair</string>
<string name="action_stay">Stay</string> <!-- TODO Add translation -->
<string name="action_files">Arquivos</string> <string name="action_files">Arquivos</string>
<string name="action_confirm_password">Confirme a nova senha</string> <string name="action_confirm_password">Confirme a nova senha</string>
<string name="action_join_chat">Entrar no Chat</string> <string name="action_join_chat">Entrar no Chat</string>
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
<string name="title_update_profile">Обновить профиль</string> <string name="title_update_profile">Обновить профиль</string>
<string name="title_about">О программе</string> <string name="title_about">О программе</string>
<string name="title_create_channel">Создать новый канал</string> <string name="title_create_channel">Создать новый канал</string>
<string name="title_confirmation">Are You Sure you want to logout?</string> <!-- TODO Add translation -->
<!-- Actions --> <!-- Actions -->
<string name="action_connect">Подключиться</string> <string name="action_connect">Подключиться</string>
...@@ -33,6 +35,7 @@ ...@@ -33,6 +35,7 @@
<string name="action_create_channel">Создать канал</string> <string name="action_create_channel">Создать канал</string>
<string name="action_create">Создать</string> <string name="action_create">Создать</string>
<string name="action_logout">Выйти</string> <string name="action_logout">Выйти</string>
<string name="action_stay">Stay</string> <!-- TODO Add translation -->
<string name="action_files">Файлы</string> <string name="action_files">Файлы</string>
<string name="action_confirm_password">Подтверждение изменения пароля</string> <string name="action_confirm_password">Подтверждение изменения пароля</string>
<string name="action_join_chat">Присоединиться к чату</string> <string name="action_join_chat">Присоединиться к чату</string>
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
<string name="title_update_profile">Profilinizi Düzenleyin</string> <string name="title_update_profile">Profilinizi Düzenleyin</string>
<string name="title_about">Hakkında</string> <string name="title_about">Hakkında</string>
<string name="title_create_channel">Yeni Kanal Oluştur</string> <string name="title_create_channel">Yeni Kanal Oluştur</string>
<string name="title_confirmation">Are You Sure you want to logout?</string> <!-- TODO Add translation -->
<!-- Actions --> <!-- Actions -->
<string name="action_connect">Bağlan</string> <string name="action_connect">Bağlan</string>
...@@ -33,6 +35,7 @@ ...@@ -33,6 +35,7 @@
<string name="action_create_channel">Yeni Kanal Oluştur</string> <string name="action_create_channel">Yeni Kanal Oluştur</string>
<string name="action_create">Oluştur</string> <string name="action_create">Oluştur</string>
<string name="action_logout">Çıkış Yap</string> <string name="action_logout">Çıkış Yap</string>
<string name="action_stay">Stay</string> <!-- TODO Add translation -->
<string name="action_files">Dosyalar</string> <string name="action_files">Dosyalar</string>
<string name="action_confirm_password">Şifre Değişikliğini Onaylayın</string> <string name="action_confirm_password">Şifre Değişikliğini Onaylayın</string>
<string name="action_join_chat">Sohbete Bağlan</string> <string name="action_join_chat">Sohbete Bağlan</string>
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
<string name="title_update_profile">Оновити профіль</string> <string name="title_update_profile">Оновити профіль</string>
<string name="title_about">"Про програму"</string> <string name="title_about">"Про програму"</string>
<string name="title_create_channel">Створити новий канал</string> <string name="title_create_channel">Створити новий канал</string>
<string name="title_confirmation">Are You Sure you want to logout?</string> <!-- TODO Add translation -->
<!-- Actions --> <!-- Actions -->
<string name="action_connect">Підключитися</string> <string name="action_connect">Підключитися</string>
...@@ -33,6 +35,7 @@ ...@@ -33,6 +35,7 @@
<string name="action_create_channel">Створити канал</string> <string name="action_create_channel">Створити канал</string>
<string name="action_create">Створити</string> <string name="action_create">Створити</string>
<string name="action_logout">Вийти</string> <string name="action_logout">Вийти</string>
<string name="action_stay">Stay</string> <!-- TODO Add translation -->
<string name="action_files">Файли</string> <string name="action_files">Файли</string>
<string name="action_confirm_password">Підтвердження зміни пароля</string> <string name="action_confirm_password">Підтвердження зміни пароля</string>
<string name="action_join_chat">Приєднатися до чату</string> <string name="action_join_chat">Приєднатися до чату</string>
......
...@@ -59,4 +59,6 @@ ...@@ -59,4 +59,6 @@
<!-- Default Background Color --> <!-- Default Background Color -->
<color name="default_background">#FAFAFA</color> <color name="default_background">#FAFAFA</color>
<color name="reaction_text">#868585</color>
</resources> </resources>
...@@ -32,6 +32,7 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin ...@@ -32,6 +32,7 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<string name="title_update_profile">Update profile</string> <string name="title_update_profile">Update profile</string>
<string name="title_about">About</string> <string name="title_about">About</string>
<string name="title_create_channel">Create Channel</string> <string name="title_create_channel">Create Channel</string>
<string name="title_confirmation">Are You Sure you want to logout?</string>
<!-- Actions --> <!-- Actions -->
<string name="action_connect">Connect</string> <string name="action_connect">Connect</string>
...@@ -45,6 +46,7 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin ...@@ -45,6 +46,7 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<string name="action_create_channel">Create channel</string> <string name="action_create_channel">Create channel</string>
<string name="action_create">Create</string> <string name="action_create">Create</string>
<string name="action_logout">Logout</string> <string name="action_logout">Logout</string>
<string name="action_stay">Stay</string>
<string name="action_files">Files</string> <string name="action_files">Files</string>
<string name="action_confirm_password">Confirm Password Change</string> <string name="action_confirm_password">Confirm Password Change</string>
<string name="action_join_chat">Join Chat</string> <string name="action_join_chat">Join Chat</string>
......
...@@ -10,16 +10,13 @@ buildscript { ...@@ -10,16 +10,13 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.3.0-alpha12' classpath 'com.android.tools.build:gradle:3.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
classpath "org.jetbrains.dokka:dokka-gradle-plugin:${versions.dokka}" classpath "org.jetbrains.dokka:dokka-gradle-plugin:${versions.dokka}"
classpath 'com.google.gms:google-services:4.0.2' classpath 'com.google.gms:google-services:4.1.0'
classpath 'io.fabric.tools:gradle:1.25.4' classpath 'io.fabric.tools:gradle:1.25.4'
classpath "com.github.ben-manes:gradle-versions-plugin:0.20.0" classpath "com.github.ben-manes:gradle-versions-plugin:0.20.0"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
} }
} }
......
...@@ -9,7 +9,7 @@ ext { ...@@ -9,7 +9,7 @@ ext {
dokka : '0.9.16', dokka : '0.9.16',
// For app // For app
kotlin : '1.2.61', kotlin : '1.2.71',
coroutine : '0.25.0', coroutine : '0.25.0',
appCompat : '1.0.0', appCompat : '1.0.0',
...@@ -25,7 +25,7 @@ ext { ...@@ -25,7 +25,7 @@ ext {
firebaseAnalytics : '16.0.3', firebaseAnalytics : '16.0.3',
playServices : '16.0.0', playServices : '16.0.0',
exoPlayer : '2.8.2', exoPlayer : '2.8.2',
flexbox : '1.0.0', flexbox : '1.1.0',
material : '1.0.0-beta01', material : '1.0.0-beta01',
room : '2.0.0', room : '2.0.0',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment