Unverified Commit b5e748b3 authored by divyanshu bhargava's avatar divyanshu bhargava Committed by GitHub

Merge branch 'develop' into tap-on-message

parents 213c89fb d9242c67
...@@ -58,6 +58,9 @@ jobs: ...@@ -58,6 +58,9 @@ jobs:
- run: - run:
name: Run Unit test name: Run Unit test
command: ./gradlew test command: ./gradlew test
- run:
name: Compile Instrumentation test
command: ./gradlew assembleAndroidTest
- store_artifacts: - store_artifacts:
path: app/build/reports/ path: app/build/reports/
destination: reports destination: reports
......
...@@ -13,7 +13,7 @@ android { ...@@ -13,7 +13,7 @@ android {
applicationId "chat.rocket.android" applicationId "chat.rocket.android"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion versions.targetSdk targetSdkVersion versions.targetSdk
versionCode 2015 versionCode 2019
versionName "2.1.0" versionName "2.1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true multiDexEnabled true
...@@ -114,9 +114,9 @@ dependencies { ...@@ -114,9 +114,9 @@ dependencies {
} }
testImplementation libraries.junit testImplementation libraries.junit
androidTestImplementation(libraries.expressoCore, { testImplementation libraries.truth
exclude group: 'com.android.support', module: 'support-annotations' androidTestImplementation libraries.espressoCore
}) androidTestImplementation libraries.espressoIntents
} }
kotlin { kotlin {
......
package chat.rocket.android.chatroom.ui
import android.content.Intent
import android.support.test.espresso.intent.rule.IntentsTestRule
import android.support.test.filters.LargeTest
import org.junit.Rule
import org.junit.Test
import android.app.Activity
import android.app.Instrumentation.ActivityResult
import android.support.test.InstrumentationRegistry
import android.support.test.espresso.intent.Intents.intended
import android.support.test.espresso.intent.Intents.intending
import android.support.test.espresso.intent.matcher.IntentMatchers.*
import org.hamcrest.Matchers.allOf
import org.hamcrest.Matchers.not
import org.junit.Before
@LargeTest
class ChatRoomFragmentTest {
@JvmField
@Rule
val activityRule = IntentsTestRule<ChatRoomActivity>(ChatRoomActivity::class.java, false, false)
@Before
fun stubAllExternalIntents() {
val activityIntent = InstrumentationRegistry.getTargetContext().chatRoomIntent("id", "name", "type", false, 0L)
activityRule.launchActivity(activityIntent)
intending(not(isInternal())).respondWith(ActivityResult(Activity.RESULT_OK, null))
}
@Test
fun showFileSelection_nonNullFiltersAreApplied() {
val fragment = activityRule.activity.supportFragmentManager.findFragmentByTag(ChatRoomActivity.TAG_CHAT_ROOM_FRAGMENT) as ChatRoomFragment
val filters = arrayOf("image/*")
fragment.showFileSelection(filters)
intended(allOf(
hasAction(Intent.ACTION_GET_CONTENT),
hasType("*/*"),
hasCategories(setOf(Intent.CATEGORY_OPENABLE)),
hasExtra(Intent.EXTRA_MIME_TYPES, filters)))
}
@Test
fun showFileSelection_nullFiltersAreNotApplied() {
val fragment = activityRule.activity.supportFragmentManager.findFragmentByTag(ChatRoomActivity.TAG_CHAT_ROOM_FRAGMENT) as ChatRoomFragment
fragment.showFileSelection(null)
intended(allOf(
hasAction(Intent.ACTION_GET_CONTENT),
hasType("*/*"),
hasCategories(setOf(Intent.CATEGORY_OPENABLE)),
not(hasExtraWithKey(Intent.EXTRA_MIME_TYPES))))
}
}
\ No newline at end of file
...@@ -80,12 +80,6 @@ ...@@ -80,12 +80,6 @@
android:theme="@style/AppTheme" android:theme="@style/AppTheme"
android:windowSoftInputMode="adjustResize|stateAlwaysHidden" /> android:windowSoftInputMode="adjustResize|stateAlwaysHidden" />
<!-- TODO: Change to fragment-->
<activity
android:name=".chatroom.ui.PinnedMessagesActivity"
android:theme="@style/AppTheme"
android:windowSoftInputMode="adjustResize|stateAlwaysHidden" />
<!-- TODO: Change to fragment--> <!-- TODO: Change to fragment-->
<activity <activity
android:name=".settings.password.ui.PasswordActivity" android:name=".settings.password.ui.PasswordActivity"
......
...@@ -268,14 +268,13 @@ class LoginPresenter @Inject constructor( ...@@ -268,14 +268,13 @@ class LoginPresenter @Inject constructor(
val token = retryIO("login") { val token = retryIO("login") {
when (loginType) { when (loginType) {
TYPE_LOGIN_USER_EMAIL -> { TYPE_LOGIN_USER_EMAIL -> {
if (usernameOrEmail.isEmail()) { when {
client.loginWithEmail(usernameOrEmail, password) settings.isLdapAuthenticationEnabled() ->
} else {
if (settings.isLdapAuthenticationEnabled()) {
client.loginWithLdap(usernameOrEmail, password) client.loginWithLdap(usernameOrEmail, password)
} else { usernameOrEmail.isEmail() ->
client.loginWithEmail(usernameOrEmail, password)
else ->
client.login(usernameOrEmail, password) client.login(usernameOrEmail, password)
}
} }
} }
TYPE_LOGIN_CAS -> { TYPE_LOGIN_CAS -> {
......
...@@ -14,10 +14,9 @@ class AudioAttachmentViewHolder(itemView: View, ...@@ -14,10 +14,9 @@ class AudioAttachmentViewHolder(itemView: View,
init { init {
with(itemView) { with(itemView) {
setupActionMenu(attachment_container)
image_attachment.setVisible(false) image_attachment.setVisible(false)
audio_video_attachment.setVisible(true) audio_video_attachment.setVisible(true)
setupActionMenu(attachment_container)
setupActionMenu(audio_video_attachment)
} }
} }
......
...@@ -19,12 +19,9 @@ class AuthorAttachmentViewHolder(itemView: View, ...@@ -19,12 +19,9 @@ class AuthorAttachmentViewHolder(itemView: View,
init { init {
with(itemView) { with(itemView) {
setupActionMenu(author_attachment_container) setupActionMenu(author_attachment_container)
setupActionMenu(text_fields)
setupActionMenu(text_author_name)
} }
} }
override fun bindViews(data: AuthorAttachmentViewModel) { override fun bindViews(data: AuthorAttachmentViewModel) {
with(itemView) { with(itemView) {
data.icon?.let { icon -> data.icon?.let { icon ->
......
...@@ -3,6 +3,8 @@ package chat.rocket.android.chatroom.adapter ...@@ -3,6 +3,8 @@ package chat.rocket.android.chatroom.adapter
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup
import androidx.core.view.children
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.chatroom.ui.bottomsheet.BottomSheetMenu import chat.rocket.android.chatroom.ui.bottomsheet.BottomSheetMenu
import chat.rocket.android.chatroom.ui.bottomsheet.adapter.ActionListAdapter import chat.rocket.android.chatroom.ui.bottomsheet.adapter.ActionListAdapter
...@@ -74,7 +76,7 @@ abstract class BaseViewHolder<T : BaseViewModel<*>>( ...@@ -74,7 +76,7 @@ abstract class BaseViewHolder<T : BaseViewModel<*>>(
fun onActionSelected(item: MenuItem, message: Message) fun onActionSelected(item: MenuItem, message: Message)
} }
val onClickListener = { view: View -> private val onClickListener = { view: View ->
if (data?.message?.isSystemMessage() == false) { if (data?.message?.isSystemMessage() == false) {
val menuItems = view.context.inflate(R.menu.message_actions).toList() val menuItems = view.context.inflate(R.menu.message_actions).toList()
menuItems.find { it.itemId == R.id.action_menu_msg_pin_unpin }?.apply { menuItems.find { it.itemId == R.id.action_menu_msg_pin_unpin }?.apply {
...@@ -90,6 +92,13 @@ abstract class BaseViewHolder<T : BaseViewModel<*>>( ...@@ -90,6 +92,13 @@ abstract class BaseViewHolder<T : BaseViewModel<*>>(
internal fun setupActionMenu(view: View) { internal fun setupActionMenu(view: View) {
if (listener.isActionsEnabled()) { if (listener.isActionsEnabled()) {
view.setOnClickListener(onClickListener) view.setOnClickListener(onClickListener)
if (view is ViewGroup) {
for (child in view.children) {
if (child !is RecyclerView && child.id != R.id.recycler_view_reactions) {
setupActionMenu(child)
}
}
}
} }
} }
......
...@@ -20,7 +20,6 @@ class ColorAttachmentViewHolder(itemView: View, ...@@ -20,7 +20,6 @@ class ColorAttachmentViewHolder(itemView: View,
init { init {
with(itemView) { with(itemView) {
setupActionMenu(attachment_text)
setupActionMenu(color_attachment_container) setupActionMenu(color_attachment_container)
attachment_text.movementMethod = LinkMovementMethod() attachment_text.movementMethod = LinkMovementMethod()
} }
......
...@@ -17,11 +17,9 @@ class GenericFileAttachmentViewHolder(itemView: View, ...@@ -17,11 +17,9 @@ class GenericFileAttachmentViewHolder(itemView: View,
init { init {
with(itemView) { with(itemView) {
setupActionMenu(file_attachment_container) setupActionMenu(file_attachment_container)
setupActionMenu(text_file_name)
} }
} }
override fun bindViews(data: GenericFileAttachmentViewModel) { override fun bindViews(data: GenericFileAttachmentViewModel) {
with(itemView) { with(itemView) {
text_file_name.content = data.attachmentTitle text_file_name.content = data.attachmentTitle
......
...@@ -47,7 +47,6 @@ class ImageAttachmentViewHolder(itemView: View, ...@@ -47,7 +47,6 @@ class ImageAttachmentViewHolder(itemView: View,
init { init {
with(itemView) { with(itemView) {
setupActionMenu(attachment_container) setupActionMenu(attachment_container)
setupActionMenu(image_attachment)
} }
} }
......
...@@ -4,7 +4,7 @@ import android.text.method.LinkMovementMethod ...@@ -4,7 +4,7 @@ import android.text.method.LinkMovementMethod
import android.view.View import android.view.View
import chat.rocket.android.chatroom.viewmodel.MessageAttachmentViewModel import chat.rocket.android.chatroom.viewmodel.MessageAttachmentViewModel
import chat.rocket.android.widget.emoji.EmojiReactionListener import chat.rocket.android.widget.emoji.EmojiReactionListener
import kotlinx.android.synthetic.main.item_message.view.* import kotlinx.android.synthetic.main.item_message_attachment.view.*
class MessageAttachmentViewHolder( class MessageAttachmentViewHolder(
itemView: View, itemView: View,
...@@ -14,8 +14,8 @@ class MessageAttachmentViewHolder( ...@@ -14,8 +14,8 @@ class MessageAttachmentViewHolder(
init { init {
with(itemView) { with(itemView) {
setupActionMenu(attachment_container)
text_content.movementMethod = LinkMovementMethod() text_content.movementMethod = LinkMovementMethod()
setupActionMenu(text_content)
} }
} }
......
...@@ -4,7 +4,9 @@ import android.graphics.Color ...@@ -4,7 +4,9 @@ import android.graphics.Color
import android.text.method.LinkMovementMethod import android.text.method.LinkMovementMethod
import android.view.View import android.view.View
import chat.rocket.android.chatroom.viewmodel.MessageViewModel import chat.rocket.android.chatroom.viewmodel.MessageViewModel
import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.widget.emoji.EmojiReactionListener import chat.rocket.android.widget.emoji.EmojiReactionListener
import chat.rocket.core.model.isSystemMessage
import kotlinx.android.synthetic.main.avatar.view.* import kotlinx.android.synthetic.main.avatar.view.*
import kotlinx.android.synthetic.main.item_message.view.* import kotlinx.android.synthetic.main.item_message.view.*
...@@ -16,8 +18,8 @@ class MessageViewHolder( ...@@ -16,8 +18,8 @@ class MessageViewHolder(
init { init {
with(itemView) { with(itemView) {
setupActionMenu(message_container)
text_content.movementMethod = LinkMovementMethod() text_content.movementMethod = LinkMovementMethod()
setupActionMenu(text_content)
} }
} }
...@@ -33,6 +35,11 @@ class MessageViewHolder( ...@@ -33,6 +35,11 @@ class MessageViewHolder(
text_content.setTextColor( text_content.setTextColor(
if (data.isTemporary) Color.GRAY else Color.BLACK if (data.isTemporary) Color.GRAY else Color.BLACK
) )
if (!data.message.isSystemMessage() && data.message.editedBy != null){
text_edit_indicator.setVisible(true)
}else{
text_edit_indicator.setVisible(false)
}
} }
} }
} }
\ No newline at end of file
...@@ -5,6 +5,7 @@ import android.net.Uri ...@@ -5,6 +5,7 @@ import android.net.Uri
import android.view.View import android.view.View
import chat.rocket.android.chatroom.viewmodel.UrlPreviewViewModel import chat.rocket.android.chatroom.viewmodel.UrlPreviewViewModel
import chat.rocket.android.util.extensions.content import chat.rocket.android.util.extensions.content
import chat.rocket.android.util.extensions.openTabbedUrl
import chat.rocket.android.util.extensions.setVisible import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.widget.emoji.EmojiReactionListener import chat.rocket.android.widget.emoji.EmojiReactionListener
import kotlinx.android.synthetic.main.message_url_preview.view.* import kotlinx.android.synthetic.main.message_url_preview.view.*
...@@ -32,10 +33,17 @@ class UrlPreviewViewHolder(itemView: View, ...@@ -32,10 +33,17 @@ class UrlPreviewViewHolder(itemView: View,
text_title.content = data.title text_title.content = data.title
text_description.content = data.description ?: "" text_description.content = data.description ?: ""
url_preview_layout.setOnClickListener { view -> url_preview_layout.setOnClickListener(onClickListener)
view.context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(data.rawData.url))) text_host.setOnClickListener(onClickListener)
} text_title.setOnClickListener(onClickListener)
image_preview.setOnClickListener(onClickListener)
text_description.setOnClickListener(onClickListener)
} }
} }
private val onClickListener = { view: View ->
if (data != null) {
view.openTabbedUrl(Uri.parse(data!!.rawData.url))
}
}
} }
\ No newline at end of file
...@@ -14,10 +14,9 @@ class VideoAttachmentViewHolder(itemView: View, ...@@ -14,10 +14,9 @@ class VideoAttachmentViewHolder(itemView: View,
init { init {
with(itemView) { with(itemView) {
setupActionMenu(attachment_container)
image_attachment.setVisible(false) image_attachment.setVisible(false)
audio_video_attachment.setVisible(true) audio_video_attachment.setVisible(true)
setupActionMenu(attachment_container)
setupActionMenu(audio_video_attachment)
} }
} }
......
...@@ -14,6 +14,12 @@ class ChatRoomNavigator(internal val activity: ChatRoomActivity) { ...@@ -14,6 +14,12 @@ class ChatRoomNavigator(internal val activity: ChatRoomActivity) {
} }
} }
fun toPinnedMessageList(chatRoomId: String, chatRoomType: String) {
activity.addFragmentBackStack("PinnedMessages", R.id.fragment_container){
chat.rocket.android.pinnedmessages.ui.newInstance(chatRoomId,chatRoomType)
}
}
fun toNewServer() { fun toNewServer() {
activity.startActivity(activity.changeServerIntent()) activity.startActivity(activity.changeServerIntent())
activity.finish() activity.finish()
......
...@@ -502,6 +502,8 @@ class ChatRoomPresenter @Inject constructor( ...@@ -502,6 +502,8 @@ class ChatRoomPresenter @Inject constructor(
fun toMembersList(chatRoomId: String, chatRoomType: String) = navigator.toMembersList(chatRoomId, chatRoomType) fun toMembersList(chatRoomId: String, chatRoomType: String) = navigator.toMembersList(chatRoomId, chatRoomType)
fun toPinnedMessageList(chatRoomId: String, chatRoomType: String) = navigator.toPinnedMessageList(chatRoomId,chatRoomType)
fun loadChatRooms() { fun loadChatRooms() {
launchUI(strategy) { launchUI(strategy) {
try { try {
......
...@@ -28,7 +28,7 @@ interface ChatRoomView : LoadingView, MessageView { ...@@ -28,7 +28,7 @@ interface ChatRoomView : LoadingView, MessageView {
/** /**
* Perform file selection with the mime type [filter] * Perform file selection with the mime type [filter]
*/ */
fun showFileSelection(filter: Array<String>) fun showFileSelection(filter: Array<String>?)
/** /**
* Uploads a file to a chat room. * Uploads a file to a chat room.
......
...@@ -93,8 +93,8 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector { ...@@ -93,8 +93,8 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
isChatRoomSubscribed = intent.getBooleanExtra(INTENT_CHAT_IS_SUBSCRIBED, true) isChatRoomSubscribed = intent.getBooleanExtra(INTENT_CHAT_IS_SUBSCRIBED, true)
if (supportFragmentManager.findFragmentByTag("ChatRoomFragment") == null) { if (supportFragmentManager.findFragmentByTag(TAG_CHAT_ROOM_FRAGMENT) == null) {
addFragment("ChatRoomFragment", R.id.fragment_container) { addFragment(TAG_CHAT_ROOM_FRAGMENT, R.id.fragment_container) {
newInstance(chatRoomId, chatRoomName, chatRoomType, isChatRoomReadOnly, chatRoomLastSeen, newInstance(chatRoomId, chatRoomName, chatRoomType, isChatRoomReadOnly, chatRoomLastSeen,
isChatRoomSubscribed) isChatRoomSubscribed)
} }
...@@ -156,4 +156,8 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector { ...@@ -156,4 +156,8 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
super.onBackPressed() super.onBackPressed()
overridePendingTransition(R.anim.close_enter, R.anim.close_exit) overridePendingTransition(R.anim.close_enter, R.anim.close_exit)
} }
companion object {
const val TAG_CHAT_ROOM_FRAGMENT = "ChatRoomFragment"
}
} }
\ No newline at end of file
...@@ -35,7 +35,6 @@ import kotlinx.android.synthetic.main.fragment_chat_room.* ...@@ -35,7 +35,6 @@ import kotlinx.android.synthetic.main.fragment_chat_room.*
import kotlinx.android.synthetic.main.message_attachment_options.* import kotlinx.android.synthetic.main.message_attachment_options.*
import kotlinx.android.synthetic.main.message_composer.* import kotlinx.android.synthetic.main.message_composer.*
import kotlinx.android.synthetic.main.message_list.* import kotlinx.android.synthetic.main.message_list.*
import timber.log.Timber
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
import javax.inject.Inject import javax.inject.Inject
...@@ -177,12 +176,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -177,12 +176,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
presenter.toMembersList(chatRoomId, chatRoomType) presenter.toMembersList(chatRoomId, chatRoomType)
} }
R.id.action_pinned_messages -> { R.id.action_pinned_messages -> {
val intent = Intent(activity, PinnedMessagesActivity::class.java).apply { presenter.toPinnedMessageList(chatRoomId,chatRoomType)
putExtra(BUNDLE_CHAT_ROOM_ID, chatRoomId)
putExtra(BUNDLE_CHAT_ROOM_TYPE, chatRoomType)
putExtra(BUNDLE_CHAT_ROOM_NAME, chatRoomName)
}
startActivity(intent)
} }
} }
return true return true
...@@ -485,12 +479,18 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -485,12 +479,18 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
button_add_reaction.tag = drawableId button_add_reaction.tag = drawableId
} }
override fun showFileSelection(filter: Array<String>) { override fun showFileSelection(filter: Array<String>?) {
ui { ui {
val intent = Intent(Intent.ACTION_GET_CONTENT) val intent = Intent(Intent.ACTION_GET_CONTENT)
// Must set a type otherwise the intent won't resolve
intent.type = "*/*" intent.type = "*/*"
intent.putExtra(Intent.EXTRA_MIME_TYPES, filter)
intent.addCategory(Intent.CATEGORY_OPENABLE) intent.addCategory(Intent.CATEGORY_OPENABLE)
// Filter selectable files to those that match the whitelist for this particular server
if (filter != null) {
intent.putExtra(Intent.EXTRA_MIME_TYPES, filter)
}
startActivityForResult(intent, REQUEST_CODE_FOR_PERFORM_SAF) startActivityForResult(intent, REQUEST_CODE_FOR_PERFORM_SAF)
} }
} }
......
package chat.rocket.android.chatroom.ui
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity
import chat.rocket.android.R
import chat.rocket.android.util.extensions.addFragment
import chat.rocket.android.util.extensions.textContent
import dagger.android.AndroidInjection
import dagger.android.AndroidInjector
import dagger.android.DispatchingAndroidInjector
import dagger.android.support.HasSupportFragmentInjector
import kotlinx.android.synthetic.main.app_bar_chat_room.*
import javax.inject.Inject
private const val INTENT_CHAT_ROOM_ID = "chat_room_id"
private const val INTENT_CHAT_ROOM_NAME = "chat_room_name"
private const val INTENT_CHAT_ROOM_TYPE = "chat_room_type"
class PinnedMessagesActivity : AppCompatActivity(), HasSupportFragmentInjector {
@Inject lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
private lateinit var chatRoomId: String
private lateinit var chatRoomName: String
private lateinit var chatRoomType: String
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_pinned_messages)
chatRoomId = intent.getStringExtra(INTENT_CHAT_ROOM_ID)
requireNotNull(chatRoomId) { "no chat_room_id provided in Intent extras" }
chatRoomName = intent.getStringExtra(INTENT_CHAT_ROOM_NAME)
requireNotNull(chatRoomName) { "no chat_room_name provided in Intent extras" }
chatRoomType = intent.getStringExtra(INTENT_CHAT_ROOM_TYPE)
requireNotNull(chatRoomType) { "no chat_room_type provided in Intent extras" }
setupToolbar()
addFragment("PinnedMessagesFragment", R.id.fragment_container) {
newPinnedMessagesFragment(chatRoomId, chatRoomName, chatRoomType)
}
}
override fun onBackPressed() = finishActivity()
override fun supportFragmentInjector(): AndroidInjector<Fragment> {
return fragmentDispatchingAndroidInjector
}
private fun setupToolbar() {
setSupportActionBar(toolbar)
supportActionBar?.setDisplayShowTitleEnabled(false)
text_room_name.textContent = getString(R.string.title_pinned_messages)
toolbar.setNavigationOnClickListener {
finishActivity()
}
}
private fun finishActivity() {
super.onBackPressed()
overridePendingTransition(R.anim.close_enter, R.anim.close_exit)
}
}
\ No newline at end of file
...@@ -64,6 +64,10 @@ class ChatRoomsPresenter @Inject constructor( ...@@ -64,6 +64,10 @@ class ChatRoomsPresenter @Inject constructor(
view.showLoading() view.showLoading()
subscribeStatusChange() subscribeStatusChange()
try { try {
// If we still don't have 'Store_Last_Message' setting, refresh the settings
if (!settings.hasShowLastMessage()) {
refreshSettingsInteractor.refresh(currentServer)
}
view.updateChatRooms(getUserChatRooms()) view.updateChatRooms(getUserChatRooms())
} catch (ex: RocketChatException) { } catch (ex: RocketChatException) {
ex.message?.let { ex.message?.let {
...@@ -226,9 +230,11 @@ class ChatRoomsPresenter @Inject constructor( ...@@ -226,9 +230,11 @@ class ChatRoomsPresenter @Inject constructor(
} }
ChatRoomsSortOrder.ACTIVITY -> { ChatRoomsSortOrder.ACTIVITY -> {
when (groupByType) { when (groupByType) {
true -> openChatRooms.sortedWith(compareBy(ChatRoom::type).thenByDescending { it.lastMessage?.timestamp }) true -> openChatRooms.sortedWith(compareBy(ChatRoom::type).thenByDescending { chatroom ->
chatRoomTimestamp(chatroom)
})
false -> openChatRooms.sortedByDescending { chatRoom -> false -> openChatRooms.sortedByDescending { chatRoom ->
chatRoom.lastMessage?.timestamp chatRoomTimestamp(chatRoom)
} }
} }
} }
...@@ -238,6 +244,14 @@ class ChatRoomsPresenter @Inject constructor( ...@@ -238,6 +244,14 @@ class ChatRoomsPresenter @Inject constructor(
} }
} }
private fun chatRoomTimestamp(chatRoom: ChatRoom): Long? {
return if (settings.hasShowLastMessage() && settings.showLastMessage()) {
chatRoom.lastMessage?.timestamp ?: chatRoom.updatedAt
} else {
chatRoom.updatedAt
}
}
private fun compareBy(selector: KProperty1<ChatRoom, RoomType>): Comparator<ChatRoom> { private fun compareBy(selector: KProperty1<ChatRoom, RoomType>): Comparator<ChatRoom> {
return Comparator { a, b -> getTypeConstant(a.type) - getTypeConstant(b.type) } return Comparator { a, b -> getTypeConstant(a.type) - getTypeConstant(b.type) }
} }
...@@ -289,8 +303,9 @@ class ChatRoomsPresenter @Inject constructor( ...@@ -289,8 +303,9 @@ class ChatRoomsPresenter @Inject constructor(
private suspend fun getChatRoomsWithPreviews(chatRooms: List<ChatRoom>): List<ChatRoom> { private suspend fun getChatRoomsWithPreviews(chatRooms: List<ChatRoom>): List<ChatRoom> {
return chatRooms.map { return chatRooms.map {
if (it.lastMessage != null) { val lastMessage = it.lastMessage
it.copy(lastMessage = viewModelMapper.map(it.lastMessage!!).last().preview) if (lastMessage != null) {
it.copy(lastMessage = viewModelMapper.map(lastMessage).last().preview)
} else { } else {
it it
} }
......
...@@ -16,12 +16,9 @@ import chat.rocket.android.R ...@@ -16,12 +16,9 @@ import chat.rocket.android.R
import chat.rocket.android.infrastructure.LocalRepository import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.infrastructure.checkIfMyself import chat.rocket.android.infrastructure.checkIfMyself
import chat.rocket.android.server.domain.PublicSettings import chat.rocket.android.server.domain.PublicSettings
import chat.rocket.android.server.domain.showLastMessage
import chat.rocket.android.server.domain.useRealName import chat.rocket.android.server.domain.useRealName
import chat.rocket.android.util.extensions.avatarUrl import chat.rocket.android.util.extensions.*
import chat.rocket.android.util.extensions.content
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.textContent
import chat.rocket.common.model.RoomType import chat.rocket.common.model.RoomType
import chat.rocket.core.model.ChatRoom import chat.rocket.core.model.ChatRoom
import com.facebook.drawee.view.SimpleDraweeView import com.facebook.drawee.view.SimpleDraweeView
...@@ -51,24 +48,31 @@ class ChatRoomsAdapter(private val context: Context, ...@@ -51,24 +48,31 @@ class ChatRoomsAdapter(private val context: Context,
bindAvatar(chatRoom, image_avatar) bindAvatar(chatRoom, image_avatar)
bindName(chatRoom, text_chat_name) bindName(chatRoom, text_chat_name)
bindIcon(chatRoom, image_chat_icon) bindIcon(chatRoom, image_chat_icon)
bindLastMessageDateTime(chatRoom, text_last_message_date_time) if (settings.showLastMessage()) {
bindLastMessage(chatRoom, text_last_message) text_last_message.setVisible(true)
text_last_message_date_time.setVisible(true)
bindLastMessageDateTime(chatRoom, text_last_message_date_time)
bindLastMessage(chatRoom, text_last_message)
} else {
text_last_message.setVisible(false)
text_last_message_date_time.setVisible(false)
}
bindUnreadMessages(chatRoom, text_total_unread_messages) bindUnreadMessages(chatRoom, text_total_unread_messages)
if (chatRoom.alert || chatRoom.unread > 0) { if (chatRoom.alert || chatRoom.unread > 0) {
text_chat_name.setTextColor(ContextCompat.getColor(context, text_chat_name.setTextColor(ContextCompat.getColor(context,
R.color.colorPrimaryText)) R.color.colorPrimaryText))
text_last_message_date_time.setTextColor(ContextCompat.getColor(context, text_last_message_date_time.setTextColor(ContextCompat.getColor(context,
R.color.colorAccent)) R.color.colorAccent))
text_last_message.setTextColor(ContextCompat.getColor(context, text_last_message.setTextColor(ContextCompat.getColor(context,
android.R.color.primary_text_light)) android.R.color.primary_text_light))
} else { } else {
text_chat_name.setTextColor(ContextCompat.getColor(context, text_chat_name.setTextColor(ContextCompat.getColor(context,
R.color.colorSecondaryText)) R.color.colorSecondaryText))
text_last_message_date_time.setTextColor(ContextCompat.getColor(context, text_last_message_date_time.setTextColor(ContextCompat.getColor(context,
R.color.colorSecondaryText)) R.color.colorSecondaryText))
text_last_message.setTextColor(ContextCompat.getColor(context, text_last_message.setTextColor(ContextCompat.getColor(context,
R.color.colorSecondaryText)) R.color.colorSecondaryText))
} }
setOnClickListener { listener(chatRoom) } setOnClickListener { listener(chatRoom) }
...@@ -112,7 +116,15 @@ class ChatRoomsAdapter(private val context: Context, ...@@ -112,7 +116,15 @@ class ChatRoomsAdapter(private val context: Context,
} }
private fun bindName(chatRoom: ChatRoom, textView: TextView) { private fun bindName(chatRoom: ChatRoom, textView: TextView) {
textView.textContent = chatRoom.name textView.textContent = chatRoomName(chatRoom)
}
private fun chatRoomName(chatRoom: ChatRoom): String {
return if (settings.useRealName()) {
chatRoom.fullName ?: chatRoom.name
} else {
chatRoom.name
}
} }
private fun bindLastMessageDateTime(chatRoom: ChatRoom, textView: TextView) { private fun bindLastMessageDateTime(chatRoom: ChatRoom, textView: TextView) {
......
...@@ -23,6 +23,7 @@ import chat.rocket.android.helper.SharedPreferenceHelper ...@@ -23,6 +23,7 @@ import chat.rocket.android.helper.SharedPreferenceHelper
import chat.rocket.android.infrastructure.LocalRepository import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.server.domain.GetCurrentServerInteractor import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.domain.SettingsRepository import chat.rocket.android.server.domain.SettingsRepository
import chat.rocket.android.server.domain.showLastMessage
import chat.rocket.android.util.extensions.* import chat.rocket.android.util.extensions.*
import chat.rocket.android.widget.DividerItemDecoration import chat.rocket.android.widget.DividerItemDecoration
import chat.rocket.common.model.RoomType import chat.rocket.common.model.RoomType
...@@ -240,6 +241,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -240,6 +241,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
recycler_view.itemAnimator = DefaultItemAnimator() recycler_view.itemAnimator = DefaultItemAnimator()
// TODO - use a ViewModel Mapper instead of using settings on the adapter // TODO - use a ViewModel Mapper instead of using settings on the adapter
println(serverInteractor.get() + " -> ${settingsRepository.get(serverInteractor.get()!!).showLastMessage()}")
val baseAdapter = ChatRoomsAdapter(it, val baseAdapter = ChatRoomsAdapter(it,
settingsRepository.get(serverInteractor.get()!!), localRepository) { settingsRepository.get(serverInteractor.get()!!), localRepository) {
chatRoom -> presenter.loadChatRoom(chatRoom) chatRoom -> presenter.loadChatRoom(chatRoom)
......
...@@ -12,7 +12,6 @@ import chat.rocket.android.chatroom.di.ChatRoomFragmentProvider ...@@ -12,7 +12,6 @@ import chat.rocket.android.chatroom.di.ChatRoomFragmentProvider
import chat.rocket.android.chatroom.di.ChatRoomModule import chat.rocket.android.chatroom.di.ChatRoomModule
import chat.rocket.android.chatroom.di.PinnedMessagesFragmentProvider import chat.rocket.android.chatroom.di.PinnedMessagesFragmentProvider
import chat.rocket.android.chatroom.ui.ChatRoomActivity import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatroom.ui.PinnedMessagesActivity
import chat.rocket.android.chatrooms.di.ChatRoomsFragmentProvider import chat.rocket.android.chatrooms.di.ChatRoomsFragmentProvider
import chat.rocket.android.dagger.scope.PerActivity import chat.rocket.android.dagger.scope.PerActivity
import chat.rocket.android.main.di.MainModule import chat.rocket.android.main.di.MainModule
...@@ -50,13 +49,10 @@ abstract class ActivityBuilder { ...@@ -50,13 +49,10 @@ abstract class ActivityBuilder {
@PerActivity @PerActivity
@ContributesAndroidInjector(modules = [ChatRoomModule::class, @ContributesAndroidInjector(modules = [ChatRoomModule::class,
ChatRoomFragmentProvider::class, ChatRoomFragmentProvider::class,
MembersFragmentProvider::class]) MembersFragmentProvider::class,
PinnedMessagesFragmentProvider::class])
abstract fun bindChatRoomActivity(): ChatRoomActivity abstract fun bindChatRoomActivity(): ChatRoomActivity
@PerActivity
@ContributesAndroidInjector(modules = [PinnedMessagesFragmentProvider::class])
abstract fun bindPinnedMessagesActivity(): PinnedMessagesActivity
@PerActivity @PerActivity
@ContributesAndroidInjector(modules = [PasswordFragmentProvider::class]) @ContributesAndroidInjector(modules = [PasswordFragmentProvider::class])
abstract fun bindPasswordActivity(): PasswordActivity abstract fun bindPasswordActivity(): PasswordActivity
......
...@@ -38,7 +38,6 @@ import chat.rocket.core.internal.ReactionsAdapter ...@@ -38,7 +38,6 @@ import chat.rocket.core.internal.ReactionsAdapter
import com.facebook.drawee.backends.pipeline.DraweeConfig import com.facebook.drawee.backends.pipeline.DraweeConfig
import com.facebook.imagepipeline.backends.okhttp3.OkHttpImagePipelineConfigFactory import com.facebook.imagepipeline.backends.okhttp3.OkHttpImagePipelineConfigFactory
import com.facebook.imagepipeline.core.ImagePipelineConfig import com.facebook.imagepipeline.core.ImagePipelineConfig
import com.facebook.imagepipeline.listener.RequestListener
import com.facebook.imagepipeline.listener.RequestLoggingListener import com.facebook.imagepipeline.listener.RequestLoggingListener
import com.squareup.moshi.Moshi import com.squareup.moshi.Moshi
import dagger.Module import dagger.Module
...@@ -111,12 +110,12 @@ class AppModule { ...@@ -111,12 +110,12 @@ class AppModule {
@Provides @Provides
@Singleton @Singleton
fun provideOkHttpClient(logger: HttpLoggingInterceptor): OkHttpClient { fun provideOkHttpClient(logger: HttpLoggingInterceptor): OkHttpClient {
return OkHttpClient.Builder().apply { return OkHttpClient.Builder()
addInterceptor(logger) .addInterceptor(logger)
connectTimeout(15, TimeUnit.SECONDS) .connectTimeout(15, TimeUnit.SECONDS)
readTimeout(20, TimeUnit.SECONDS) .readTimeout(20, TimeUnit.SECONDS)
writeTimeout(15, TimeUnit.SECONDS) .writeTimeout(15, TimeUnit.SECONDS)
}.build() .build()
} }
@Provides @Provides
...@@ -138,8 +137,7 @@ class AppModule { ...@@ -138,8 +137,7 @@ class AppModule {
@Provides @Provides
@Singleton @Singleton
fun provideImagePipelineConfig(context: Context, @ForFresco okHttpClient: OkHttpClient): ImagePipelineConfig { fun provideImagePipelineConfig(context: Context, @ForFresco okHttpClient: OkHttpClient): ImagePipelineConfig {
val listeners = HashSet<RequestListener>() val listeners = setOf(RequestLoggingListener())
listeners.add(RequestLoggingListener())
return OkHttpImagePipelineConfigFactory.newBuilder(context, okHttpClient) return OkHttpImagePipelineConfigFactory.newBuilder(context, okHttpClient)
.setRequestListeners(listeners) .setRequestListeners(listeners)
......
...@@ -6,7 +6,6 @@ import android.graphics.Canvas ...@@ -6,7 +6,6 @@ import android.graphics.Canvas
import android.graphics.Paint import android.graphics.Paint
import android.graphics.RectF import android.graphics.RectF
import android.net.Uri import android.net.Uri
import android.support.customtabs.CustomTabsIntent
import android.support.v4.content.res.ResourcesCompat import android.support.v4.content.res.ResourcesCompat
import android.text.Spanned import android.text.Spanned
import android.text.style.ClickableSpan import android.text.style.ClickableSpan
...@@ -16,6 +15,7 @@ import android.view.View ...@@ -16,6 +15,7 @@ import android.view.View
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.server.domain.PublicSettings import chat.rocket.android.server.domain.PublicSettings
import chat.rocket.android.server.domain.useRealName import chat.rocket.android.server.domain.useRealName
import chat.rocket.android.util.extensions.openTabbedUrl
import chat.rocket.android.widget.emoji.EmojiParser import chat.rocket.android.widget.emoji.EmojiParser
import chat.rocket.android.widget.emoji.EmojiRepository import chat.rocket.android.widget.emoji.EmojiRepository
import chat.rocket.android.widget.emoji.EmojiTypefaceSpan import chat.rocket.android.widget.emoji.EmojiTypefaceSpan
...@@ -151,12 +151,7 @@ class MessageParser @Inject constructor( ...@@ -151,12 +151,7 @@ class MessageParser @Inject constructor(
if (!link.startsWith("@") && link !in consumed) { if (!link.startsWith("@") && link !in consumed) {
builder.setSpan(object : ClickableSpan() { builder.setSpan(object : ClickableSpan() {
override fun onClick(view: View) { override fun onClick(view: View) {
with(view) { view.openTabbedUrl(getUri(link))
val tabsbuilder = CustomTabsIntent.Builder()
tabsbuilder.setToolbarColor(ResourcesCompat.getColor(context.resources, R.color.colorPrimary, context.theme))
val customTabsIntent = tabsbuilder.build()
customTabsIntent.launchUrl(context, getUri(link))
}
} }
}, matcher.start(0), matcher.end(0)) }, matcher.start(0), matcher.end(0))
consumed.add(link) consumed.add(link)
......
package chat.rocket.android.chatroom.di package chat.rocket.android.chatroom.di
import android.arch.lifecycle.LifecycleOwner import android.arch.lifecycle.LifecycleOwner
import chat.rocket.android.chatroom.presentation.PinnedMessagesView
import chat.rocket.android.chatroom.ui.PinnedMessagesFragment
import chat.rocket.android.core.lifecycle.CancelStrategy import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.dagger.scope.PerFragment import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.pinnedmessages.presentation.PinnedMessagesView
import chat.rocket.android.pinnedmessages.ui.PinnedMessagesFragment
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import kotlinx.coroutines.experimental.Job import kotlinx.coroutines.experimental.Job
......
package chat.rocket.android.chatroom.di package chat.rocket.android.chatroom.di
import chat.rocket.android.chatroom.ui.PinnedMessagesFragment import chat.rocket.android.pinnedmessages.ui.PinnedMessagesFragment
import dagger.Module import dagger.Module
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
......
package chat.rocket.android.chatroom.presentation package chat.rocket.android.pinnedmessages.presentation
import chat.rocket.android.chatroom.viewmodel.ViewModelMapper import chat.rocket.android.chatroom.viewmodel.ViewModelMapper
import chat.rocket.android.core.lifecycle.CancelStrategy import chat.rocket.android.core.lifecycle.CancelStrategy
......
package chat.rocket.android.chatroom.presentation package chat.rocket.android.pinnedmessages.presentation
import chat.rocket.android.chatroom.viewmodel.BaseViewModel import chat.rocket.android.chatroom.viewmodel.BaseViewModel
import chat.rocket.android.core.behaviours.LoadingView import chat.rocket.android.core.behaviours.LoadingView
......
package chat.rocket.android.chatroom.ui package chat.rocket.android.pinnedmessages.ui
import android.os.Bundle import android.os.Bundle
import android.support.v4.app.Fragment import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.DefaultItemAnimator import android.support.v7.widget.DefaultItemAnimator
import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
...@@ -10,10 +11,12 @@ import android.view.View ...@@ -10,10 +11,12 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.chatroom.adapter.ChatRoomAdapter import chat.rocket.android.chatroom.adapter.ChatRoomAdapter
import chat.rocket.android.chatroom.presentation.PinnedMessagesPresenter import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatroom.presentation.PinnedMessagesView
import chat.rocket.android.chatroom.viewmodel.BaseViewModel import chat.rocket.android.chatroom.viewmodel.BaseViewModel
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.pinnedmessages.presentation.PinnedMessagesPresenter
import chat.rocket.android.pinnedmessages.presentation.PinnedMessagesView
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.setVisible import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui import chat.rocket.android.util.extensions.ui
...@@ -21,54 +24,69 @@ import dagger.android.support.AndroidSupportInjection ...@@ -21,54 +24,69 @@ import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_pinned_messages.* import kotlinx.android.synthetic.main.fragment_pinned_messages.*
import javax.inject.Inject import javax.inject.Inject
private const val BUNDLE_CHAT_ROOM_ID = "chat_room_id" fun newInstance(chatRoomId: String, chatRoomType: String) : Fragment {
private const val BUNDLE_CHAT_ROOM_NAME = "chat_room_name"
private const val BUNDLE_CHAT_ROOM_TYPE = "chat_room_type"
fun newPinnedMessagesFragment(chatRoomId: String, chatRoomType: String, chatRoomName: String): Fragment {
return PinnedMessagesFragment().apply { return PinnedMessagesFragment().apply {
arguments = Bundle(3).apply { arguments = Bundle(1).apply {
putString(BUNDLE_CHAT_ROOM_ID, chatRoomId) putString(BUNDLE_CHAT_ROOM_ID, chatRoomId)
putString(BUNDLE_CHAT_ROOM_NAME, chatRoomName)
putString(BUNDLE_CHAT_ROOM_TYPE, chatRoomType) putString(BUNDLE_CHAT_ROOM_TYPE, chatRoomType)
} }
} }
} }
private const val BUNDLE_CHAT_ROOM_ID = "chat_room_id"
private const val BUNDLE_CHAT_ROOM_TYPE = "chat_room_type"
class PinnedMessagesFragment : Fragment(), PinnedMessagesView { class PinnedMessagesFragment : Fragment(), PinnedMessagesView {
@Inject lateinit var presenter: PinnedMessagesPresenter
private lateinit var chatRoomId: String private lateinit var chatRoomId: String
private lateinit var chatRoomName: String
private lateinit var chatRoomType: String private lateinit var chatRoomType: String
private lateinit var adapter: ChatRoomAdapter private lateinit var adapter: ChatRoomAdapter
@Inject
lateinit var presenter: PinnedMessagesPresenter
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this) AndroidSupportInjection.inject(this)
val bundle = arguments val bundle = arguments
if (bundle != null) { if (bundle != null){
chatRoomId = bundle.getString(BUNDLE_CHAT_ROOM_ID) chatRoomId = bundle.getString(BUNDLE_CHAT_ROOM_ID)
chatRoomName = bundle.getString(BUNDLE_CHAT_ROOM_NAME)
chatRoomType = bundle.getString(BUNDLE_CHAT_ROOM_TYPE) chatRoomType = bundle.getString(BUNDLE_CHAT_ROOM_TYPE)
}else{
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
} }
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) = override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = container?.inflate(R.layout.fragment_pinned_messages)
inflater.inflate(R.layout.fragment_pinned_messages, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setupToolbar()
presenter.loadPinnedMessages(chatRoomId) presenter.loadPinnedMessages(chatRoomId)
} }
override fun showLoading() { override fun showPinnedMessages(pinnedMessages: List<BaseViewModel<*>>) {
ui { view_loading.setVisible(true) } ui {
} if (recycler_view_pinned.adapter == null){
adapter = ChatRoomAdapter(chatRoomType,"",null,false)
recycler_view_pinned.adapter = adapter
val linearLayoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL,false)
recycler_view_pinned.layoutManager = linearLayoutManager
recycler_view_pinned.itemAnimator = DefaultItemAnimator()
if (pinnedMessages.size > 10){
recycler_view_pinned.addOnScrollListener(object : EndlessRecyclerViewScrollListener(linearLayoutManager){
override fun onLoadMore(page: Int, totalItemsCount: Int, recyclerView: RecyclerView?) {
presenter.loadPinnedMessages(chatRoomId)
}
override fun hideLoading() { })
ui { view_loading.setVisible(false) } }
togglePinView(pinnedMessages.size)
}
adapter.appendData(pinnedMessages)
}
} }
override fun showMessage(resId: Int) { override fun showMessage(resId: Int) {
...@@ -85,38 +103,23 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView { ...@@ -85,38 +103,23 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView {
override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error)) override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error))
override fun showPinnedMessages(pinnedMessages: List<BaseViewModel<*>>) { override fun showLoading() {
ui { ui{ view_loading.setVisible(true) }
if (recycler_view_pinned.adapter == null) { }
// TODO - add a better constructor for this case...
adapter = ChatRoomAdapter(chatRoomType, chatRoomName, null, false)
recycler_view_pinned.adapter = adapter
val linearLayoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
recycler_view_pinned.layoutManager = linearLayoutManager
recycler_view_pinned.itemAnimator = DefaultItemAnimator()
if (pinnedMessages.size > 10) {
recycler_view_pinned.addOnScrollListener(object : EndlessRecyclerViewScrollListener(linearLayoutManager) {
override fun onLoadMore(page: Int, totalItemsCount: Int, recyclerView: RecyclerView?) {
presenter.loadPinnedMessages(chatRoomId)
}
})
}
togglePinView(pinnedMessages.size)
}
adapter.appendData(pinnedMessages) override fun hideLoading() {
} ui { view_loading.setVisible(false) }
}
private fun setupToolbar() {
(activity as ChatRoomActivity).setupToolbarTitle(getString(R.string.title_pinned_messages))
} }
private fun togglePinView(size: Int) { private fun togglePinView(size : Int){
if (size == 0){ if (size == 0){
iv_pin_icon.setVisible(true) pin_view.setVisible(true)
tv_pin_title.setVisible(true)
tv_pin_description.setVisible(true)
}else{ }else{
iv_pin_icon.setVisible(false) pin_view.setVisible(false)
tv_pin_title.setVisible(false)
tv_pin_description.setVisible(false)
} }
} }
} }
\ No newline at end of file
...@@ -25,7 +25,7 @@ class RefreshSettingsInteractor @Inject constructor( ...@@ -25,7 +25,7 @@ class RefreshSettingsInteractor @Inject constructor(
HIDE_USER_JOIN, HIDE_USER_LEAVE, HIDE_USER_JOIN, HIDE_USER_LEAVE,
HIDE_TYPE_AU, HIDE_MUTE_UNMUTE, HIDE_TYPE_RU, ALLOW_MESSAGE_DELETING, HIDE_TYPE_AU, HIDE_MUTE_UNMUTE, HIDE_TYPE_RU, ALLOW_MESSAGE_DELETING,
ALLOW_MESSAGE_EDITING, ALLOW_MESSAGE_PINNING, SHOW_DELETED_STATUS, SHOW_EDITED_STATUS, ALLOW_MESSAGE_EDITING, ALLOW_MESSAGE_PINNING, SHOW_DELETED_STATUS, SHOW_EDITED_STATUS,
WIDE_TILE_310) WIDE_TILE_310, STORE_LAST_MESSAGE)
suspend fun refresh(server: String) { suspend fun refresh(server: String) {
withContext(CommonPool) { withContext(CommonPool) {
......
...@@ -49,6 +49,7 @@ const val ALLOW_MESSAGE_EDITING = "Message_AllowEditing" ...@@ -49,6 +49,7 @@ const val ALLOW_MESSAGE_EDITING = "Message_AllowEditing"
const val SHOW_DELETED_STATUS = "Message_ShowDeletedStatus" const val SHOW_DELETED_STATUS = "Message_ShowDeletedStatus"
const val SHOW_EDITED_STATUS = "Message_ShowEditedStatus" const val SHOW_EDITED_STATUS = "Message_ShowEditedStatus"
const val ALLOW_MESSAGE_PINNING = "Message_AllowPinning" const val ALLOW_MESSAGE_PINNING = "Message_AllowPinning"
const val STORE_LAST_MESSAGE = "Store_Last_Message"
/* /*
* Extension functions for Public Settings. * Extension functions for Public Settings.
...@@ -57,6 +58,7 @@ const val ALLOW_MESSAGE_PINNING = "Message_AllowPinning" ...@@ -57,6 +58,7 @@ const val ALLOW_MESSAGE_PINNING = "Message_AllowPinning"
* ServerPresenter.kt and a extension function to access it * ServerPresenter.kt and a extension function to access it
*/ */
fun PublicSettings.isLdapAuthenticationEnabled(): Boolean = this[LDAP_ENABLE]?.value == true fun PublicSettings.isLdapAuthenticationEnabled(): Boolean = this[LDAP_ENABLE]?.value == true
fun PublicSettings.isCasAuthenticationEnabled(): Boolean = this[CAS_ENABLE]?.value == true fun PublicSettings.isCasAuthenticationEnabled(): Boolean = this[CAS_ENABLE]?.value == true
fun PublicSettings.casLoginUrl(): String = this[CAS_LOGIN_URL]?.value.toString() fun PublicSettings.casLoginUrl(): String = this[CAS_LOGIN_URL]?.value.toString()
fun PublicSettings.isRegistrationEnabledForNewUsers(): Boolean = this[ACCOUNT_REGISTRATION]?.value == "Public" fun PublicSettings.isRegistrationEnabledForNewUsers(): Boolean = this[ACCOUNT_REGISTRATION]?.value == "Public"
...@@ -84,13 +86,15 @@ fun PublicSettings.allowedMessagePinning(): Boolean = this[ALLOW_MESSAGE_PINNING ...@@ -84,13 +86,15 @@ fun PublicSettings.allowedMessagePinning(): Boolean = this[ALLOW_MESSAGE_PINNING
fun PublicSettings.allowedMessageEditing(): Boolean = this[ALLOW_MESSAGE_EDITING]?.value == true fun PublicSettings.allowedMessageEditing(): Boolean = this[ALLOW_MESSAGE_EDITING]?.value == true
fun PublicSettings.allowedMessageDeleting(): Boolean = this[ALLOW_MESSAGE_DELETING]?.value == true fun PublicSettings.allowedMessageDeleting(): Boolean = this[ALLOW_MESSAGE_DELETING]?.value == true
fun PublicSettings.uploadMimeTypeFilter(): Array<String> { fun PublicSettings.hasShowLastMessage(): Boolean = this[STORE_LAST_MESSAGE] != null
val values = this[UPLOAD_WHITELIST_MIMETYPES]?.value fun PublicSettings.showLastMessage(): Boolean = this[STORE_LAST_MESSAGE]?.value == true
values?.let { it as String }?.split(",")?.let {
return it.mapToTypedArray { it.trim() }
}
return arrayOf("*/*") fun PublicSettings.uploadMimeTypeFilter(): Array<String>? {
val values = this[UPLOAD_WHITELIST_MIMETYPES]?.value as String?
if (!values.isNullOrBlank()) {
return values!!.split(",").mapToTypedArray { it.trim() }
}
return null
} }
fun PublicSettings.uploadMaxFileSize(): Int { fun PublicSettings.uploadMaxFileSize(): Int {
......
...@@ -5,4 +5,4 @@ inline fun <T, reified R> List<T>.mapToTypedArray(transform: (T) -> R): Array<R> ...@@ -5,4 +5,4 @@ inline fun <T, reified R> List<T>.mapToTypedArray(transform: (T) -> R): Array<R>
is RandomAccess -> Array(size) { index -> transform(this[index]) } is RandomAccess -> Array(size) { index -> transform(this[index]) }
else -> with(iterator()) { Array(size) { transform(next()) } } else -> with(iterator()) { Array(size) { transform(next()) } }
} }
} }
\ No newline at end of file
package chat.rocket.android.util.extensions
import android.net.Uri
import android.support.customtabs.CustomTabsIntent
import android.support.v4.content.res.ResourcesCompat
import android.view.View
import chat.rocket.android.R
fun View.openTabbedUrl(url: Uri) {
with(this) {
val tabsbuilder = CustomTabsIntent.Builder()
tabsbuilder.setToolbarColor(ResourcesCompat.getColor(context.resources, R.color.colorPrimary, context.theme))
val customTabsIntent = tabsbuilder.build()
customTabsIntent.launchUrl(context, url)
}
}
\ No newline at end of file
...@@ -37,14 +37,12 @@ ...@@ -37,14 +37,12 @@
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="100dp" android:layout_height="100dp"
android:src="@drawable/ic_pin_black_24dp" android:src="@drawable/ic_pin_black_24dp"
android:tint="#AFADAF" android:tint="@color/icon_grey"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/tv_pin_title" app:layout_constraintBottom_toTopOf="@id/tv_pin_title"
app:layout_constraintVertical_chainStyle="packed" app:layout_constraintVertical_chainStyle="packed" />
android:visibility="gone"
tools:visibility="visible" />
<TextView <TextView
android:id="@+id/tv_pin_title" android:id="@+id/tv_pin_title"
...@@ -58,9 +56,7 @@ ...@@ -58,9 +56,7 @@
android:textSize="20sp" android:textSize="20sp"
android:layout_marginTop="24dp" android:layout_marginTop="24dp"
android:textStyle="bold" android:textStyle="bold"
android:textColor="#8B8B8B" android:textColor="@color/colorSecondaryText"/>
android:visibility="gone"
tools:visibility="visible"/>
<TextView <TextView
android:id="@+id/tv_pin_description" android:id="@+id/tv_pin_description"
...@@ -74,8 +70,14 @@ ...@@ -74,8 +70,14 @@
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:textAlignment="center" android:textAlignment="center"
android:textSize="16sp" android:textSize="16sp"
android:textColor="#c1c1c1" android:textColor="@color/colorSecondaryTextLight"/>
<android.support.constraint.Group
android:id="@+id/pin_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="tv_pin_description,iv_pin_icon,tv_pin_title"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible"/> tools:visibility="visible" />
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>
\ No newline at end of file
...@@ -22,46 +22,64 @@ ...@@ -22,46 +22,64 @@
<ImageView <ImageView
android:id="@+id/image_chat_icon" android:id="@+id/image_chat_icon"
android:layout_width="12dp" android:layout_width="12dp"
android:layout_height="12dp" android:layout_height="0dp"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
app:layout_constraintBottom_toBottomOf="@+id/text_chat_name"
app:layout_constraintStart_toEndOf="@+id/image_avatar" app:layout_constraintStart_toEndOf="@+id/image_avatar"
app:layout_constraintTop_toTopOf="@+id/image_avatar" app:layout_constraintTop_toTopOf="@+id/text_chat_name"
tools:src="@drawable/ic_hashtag_12dp" /> tools:src="@drawable/ic_hashtag_12dp" />
<TextView
android:id="@+id/text_last_message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginTop="2dp"
android:layout_weight="0.8"
android:ellipsize="end"
android:maxLines="2"
android:textDirection="locale"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/image_chat_icon"
app:layout_constraintTop_toBottomOf="@+id/text_chat_name"
tools:text="Filipe de Lima Brito: Type something that is very big and need at least to lines, or maybe even more" />
<TextView <TextView
android:id="@+id/text_chat_name" android:id="@+id/text_chat_name"
style="@style/ChatRoom.Name.TextView" style="@style/ChatRoom.Name.TextView"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:textDirection="locale" android:textDirection="locale"
app:layout_constraintBottom_toTopOf="@+id/text_last_message"
app:layout_constraintEnd_toStartOf="@+id/text_last_message_date_time"
app:layout_constraintStart_toEndOf="@+id/image_chat_icon" app:layout_constraintStart_toEndOf="@+id/image_chat_icon"
app:layout_constraintTop_toTopOf="parent"
tools:text="general" /> tools:text="general" />
<TextView <TextView
android:id="@+id/text_last_message_date_time" android:id="@+id/text_last_message_date_time"
style="@style/Timestamp.TextView" style="@style/Timestamp.TextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="0dp"
android:layout_marginStart="8dp" android:gravity="center"
app:layout_constraintBottom_toBottomOf="@+id/text_chat_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/text_chat_name"
tools:text="11:45 AM" />
<TextView
android:id="@+id/text_last_message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
app:layout_constraintBottom_toBottomOf="@+id/layout_unread_messages_badge"
android:layout_marginTop="2dp" android:layout_marginTop="2dp"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="2" android:maxLines="2"
android:textDirection="locale" android:textDirection="locale"
tools:visibility="visible"
app:layout_constraintEnd_toStartOf="@+id/layout_unread_messages_badge" app:layout_constraintEnd_toStartOf="@+id/layout_unread_messages_badge"
app:layout_constraintStart_toStartOf="@+id/image_chat_icon" app:layout_constraintTop_toTopOf="@+id/text_chat_name"
app:layout_constraintTop_toBottomOf="@+id/text_chat_name" tools:text="11:45 AM" />
tools:text="Filipe de Lima Brito: Type something that is very big and need at least to lines, or maybe even more" />
<include <include
android:id="@+id/layout_unread_messages_badge" android:id="@+id/layout_unread_messages_badge"
...@@ -69,6 +87,6 @@ ...@@ -69,6 +87,6 @@
android:layout_width="18dp" android:layout_width="18dp"
android:layout_height="18dp" android:layout_height="18dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/text_last_message" /> app:layout_constraintTop_toTopOf="@+id/text_chat_name" />
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>
\ No newline at end of file
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <android.support.constraint.ConstraintLayout 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:id="@+id/message_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground" android:background="?android:attr/selectableItemBackground"
...@@ -74,6 +75,16 @@ ...@@ -74,6 +75,16 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="10dp" android:layout_marginStart="10dp"
tools:text="11:45 PM" /> tools:text="11:45 PM" />
<TextView
android:id="@+id/text_edit_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/msg_edited"
android:layout_marginStart="8dp"
android:textStyle="italic"
android:visibility="gone"
tools:visibility="visible" />
</LinearLayout> </LinearLayout>
<TextView <TextView
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <android.support.constraint.ConstraintLayout 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:id="@+id/attachment_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground" android:background="?android:attr/selectableItemBackground"
......
...@@ -100,7 +100,6 @@ ...@@ -100,7 +100,6 @@
<string name="msg_ver_not_minimum"> <string name="msg_ver_not_minimum">
Parece que la versión del servidor está por debajo de la versión mínima requerida %1$s.\nActualice su servidor para iniciar sesión! Parece que la versión del servidor está por debajo de la versión mínima requerida %1$s.\nActualice su servidor para iniciar sesión!
</string> </string>
<string name="msg_proceed">PROCEDER</string> <string name="msg_proceed">PROCEDER</string>
<string name="msg_cancel">CANCELAR</string> <string name="msg_cancel">CANCELAR</string>
<string name="msg_warning">ADVERTENCIA</string> <string name="msg_warning">ADVERTENCIA</string>
...@@ -111,6 +110,7 @@ ...@@ -111,6 +110,7 @@
<string name="msg_image_saved_failed">Error al guardar la imagen</string> <string name="msg_image_saved_failed">Error al guardar la imagen</string>
<string name="msg_no_chat_title">Sin mensajes de chat</string> <string name="msg_no_chat_title">Sin mensajes de chat</string>
<string name="msg_no_chat_description">Comience a conversar para ver\nsus mensajes aquí.</string> <string name="msg_no_chat_description">Comience a conversar para ver\nsus mensajes aquí.</string>
<string name="msg_edited">(editado)</string>
<!-- System messages --> <!-- System messages -->
<string name="message_room_name_changed">Nombre de la sala cambiado para: %1$s por %2$s</string> <string name="message_room_name_changed">Nombre de la sala cambiado para: %1$s por %2$s</string>
......
...@@ -110,6 +110,7 @@ ...@@ -110,6 +110,7 @@
<string name="msg_image_saved_failed">Échec de l\'enregistrement de l\'image</string> <string name="msg_image_saved_failed">Échec de l\'enregistrement de l\'image</string>
<string name="msg_no_chat_title">Aucun message de discussion</string> <string name="msg_no_chat_title">Aucun message de discussion</string>
<string name="msg_no_chat_description">Commencez à converser pour voir\nvos messages ici.</string> <string name="msg_no_chat_description">Commencez à converser pour voir\nvos messages ici.</string>
<string name="msg_edited">(édité)</string>
<!-- System messages --> <!-- System messages -->
<string name="message_room_name_changed">Le nom de le salle a changé à: %1$s par %2$s</string> <string name="message_room_name_changed">Le nom de le salle a changé à: %1$s par %2$s</string>
......
...@@ -112,6 +112,7 @@ ...@@ -112,6 +112,7 @@
<string name="msg_image_saved_failed">छवि को सहेजने में विफल</string> <string name="msg_image_saved_failed">छवि को सहेजने में विफल</string>
<string name="msg_no_chat_title">कोई चैट संदेश नहीं</string> <string name="msg_no_chat_title">कोई चैट संदेश नहीं</string>
<string name="msg_no_chat_description">यहां अपने संदेश देखने के लिए\nबातचीत शुरू करें।</string> <string name="msg_no_chat_description">यहां अपने संदेश देखने के लिए\nबातचीत शुरू करें।</string>
<string name="msg_edited">(संपादित)</string>
<!-- System messages --> <!-- System messages -->
<string name="message_room_name_changed">%2$s ने रूम का नाम बदलकर %1$s किया</string> <string name="message_room_name_changed">%2$s ने रूम का नाम बदलकर %1$s किया</string>
......
...@@ -106,7 +106,8 @@ ...@@ -106,7 +106,8 @@
<string name="msg_invalid_server_protocol">O protocolo selecionado não é suportado pelo servidor, por favor utilize HTTPS e tente novamente</string> <string name="msg_invalid_server_protocol">O protocolo selecionado não é suportado pelo servidor, por favor utilize HTTPS e tente novamente</string>
<string name="msg_image_saved_successfully">Imagem salva na galeria</string> <string name="msg_image_saved_successfully">Imagem salva na galeria</string>
<string name="msg_image_saved_failed">Falha ao salvar a imagem</string> <string name="msg_image_saved_failed">Falha ao salvar a imagem</string>
<string name="msg_edited">(editado)</string>
<!-- System messages --> <!-- System messages -->
<string name="message_room_name_changed">Nome da sala alterado para: %1$s por %2$s</string> <string name="message_room_name_changed">Nome da sala alterado para: %1$s por %2$s</string>
<string name="message_user_added_by">Usuário %1$s adicionado por %2$s</string> <string name="message_user_added_by">Usuário %1$s adicionado por %2$s</string>
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<string name="app_name" translatable="false">Rocket.Chat</string> <string name="app_name" translatable="false">Rocket.Chat</string>
<!-- Titles --> <!-- Titles -->
<string name="title_sign_in_your_server">Sign in your server</string> <string name="title_sign_in_your_server">Sign in to your server</string>
<string name="title_log_in">Log in</string> <string name="title_log_in">Log in</string>
<string name="title_register_username">Register username</string> <string name="title_register_username">Register username</string>
<string name="title_reset_password">Reset password</string> <string name="title_reset_password">Reset password</string>
...@@ -107,6 +107,7 @@ ...@@ -107,6 +107,7 @@
<string name="msg_invalid_server_protocol">The selected protocol is not accepted by this server, try using HTTPS</string> <string name="msg_invalid_server_protocol">The selected protocol is not accepted by this server, try using HTTPS</string>
<string name="msg_image_saved_successfully">Image has been saved to gallery</string> <string name="msg_image_saved_successfully">Image has been saved to gallery</string>
<string name="msg_image_saved_failed">Failed to save image</string> <string name="msg_image_saved_failed">Failed to save image</string>
<string name="msg_edited">(edited)</string>
<!-- System messages --> <!-- System messages -->
<string name="message_room_name_changed">Room name changed to: %1$s by %2$s</string> <string name="message_room_name_changed">Room name changed to: %1$s by %2$s</string>
......
package chat.rocket.android.server.domain
import chat.rocket.core.model.Value
import com.google.common.truth.Truth.assertThat
import org.junit.Test
class SettingsRepositoryTest {
@Test
fun `uploadMimeFilter returns null if not specified`() {
val settings = emptyMap<String, Value<Any>>()
val filter = settings.uploadMimeTypeFilter()
assertThat(filter).isNull()
}
}
\ No newline at end of file
package chat.rocket.android.server.domain
import chat.rocket.core.model.Value
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
class `SettingsRepository UploadMimeTypeFilter WhitelistIsSet Test`(private val allowedMimeTypes: String,
private val expectedFilter: Array<String>?) {
companion object {
@JvmStatic
@Parameterized.Parameters(name = "\"{0}\"")
fun data(): Collection<Array<Any?>> = listOf(
arrayOf<Any?>("", null),
arrayOf<Any?>(" ", null),
arrayOf<Any?>("image/*", arrayOf("image/*")),
arrayOf<Any?>("image/*,video/*", arrayOf("image/*", "video/*")),
arrayOf<Any?>("image/*, video/*", arrayOf("image/*", "video/*")),
arrayOf<Any?>("image/*,\tvideo/*", arrayOf("image/*", "video/*"))
)
}
@Test
fun test() {
val settings = mapOf<String, Value<Any>>(Pair(UPLOAD_WHITELIST_MIMETYPES, Value(allowedMimeTypes)))
val filter = settings.uploadMimeTypeFilter()
assertThat(filter).isEqualTo(expectedFilter)
}
}
...@@ -4,13 +4,13 @@ ext { ...@@ -4,13 +4,13 @@ ext {
compileSdk : 27, compileSdk : 27,
targetSdk : 27, targetSdk : 27,
buildTools : '27.0.3', buildTools : '27.0.3',
kotlin : '1.2.40', kotlin : '1.2.41',
coroutine : '0.22.5', coroutine : '0.22.5',
dokka : '0.9.16', dokka : '0.9.16',
// Main dependencies // Main dependencies
support : '27.1.0', support : '27.1.1',
constraintLayout : '1.0.2', constraintLayout : '1.1.0',
androidKtx : '0.3', androidKtx : '0.3',
dagger : '2.14.1', dagger : '2.14.1',
exoPlayer : '2.6.0', exoPlayer : '2.6.0',
...@@ -35,7 +35,7 @@ ext { ...@@ -35,7 +35,7 @@ ext {
// For testing // For testing
junit : '4.12', junit : '4.12',
truth : '0.36', truth : '0.36',
expresso : '3.0.1', espresso : '3.0.2',
mockito : '2.10.0' mockito : '2.10.0'
] ]
libraries = [ libraries = [
...@@ -98,8 +98,9 @@ ext { ...@@ -98,8 +98,9 @@ ext {
// For testing // For testing
junit : "junit:junit:$versions.junit", junit : "junit:junit:$versions.junit",
expressoCore : "com.android.support.test.espresso:espresso-core:${versions.expresso}", espressoCore : "com.android.support.test.espresso:espresso-core:${versions.espresso}",
espressoIntents : "com.android.support.test.espresso:espresso-intents:${versions.espresso}",
roomTest : "android.arch.persistence.room:testing:${versions.room}", roomTest : "android.arch.persistence.room:testing:${versions.room}",
truth : "com.google.truth:truth:$versions.truth", truth : "com.google.truth:truth:$versions.truth",
] ]
} }
\ No newline at end of file
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