Commit a6184397 authored by Samer Alabi's avatar Samer Alabi

Recreation of Original Chat Details

parent 644d6518
......@@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 10,
"identityHash": "db46c12dbb8747200288f48d5dc5558b",
"identityHash": "4024406c23a09800c0c3e987c6b5d40b",
"entities": [
{
"tableName": "users",
......@@ -59,7 +59,7 @@
},
{
"tableName": "chatrooms",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` TEXT NOT NULL, `type` TEXT NOT NULL, `name` TEXT NOT NULL, `fullname` TEXT, `userId` TEXT, `ownerId` TEXT, `readonly` INTEGER, `isDefault` INTEGER, `favorite` INTEGER, `open` INTEGER NOT NULL, `alert` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `userMentions` INTEGER, `groupMentions` INTEGER, `updatedAt` INTEGER, `timestamp` INTEGER, `lastSeen` INTEGER, `lastMessageText` TEXT, `lastMessageUserId` TEXT, `lastMessageTimestamp` INTEGER, `broadcast` INTEGER, PRIMARY KEY(`id`), FOREIGN KEY(`ownerId`) REFERENCES `users`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`userId`) REFERENCES `users`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`lastMessageUserId`) REFERENCES `users`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` TEXT NOT NULL, `type` TEXT NOT NULL, `name` TEXT NOT NULL, `fullname` TEXT, `userId` TEXT, `ownerId` TEXT, `readonly` INTEGER, `isDefault` INTEGER, `favorite` INTEGER, `topic` TEXT, `announcement` TEXT, `description` TEXT, `open` INTEGER NOT NULL, `alert` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `userMentions` INTEGER, `groupMentions` INTEGER, `updatedAt` INTEGER, `timestamp` INTEGER, `lastSeen` INTEGER, `lastMessageText` TEXT, `lastMessageUserId` TEXT, `lastMessageTimestamp` INTEGER, `broadcast` INTEGER, PRIMARY KEY(`id`), FOREIGN KEY(`ownerId`) REFERENCES `users`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`userId`) REFERENCES `users`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`lastMessageUserId`) REFERENCES `users`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [
{
"fieldPath": "id",
......@@ -121,6 +121,24 @@
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "topic",
"columnName": "topic",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "announcement",
"columnName": "announcement",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "description",
"columnName": "description",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "open",
"columnName": "open",
......@@ -1075,7 +1093,7 @@
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"db46c12dbb8747200288f48d5dc5558b\")"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"4024406c23a09800c0c3e987c6b5d40b\")"
]
}
}
\ No newline at end of file
This diff is collapsed.
......@@ -78,6 +78,11 @@
android:theme="@style/AppTheme"
android:windowSoftInputMode="adjustResize|stateAlwaysHidden" />
<activity
android:name=".chatdetails.ui.ChatDetailsActivity"
android:theme="@style/AppTheme"
android:windowSoftInputMode="adjustResize|stateAlwaysHidden" />
<activity
android:name=".chatinformation.ui.MessageInfoActivity"
android:theme="@style/AppTheme"
......
package chat.rocket.android.chatdetails.di
import androidx.lifecycle.LifecycleOwner
import chat.rocket.android.chatdetails.presentation.ChatDetailsView
import chat.rocket.android.chatdetails.ui.ChatDetailsFragment
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.db.ChatRoomDao
import chat.rocket.android.db.DatabaseManager
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.experimental.Job
@Module
class ChatDetailsFragmentModule {
@Provides
@PerFragment
fun provideJob() = Job()
@Provides
@PerFragment
fun chatDetailsView(frag: ChatDetailsFragment): ChatDetailsView {
return frag
}
@Provides
@PerFragment
fun provideChatRoomDao(manager: DatabaseManager): ChatRoomDao = manager.chatRoomDao()
@Provides
@PerFragment
fun provideLifecycleOwner(frag: ChatDetailsFragment): LifecycleOwner {
return frag
}
@Provides
@PerFragment
fun provideCancelStrategy(owner: LifecycleOwner, jobs: Job): CancelStrategy {
return CancelStrategy(owner, jobs)
}
}
\ No newline at end of file
package chat.rocket.android.chatdetails.di
import chat.rocket.android.chatdetails.ui.ChatDetailsFragment
import chat.rocket.android.dagger.scope.PerFragment
import dagger.Module
import dagger.android.ContributesAndroidInjector
@Module
abstract class ChatDetailsFragmentProvider {
@ContributesAndroidInjector(modules = [ChatDetailsFragmentModule::class])
@PerFragment
abstract fun providesChatDetailsFragment(): ChatDetailsFragment
}
\ No newline at end of file
package chat.rocket.android.chatdetails.di
import chat.rocket.android.chatdetails.presentation.ChatDetailsNavigator
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.dagger.scope.PerActivity
import dagger.Module
import dagger.Provides
@Module
class ChatDetailsModule {
@Provides
@PerActivity
fun providesNavigator(activity: ChatDetailsActivity) = ChatDetailsNavigator(activity)
}
\ No newline at end of file
package chat.rocket.android.chatdetails.domain
data class ChatDetails(
val name: String?,
val fullName: String?,
val type: String?,
val topic: String?,
val announcement: String?,
val description: String?
)
\ No newline at end of file
package chat.rocket.android.chatdetails.presentation
import chat.rocket.android.R
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.favoritemessages.ui.TAG_FAVORITE_MESSAGES_FRAGMENT
import chat.rocket.android.files.ui.TAG_FILES_FRAGMENT
import chat.rocket.android.members.ui.TAG_MEMBERS_FRAGMENT
import chat.rocket.android.mentions.ui.TAG_MENTIONS_FRAGMENT
import chat.rocket.android.pinnedmessages.ui.TAG_PINNED_MESSAGES_FRAGMENT
import chat.rocket.android.util.extensions.addFragmentBackStack
class ChatDetailsNavigator(internal val activity: ChatDetailsActivity) {
fun toMembersList(chatRoomId: String) {
activity.addFragmentBackStack(TAG_MEMBERS_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.members.ui.newInstance(chatRoomId)
}
}
fun toMentions(chatRoomId: String) {
activity.addFragmentBackStack(TAG_MENTIONS_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.mentions.ui.newInstance(chatRoomId)
}
}
fun toPinnedMessageList(chatRoomId: String) {
activity.addFragmentBackStack(TAG_PINNED_MESSAGES_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.pinnedmessages.ui.newInstance(chatRoomId)
}
}
fun toFavoriteMessageList(chatRoomId: String) {
activity.addFragmentBackStack(TAG_FAVORITE_MESSAGES_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.favoritemessages.ui.newInstance(chatRoomId)
}
}
fun toFileList(chatRoomId: String) {
activity.addFragmentBackStack(TAG_FILES_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.files.ui.newInstance(chatRoomId)
}
}
}
package chat.rocket.android.chatdetails.presentation
import chat.rocket.android.chatdetails.domain.ChatDetails
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import chat.rocket.android.util.extension.launchUI
import chat.rocket.common.model.roomTypeOf
import chat.rocket.common.util.ifNull
import chat.rocket.core.internal.rest.getInfo
import chat.rocket.core.model.Room
import javax.inject.Inject
class ChatDetailsPresenter @Inject constructor(
private val view: ChatDetailsView,
private val navigator: ChatDetailsNavigator,
private val strategy: CancelStrategy,
serverInteractor: GetCurrentServerInteractor,
factory: ConnectionManagerFactory
) {
private val currentServer = serverInteractor.get()!!
private val manager = factory.create(currentServer)
private val client = manager.client
fun getDetails(chatRoomId: String, chatRoomType: String) {
launchUI(strategy) {
try {
view.displayDetails(roomToChatDetails(client.getInfo(chatRoomId, null, roomTypeOf(chatRoomType))))
} catch(e: Exception) {
e.message.let {
view.showMessage(it!!)
}.ifNull {
view.showGenericErrorMessage()
}
}
}
}
fun toFiles(chatRoomId: String) {
navigator.toFileList(chatRoomId)
}
fun toMembers(chatRoomId: String) {
navigator.toMembersList(chatRoomId)
}
fun toMentions(chatRoomId: String) {
navigator.toMentions(chatRoomId)
}
fun toPinned(chatRoomId: String) {
navigator.toPinnedMessageList(chatRoomId)
}
fun toFavorites(chatRoomId: String) {
navigator.toFavoriteMessageList(chatRoomId)
}
private fun roomToChatDetails(room: Room): ChatDetails {
return with(room) {
ChatDetails(
name = name,
fullName = fullName,
type = type.toString(),
topic = topic,
description = description,
announcement = announcement
)
}
}
}
\ No newline at end of file
package chat.rocket.android.chatdetails.presentation
import chat.rocket.android.chatdetails.domain.ChatDetails
import chat.rocket.android.core.behaviours.LoadingView
import chat.rocket.android.core.behaviours.MessageView
interface ChatDetailsView: MessageView {
fun displayDetails(room: ChatDetails)
}
\ No newline at end of file
package chat.rocket.android.chatdetails.ui
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import chat.rocket.android.R
import chat.rocket.android.util.extensions.addFragment
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_details.*
import javax.inject.Inject
fun Context.chatDetailsIntent(
chatRoomId: String,
chatRoomType: String,
isSubscribed: Boolean = true,
isMenuDisabled: Boolean = false
): Intent {
return Intent(this, ChatDetailsActivity::class.java).apply {
putExtra(INTENT_CHAT_ROOM_ID, chatRoomId)
putExtra(INTENT_CHAT_ROOM_TYPE, chatRoomType)
putExtra(INTENT_CHAT_IS_SUBSCRIBED, isSubscribed)
putExtra(INTENT_CHAT_DISABLED_MENU, isMenuDisabled)
}
}
private const val INTENT_CHAT_ROOM_ID = "chat_room_id"
private const val INTENT_CHAT_ROOM_TYPE = "chat_room_type"
private const val INTENT_CHAT_IS_SUBSCRIBED = "is_chat_room_subscribed"
private const val INTENT_CHAT_DISABLED_MENU = "is_menu_disabled"
class ChatDetailsActivity: AppCompatActivity(), HasSupportFragmentInjector {
@Inject
lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat_details)
setupToolbar()
val chatRoomId = intent.getStringExtra(INTENT_CHAT_ROOM_ID)
requireNotNull(chatRoomId) { "no chat_room_id provided in Intent extras" }
val chatRoomType = intent.getStringExtra(INTENT_CHAT_ROOM_TYPE)
requireNotNull(chatRoomType) { "no chat_room_type provided in Intent extras" }
val isSubscribed = intent.getBooleanExtra(INTENT_CHAT_IS_SUBSCRIBED, true)
val disableMenu = intent.getBooleanExtra(INTENT_CHAT_DISABLED_MENU, false)
if (supportFragmentManager.findFragmentByTag(TAG_CHAT_DETAILS_FRAGMENT) == null) {
addFragment(TAG_CHAT_DETAILS_FRAGMENT, R.id.fragment_container) {
newInstance(chatRoomId, chatRoomType, isSubscribed, disableMenu)
}
}
}
override fun supportFragmentInjector(): AndroidInjector<Fragment> =
fragmentDispatchingAndroidInjector
override fun onBackPressed() {
super.onBackPressed()
overridePendingTransition(R.anim.close_enter, R.anim.close_exit)
}
fun setNavigationIcon(resource: Int) {
toolbar.setNavigationIcon(resource)
}
fun setToolbarTitle(title: String) {
toolbar_title.text = title
}
private fun setupToolbar() {
setSupportActionBar(toolbar)
supportActionBar?.setDisplayShowTitleEnabled(false)
setToolbarTitle(getString(R.string.title_channel_details))
setNavigationIcon(R.drawable.ic_close_white_24dp)
toolbar.setNavigationOnClickListener { onBackPressed() }
}
}
\ No newline at end of file
package chat.rocket.android.chatdetails.ui
import android.content.Context
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R
import chat.rocket.android.util.extensions.inflate
import kotlinx.android.synthetic.main.item_detail_option.view.*
class ChatDetailsAdapter(private val context: Context): RecyclerView.Adapter<ChatDetailsAdapter.ViewHolder>() {
private val options: MutableList<Option> = ArrayList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder = ViewHolder(parent.inflate(R.layout.item_detail_option))
override fun onBindViewHolder(holder: ViewHolder, position: Int) = holder.bind(options[position])
override fun getItemCount(): Int = options.size
inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
fun bind(option: Option) {
bindName(option, itemView.name)
bindIcon(option, itemView.icon)
itemView.setOnClickListener { option.listener() }
}
}
inner class Option(val name: String, val icon: Int, val listener: () -> Unit)
fun addOption(name: String, icon: Int, listener: () -> Unit) {
options.add(Option(name, icon, listener))
notifyDataSetChanged()
}
private fun bindName(option: Option, view: TextView) {
view.text = option.name
}
private fun bindIcon(option: Option, view: ImageView) {
val drawable = DrawableHelper.getDrawableFromId(option.icon, context)
drawable.let { image ->
val mutateDrawable = DrawableHelper.wrapDrawable(image).mutate()
DrawableHelper.tintDrawable(mutateDrawable, context, R.color.colorPrimaryText)
view.setImageDrawable(mutateDrawable)
}
}
}
\ No newline at end of file
package chat.rocket.android.chatdetails.ui
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import chat.rocket.android.R
import chat.rocket.android.chatdetails.domain.ChatDetails
import chat.rocket.android.chatdetails.presentation.ChatDetailsPresenter
import chat.rocket.android.chatdetails.presentation.ChatDetailsView
import chat.rocket.android.chatdetails.viewmodel.ChatDetailsViewModel
import chat.rocket.android.chatdetails.viewmodel.ChatDetailsViewModelFactory
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui
import chat.rocket.android.widget.DividerItemDecoration
import chat.rocket.common.model.RoomType
import chat.rocket.common.model.roomTypeOf
import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_chat_details.*
import javax.inject.Inject
fun newInstance(
chatRoomId: String,
chatRoomType: String,
isSubscribed: Boolean,
disableMenu: Boolean
): ChatDetailsFragment {
return ChatDetailsFragment().apply {
arguments = Bundle(1).apply {
putString(BUNDLE_CHAT_ROOM_ID, chatRoomId)
putString(BUNDLE_CHAT_ROOM_TYPE, chatRoomType)
putBoolean(BUNDLE_IS_SUBSCRIBED, isSubscribed)
putBoolean(BUNDLE_DISABLE_MENU, disableMenu)
}
}
}
internal const val TAG_CHAT_DETAILS_FRAGMENT = "ChatDetailsFragment"
private const val BUNDLE_CHAT_ROOM_ID = "BUNDLE_CHAT_ROOM_ID"
private const val BUNDLE_CHAT_ROOM_TYPE = "BUNDLE_CHAT_ROOM_TYPE"
private const val BUNDLE_IS_SUBSCRIBED = "BUNDLE_IS_SUBSCRIBED"
private const val BUNDLE_DISABLE_MENU = "BUNDLE_DISABLE_MENU"
class ChatDetailsFragment: Fragment(), ChatDetailsView {
@Inject
lateinit var presenter: ChatDetailsPresenter
@Inject
lateinit var factory: ChatDetailsViewModelFactory
private var adapter: ChatDetailsAdapter? = null
private lateinit var viewModel: ChatDetailsViewModel
private var chatRoomId: String? = null
private var chatRoomType: String? = null
private var isSubscribed: Boolean? = null
private var disableMenu: Boolean? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this)
val bundle = arguments
if (bundle != null) {
chatRoomId = bundle.getString(BUNDLE_CHAT_ROOM_ID)
chatRoomType = bundle.getString(BUNDLE_CHAT_ROOM_TYPE)
isSubscribed = bundle.getBoolean(BUNDLE_IS_SUBSCRIBED)
disableMenu = bundle.getBoolean(BUNDLE_DISABLE_MENU)
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = container?.inflate(R.layout.fragment_chat_details)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProviders.of(this, factory).get(ChatDetailsViewModel::class.java)
setupOptions()
setupToolbar()
getDetails()
}
override fun displayDetails(room: ChatDetails) {
ui {
val text = " " + room.name
name.text = text
bindImage(chatRoomType!!)
content_topic.text = if (room.topic.isNullOrEmpty()) getString(R.string.msg_no_topic) else room.topic
content_announcement.text = if (room.announcement.isNullOrEmpty()) getString(R.string.msg_no_announcement) else room.announcement
content_description.text = if (room.description.isNullOrEmpty()) getString(R.string.msg_no_description) else room.description
}
}
override fun showGenericErrorMessage() = showMessage(R.string.msg_generic_error)
override fun showMessage(resId: Int) {
ui {
showToast(resId)
}
}
override fun showMessage(message: String) {
ui {
showToast(message)
}
}
private fun addOptions(adapter: ChatDetailsAdapter) {
if (!disableMenu!!) {
adapter.addOption(getString(R.string.title_files), R.drawable.ic_files_24dp) {
presenter.toFiles(chatRoomId!!)
}
}
if (chatRoomType != RoomType.DIRECT_MESSAGE && !disableMenu!!) {
adapter.addOption(getString(R.string.msg_mentions), R.drawable.ic_at_black_20dp) {
presenter.toMentions(chatRoomId!!)
}
adapter.addOption(getString(R.string.title_members), R.drawable.ic_people_outline_black_24dp) {
presenter.toMembers(chatRoomId!!)
}
}
adapter.addOption(getString(R.string.title_favorite_messages), R.drawable.ic_star_border_white_24dp) {
presenter.toFavorites(chatRoomId!!)
}
adapter.addOption(getString(R.string.title_pinned_messages), R.drawable.ic_action_message_pin_24dp) {
presenter.toPinned(chatRoomId!!)
}
}
private fun bindImage(chatRoomType: String) {
val drawable = when (roomTypeOf(chatRoomType)) {
is RoomType.Channel -> {
DrawableHelper.getDrawableFromId(R.drawable.ic_hashtag_black_12dp, context!!)
}
is RoomType.PrivateGroup -> {
DrawableHelper.getDrawableFromId(R.drawable.ic_lock_black_12_dp, context!!)
}
else -> null
}
drawable?.let {
val wrappedDrawable = DrawableHelper.wrapDrawable(it)
val mutableDrawable = wrappedDrawable.mutate()
DrawableHelper.tintDrawable(mutableDrawable, context!!, R.color.colorPrimary)
DrawableHelper.compoundDrawable(name, mutableDrawable)
}
}
private fun getDetails() {
if (isSubscribed!!)
viewModel.getDetails(chatRoomId!!).observe(viewLifecycleOwner, Observer { details ->
displayDetails(details)
})
else
presenter.getDetails(chatRoomId!!, chatRoomType!!)
}
private fun setupOptions() {
ui {
if (options.adapter == null) {
adapter = ChatDetailsAdapter(context!!)
options.adapter = adapter
with(options) {
layoutManager = LinearLayoutManager(it)
addItemDecoration(
DividerItemDecoration(
it,
resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_start),
resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_end)
)
)
itemAnimator = DefaultItemAnimator()
isNestedScrollingEnabled = false
}
}
addOptions(adapter!!)
}
}
private fun setupToolbar() {
with(activity as ChatDetailsActivity) {
setNavigationIcon(R.drawable.ic_close_white_24dp)
setToolbarTitle(getString(R.string.title_channel_details))
}
}
}
\ No newline at end of file
package chat.rocket.android.chatdetails.viewmodel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel
import chat.rocket.android.chatdetails.domain.ChatDetails
import chat.rocket.android.db.ChatRoomDao
class ChatDetailsViewModel(private val chatRoomDao: ChatRoomDao): ViewModel() {
fun getDetails(chatRoomId: String): LiveData<ChatDetails> {
return Transformations.switchMap(chatRoomDao.get(chatRoomId)) { room ->
val entity = room.chatRoom
val data: MutableLiveData<ChatDetails> = MutableLiveData()
data.value = ChatDetails(
entity.name,
entity.fullname,
entity.type,
entity.topic,
entity.announcement,
entity.description
)
return@switchMap data
}
}
}
\ No newline at end of file
package chat.rocket.android.chatdetails.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import chat.rocket.android.db.ChatRoomDao
import javax.inject.Inject
class ChatDetailsViewModelFactory @Inject constructor(private val chatRoomDao: ChatRoomDao) : ViewModelProvider.NewInstanceFactory() {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(modelClass: Class<T>) =
ChatDetailsViewModel(chatRoomDao) as T
}
\ No newline at end of file
package chat.rocket.android.chatroom.presentation
import chat.rocket.android.R
import chat.rocket.android.chatdetails.ui.chatDetailsIntent
import chat.rocket.android.chatinformation.ui.messageInformationIntent
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatroom.ui.chatRoomIntent
......@@ -13,35 +14,20 @@ import chat.rocket.android.server.ui.changeServerIntent
import chat.rocket.android.util.extensions.addFragmentBackStack
class ChatRoomNavigator(internal val activity: ChatRoomActivity) {
fun toMembersList(chatRoomId: String) {
activity.addFragmentBackStack(TAG_MEMBERS_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.members.ui.newInstance(chatRoomId)
}
}
fun toMentions(chatRoomId: String) {
activity.addFragmentBackStack(TAG_MENTIONS_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.mentions.ui.newInstance(chatRoomId)
}
}
fun toPinnedMessageList(chatRoomId: String) {
activity.addFragmentBackStack(TAG_PINNED_MESSAGES_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.pinnedmessages.ui.newInstance(chatRoomId)
}
}
fun toFavoriteMessageList(chatRoomId: String) {
activity.addFragmentBackStack(TAG_FAVORITE_MESSAGES_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.favoritemessages.ui.newInstance(chatRoomId)
}
}
fun toFileList(chatRoomId: String) {
activity.addFragmentBackStack(TAG_FILES_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.files.ui.newInstance(chatRoomId)
}
fun toChatDetails(
chatRoomId: String,
chatRoomType: String,
isChatRoomSubscribed: Boolean,
isMenuDisabled: Boolean
) {
activity.startActivity(
activity.chatDetailsIntent(
chatRoomId,
chatRoomType,
isChatRoomSubscribed,
isMenuDisabled
)
)
}
fun toNewServer() {
......
......@@ -863,20 +863,14 @@ class ChatRoomPresenter @Inject constructor(
}
}
fun toMembersList(chatRoomId: String) =
navigator.toMembersList(chatRoomId)
fun toMentions(chatRoomId: String) =
navigator.toMentions(chatRoomId)
fun toPinnedMessageList(chatRoomId: String) =
navigator.toPinnedMessageList(chatRoomId)
fun toFavoriteMessageList(chatRoomId: String) =
navigator.toFavoriteMessageList(chatRoomId)
fun toFileList(chatRoomId: String) =
navigator.toFileList(chatRoomId)
fun toChatDetails(
chatRoomId: String,
chatRoomType: String,
isSubscribed: Boolean,
isMenuDisabled: Boolean
) {
navigator.toChatDetails(chatRoomId, chatRoomType, isSubscribed, isMenuDisabled)
}
fun loadChatRooms() {
launchUI(strategy) {
......@@ -904,7 +898,7 @@ class ChatRoomPresenter @Inject constructor(
// TODO: move this to new interactor or FetchChatRoomsInteractor?
private suspend fun getChatRoomAsync(roomId: String): ChatRoom? = withContext(CommonPool) {
return@withContext dbManager.chatRoomDao().get(roomId)?.let {
return@withContext dbManager.chatRoomDao().getSync(roomId)?.let {
with(it.chatRoom) {
ChatRoom(
id = id,
......
......@@ -128,11 +128,7 @@ private const val BUNDLE_CHAT_ROOM_IS_FAVORITE = "chat_room_is_favorite"
private const val BUNDLE_CHAT_ROOM_MESSAGE = "chat_room_message"
internal const val MENU_ACTION_FAVORITE_UNFAVORITE_CHAT = 1
internal const val MENU_ACTION_MEMBER = 2
internal const val MENU_ACTION_MENTIONS = 3
internal const val MENU_ACTION_PINNED_MESSAGES = 4
internal const val MENU_ACTION_FAVORITE_MESSAGES = 5
internal const val MENU_ACTION_FILES = 6
internal const val MENU_ACTION_SHOW_DETAILS = 2
class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiReactionListener,
ChatRoomAdapter.OnActionSelected, Drawable.Callback {
......@@ -149,7 +145,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
internal lateinit var chatRoomType: String
private var newMessageCount: Int = 0
private var chatRoomMessage: String? = null
private var isSubscribed: Boolean = true
internal var isSubscribed: Boolean = true
private var isReadOnly: Boolean = false
private var isCreator: Boolean = false
internal var isFavorite: Boolean = false
......@@ -296,8 +292,8 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
super.onPrepareOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
setOnMenuItemClickListener(item)
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
setOnMenuItemClickListener(item!!)
return true
}
......
......@@ -8,50 +8,11 @@ import androidx.appcompat.widget.SearchView
import androidx.core.content.res.ResourcesCompat
import chat.rocket.android.R
import chat.rocket.android.util.extension.onQueryTextListener
import chat.rocket.common.model.RoomType
internal fun ChatRoomFragment.setupMenu(menu: Menu) {
setupSearchMessageMenuItem(menu, requireContext())
setupFavoriteMenuItem(menu)
menu.add(
Menu.NONE,
MENU_ACTION_PINNED_MESSAGES,
Menu.NONE,
R.string.title_pinned_messages
)
menu.add(
Menu.NONE,
MENU_ACTION_FAVORITE_MESSAGES,
Menu.NONE,
R.string.title_favorite_messages
)
if (chatRoomType != RoomType.DIRECT_MESSAGE && !disableMenu) {
menu.add(
Menu.NONE,
MENU_ACTION_MEMBER,
Menu.NONE,
R.string.title_members_list
)
menu.add(
Menu.NONE,
MENU_ACTION_MENTIONS,
Menu.NONE,
R.string.msg_mentions
)
}
if (!disableMenu) {
menu.add(
Menu.NONE,
MENU_ACTION_FILES,
Menu.NONE,
R.string.title_files
)
}
setupDetailsMenuItem(menu)
}
internal fun ChatRoomFragment.setOnMenuItemClickListener(item: MenuItem) {
......@@ -60,11 +21,12 @@ internal fun ChatRoomFragment.setOnMenuItemClickListener(item: MenuItem) {
chatRoomId,
isFavorite
)
MENU_ACTION_MEMBER -> presenter.toMembersList(chatRoomId)
MENU_ACTION_MENTIONS -> presenter.toMentions(chatRoomId)
MENU_ACTION_PINNED_MESSAGES -> presenter.toPinnedMessageList(chatRoomId)
MENU_ACTION_FAVORITE_MESSAGES -> presenter.toFavoriteMessageList(chatRoomId)
MENU_ACTION_FILES -> presenter.toFileList(chatRoomId)
MENU_ACTION_SHOW_DETAILS -> presenter.toChatDetails(
chatRoomId,
chatRoomType,
isSubscribed,
disableMenu
)
}
}
......@@ -139,4 +101,14 @@ private fun ChatRoomFragment.setupFavoriteMenuItem(menu: Menu) {
).setIcon(R.drawable.ic_star_border_white_24dp)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
}
}
private fun ChatRoomFragment.setupDetailsMenuItem(menu: Menu) {
menu.add(
Menu.NONE,
MENU_ACTION_SHOW_DETAILS,
Menu.NONE,
"Channel Details"
).setIcon(R.drawable.ic_info_outline_white_24dp)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
}
\ No newline at end of file
......@@ -162,7 +162,7 @@ class UiModelMapper @Inject constructor(
// TODO: move this to new interactor or FetchChatRoomsInteractor?
private suspend fun getChatRoomAsync(roomId: String): ChatRoom? = withContext(CommonPool) {
return@withContext dbManager.chatRoomDao().get(roomId)?.let {
return@withContext dbManager.chatRoomDao().getSync(roomId)?.let {
with(it.chatRoom) {
ChatRoom(
id = id,
......
......@@ -11,6 +11,9 @@ import chat.rocket.android.authentication.server.di.ServerFragmentProvider
import chat.rocket.android.authentication.signup.di.SignupFragmentProvider
import chat.rocket.android.authentication.twofactor.di.TwoFAFragmentProvider
import chat.rocket.android.authentication.ui.AuthenticationActivity
import chat.rocket.android.chatdetails.di.ChatDetailsFragmentProvider
import chat.rocket.android.chatdetails.di.ChatDetailsModule
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.chatinformation.di.MessageInfoFragmentProvider
import chat.rocket.android.chatinformation.ui.MessageInfoActivity
import chat.rocket.android.chatroom.di.ChatRoomFragmentProvider
......@@ -41,7 +44,6 @@ import dagger.android.ContributesAndroidInjector
@Module
abstract class ActivityBuilder {
@PerActivity
@ContributesAndroidInjector(
modules = [AuthenticationModule::class,
......@@ -75,7 +77,16 @@ abstract class ActivityBuilder {
@ContributesAndroidInjector(
modules = [
ChatRoomModule::class,
ChatRoomFragmentProvider::class,
ChatRoomFragmentProvider::class
]
)
abstract fun bindChatRoomActivity(): ChatRoomActivity
@PerActivity
@ContributesAndroidInjector(
modules = [
ChatDetailsModule::class,
ChatDetailsFragmentProvider::class,
MembersFragmentProvider::class,
MentionsFragmentProvider::class,
PinnedMessagesFragmentProvider::class,
......@@ -83,7 +94,7 @@ abstract class ActivityBuilder {
FilesFragmentProvider::class
]
)
abstract fun bindChatRoomActivity(): ChatRoomActivity
abstract fun bindChatDetailsActivity(): ChatDetailsActivity
@PerActivity
@ContributesAndroidInjector(modules = [PasswordFragmentProvider::class])
......@@ -96,6 +107,7 @@ abstract class ActivityBuilder {
@PerActivity
@ContributesAndroidInjector(modules = [MessageInfoFragmentProvider::class])
abstract fun bindMessageInfoActiviy(): MessageInfoActivity
@ContributesAndroidInjector(modules = [DrawModule::class])
abstract fun bindDrawingActivity(): DrawingActivity
}
......@@ -9,7 +9,6 @@ import androidx.room.Transaction
import androidx.room.Update
import chat.rocket.android.db.model.ChatRoom
import chat.rocket.android.db.model.ChatRoomEntity
import chat.rocket.common.model.RoomType
@Dao
abstract class ChatRoomDao : BaseDao<ChatRoomEntity> {
......@@ -18,7 +17,14 @@ abstract class ChatRoomDao : BaseDao<ChatRoomEntity> {
$BASE_QUERY
WHERE chatrooms.id = :id
""")
abstract fun get(id: String): ChatRoom?
abstract fun get(id: String): LiveData<ChatRoom>
@Transaction
@Query("""
$BASE_QUERY
WHERE chatrooms.id = :id
""")
abstract fun getSync(id: String): ChatRoom?
@Transaction
@Query("$BASE_QUERY $FILTER_NOT_OPENED")
......
......@@ -96,7 +96,7 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
}
suspend fun getRoom(id: String) = withContext(dbManagerContext) {
chatRoomDao().get(id)
chatRoomDao().getSync(id)
}
fun processUsersBatch(users: List<User>) {
......@@ -335,7 +335,7 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
}
private suspend fun updateRoom(data: Room): ChatRoomEntity? {
return chatRoomDao().get(data.id)?.let { current ->
return chatRoomDao().getSync(data.id)?.let { current ->
with(data) {
val chatRoom = current.chatRoom
......@@ -348,10 +348,13 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
ownerId = user?.id ?: chatRoom.ownerId,
readonly = readonly,
updatedAt = updatedAt ?: chatRoom.updatedAt,
topic = topic,
announcement = announcement,
description = description,
lastMessageText = mapLastMessageText(lastMessage),
lastMessageUserId = lastMessage?.sender?.id,
lastMessageTimestamp = lastMessage?.timestamp,
muted = muted
muted = chatRoom.muted
)
}
}
......@@ -373,7 +376,7 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
context.getString(R.string.msg_sent_attachment)
private suspend fun updateSubscription(data: Subscription): ChatRoomEntity? {
return chatRoomDao().get(data.roomId)?.let { current ->
return chatRoomDao().getSync(data.roomId)?.let { current ->
with(data) {
val userId = if (type is RoomType.DirectMessage) {
......@@ -396,6 +399,9 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
readonly = readonly ?: chatRoom.readonly,
isDefault = isDefault,
favorite = isFavorite,
topic = chatRoom.topic,
announcement = chatRoom.announcement,
description = chatRoom.description,
open = open,
alert = alert,
unread = unread,
......@@ -461,6 +467,9 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
readonly = subscription.readonly,
isDefault = subscription.isDefault,
favorite = subscription.isFavorite,
topic = room.topic,
announcement = room.announcement,
description = room.description,
open = subscription.open,
alert = subscription.alert,
unread = subscription.unread,
......@@ -498,6 +507,9 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
readonly = readonly,
isDefault = default,
favorite = favorite,
topic = topic,
announcement = announcement,
description = description,
open = open,
alert = alert,
unread = unread,
......
......@@ -34,6 +34,9 @@ data class ChatRoomEntity(
var readonly: Boolean? = false,
var isDefault: Boolean? = false,
var favorite: Boolean? = false,
var topic: String? = null,
var announcement: String? = null,
var description: String? = null,
var open: Boolean = true,
var alert: Boolean = false,
var unread: Long = 0,
......
......@@ -12,6 +12,7 @@ import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.chatroom.adapter.ChatRoomAdapter
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatroom.uimodel.BaseUiModel
......@@ -115,9 +116,9 @@ class FavoriteMessagesFragment : Fragment(), FavoriteMessagesView {
}
private fun setupToolbar() {
(activity as ChatRoomActivity).let {
it.showToolbarTitle(getString(R.string.title_favorite_messages))
it.hideToolbarChatRoomIcon()
with(activity as ChatDetailsActivity) {
setToolbarTitle(getString(R.string.title_favorite_messages))
setNavigationIcon(R.drawable.ic_arrow_back_white_24dp)
}
}
}
\ No newline at end of file
......@@ -15,7 +15,7 @@ import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.files.adapter.FilesAdapter
import chat.rocket.android.files.presentation.FilesPresenter
import chat.rocket.android.files.presentation.FilesView
......@@ -152,9 +152,9 @@ class FilesFragment : Fragment(), FilesView {
}
private fun setupToolbar(totalFiles: Long) {
(activity as ChatRoomActivity).let {
it.showToolbarTitle(getString(R.string.title_files_total, totalFiles))
it.hideToolbarChatRoomIcon()
with(activity as ChatDetailsActivity) {
setToolbarTitle(getString(R.string.title_files_total, totalFiles))
setNavigationIcon(R.drawable.ic_arrow_back_white_24dp)
}
}
}
\ No newline at end of file
package chat.rocket.android.members.di
import androidx.lifecycle.LifecycleOwner
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.members.presentation.MembersNavigator
......@@ -22,7 +22,7 @@ class MembersFragmentModule {
@Provides
@PerFragment
fun provideChatRoomNavigator(activity: ChatRoomActivity) = MembersNavigator(activity)
fun provideChatRoomNavigator(activity: ChatDetailsActivity) = MembersNavigator(activity)
@Provides
@PerFragment
......
package chat.rocket.android.members.presentation
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.members.ui.TAG_MEMBER_BOTTOM_SHEET_FRAGMENT
import chat.rocket.android.members.ui.newInstance
class MembersNavigator(internal val activity: ChatRoomActivity) {
class MembersNavigator(internal val activity: ChatDetailsActivity) {
fun toMemberDetails(avatarUri: String, realName: String, username: String, email: String, utcOffset: String) {
activity.apply {
......
......@@ -12,7 +12,7 @@ import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.members.adapter.MembersAdapter
import chat.rocket.android.members.presentation.MembersPresenter
......@@ -127,13 +127,13 @@ class MembersFragment : Fragment(), MembersView {
}
private fun setupToolbar(totalMembers: Long? = null) {
(activity as ChatRoomActivity).let {
with (activity as ChatDetailsActivity) {
if (totalMembers != null) {
it.showToolbarTitle(getString(R.string.title_counted_members, totalMembers))
setToolbarTitle(getString(R.string.title_counted_members, totalMembers))
} else {
it.showToolbarTitle(getString(R.string.title_members))
setToolbarTitle(getString(R.string.title_members))
}
it.hideToolbarChatRoomIcon()
setNavigationIcon(R.drawable.ic_arrow_back_white_24dp)
}
}
}
\ No newline at end of file
......@@ -12,8 +12,8 @@ import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.chatroom.adapter.ChatRoomAdapter
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatroom.uimodel.BaseUiModel
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.mentions.presentention.MentionsPresenter
......@@ -122,9 +122,9 @@ class MentionsFragment : Fragment(), MentionsView {
}
private fun setupToolbar() {
(activity as ChatRoomActivity).let {
it.showToolbarTitle(getString(R.string.msg_mentions))
it.hideToolbarChatRoomIcon()
with(activity as ChatDetailsActivity) {
setToolbarTitle(getString(R.string.msg_mentions))
setNavigationIcon(R.drawable.ic_arrow_back_white_24dp)
}
}
}
\ No newline at end of file
......@@ -12,6 +12,7 @@ import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.chatroom.adapter.ChatRoomAdapter
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatroom.uimodel.BaseUiModel
......@@ -122,9 +123,9 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView {
}
private fun setupToolbar() {
(activity as ChatRoomActivity).let {
it.showToolbarTitle(getString(R.string.title_pinned_messages))
it.hideToolbarChatRoomIcon()
with(activity as ChatDetailsActivity) {
setToolbarTitle(getString(R.string.title_pinned_messages))
setNavigationIcon(R.drawable.ic_arrow_back_white_24dp)
}
}
}
\ No newline at end of file
......@@ -3,10 +3,8 @@
android:height="24dp"
android:viewportHeight="17.0"
android:viewportWidth="18.0">
<path
android:fillColor="#FF1D74F5"
android:fillType="nonZero"
android:pathData="M4.221,11.799L10.444,5.576C10.97,5.05 11.833,5.067 12.383,5.617C12.928,6.163 12.946,7.034 12.423,7.557L6.195,13.785C5.226,14.754 3.613,14.717 2.599,13.704C1.582,12.687 1.546,11.08 2.52,10.106L9.295,3.331C10.713,1.913 13.07,1.966 14.552,3.448C16.035,4.931 16.087,7.287 14.668,8.706L7.898,15.476L8.747,16.324L15.516,9.555C17.383,7.688 17.316,4.588 15.364,2.636C13.414,0.686 10.313,0.616 8.446,2.483L1.671,9.258C0.248,10.681 0.302,13.03 1.788,14.515C3.27,15.997 5.626,16.051 7.044,14.633L13.272,8.405C14.242,7.435 14.209,5.82 13.195,4.805C12.175,3.786 10.569,3.754 9.595,4.728L3.373,10.95L4.221,11.799Z" />
</vector>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M16.5,13c-1.2,0 -3.07,0.34 -4.5,1 -1.43,-0.67 -3.3,-1 -4.5,-1C5.33,13 1,14.08 1,16.25L1,19h22v-2.75c0,-2.17 -4.33,-3.25 -6.5,-3.25zM12.5,17.5h-10v-1.25c0,-0.54 2.56,-1.75 5,-1.75s5,1.21 5,1.75v1.25zM21.5,17.5L14,17.5v-1.25c0,-0.46 -0.2,-0.86 -0.52,-1.22 0.88,-0.3 1.96,-0.53 3.02,-0.53 2.44,0 5,1.21 5,1.75v1.25zM7.5,12c1.93,0 3.5,-1.57 3.5,-3.5S9.43,5 7.5,5 4,6.57 4,8.5 5.57,12 7.5,12zM7.5,6.5c1.1,0 2,0.9 2,2s-0.9,2 -2,2 -2,-0.9 -2,-2 0.9,-2 2,-2zM16.5,12c1.93,0 3.5,-1.57 3.5,-3.5S18.43,5 16.5,5 13,6.57 13,8.5s1.57,3.5 3.5,3.5zM16.5,6.5c1.1,0 2,0.9 2,2s-0.9,2 -2,2 -2,-0.9 -2,-2 0.9,-2 2,-2z"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".chatdetails.ui.ChatDetailsActivity">
<include
android:id="@+id/layout_app_bar"
layout="@layout/app_bar_chat_details" />
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.appbar.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"
app:navigationIcon="@drawable/ic_close_white_24dp"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<TextView
android:id="@+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawablePadding="@dimen/text_view_drawable_padding"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@color/colorWhite"
android:textSize="18sp"
android:textStyle="bold"
tools:text="@string/title_channel_details" />
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:background="@color/whitesmoke"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:background="@color/colorWhite"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="15dp">
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/ChatDetails.Title.TextView"
tools:text="#important"/>
<TextView
android:id="@+id/title_topic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/name"
android:layout_marginTop="20dp"
style="@style/ChatDetails.Title.TextView"
android:text="@string/title_topic" />
<TextView
android:id="@+id/content_topic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/title_topic"
style="@style/ChatDetails.Content.TextView"
android:text="@string/msg_no_topic" />
<TextView
android:id="@+id/title_announcement"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/content_topic"
android:layout_marginTop="15dp"
style="@style/ChatDetails.Title.TextView"
android:text="@string/title_announcement" />
<TextView
android:id="@+id/content_announcement"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/title_announcement"
style="@style/ChatDetails.Content.TextView"
android:text="@string/msg_no_announcement" />
<TextView
android:id="@+id/title_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/content_announcement"
android:layout_marginTop="15dp"
style="@style/ChatDetails.Title.TextView"
android:text="@string/title_description" />
<TextView
android:id="@+id/content_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/title_description"
android:layout_marginBottom="10dp"
style="@style/ChatDetails.Content.TextView"
android:text="@string/msg_no_description" />
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/options"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
android:padding="20dp">
<ImageView
android:id="@+id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
tools:ignore="ContentDescription"
android:src="@drawable/ic_add_24dp"/>
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/icon"
android:layout_alignBottom="@id/icon"
android:gravity="center_vertical"
android:layout_marginStart="57dp"
style="@style/ChatDetails.Title.TextView"
tools:text="Files"/>
</RelativeLayout>
\ No newline at end of file
......@@ -22,6 +22,10 @@
<string name="title_about">Über</string>
<string name="title_create_channel">Erstelle Raum</string>
<string name="title_are_you_sure">Are you sure?</string><!-- TODO Add translation -->
<string name="title_channel_details">Channel Details</string> <!-- TODO add translation -->
<string name="title_topic">Thema</string>
<string name="title_announcement">Ankündigung</string>
<string name="title_description">Beschreibung</string>
<!-- Actions -->
<string name="action_connect">Verbinde</string>
......@@ -171,6 +175,9 @@
<string name="msg_view_less">view less</string>
<!-- TODO - Add proper translation -->
<string name="msg_permalink_copied">Permalink copied</string>
<string name="msg_no_topic">No topic added</string> <!-- TODO Add translation -->
<string name="msg_no_announcement">No announcement added</string> <!-- TODO Add translation -->
<string name="msg_no_description">No description added</string> <!-- TODO Add translation -->
<!-- Preferences messages -->
<string name="msg_analytics_tracking">Analytics tracking</string> <!-- TODO Add translation -->
......@@ -313,5 +320,6 @@
<string name="notif_success_sending">Nachricht gesendet nach %1$s!</string>
<string name="read_by">Gelesen von</string>
<string name="message_information_title">Nachricht Information</string>
<string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string> <!--TODO - Add proper translation-->
<!--TODO - Add proper translation-->
<string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string>
</resources>
\ No newline at end of file
......@@ -21,6 +21,10 @@
<string name="title_about">Acerca de</string>
<string name="title_create_channel">Crear canal</string>
<string name="title_are_you_sure">Are you sure?</string> <!-- TODO Add translation -->
<string name="title_channel_details">Channel Details</string> <!-- TODO add translation -->
<string name="title_topic">Tema</string>
<string name="title_announcement">Anuncio</string>
<string name="title_description">Descripción</string>
<!-- Actions -->
<string name="action_connect">Conectar</string>
......@@ -168,6 +172,9 @@
<string name="msg_permalink_copied">Permalink copied</string>
<!-- TODO - Add proper translation -->
<string name="msg_muted_on_this_channel">You are muted on this channel</string>
<string name="msg_no_topic">No topic added</string> <!-- TODO Add translation -->
<string name="msg_no_announcement">No announcement added</string> <!-- TODO Add translation -->
<string name="msg_no_description">No description added</string> <!-- TODO Add translation -->
<!-- Preferences messages -->
<string name="msg_analytics_tracking">Analytics tracking</string> <!-- TODO Add translation -->
......@@ -317,5 +324,4 @@
<string name="msg_sent_attachment">Envió un archivo</string>
<!--TODO - Add proper translation-->
<string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string>
</resources>
......@@ -22,6 +22,10 @@
<string name="title_about">À propos</string>
<string name="title_create_channel">Créer salon</string>
<string name="title_are_you_sure">Are you sure?</string> <!-- TODO Add translation -->
<string name="title_channel_details">Channel Details</string> <!-- TODO add translation -->
<string name="title_topic">Sujet</string>
<string name="title_announcement">Annonce</string>
<string name="title_description">La description</string>
<!-- Actions -->
<string name="action_connect">Se connecter</string>
......@@ -160,6 +164,9 @@
<string name="msg_permalink_copied">Permalink copied</string>
<!-- TODO - Add proper translation -->
<string name="msg_muted_on_this_channel">You are muted on this channel</string>
<string name="msg_no_topic">No topic added</string> <!-- TODO Add translation -->
<string name="msg_no_announcement">No announcement added</string> <!-- TODO Add translation -->
<string name="msg_no_description">No description added</string> <!-- TODO Add translation -->
<!-- Create channel messages -->
<string name="msg_private_channel">Privé</string>
......
......@@ -22,6 +22,10 @@
<string name="title_about">परिचय</string>
<string name="title_create_channel">चैनल बनाएं</string>
<string name="title_are_you_sure">Are you sure?</string> <!-- TODO Add translation -->
<string name="title_channel_details">Channel Details</string> <!-- TODO add translation -->
<string name="title_topic">विषय</string>
<string name="title_announcement">घोषणा</string>
<string name="title_description">विवरण</string>
<!-- Actions -->
<string name="action_connect">जुडिये</string>
......@@ -172,6 +176,9 @@
<string name="msg_permalink_copied">Permalink copied</string>
<!-- TODO - Add proper translation -->
<string name="msg_muted_on_this_channel">You are muted on this channel</string>
<string name="msg_no_topic">No topic added</string> <!-- TODO Add translation -->
<string name="msg_no_announcement">No announcement added</string> <!-- TODO Add translation -->
<string name="msg_no_description">No description added</string> <!-- TODO Add translation -->
<!-- Preferences messages -->
<string name="msg_analytics_tracking">एनालिटिक्स ट्रैकिंग</string>
......
......@@ -24,6 +24,10 @@
<string name="title_about">About</string>
<string name="title_create_channel">新しいチャネルを作成します</string>
<string name="title_are_you_sure">Are you sure?</string> <!-- TODO Add translation -->
<string name="title_channel_details">Channel Details</string> <!-- TODO add translation -->
<string name="title_topic">トピック</string>
<string name="title_announcement">発表</string>
<string name="title_description">説明</string>
<!-- Actions -->
<string name="action_connect">接続</string>
......@@ -177,6 +181,9 @@
<string name="msg_delete_description">このメッセージを削除してもよろしいですか?</string>
<!-- TODO - Add proper translation -->
<string name="msg_permalink_copied">Permalink copied</string>
<string name="msg_no_topic">No topic added</string> <!-- TODO Add translation -->
<string name="msg_no_announcement">No announcement added</string> <!-- TODO Add translation -->
<string name="msg_no_description">No description added</string> <!-- TODO Add translation -->
<!-- Preferences messages -->
<string name="msg_analytics_tracking">Analytics tracking</string> <!-- TODO Add translation -->
......
......@@ -22,6 +22,10 @@
<string name="title_about">Sobre</string>
<string name="title_create_channel">Criar chat</string>
<string name="title_are_you_sure">Você tem certeza?</string>
<string name="title_channel_details">Channel Details</string> <!-- TODO add translation -->
<string name="title_topic">Tópico</string>
<string name="title_announcement">Anúncio</string>
<string name="title_description">Descrição</string>
<!-- Actions -->
<string name="action_connect">Conectar</string>
......@@ -158,6 +162,9 @@
<!-- TODO - Add proper translation -->
<string name="msg_permalink_copied">Permalink copiado</string>
<string name="msg_muted_on_this_channel">Você está silenciado neste canal</string>
<string name="msg_no_topic">No topic added</string> <!-- TODO Add translation -->
<string name="msg_no_announcement">No announcement added</string> <!-- TODO Add translation -->
<string name="msg_no_description">No description added</string> <!-- TODO Add translation -->
<!-- Create channel messages -->
<string name="msg_private_channel">Privado</string>
......
......@@ -22,6 +22,10 @@
<string name="title_about">О программе</string>
<string name="title_create_channel">Создать новый канал</string>
<string name="title_are_you_sure">Are you sure?</string> <!-- TODO Add translation -->
<string name="title_channel_details">Channel Details</string> <!-- TODO add translation -->
<string name="title_topic">Тема</string>
<string name="title_announcement">Объявление</string>
<string name="title_description">Описание</string>
<!-- Actions -->
<string name="action_connect">Подключиться</string>
......@@ -156,6 +160,9 @@
<string name="msg_permalink_copied">Ссылка скопирована</string>
<!-- TODO - Add proper translation -->
<string name="msg_muted_on_this_channel">You are muted on this channel</string>
<string name="msg_no_topic">No topic added</string> <!-- TODO Add translation -->
<string name="msg_no_announcement">No announcement added</string> <!-- TODO Add translation -->
<string name="msg_no_description">No description added</string> <!-- TODO Add translation -->
<!-- Create channel messages -->
<string name="msg_private_channel">Приватный</string>
......
......@@ -22,6 +22,10 @@
<string name="title_about">Hakkında</string>
<string name="title_create_channel">Yeni Kanal Oluştur</string>
<string name="title_are_you_sure">Are you sure?</string> <!-- TODO Add translation -->
<string name="title_channel_details">Channel Details</string> <!-- TODO add translation -->
<string name="title_topic">konu</string>
<string name="title_announcement">duyuru</string>
<string name="title_description">Açıklama</string>
<!-- Actions -->
<string name="action_connect">Bağlan</string>
......@@ -173,6 +177,9 @@
<string name="msg_permalink_copied">Permalink copied</string>
<!-- TODO - Add proper translation -->
<string name="msg_muted_on_this_channel">You are muted on this channel</string>
<string name="msg_no_topic">No topic added</string> <!-- TODO Add translation -->
<string name="msg_no_announcement">No announcement added</string> <!-- TODO Add translation -->
<string name="msg_no_description">No description added</string> <!-- TODO Add translation -->
<!-- Preferences messages -->
<string name="msg_analytics_tracking">İstatistik takibi</string>
......@@ -317,5 +324,4 @@
<string name="message_information_title">Mesaj bilgisi</string>
<!--TODO - Add proper translation-->
<string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string>
</resources>
......@@ -22,6 +22,10 @@
<string name="title_about">"Про програму"</string>
<string name="title_create_channel">Створити новий канал</string>
<string name="title_are_you_sure">Are you sure?</string> <!-- TODO Add translation -->
<string name="title_channel_details">Channel Details</string> <!-- TODO add translation -->
<string name="title_topic">Тема</string>
<string name="title_announcement">Оголошення</string>
<string name="title_description">Опис</string>
<!-- Actions -->
<string name="action_connect">Підключитися</string>
......@@ -158,6 +162,9 @@
<string name="msg_permalink_copied">Permalink copied</string>
<!-- TODO - Add proper translation -->
<string name="msg_muted_on_this_channel">You are muted on this channel</string>
<string name="msg_no_topic">No topic added</string> <!-- TODO Add translation -->
<string name="msg_no_announcement">No announcement added</string> <!-- TODO Add translation -->
<string name="msg_no_description">No description added</string> <!-- TODO Add translation -->
<!-- Create channel messages -->
<string name="msg_private_channel">Приватний</string>
......
......@@ -9,6 +9,7 @@
<!-- Text colors -->
<color name="colorPrimaryText">#DE000000</color>
<color name="colorSecondaryText">#FF787878</color>
<color name="colorLightGrey">#F4F5F7</color>
<color name="colorSecondaryTextLight">#FFC1C1C1</color>
<!-- User status colors -->
......
......@@ -34,6 +34,11 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<string name="title_about">About</string>
<string name="title_create_channel">Create Channel</string>
<string name="title_are_you_sure">Are you sure?</string>
<string name="title_confirmation">Are You Sure you want to logout?</string>
<string name="title_channel_details">Channel Details</string>
<string name="title_topic">Topic</string>
<string name="title_announcement">Announcement</string>
<string name="title_description">Description</string>
<!-- Actions -->
<string name="action_connect">Connect</string>
......@@ -166,6 +171,9 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<string name="msg_two_factor_authentication">Two-factor Authentication</string>
<string name="msg__your_2fa_code">What’s your 2FA code?</string>
<string name="msg_permalink_copied">Permalink copied</string>
<string name="msg_no_topic">No topic added</string>
<string name="msg_no_announcement">No announcement added</string>
<string name="msg_no_description">No description added</string>
<!-- Create channel messages -->
<string name="msg_private_channel">Private</string>
......
......@@ -142,10 +142,20 @@
<item name="android:textSize">16sp</item>
</style>
<style name="ChatDetails.Title.TextView" parent="TextAppearance.AppCompat.Title">
<item name="android:textSize">16sp</item>
<item name="android:textColor">@color/colorPrimary</item>
</style>
<style name="ChatDetails.Content.TextView" parent="TextAppearance.AppCompat.Title">
<item name="android:textSize">12sp</item>
<item name="android:textColor">@color/colorSecondaryTextLight</item>
</style>
<style name="Sender.Name.TextView" parent="TextAppearance.AppCompat.Title">
<item name="android:ellipsize">end</item>
<item name="android:maxLines">1</item>
<item name="android:textSize">16sp</item>
<item name="android:textSize">20sp</item>
</style>
<style name="Message.TextView" parent="android:TextAppearance">
......
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