Unverified Commit 7c8d979d authored by Leonardo Aramaki's avatar Leonardo Aramaki Committed by GitHub

Merge branch 'develop-2.x' into pjl_customtabs

parents 866bd529 e38a52ce
version: 2
jobs:
build-kotlin-sdk:
docker:
- image: circleci/android:api-27-alpha
environment:
JVM_OPTS: -Xmx3200m
steps:
- checkout
- run:
name: checkout Rocket.Chat.Kotlin.SDK
command: git clone https://github.com/RocketChat/Rocket.Chat.Kotlin.SDK.git ../Rocket.Chat.Kotlin.SDK
- run:
name: ANDROID_HOME
command: echo "sdk.dir="$ANDROID_HOME > local.properties
- run:
name: Build Kotlin.SDK
command: pushd app/ ; ./build-sdk.sh ; popd
- save_cache:
paths:
- ~/.gradle
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "player/build.gradle" }}
- save_cache:
paths:
- app/libs/
- ../Rocket.Chat.Kotlin.SDK/.last_commit_hash
key: kotlin-sdk-{{ .Revision }}
- store_artifacts:
path: app/libs/
destination: libs
code-analysis:
docker:
- image: circleci/android:api-27-alpha
environment:
JVM_OPTS: -Xmx3200m
steps:
- checkout
- run:
name: ANDROID_HOME
command: echo "sdk.dir="$ANDROID_HOME > local.properties
- run:
name: checkout Rocket.Chat.Kotlin.SDK
command: git clone https://github.com/RocketChat/Rocket.Chat.Kotlin.SDK.git ../Rocket.Chat.Kotlin.SDK
- restore_cache:
key: kotlin-sdk-{{ .Revision }}
- restore_cache:
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "player/build.gradle" }}
- run:
name: Download Dependencies
command: ./gradlew androidDependencies --quiet --console=plain
- save_cache:
paths:
- ~/.gradle
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "player/build.gradle" }}
- run:
name: Run Lint #, Checkstyles, PMD, Findbugs...
command: ./gradlew lint
- run:
name: Run Unit test
command: echo ./gradlew test # TODO: Fix unit test errors soon...
- store_artifacts:
path: app/build/reports/
destination: reports
build-apk:
docker:
- image: circleci/android:api-27-alpha
environment:
JVM_OPTS: -Xmx3200m
steps:
- checkout
- run:
name: restore files from ENV
command: |
echo $ROCKET_JKS_BASE64 | base64 --decode > Rocket.jks
echo $ROCKET_PLAY_JSON | base64 --decode > app/rocket-chat.json
- run:
name: checkout Rocket.Chat.Kotlin.SDK
command: git clone https://github.com/RocketChat/Rocket.Chat.Kotlin.SDK.git ../Rocket.Chat.Kotlin.SDK
- restore_cache:
key: kotlin-sdk-{{ .Revision }}
- restore_cache:
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "player/build.gradle" }}
- run:
name: Download Dependencies
command: ./gradlew androidDependencies --quiet --console=plain
- save_cache:
paths:
- ~/.gradle
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}-{{ checksum "player/build.gradle" }}
- run:
name: Build APK
command: |
./gradlew assembleRelease --quiet --console=plain --stacktrace
- store_artifacts:
path: app/build/outputs/apk
destination: apks
workflows:
version: 2
build-deploy:
jobs:
- build-kotlin-sdk
- code-analysis:
requires:
- build-kotlin-sdk
filters:
branches:
ignore: # skip on merge commits.
- develop
- develop-2.x
- master
- build-apk:
requires:
- build-kotlin-sdk
...@@ -120,7 +120,6 @@ class ChatRoomAdapter( ...@@ -120,7 +120,6 @@ class ChatRoomAdapter(
val indexOfFirst = dataSet.indexOfFirst { it.messageId == message.messageId } val indexOfFirst = dataSet.indexOfFirst { it.messageId == message.messageId }
Timber.d("index: $index") Timber.d("index: $index")
if (index > -1) { if (index > -1) {
message.nextDownStreamMessage = dataSet[index].nextDownStreamMessage
dataSet[index] = message dataSet[index] = message
notifyItemChanged(index) notifyItemChanged(index)
while (dataSet[index].nextDownStreamMessage != null) { while (dataSet[index].nextDownStreamMessage != null) {
......
package chat.rocket.android.chatroom.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import chat.rocket.android.R
import chat.rocket.android.chatroom.adapter.CommandSuggestionsAdapter.CommandSuggestionsViewHolder
import chat.rocket.android.chatroom.viewmodel.suggestion.CommandSuggestionViewModel
import chat.rocket.android.widget.autocompletion.model.SuggestionModel
import chat.rocket.android.widget.autocompletion.ui.BaseSuggestionViewHolder
import chat.rocket.android.widget.autocompletion.ui.SuggestionsAdapter
class CommandSuggestionsAdapter : SuggestionsAdapter<CommandSuggestionsViewHolder>(token = "/",
constraint = CONSTRAINT_BOUND_TO_START, threshold = UNLIMITED_RESULT_COUNT) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CommandSuggestionsViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.suggestion_command_item, parent,
false)
return CommandSuggestionsViewHolder(view)
}
class CommandSuggestionsViewHolder(view: View) : BaseSuggestionViewHolder(view) {
override fun bind(item: SuggestionModel, itemClickListener: SuggestionsAdapter.ItemClickListener?) {
item as CommandSuggestionViewModel
with(itemView) {
val nameTextView = itemView.findViewById<TextView>(R.id.text_command_name)
val descriptionTextView = itemView.findViewById<TextView>(R.id.text_command_description)
nameTextView.text = "/${item.text}"
val res = context.resources
val id = res.getIdentifier(item.description, "string", context.packageName)
val description = if (id > 0) res.getString(id) else ""
descriptionTextView.text = description.toLowerCase()
setOnClickListener {
itemClickListener?.onClick(item)
}
}
}
}
}
\ No newline at end of file
...@@ -8,7 +8,7 @@ import android.widget.ImageView ...@@ -8,7 +8,7 @@ import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.chatroom.adapter.PeopleSuggestionsAdapter.PeopleSuggestionViewHolder import chat.rocket.android.chatroom.adapter.PeopleSuggestionsAdapter.PeopleSuggestionViewHolder
import chat.rocket.android.chatroom.viewmodel.PeopleViewModel import chat.rocket.android.chatroom.viewmodel.suggestion.PeopleSuggestionViewModel
import chat.rocket.android.util.extensions.setVisible import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.widget.autocompletion.model.SuggestionModel import chat.rocket.android.widget.autocompletion.model.SuggestionModel
import chat.rocket.android.widget.autocompletion.ui.BaseSuggestionViewHolder import chat.rocket.android.widget.autocompletion.ui.BaseSuggestionViewHolder
...@@ -26,7 +26,7 @@ class PeopleSuggestionsAdapter : SuggestionsAdapter<PeopleSuggestionViewHolder>( ...@@ -26,7 +26,7 @@ class PeopleSuggestionsAdapter : SuggestionsAdapter<PeopleSuggestionViewHolder>(
class PeopleSuggestionViewHolder(view: View) : BaseSuggestionViewHolder(view) { class PeopleSuggestionViewHolder(view: View) : BaseSuggestionViewHolder(view) {
override fun bind(item: SuggestionModel, itemClickListener: SuggestionsAdapter.ItemClickListener?) { override fun bind(item: SuggestionModel, itemClickListener: SuggestionsAdapter.ItemClickListener?) {
item as PeopleViewModel item as PeopleSuggestionViewModel
with(itemView) { with(itemView) {
val username = itemView.findViewById<TextView>(R.id.text_username) val username = itemView.findViewById<TextView>(R.id.text_username)
val name = itemView.findViewById<TextView>(R.id.text_name) val name = itemView.findViewById<TextView>(R.id.text_name)
......
...@@ -6,7 +6,7 @@ import android.view.ViewGroup ...@@ -6,7 +6,7 @@ import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.chatroom.adapter.RoomSuggestionsAdapter.RoomSuggestionsViewHolder import chat.rocket.android.chatroom.adapter.RoomSuggestionsAdapter.RoomSuggestionsViewHolder
import chat.rocket.android.chatroom.viewmodel.ChatRoomViewModel import chat.rocket.android.chatroom.viewmodel.suggestion.ChatRoomSuggestionViewModel
import chat.rocket.android.widget.autocompletion.model.SuggestionModel import chat.rocket.android.widget.autocompletion.model.SuggestionModel
import chat.rocket.android.widget.autocompletion.ui.BaseSuggestionViewHolder import chat.rocket.android.widget.autocompletion.ui.BaseSuggestionViewHolder
import chat.rocket.android.widget.autocompletion.ui.SuggestionsAdapter import chat.rocket.android.widget.autocompletion.ui.SuggestionsAdapter
...@@ -22,7 +22,7 @@ class RoomSuggestionsAdapter : SuggestionsAdapter<RoomSuggestionsViewHolder>("#" ...@@ -22,7 +22,7 @@ class RoomSuggestionsAdapter : SuggestionsAdapter<RoomSuggestionsViewHolder>("#"
class RoomSuggestionsViewHolder(view: View) : BaseSuggestionViewHolder(view) { class RoomSuggestionsViewHolder(view: View) : BaseSuggestionViewHolder(view) {
override fun bind(item: SuggestionModel, itemClickListener: SuggestionsAdapter.ItemClickListener?) { override fun bind(item: SuggestionModel, itemClickListener: SuggestionsAdapter.ItemClickListener?) {
item as ChatRoomViewModel item as ChatRoomSuggestionViewModel
with(itemView) { with(itemView) {
val fullname = itemView.findViewById<TextView>(R.id.text_fullname) val fullname = itemView.findViewById<TextView>(R.id.text_fullname)
val name = itemView.findViewById<TextView>(R.id.text_name) val name = itemView.findViewById<TextView>(R.id.text_name)
......
...@@ -2,8 +2,9 @@ package chat.rocket.android.chatroom.presentation ...@@ -2,8 +2,9 @@ package chat.rocket.android.chatroom.presentation
import android.net.Uri import android.net.Uri
import chat.rocket.android.chatroom.viewmodel.BaseViewModel import chat.rocket.android.chatroom.viewmodel.BaseViewModel
import chat.rocket.android.chatroom.viewmodel.ChatRoomViewModel import chat.rocket.android.chatroom.viewmodel.suggestion.ChatRoomSuggestionViewModel
import chat.rocket.android.chatroom.viewmodel.PeopleViewModel import chat.rocket.android.chatroom.viewmodel.suggestion.CommandSuggestionViewModel
import chat.rocket.android.chatroom.viewmodel.suggestion.PeopleSuggestionViewModel
import chat.rocket.android.core.behaviours.LoadingView import chat.rocket.android.core.behaviours.LoadingView
import chat.rocket.android.core.behaviours.MessageView import chat.rocket.android.core.behaviours.MessageView
import chat.rocket.core.internal.realtime.State import chat.rocket.core.internal.realtime.State
...@@ -102,12 +103,19 @@ interface ChatRoomView : LoadingView, MessageView { ...@@ -102,12 +103,19 @@ interface ChatRoomView : LoadingView, MessageView {
fun showInvalidFileSize(fileSize: Int, maxFileSize: Int) fun showInvalidFileSize(fileSize: Int, maxFileSize: Int)
fun showConnectionState(state: State) fun showConnectionState(state: State)
fun populateMembers(members: List<PeopleViewModel>) fun populatePeopleSuggestions(members: List<PeopleSuggestionViewModel>)
fun populateRooms(chatRooms: List<ChatRoomViewModel>) fun populateRoomSuggestions(chatRooms: List<ChatRoomSuggestionViewModel>)
/** /**
* This user has joined the chat callback. * This user has joined the chat callback.
*/ */
fun onJoined() fun onJoined()
fun showReactionsPopup(messageId: String) fun showReactionsPopup(messageId: String)
/**
* Show list of commands.
*
* @param commands The list of available commands.
*/
fun populateCommandSuggestions(commands: List<CommandSuggestionViewModel>)
} }
\ No newline at end of file
...@@ -86,9 +86,11 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector { ...@@ -86,9 +86,11 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
isChatRoomSubscribed = intent.getBooleanExtra(INTENT_CHAT_IS_SUBSCRIBED, true) isChatRoomSubscribed = intent.getBooleanExtra(INTENT_CHAT_IS_SUBSCRIBED, true)
addFragment("ChatRoomFragment", R.id.fragment_container) { if (supportFragmentManager.findFragmentByTag("ChatRoomFragment") == null) {
newInstance(chatRoomId, chatRoomName, chatRoomType, isChatRoomReadOnly, chatRoomLastSeen, addFragment("ChatRoomFragment", R.id.fragment_container) {
isChatRoomSubscribed) newInstance(chatRoomId, chatRoomName, chatRoomType, isChatRoomReadOnly, chatRoomLastSeen,
isChatRoomSubscribed)
}
} }
} }
......
...@@ -15,16 +15,14 @@ import android.support.v7.widget.LinearLayoutManager ...@@ -15,16 +15,14 @@ import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.view.* import android.view.*
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.chatroom.adapter.ChatRoomAdapter import chat.rocket.android.chatroom.adapter.*
import chat.rocket.android.chatroom.adapter.PEOPLE
import chat.rocket.android.chatroom.adapter.PeopleSuggestionsAdapter
import chat.rocket.android.chatroom.adapter.RoomSuggestionsAdapter
import chat.rocket.android.chatroom.presentation.ChatRoomPresenter import chat.rocket.android.chatroom.presentation.ChatRoomPresenter
import chat.rocket.android.chatroom.presentation.ChatRoomView import chat.rocket.android.chatroom.presentation.ChatRoomView
import chat.rocket.android.chatroom.viewmodel.BaseViewModel import chat.rocket.android.chatroom.viewmodel.BaseViewModel
import chat.rocket.android.chatroom.viewmodel.ChatRoomViewModel
import chat.rocket.android.chatroom.viewmodel.MessageViewModel import chat.rocket.android.chatroom.viewmodel.MessageViewModel
import chat.rocket.android.chatroom.viewmodel.PeopleViewModel import chat.rocket.android.chatroom.viewmodel.suggestion.ChatRoomSuggestionViewModel
import chat.rocket.android.chatroom.viewmodel.suggestion.CommandSuggestionViewModel
import chat.rocket.android.chatroom.viewmodel.suggestion.PeopleSuggestionViewModel
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.helper.KeyboardHelper import chat.rocket.android.helper.KeyboardHelper
import chat.rocket.android.helper.MessageParser import chat.rocket.android.helper.MessageParser
...@@ -133,6 +131,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -133,6 +131,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
presenter.unsubscribeMessages(chatRoomId) presenter.unsubscribeMessages(chatRoomId)
handler.removeCallbacksAndMessages(null) handler.removeCallbacksAndMessages(null)
unsubscribeTextMessage() unsubscribeTextMessage()
// Hides the keyboard (if it's opened) before going to any view.
activity?.apply {
hideKeyboard()
}
super.onDestroyView() super.onDestroyView()
} }
...@@ -218,7 +221,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -218,7 +221,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
override fun sendMessage(text: String) { override fun sendMessage(text: String) {
if (!text.isBlank()) { if (!text.isBlank()) {
presenter.sendMessage(chatRoomId, text, editingMessageId) if (!text.startsWith("/")) {
presenter.sendMessage(chatRoomId, text, editingMessageId)
} else {
presenter.runCommand(text, chatRoomId)
}
} }
} }
...@@ -287,14 +294,18 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -287,14 +294,18 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error)) override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error))
override fun populateMembers(members: List<PeopleViewModel>) { override fun populatePeopleSuggestions(members: List<PeopleSuggestionViewModel>) {
suggestions_view.addItems("@", members) suggestions_view.addItems("@", members)
} }
override fun populateRooms(chatRooms: List<ChatRoomViewModel>) { override fun populateRoomSuggestions(chatRooms: List<ChatRoomSuggestionViewModel>) {
suggestions_view.addItems("#", chatRooms) suggestions_view.addItems("#", chatRooms)
} }
override fun populateCommandSuggestions(commands: List<CommandSuggestionViewModel>) {
suggestions_view.addItems("/", commands)
}
override fun copyToClipboard(message: String) { override fun copyToClipboard(message: String) {
activity?.apply { activity?.apply {
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
...@@ -492,9 +503,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -492,9 +503,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
private fun setupSuggestionsView() { private fun setupSuggestionsView() {
suggestions_view.anchor(text_message) suggestions_view.anchorTo(text_message)
.bindTokenAdapter(PeopleSuggestionsAdapter()) .setMaximumHeight(resources.getDimensionPixelSize(R.dimen.suggestions_box_max_height))
.bindTokenAdapter(RoomSuggestionsAdapter()) .addTokenAdapter(PeopleSuggestionsAdapter())
.addTokenAdapter(CommandSuggestionsAdapter())
.addTokenAdapter(RoomSuggestionsAdapter())
.addSuggestionProviderAction("@") { query -> .addSuggestionProviderAction("@") { query ->
if (query.isNotEmpty()) { if (query.isNotEmpty()) {
presenter.spotlight(query, PEOPLE, true) presenter.spotlight(query, PEOPLE, true)
...@@ -505,6 +518,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -505,6 +518,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
presenter.loadChatRooms() presenter.loadChatRooms()
} }
} }
.addSuggestionProviderAction("/") { _ ->
presenter.loadCommands()
}
presenter.loadCommands()
} }
private fun openEmojiKeyboardPopup() { private fun openEmojiKeyboardPopup() {
......
package chat.rocket.android.chatroom.viewmodel
import chat.rocket.android.widget.autocompletion.model.SuggestionModel
class ChatRoomViewModel(text: String,
val fullName: String,
val name: String,
searchList: List<String>) : SuggestionModel(text, searchList, false) {
}
\ No newline at end of file
package chat.rocket.android.chatroom.viewmodel
import chat.rocket.android.widget.autocompletion.model.SuggestionModel
import chat.rocket.common.model.UserStatus
class PeopleViewModel(val imageUri: String,
text: String,
val username: String,
val name: String,
val status: UserStatus?,
pinned: Boolean = false,
searchList: List<String>) : SuggestionModel(text, searchList, pinned) {
override fun toString(): String {
return "PeopleViewModel(imageUri='$imageUri', username='$username', name='$name', status=$status, pinned=$pinned)"
}
}
\ No newline at end of file
package chat.rocket.android.chatroom.viewmodel.suggestion
import chat.rocket.android.widget.autocompletion.model.SuggestionModel
class ChatRoomSuggestionViewModel(text: String,
val fullName: String,
val name: String,
searchList: List<String>) : SuggestionModel(text, searchList, false) {
}
\ No newline at end of file
package chat.rocket.android.chatroom.viewmodel.suggestion
import chat.rocket.android.widget.autocompletion.model.SuggestionModel
class CommandSuggestionViewModel(text: String,
val description: String,
searchList: List<String>) : SuggestionModel(text, searchList)
\ No newline at end of file
package chat.rocket.android.chatroom.viewmodel.suggestion
import chat.rocket.android.widget.autocompletion.model.SuggestionModel
import chat.rocket.common.model.UserStatus
class PeopleSuggestionViewModel(val imageUri: String,
text: String,
val username: String,
val name: String,
val status: UserStatus?,
pinned: Boolean = false,
searchList: List<String>) : SuggestionModel(text, searchList, pinned) {
override fun toString(): String {
return "PeopleSuggestionViewModel(imageUri='$imageUri', username='$username', name='$name', status=$status, pinned=$pinned)"
}
}
\ No newline at end of file
...@@ -82,15 +82,19 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView, ...@@ -82,15 +82,19 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
fun chatRoomsByName(name: String) { fun chatRoomsByName(name: String) {
val currentServer = serverInteractor.get()!! val currentServer = serverInteractor.get()!!
launchUI(strategy) { launchUI(strategy) {
val roomList = getChatRoomsInteractor.getByName(currentServer, name) try {
if (roomList.isEmpty()) { val roomList = getChatRoomsInteractor.getByName(currentServer, name)
val (users, rooms) = client.spotlight(name) if (roomList.isEmpty()) {
val chatRoomsCombined = mutableListOf<ChatRoom>() val (users, rooms) = client.spotlight(name)
chatRoomsCombined.addAll(usersToChatRooms(users)) val chatRoomsCombined = mutableListOf<ChatRoom>()
chatRoomsCombined.addAll(roomsToChatRooms(rooms)) chatRoomsCombined.addAll(usersToChatRooms(users))
view.updateChatRooms(chatRoomsCombined) chatRoomsCombined.addAll(roomsToChatRooms(rooms))
} else { view.updateChatRooms(chatRoomsCombined)
view.updateChatRooms(roomList) } else {
view.updateChatRooms(roomList)
}
} catch (ex: RocketChatException) {
Timber.e(ex)
} }
} }
} }
......
...@@ -73,6 +73,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -73,6 +73,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
val searchItem = menu.findItem(R.id.action_search) val searchItem = menu.findItem(R.id.action_search)
searchView = searchItem?.actionView as SearchView searchView = searchItem?.actionView as SearchView
searchView?.maxWidth = Integer.MAX_VALUE
searchView?.setOnQueryTextListener(object : SearchView.OnQueryTextListener { searchView?.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean { override fun onQueryTextSubmit(query: String?): Boolean {
return queryChatRoomsByName(query) return queryChatRoomsByName(query)
......
...@@ -15,7 +15,6 @@ import chat.rocket.android.members.adapter.MembersAdapter ...@@ -15,7 +15,6 @@ import chat.rocket.android.members.adapter.MembersAdapter
import chat.rocket.android.members.presentation.MembersPresenter import chat.rocket.android.members.presentation.MembersPresenter
import chat.rocket.android.members.presentation.MembersView import chat.rocket.android.members.presentation.MembersView
import chat.rocket.android.members.viewmodel.MemberViewModel import chat.rocket.android.members.viewmodel.MemberViewModel
import chat.rocket.android.util.extensions.hideKeyboard
import chat.rocket.android.util.extensions.inflate 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
...@@ -23,9 +22,6 @@ import chat.rocket.android.widget.DividerItemDecoration ...@@ -23,9 +22,6 @@ import chat.rocket.android.widget.DividerItemDecoration
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_members.* import kotlinx.android.synthetic.main.fragment_members.*
import javax.inject.Inject import javax.inject.Inject
import android.view.inputmethod.InputMethodManager.HIDE_IMPLICIT_ONLY
import android.app.Activity
import android.view.inputmethod.InputMethodManager
fun newInstance(chatRoomId: String, chatRoomType: String): Fragment { fun newInstance(chatRoomId: String, chatRoomType: String): Fragment {
...@@ -65,8 +61,6 @@ class MembersFragment : Fragment(), MembersView { ...@@ -65,8 +61,6 @@ class MembersFragment : Fragment(), MembersView {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
val imm = activity?.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0)
(activity as AppCompatActivity).supportActionBar?.title = "" (activity as AppCompatActivity).supportActionBar?.title = ""
......
...@@ -46,8 +46,10 @@ fun AppCompatActivity.addFragmentBackStack(tag: String, layoutId: Int, newInstan ...@@ -46,8 +46,10 @@ fun AppCompatActivity.addFragmentBackStack(tag: String, layoutId: Int, newInstan
} }
fun Activity.hideKeyboard() { fun Activity.hideKeyboard() {
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager if (currentFocus != null) {
imm.hideSoftInputFromWindow(currentFocus.windowToken, InputMethodManager.RESULT_UNCHANGED_SHOWN) val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(currentFocus.windowToken, InputMethodManager.RESULT_UNCHANGED_SHOWN)
}
} }
fun Activity.showToast(@StringRes resource: Int, duration: Int = Toast.LENGTH_SHORT) = showToast(getString(resource), duration) fun Activity.showToast(@StringRes resource: Int, duration: Int = Toast.LENGTH_SHORT) = showToast(getString(resource), duration)
......
...@@ -2,24 +2,25 @@ package chat.rocket.android.widget.autocompletion.strategy.regex ...@@ -2,24 +2,25 @@ package chat.rocket.android.widget.autocompletion.strategy.regex
import chat.rocket.android.widget.autocompletion.model.SuggestionModel import chat.rocket.android.widget.autocompletion.model.SuggestionModel
import chat.rocket.android.widget.autocompletion.strategy.CompletionStrategy import chat.rocket.android.widget.autocompletion.strategy.CompletionStrategy
import chat.rocket.android.widget.autocompletion.ui.SuggestionsAdapter
import java.util.concurrent.CopyOnWriteArrayList import java.util.concurrent.CopyOnWriteArrayList
internal class StringMatchingCompletionStrategy : CompletionStrategy { internal class StringMatchingCompletionStrategy(private val threshold: Int = -1) : CompletionStrategy {
private val list = CopyOnWriteArrayList<SuggestionModel>() private val list = CopyOnWriteArrayList<SuggestionModel>()
override fun autocompleteItems(prefix: String): List<SuggestionModel> { override fun autocompleteItems(prefix: String): List<SuggestionModel> {
return list.filter { val result = list.filter {
it.searchList.forEach { word -> it.searchList.forEach { word ->
if (word.contains(prefix, ignoreCase = true)) { if (word.contains(prefix, ignoreCase = true)) {
return@filter true return@filter true
} }
} }
false false
}.sortedByDescending { it.pinned }.take(5) }.sortedByDescending { it.pinned }
return if (threshold == SuggestionsAdapter.UNLIMITED_RESULT_COUNT) result else result.take(threshold)
} }
override fun addAll(list: List<SuggestionModel>) { override fun addAll(list: List<SuggestionModel>) {
// this.list.removeAll { !it.pinned }
this.list.addAllAbsent(list) this.list.addAllAbsent(list)
} }
......
...@@ -7,14 +7,32 @@ import chat.rocket.android.widget.autocompletion.strategy.regex.StringMatchingCo ...@@ -7,14 +7,32 @@ import chat.rocket.android.widget.autocompletion.strategy.regex.StringMatchingCo
import java.lang.reflect.Type import java.lang.reflect.Type
import kotlin.properties.Delegates import kotlin.properties.Delegates
abstract class SuggestionsAdapter<VH : BaseSuggestionViewHolder>(val token: String) : RecyclerView.Adapter<VH>() { abstract class SuggestionsAdapter<VH : BaseSuggestionViewHolder>(
private val strategy: CompletionStrategy = StringMatchingCompletionStrategy() val token: String,
val constraint: Int = CONSTRAINT_UNBOUND,
threshold: Int = MAX_RESULT_COUNT) : RecyclerView.Adapter<VH>() {
companion object {
// Any number of results.
const val UNLIMITED_RESULT_COUNT = -1
// Trigger suggestions only if on the line start.
const val CONSTRAINT_BOUND_TO_START = 0
// Trigger suggestions from anywhere.
const val CONSTRAINT_UNBOUND = 1
// Maximum number of results to display by default.
private const val MAX_RESULT_COUNT = 5
}
private var itemType: Type? = null private var itemType: Type? = null
private var itemClickListener: ItemClickListener? = null private var itemClickListener: ItemClickListener? = null
// Called to gather results when no results have previously matched.
private var providerExternal: ((query: String) -> Unit)? = null private var providerExternal: ((query: String) -> Unit)? = null
private var prefix: String by Delegates.observable("", { _, _, _ -> // Maximum number of results/suggestions to display.
strategy.autocompleteItems(prefix) private var resultsThreshold: Int = if (threshold > 0) threshold else UNLIMITED_RESULT_COUNT
notifyItemRangeChanged(0, 5) // The strategy used for suggesting completions.
private val strategy: CompletionStrategy = StringMatchingCompletionStrategy(resultsThreshold)
// Current input term to look up for suggestions.
private var currentTerm: String by Delegates.observable("", { _, _, newTerm ->
val items = strategy.autocompleteItems(newTerm)
notifyDataSetChanged()
}) })
init { init {
...@@ -29,21 +47,21 @@ abstract class SuggestionsAdapter<VH : BaseSuggestionViewHolder>(val token: Stri ...@@ -29,21 +47,21 @@ abstract class SuggestionsAdapter<VH : BaseSuggestionViewHolder>(val token: Stri
holder.bind(getItem(position), itemClickListener) holder.bind(getItem(position), itemClickListener)
} }
override fun getItemCount() = strategy.autocompleteItems(prefix).size override fun getItemCount() = strategy.autocompleteItems(currentTerm).size
private fun getItem(position: Int): SuggestionModel { private fun getItem(position: Int): SuggestionModel {
return strategy.autocompleteItems(prefix)[position] return strategy.autocompleteItems(currentTerm)[position]
} }
fun autocomplete(prefix: String) { fun autocomplete(newTerm: String) {
this.prefix = prefix.toLowerCase().trim() this.currentTerm = newTerm.toLowerCase().trim()
} }
fun addItems(list: List<SuggestionModel>) { fun addItems(list: List<SuggestionModel>) {
strategy.addAll(list) strategy.addAll(list)
// Since we've just added new items we should check for possible new completion suggestions. // Since we've just added new items we should check for possible new completion suggestions.
strategy.autocompleteItems(prefix) strategy.autocompleteItems(currentTerm)
notifyItemRangeChanged(0, 5) notifyDataSetChanged()
} }
fun setOnClickListener(clickListener: ItemClickListener) { fun setOnClickListener(clickListener: ItemClickListener) {
...@@ -52,11 +70,24 @@ abstract class SuggestionsAdapter<VH : BaseSuggestionViewHolder>(val token: Stri ...@@ -52,11 +70,24 @@ abstract class SuggestionsAdapter<VH : BaseSuggestionViewHolder>(val token: Stri
fun hasItemClickListener() = itemClickListener != null fun hasItemClickListener() = itemClickListener != null
fun prefix() = prefix /**
* Return the current searched term.
*/
fun term() = this.currentTerm
/**
* Set the maximum number of results to show.
*
* @param threshold The maximum number of suggestions to display.
*/
fun setResultsThreshold(threshold: Int) {
check(threshold > 0)
resultsThreshold = threshold
}
fun cancel() { fun cancel() {
strategy.addAll(emptyList()) strategy.addAll(emptyList())
strategy.autocompleteItems(prefix) strategy.autocompleteItems(currentTerm)
notifyDataSetChanged() notifyDataSetChanged()
} }
......
...@@ -21,7 +21,9 @@ import android.widget.EditText ...@@ -21,7 +21,9 @@ import android.widget.EditText
import android.widget.FrameLayout import android.widget.FrameLayout
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.widget.autocompletion.model.SuggestionModel import chat.rocket.android.widget.autocompletion.model.SuggestionModel
import chat.rocket.android.widget.autocompletion.ui.SuggestionsAdapter.Companion.CONSTRAINT_BOUND_TO_START
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
/** /**
...@@ -31,12 +33,14 @@ private const val NO_STATE_INDEX = 0 ...@@ -31,12 +33,14 @@ private const val NO_STATE_INDEX = 0
class SuggestionsView : FrameLayout, TextWatcher { class SuggestionsView : FrameLayout, TextWatcher {
private val recyclerView: RecyclerView private val recyclerView: RecyclerView
private val registeredTokens = CopyOnWriteArrayList<String>()
// Maps tokens to their respective adapters. // Maps tokens to their respective adapters.
private val adaptersByToken = hashMapOf<String, SuggestionsAdapter<out BaseSuggestionViewHolder>>() private val adaptersByToken = hashMapOf<String, SuggestionsAdapter<out BaseSuggestionViewHolder>>()
private val externalProvidersByToken = hashMapOf<String, ((query: String) -> Unit)>() private val externalProvidersByToken = hashMapOf<String, ((query: String) -> Unit)>()
private val localProvidersByToken = hashMapOf<String, HashMap<String, List<SuggestionModel>>>() private val localProvidersByToken = hashMapOf<String, HashMap<String, List<SuggestionModel>>>()
private var editor: WeakReference<EditText>? = null private var editor: WeakReference<EditText>? = null
private var completionStartIndex = AtomicInteger(NO_STATE_INDEX) private var completionStartIndex = AtomicInteger(NO_STATE_INDEX)
private var maxHeight: Int = 0
companion object { companion object {
private val SLIDE_TRANSITION = Slide(Gravity.BOTTOM).setDuration(200) private val SLIDE_TRANSITION = Slide(Gravity.BOTTOM).setDuration(200)
...@@ -75,6 +79,10 @@ class SuggestionsView : FrameLayout, TextWatcher { ...@@ -75,6 +79,10 @@ class SuggestionsView : FrameLayout, TextWatcher {
val new = s.subSequence(start, start + count).toString() val new = s.subSequence(start, start + count).toString()
if (adaptersByToken.containsKey(new)) { if (adaptersByToken.containsKey(new)) {
val constraint = adapter(new).constraint
if (constraint == CONSTRAINT_BOUND_TO_START && start != 0) {
return
}
swapAdapter(getAdapterForToken(new)!!) swapAdapter(getAdapterForToken(new)!!)
completionStartIndex.compareAndSet(NO_STATE_INDEX, start + 1) completionStartIndex.compareAndSet(NO_STATE_INDEX, start + 1)
editor?.let { editor?.let {
...@@ -110,9 +118,18 @@ class SuggestionsView : FrameLayout, TextWatcher { ...@@ -110,9 +118,18 @@ class SuggestionsView : FrameLayout, TextWatcher {
} }
} }
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
if (maxHeight > 0) {
val hSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST)
super.onMeasure(widthMeasureSpec, hSpec)
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}
}
private fun swapAdapter(adapter: SuggestionsAdapter<*>): SuggestionsView { private fun swapAdapter(adapter: SuggestionsAdapter<*>): SuggestionsView {
recyclerView.adapter = adapter recyclerView.adapter = adapter
// Don't override if user set an item click listener already/ // Don't override if user has set an item click listener already
if (!adapter.hasItemClickListener()) { if (!adapter.hasItemClickListener()) {
setOnItemClickListener(adapter) { setOnItemClickListener(adapter) {
// set default item click behavior // set default item click behavior
...@@ -121,16 +138,16 @@ class SuggestionsView : FrameLayout, TextWatcher { ...@@ -121,16 +138,16 @@ class SuggestionsView : FrameLayout, TextWatcher {
return this return this
} }
fun getAdapterForToken(token: String): SuggestionsAdapter<*>? = adaptersByToken.get(token) private fun getAdapterForToken(token: String): SuggestionsAdapter<*>? = adaptersByToken.get(token)
fun anchor(editText: EditText): SuggestionsView { fun anchorTo(editText: EditText): SuggestionsView {
editText.removeTextChangedListener(this) editText.removeTextChangedListener(this)
editText.addTextChangedListener(this) editText.addTextChangedListener(this)
editor = WeakReference(editText) editor = WeakReference(editText)
return this return this
} }
fun bindTokenAdapter(adapter: SuggestionsAdapter<*>): SuggestionsView { fun addTokenAdapter(adapter: SuggestionsAdapter<*>): SuggestionsView {
adaptersByToken.getOrPut(adapter.token, { adapter }) adaptersByToken.getOrPut(adapter.token, { adapter })
return this return this
} }
...@@ -139,13 +156,20 @@ class SuggestionsView : FrameLayout, TextWatcher { ...@@ -139,13 +156,20 @@ class SuggestionsView : FrameLayout, TextWatcher {
if (list.isNotEmpty()) { if (list.isNotEmpty()) {
val adapter = adapter(token) val adapter = adapter(token)
localProvidersByToken.getOrPut(token, { hashMapOf() }) localProvidersByToken.getOrPut(token, { hashMapOf() })
.put(adapter.prefix(), list) .put(adapter.term(), list)
if (completionStartIndex.get() > NO_STATE_INDEX && adapter.itemCount == 0) expand() if (completionStartIndex.get() > NO_STATE_INDEX && adapter.itemCount == 0) expand()
adapter.addItems(list) adapter.addItems(list)
} }
return this return this
} }
fun setMaximumHeight(height: Int): SuggestionsView {
check(height > 0)
this.maxHeight = height
requestLayout()
return this
}
fun setOnItemClickListener(tokenAdapter: SuggestionsAdapter<*>, fun setOnItemClickListener(tokenAdapter: SuggestionsAdapter<*>,
clickListener: (item: SuggestionModel) -> Unit): SuggestionsView { clickListener: (item: SuggestionModel) -> Unit): SuggestionsView {
tokenAdapter.setOnClickListener(object : SuggestionsAdapter.ItemClickListener { tokenAdapter.setOnClickListener(object : SuggestionsAdapter.ItemClickListener {
...@@ -160,6 +184,9 @@ class SuggestionsView : FrameLayout, TextWatcher { ...@@ -160,6 +184,9 @@ class SuggestionsView : FrameLayout, TextWatcher {
} }
fun addSuggestionProviderAction(token: String, provider: (query: String) -> Unit): SuggestionsView { fun addSuggestionProviderAction(token: String, provider: (query: String) -> Unit): SuggestionsView {
if (adaptersByToken[token] == null) {
throw IllegalStateException("token \"$token\" suggestion provider added without adapter")
}
externalProvidersByToken.getOrPut(token, { provider }) externalProvidersByToken.getOrPut(token, { provider })
return this return this
} }
......
...@@ -35,13 +35,20 @@ ...@@ -35,13 +35,20 @@
android:layout_height="1dp" android:layout_height="1dp"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight="1" android:layout_weight="1"
android:layout_marginRight="4dp" android:layout_marginEnd="4dp"
android:background="@color/red"/> android:background="@color/red"/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:text="@string/msg_unread_messages" android:text="@string/msg_unread_messages"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/red" /> android:textColor="@color/red" />
<View
android:layout_gravity="center"
android:layout_height="1dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_marginStart="4dp"
android:background="@color/red"/>
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
......
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginTop="4dp"
android:background="@color/suggestion_background_color"
android:orientation="horizontal"
android:paddingTop="2dp">
<TextView
android:id="@+id/text_command_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginStart="8dp"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@color/black"
android:textSize="14sp"
tools:text="/leave" />
<TextView
android:id="@+id/text_command_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="16dp"
android:layout_toRightOf="@id/text_command_name"
android:ellipsize="end"
android:gravity="start"
android:maxLines="1"
android:textColor="@color/gray_material"
android:textSize="14sp"
tools:text="Leave a channel" />
</RelativeLayout>
\ No newline at end of file
...@@ -114,4 +114,28 @@ ...@@ -114,4 +114,28 @@
<string name="status_authenticating">autenticando</string> <string name="status_authenticating">autenticando</string>
<string name="status_disconnecting">desconectando</string> <string name="status_disconnecting">desconectando</string>
<string name="status_waiting">conectando em %d segundos</string> <string name="status_waiting">conectando em %d segundos</string>
<!-- Slash Commands -->
<string name="Slash_Gimme_Description">Exibir ༼ つ ◕_◕ ༽つ antes de sua mensagem</string>
<string name="Slash_LennyFace_Description">Exibir ( ͡° ͜ʖ ͡°) depois de sua mensagem</string>
<string name="Slash_Shrug_Description">Exibir ¯\_(ツ)_/¯ depois de sua mensagem</string>
<string name="Slash_Tableflip_Description">Exibir (╯°□°)╯︵ ┻━┻</string>
<string name="Slash_TableUnflip_Description">Exibir ┬─┬ ノ( ゜-゜ノ)</string>
<string name="Create_A_New_Channel">Criar um novo canal</string>
<string name="Show_the_keyboard_shortcut_list">Show the keyboard shortcut list</string>
<string name="Invite_user_to_join_channel_all_from"> do [#canal] para entrar neste</string>
<string name="Invite_user_to_join_channel_all_to">Convidar todos os usuários deste canal para entrar no [#canal]</string>
<string name="Archive">Arquivar</string>
<string name="Remove_someone_from_room">Remover alguém do canal</string>
<string name="Leave_the_current_channel">Sair do canal atual</string>
<string name="Displays_action_text">Exibir texto de ação</string>
<string name="Direct_message_someone">Enviar DM para alguém</string>
<string name="Mute_someone_in_room">Mutar alguém</string>
<string name="Unmute_someone_in_room">Desmutar alguém na sala</string>
<string name="Invite_user_to_join_channel">Convidar algum usuário para entrar neste canal</string>
<string name="Unarchive">Desarquivar</string>
<string name="Join_the_given_channel">Entrar no canal especificado</string>
<string name="Guggy_Command_Description">Gera um gif baseado no texto dado</string>
<string name="Slash_Topic_Description">Definir tópico</string>
</resources> </resources>
\ No newline at end of file
...@@ -34,5 +34,6 @@ ...@@ -34,5 +34,6 @@
<!-- Autocomplete Popup --> <!-- Autocomplete Popup -->
<dimen name="popup_max_height">150dp</dimen> <dimen name="popup_max_height">150dp</dimen>
<dimen name="suggestions_box_max_height">250dp</dimen>
</resources> </resources>
\ No newline at end of file
...@@ -116,4 +116,27 @@ ...@@ -116,4 +116,27 @@
<string name="status_disconnecting">disconnecting</string> <string name="status_disconnecting">disconnecting</string>
<string name="status_waiting">connecting in %d seconds</string> <string name="status_waiting">connecting in %d seconds</string>
<!-- Slash Commands -->
<string name="Slash_Gimme_Description">Displays ༼ つ ◕_◕ ༽つ before your message</string>
<string name="Slash_LennyFace_Description">Displays ( ͡° ͜ʖ ͡°) after your message</string>
<string name="Slash_Shrug_Description">Displays ¯\_(ツ)_/¯ after your message</string>
<string name="Slash_Tableflip_Description">Displays (╯°□°)╯︵ ┻━┻</string>
<string name="Slash_TableUnflip_Description">Displays ┬─┬ ノ( ゜-゜ノ)</string>
<string name="Create_A_New_Channel">Create a new channel</string>
<string name="Show_the_keyboard_shortcut_list">Show the keyboard shortcut list</string>
<string name="Invite_user_to_join_channel_all_from">Invite all users from [#channel] to join this channel</string>
<string name="Invite_user_to_join_channel_all_to">Invite all users from this channel to join [#channel]</string>
<string name="Archive">Archive</string>
<string name="Remove_someone_from_room">Remove someone from the room</string>
<string name="Leave_the_current_channel">Leave the current channel</string>
<string name="Displays_action_text">Displays action text</string>
<string name="Direct_message_someone">Direct message someone</string>
<string name="Mute_someone_in_room">Mute someone in the room</string>
<string name="Unmute_someone_in_room">Unmute someone in the room</string>
<string name="Invite_user_to_join_channel">Invite one user to join this channel</string>
<string name="Unarchive">Unarchive</string>
<string name="Join_the_given_channel">Join the given channel</string>
<string name="Guggy_Command_Description">Generates a gif based upon the provided text</string>
<string name="Slash_Topic_Description">Set topic</string>
</resources> </resources>
\ No newline at end of file
#
# Build configuration for Circle CI
#
# See this thread for speeding up and caching directories: https://discuss.circleci.com/t/installing-android-build-tools-23-0-2/924
#
machine:
environment:
ANDROID_HOME: /usr/local/android-sdk-linux
GRADLE_OPTS: '-Xmx1536M -Dorg.gradle.jvmargs="-Xmx1536M -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError"'
JAVA_OPTS: "-Xms518m -Xmx1536M"
pre:
- git clone https://github.com/RocketChat/Rocket.Chat.Kotlin.SDK.git Rocket.Chat.Kotlin.SDK
dependencies:
pre:
- sudo service mysql stop; sleep 5
- sudo service mongod stop; sleep 5
- sudo killall postgres; sleep 5
- git fetch --tags
- echo "sdk.dir="$ANDROID_HOME > local.properties
- echo $ROCKET_JKS_BASE64 | base64 --decode > Rocket.jks
- echo $ROCKET_PLAY_JSON | base64 --decode > app/rocket-chat.json
- mkdir -p app/src/release/res/values
# TODO: remove the comment when using that file on the project
# - echo $GOOGLE_SERVICES_BASE64 | base64 --decode > app/src/release/google-services.json
# - echo $API_KEY_STRINGS_BASE64 | base64 --decode > app/src/release/res/values/api_key_strings.xml
- mkdir -p $ANDROID_HOME/licenses/
- echo 8933bad161af4178b1185d1a37fbf41ea5269c55 >> $ANDROID_HOME/licenses/android-sdk-license
- echo d56f5187479451eabf01fb78af6dfcb131a6481e >> $ANDROID_HOME/licenses/android-sdk-license
- echo y | android update sdk --no-ui --all --filter tools,platform-tools
- echo y | android update sdk --no-ui --all --filter android-27
- echo y | android update sdk --no-ui --all --filter extra-android-m2repository,extra-android-support
- echo y | android update sdk --no-ui --all --filter extra-google-m2repository,extra-google-google_play_services
- echo y | android update sdk --no-ui --all --filter build-tools-27.0.0
#- yes | sdkmanager --licenses
cache_directories:
#- /usr/local/android-sdk-linux/tools
#- /usr/local/android-sdk-linux/build-tools/27.0.0
test:
override:
- ./gradlew assembleRelease --stacktrace
- find . -name *.apk -exec mv {} $CIRCLE_ARTIFACTS/ \;
deployment:
beta:
tag: /v\d+\.\d+\.\d+(?!.)/
owner: RocketChat
commands:
- ./gradlew publishListingRelease
-Dorg.gradle.project.track=beta
alpha:
tag: /v\d+\.\d+\.\d+/
owner: RocketChat
commands:
- ./gradlew publishListingRelease
-Dorg.gradle.pr oject.track=alpha
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