Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
AloqaIM-Android
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
AloqaIM-Android
Commits
71809156
Commit
71809156
authored
Mar 05, 2018
by
Leonardo Aramaki
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'release/2.0.0-beta7' into feature/autocomplete
parents
6cf8ac9a
039e3c35
Changes
27
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
668 additions
and
95 deletions
+668
-95
build.gradle
app/build.gradle
+2
-2
LoginPresenter.kt
...droid/authentication/login/presentation/LoginPresenter.kt
+8
-1
ChatRoomFragmentModule.kt
...chat/rocket/android/chatroom/di/ChatRoomFragmentModule.kt
+5
-0
ChatRoomNavigator.kt
...rocket/android/chatroom/presentation/ChatRoomNavigator.kt
+15
-0
ChatRoomPresenter.kt
...rocket/android/chatroom/presentation/ChatRoomPresenter.kt
+19
-11
ChatRoomActivity.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt
+6
-3
ChatRoomFragment.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
+15
-3
ChatRoomsFragment.kt
...ava/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
+6
-1
ActivityBuilder.kt
...java/chat/rocket/android/dagger/module/ActivityBuilder.kt
+2
-1
MembersAdapter.kt
...ava/chat/rocket/android/members/adapter/MembersAdapter.kt
+42
-0
MembersFragmentModule.kt
...a/chat/rocket/android/members/di/MembersFragmentModule.kt
+30
-0
MembersFragmentProvider.kt
...chat/rocket/android/members/di/MembersFragmentProvider.kt
+12
-0
MembersPresenter.kt
...t/rocket/android/members/presentation/MembersPresenter.kt
+41
-0
MembersView.kt
...a/chat/rocket/android/members/presentation/MembersView.kt
+16
-0
MembersFragment.kt
...in/java/chat/rocket/android/members/ui/MembersFragment.kt
+127
-0
MemberViewModel.kt
.../chat/rocket/android/members/viewmodel/MemberViewModel.kt
+46
-0
MemberViewModelMapper.kt
...rocket/android/members/viewmodel/MemberViewModelMapper.kt
+17
-0
Animation.kt
...ain/java/chat/rocket/android/util/extensions/Animation.kt
+27
-39
Text.kt
...src/main/java/chat/rocket/android/util/extensions/Text.kt
+3
-0
ic_gitlab.xml
app/src/main/res/drawable/ic_gitlab.xml
+72
-32
fragment_authentication_server.xml
app/src/main/res/layout/fragment_authentication_server.xml
+2
-2
fragment_members.xml
app/src/main/res/layout/fragment_members.xml
+25
-0
item_member.xml
app/src/main/res/layout/item_member.xml
+31
-0
member_bottom_sheet.xml
app/src/main/res/layout/member_bottom_sheet.xml
+82
-0
chatroom_actions.xml
app/src/main/res/menu/chatroom_actions.xml
+5
-0
strings.xml
app/src/main/res/values-pt-rBR/strings.xml
+6
-0
strings.xml
app/src/main/res/values/strings.xml
+6
-0
No files found.
app/build.gradle
View file @
71809156
...
...
@@ -12,8 +12,8 @@ android {
applicationId
"chat.rocket.android"
minSdkVersion
21
targetSdkVersion
versions
.
targetSdk
versionCode
101
0
versionName
"2.0.0-dev
8
"
versionCode
101
1
versionName
"2.0.0-dev
9
"
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled
true
}
...
...
app/src/main/java/chat/rocket/android/authentication/login/presentation/LoginPresenter.kt
View file @
71809156
...
...
@@ -7,12 +7,14 @@ import chat.rocket.android.helper.NetworkHelper
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extensions.isEmailValid
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.RocketChatTwoFactorException
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.rest.login
import
chat.rocket.core.internal.rest.loginWithEmail
import
chat.rocket.core.internal.rest.me
import
chat.rocket.core.internal.rest.registerPushToken
import
javax.inject.Inject
...
...
@@ -93,7 +95,12 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
view
.
showLoading
()
try
{
val
token
=
client
.
login
(
usernameOrEmail
,
password
)
val
token
=
if
(
usernameOrEmail
.
isEmailValid
())
{
client
.
loginWithEmail
(
usernameOrEmail
,
password
)
}
else
{
client
.
login
(
usernameOrEmail
,
password
)
}
val
me
=
client
.
me
()
multiServerRepository
.
save
(
server
,
...
...
app/src/main/java/chat/rocket/android/chatroom/di/ChatRoomFragmentModule.kt
View file @
71809156
package
chat.rocket.android.chatroom.di
import
android.arch.lifecycle.LifecycleOwner
import
chat.rocket.android.chatroom.presentation.ChatRoomNavigator
import
chat.rocket.android.chatroom.presentation.ChatRoomView
import
chat.rocket.android.chatroom.ui.ChatRoomActivity
import
chat.rocket.android.chatroom.ui.ChatRoomFragment
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.dagger.scope.PerFragment
...
...
@@ -13,6 +15,9 @@ import kotlinx.coroutines.experimental.Job
@PerFragment
class
ChatRoomFragmentModule
{
@Provides
fun
provideChatRoomNavigator
(
activity
:
ChatRoomActivity
)
=
ChatRoomNavigator
(
activity
)
@Provides
fun
chatRoomView
(
frag
:
ChatRoomFragment
):
ChatRoomView
{
return
frag
...
...
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomNavigator.kt
0 → 100644
View file @
71809156
package
chat.rocket.android.chatroom.presentation
import
chat.rocket.android.R
import
chat.rocket.android.chatroom.ui.ChatRoomActivity
import
chat.rocket.android.members.ui.newInstance
import
chat.rocket.android.util.extensions.addFragmentBackStack
class
ChatRoomNavigator
(
internal
val
activity
:
ChatRoomActivity
)
{
fun
toMembersList
(
chatRoomId
:
String
,
chatRoomType
:
String
)
{
activity
.
addFragmentBackStack
(
"MembersFragment"
,
R
.
id
.
fragment_container
)
{
newInstance
(
chatRoomId
,
chatRoomType
)
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt
View file @
71809156
...
...
@@ -6,8 +6,8 @@ import chat.rocket.android.chatroom.adapter.AutoCompleteType
import
chat.rocket.android.chatroom.adapter.PEOPLE
import
chat.rocket.android.chatroom.adapter.ROOMS
import
chat.rocket.android.chatroom.domain.UriInteractor
import
chat.rocket.android.chatroom.viewmodel.PeopleViewModel
import
chat.rocket.android.chatroom.viewmodel.ChatRoomViewModel
import
chat.rocket.android.chatroom.viewmodel.PeopleViewModel
import
chat.rocket.android.chatroom.viewmodel.ViewModelMapper
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.helper.UrlHelper
...
...
@@ -35,6 +35,7 @@ import timber.log.Timber
import
javax.inject.Inject
class
ChatRoomPresenter
@Inject
constructor
(
private
val
view
:
ChatRoomView
,
private
val
navigator
:
ChatRoomNavigator
,
private
val
strategy
:
CancelStrategy
,
getSettingsInteractor
:
GetSettingsInteractor
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
...
...
@@ -434,16 +435,21 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
fun
loadChatRooms
()
{
launchUI
(
strategy
)
{
try
{
val
chatRooms
=
getChatRoomsInteractor
.
get
(
currentServer
).
map
{
chatRoom
->
val
name
=
chatRoom
.
name
val
fullName
=
chatRoom
.
fullName
?:
""
ChatRoomViewModel
(
text
=
name
,
name
=
name
,
fullName
=
fullName
,
searchList
=
listOf
(
name
,
fullName
)
)
}
val
chatRooms
=
getChatRoomsInteractor
.
get
(
currentServer
)
.
filterNot
{
it
.
type
.
toString
()
==
RoomType
.
DIRECT_MESSAGE
.
toString
()
||
it
.
type
.
toString
()
==
RoomType
.
DIRECT_MESSAGE
.
toString
()
}
.
map
{
chatRoom
->
val
name
=
chatRoom
.
name
val
fullName
=
chatRoom
.
fullName
?:
""
ChatRoomViewModel
(
text
=
name
,
name
=
name
,
fullName
=
fullName
,
searchList
=
listOf
(
name
,
fullName
)
)
}
view
.
populateRooms
(
chatRooms
)
}
catch
(
e
:
RocketChatException
)
{
Timber
.
e
(
e
)
...
...
@@ -451,6 +457,8 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
}
}
fun
toMembersList
(
chatRoomId
:
String
,
chatRoomType
:
String
)
=
navigator
.
toMembersList
(
chatRoomId
,
chatRoomType
)
private
fun
updateMessage
(
streamedMessage
:
Message
)
{
launchUI
(
strategy
)
{
val
viewModelStreamedMessage
=
mapper
.
map
(
streamedMessage
)
...
...
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt
View file @
71809156
...
...
@@ -64,7 +64,7 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
isChatRoomReadOnly
=
intent
.
getBooleanExtra
(
INTENT_IS_CHAT_ROOM_READ_ONLY
,
true
)
requireNotNull
(
chatRoomType
)
{
"no is_chat_room_read_only provided in Intent extras"
}
setupToolbar
(
chatRoomName
)
setupToolbar
()
addFragment
(
"ChatRoomFragment"
,
R
.
id
.
fragment_container
)
{
newInstance
(
chatRoomId
,
chatRoomName
,
chatRoomType
,
isChatRoomReadOnly
)
...
...
@@ -79,15 +79,18 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
return
fragmentDispatchingAndroidInjector
}
private
fun
setupToolbar
(
chatRoomName
:
String
)
{
private
fun
setupToolbar
()
{
setSupportActionBar
(
toolbar
)
supportActionBar
?.
setDisplayShowTitleEnabled
(
false
)
text_room_name
.
textContent
=
chatRoomName
toolbar
.
setNavigationOnClickListener
{
finishActivity
()
}
}
fun
setupToolbarTitle
(
toolbarTitle
:
String
)
{
text_room_name
.
textContent
=
toolbarTitle
}
private
fun
finishActivity
()
{
super
.
onBackPressed
()
overridePendingTransition
(
R
.
anim
.
close_enter
,
R
.
anim
.
close_exit
)
...
...
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
View file @
71809156
...
...
@@ -105,6 +105,8 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
override
fun
onViewCreated
(
view
:
View
,
savedInstanceState
:
Bundle
?)
{
super
.
onViewCreated
(
view
,
savedInstanceState
)
setupToolbar
(
chatRoomName
)
presenter
.
loadMessages
(
chatRoomId
,
chatRoomType
)
presenter
.
loadChatRooms
()
setupRecyclerView
()
...
...
@@ -141,6 +143,9 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
override
fun
onOptionsItemSelected
(
item
:
MenuItem
):
Boolean
{
when
(
item
.
itemId
)
{
R
.
id
.
action_members_list
->
{
presenter
.
toMembersList
(
chatRoomId
,
chatRoomType
)
}
R
.
id
.
action_pinned_messages
->
{
val
intent
=
Intent
(
activity
,
PinnedMessagesActivity
::
class
.
java
).
apply
{
putExtra
(
BUNDLE_CHAT_ROOM_ID
,
chatRoomId
)
...
...
@@ -356,6 +361,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
text_room_is_read_only
.
setVisible
(
true
)
input_container
.
setVisible
(
false
)
}
else
{
button_send
.
alpha
=
0f
button_send
.
setVisible
(
false
)
button_show_attachment_options
.
alpha
=
1f
button_show_attachment_options
.
setVisible
(
true
)
subscribeTextMessage
()
emojiKeyboardPopup
=
EmojiKeyboardPopup
(
activity
!!
,
activity
!!
.
findViewById
(
R
.
id
.
fragment_container
))
emojiKeyboardPopup
.
listener
=
this
...
...
@@ -469,9 +479,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
}
private
fun
unsubscribeTextMessage
()
{
if
(!
compositeDisposable
.
isDisposed
)
{
compositeDisposable
.
dispose
()
}
compositeDisposable
.
clear
()
}
private
fun
setupComposeMessageButtons
(
charSequence
:
CharSequence
)
{
...
...
@@ -503,4 +511,8 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
view_dim
.
setVisible
(
false
)
}
private
fun
setupToolbar
(
toolbarTitle
:
String
)
{
(
activity
as
ChatRoomActivity
).
setupToolbarTitle
(
toolbarTitle
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
View file @
71809156
...
...
@@ -62,6 +62,11 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
presenter
.
loadChatRooms
()
}
override
fun
onDestroyView
()
{
listJob
?.
cancel
()
super
.
onDestroyView
()
}
override
fun
onCreateOptionsMenu
(
menu
:
Menu
,
inflater
:
MenuInflater
)
{
super
.
onCreateOptionsMenu
(
menu
,
inflater
)
inflater
.
inflate
(
R
.
menu
.
chatrooms
,
menu
)
...
...
@@ -80,7 +85,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
}
override
suspend
fun
updateChatRooms
(
newDataSet
:
List
<
ChatRoom
>)
{
activity
.
apply
{
activity
?
.
apply
{
listJob
?.
cancel
()
listJob
=
launch
(
UI
)
{
val
adapter
=
recycler_view
.
adapter
as
ChatRoomsAdapter
...
...
app/src/main/java/chat/rocket/android/dagger/module/ActivityBuilder.kt
View file @
71809156
...
...
@@ -16,6 +16,7 @@ import chat.rocket.android.dagger.scope.PerActivity
import
chat.rocket.android.main.di.MainActivityProvider
import
chat.rocket.android.main.di.MainModule
import
chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.members.di.MembersFragmentProvider
import
chat.rocket.android.profile.di.ProfileFragmentProvider
import
dagger.Module
import
dagger.android.ContributesAndroidInjector
...
...
@@ -42,7 +43,7 @@ abstract class ActivityBuilder {
abstract
fun
bindMainActivity
():
MainActivity
@PerActivity
@ContributesAndroidInjector
(
modules
=
[
ChatRoomFragmentProvider
::
class
])
@ContributesAndroidInjector
(
modules
=
[
ChatRoomFragmentProvider
::
class
,
MembersFragmentProvider
::
class
])
abstract
fun
bindChatRoomActivity
():
ChatRoomActivity
@PerActivity
...
...
app/src/main/java/chat/rocket/android/members/adapter/MembersAdapter.kt
0 → 100644
View file @
71809156
package
chat.rocket.android.members.adapter
import
android.support.v7.widget.RecyclerView
import
android.view.View
import
android.view.ViewGroup
import
chat.rocket.android.R
import
chat.rocket.android.members.viewmodel.MemberViewModel
import
chat.rocket.android.util.extensions.content
import
chat.rocket.android.util.extensions.inflate
import
kotlinx.android.synthetic.main.avatar.view.*
import
kotlinx.android.synthetic.main.item_member.view.*
class
MembersAdapter
(
private
val
listener
:
(
MemberViewModel
)
->
Unit
)
:
RecyclerView
.
Adapter
<
MembersAdapter
.
ViewHolder
>()
{
private
var
dataSet
:
List
<
MemberViewModel
>
=
ArrayList
()
override
fun
onCreateViewHolder
(
parent
:
ViewGroup
,
viewType
:
Int
):
MembersAdapter
.
ViewHolder
=
ViewHolder
(
parent
.
inflate
(
R
.
layout
.
item_member
))
override
fun
onBindViewHolder
(
holder
:
MembersAdapter
.
ViewHolder
,
position
:
Int
)
=
holder
.
bind
(
dataSet
[
position
],
listener
)
override
fun
getItemCount
():
Int
=
dataSet
.
size
fun
prependData
(
dataSet
:
List
<
MemberViewModel
>)
{
this
.
dataSet
=
dataSet
notifyItemRangeInserted
(
0
,
dataSet
.
size
)
}
fun
appendData
(
dataSet
:
List
<
MemberViewModel
>)
{
val
previousDataSetSize
=
this
.
dataSet
.
size
this
.
dataSet
+=
dataSet
notifyItemRangeInserted
(
previousDataSetSize
,
dataSet
.
size
)
}
class
ViewHolder
(
itemView
:
View
)
:
RecyclerView
.
ViewHolder
(
itemView
)
{
fun
bind
(
memberViewModel
:
MemberViewModel
,
listener
:
(
MemberViewModel
)
->
Unit
)
=
with
(
itemView
)
{
image_avatar
.
setImageURI
(
memberViewModel
.
avatarUri
)
text_member
.
content
=
memberViewModel
.
displayName
setOnClickListener
{
listener
(
memberViewModel
)
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/members/di/MembersFragmentModule.kt
0 → 100644
View file @
71809156
package
chat.rocket.android.members.di
import
android.arch.lifecycle.LifecycleOwner
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.dagger.scope.PerFragment
import
chat.rocket.android.members.presentation.MembersView
import
chat.rocket.android.members.ui.MembersFragment
import
dagger.Module
import
dagger.Provides
import
kotlinx.coroutines.experimental.Job
@Module
@PerFragment
class
MembersFragmentModule
{
@Provides
fun
membersView
(
frag
:
MembersFragment
):
MembersView
{
return
frag
}
@Provides
fun
provideLifecycleOwner
(
frag
:
MembersFragment
):
LifecycleOwner
{
return
frag
}
@Provides
fun
provideCancelStrategy
(
owner
:
LifecycleOwner
,
jobs
:
Job
):
CancelStrategy
{
return
CancelStrategy
(
owner
,
jobs
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/members/di/MembersFragmentProvider.kt
0 → 100644
View file @
71809156
package
chat.rocket.android.members.di
import
chat.rocket.android.members.ui.MembersFragment
import
dagger.Module
import
dagger.android.ContributesAndroidInjector
@Module
abstract
class
MembersFragmentProvider
{
@ContributesAndroidInjector
(
modules
=
[
MembersFragmentModule
::
class
])
abstract
fun
provideMembersFragment
():
MembersFragment
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/members/presentation/MembersPresenter.kt
0 → 100644
View file @
71809156
package
chat.rocket.android.members.presentation
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.members.viewmodel.MemberViewModelMapper
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.model.roomTypeOf
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.rest.getMembers
import
javax.inject.Inject
class
MembersPresenter
@Inject
constructor
(
private
val
view
:
MembersView
,
private
val
strategy
:
CancelStrategy
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
factory
:
RocketChatClientFactory
,
private
val
mapper
:
MemberViewModelMapper
)
{
private
val
client
:
RocketChatClient
=
factory
.
create
(
serverInteractor
.
get
()
!!
)
fun
loadChatRoomsMembers
(
chatRoomId
:
String
,
chatRoomType
:
String
,
offset
:
Long
=
0
)
{
launchUI
(
strategy
)
{
try
{
view
.
showLoading
()
val
members
=
client
.
getMembers
(
chatRoomId
,
roomTypeOf
(
chatRoomType
),
offset
,
60
)
val
memberViewModels
=
mapper
.
mapToViewModelList
(
members
.
result
)
view
.
showMembers
(
memberViewModels
,
members
.
total
)
}
catch
(
ex
:
RocketChatException
)
{
ex
.
message
?.
let
{
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
}
}
finally
{
view
.
hideLoading
()
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/members/presentation/MembersView.kt
0 → 100644
View file @
71809156
package
chat.rocket.android.members.presentation
import
chat.rocket.android.core.behaviours.LoadingView
import
chat.rocket.android.core.behaviours.MessageView
import
chat.rocket.android.members.viewmodel.MemberViewModel
interface
MembersView
:
LoadingView
,
MessageView
{
/**
* Shows a list of members of a room.
*
* @param dataSet The data set to show.
* @param total The total number of members.
*/
fun
showMembers
(
dataSet
:
List
<
MemberViewModel
>,
total
:
Long
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/members/ui/MembersFragment.kt
0 → 100644
View file @
71809156
package
chat.rocket.android.members.ui
import
android.os.Bundle
import
android.support.design.widget.BottomSheetBehavior
import
android.support.v4.app.Fragment
import
android.support.v7.app.AppCompatActivity
import
android.support.v7.widget.LinearLayoutManager
import
android.support.v7.widget.RecyclerView
import
android.view.LayoutInflater
import
android.view.View
import
android.view.ViewGroup
import
chat.rocket.android.R
import
chat.rocket.android.chatroom.ui.ChatRoomActivity
import
chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import
chat.rocket.android.members.adapter.MembersAdapter
import
chat.rocket.android.members.presentation.MembersPresenter
import
chat.rocket.android.members.presentation.MembersView
import
chat.rocket.android.members.viewmodel.MemberViewModel
import
chat.rocket.android.util.extensions.*
import
chat.rocket.android.widget.DividerItemDecoration
import
dagger.android.support.AndroidSupportInjection
import
kotlinx.android.synthetic.main.fragment_members.*
import
kotlinx.android.synthetic.main.member_bottom_sheet.*
import
javax.inject.Inject
fun
newInstance
(
chatRoomId
:
String
,
chatRoomType
:
String
):
Fragment
{
return
MembersFragment
().
apply
{
arguments
=
Bundle
(
1
).
apply
{
putString
(
BUNDLE_CHAT_ROOM_ID
,
chatRoomId
)
putString
(
BUNDLE_CHAT_ROOM_TYPE
,
chatRoomType
)
}
}
}
private
const
val
BUNDLE_CHAT_ROOM_ID
=
"chat_room_id"
private
const
val
BUNDLE_CHAT_ROOM_TYPE
=
"chat_room_type"
class
MembersFragment
:
Fragment
(),
MembersView
{
@Inject
lateinit
var
presenter
:
MembersPresenter
private
val
adapter
:
MembersAdapter
=
MembersAdapter
{
memberViewModel
->
showMemberDetails
(
memberViewModel
)
}
private
val
linearLayoutManager
=
LinearLayoutManager
(
context
,
LinearLayoutManager
.
VERTICAL
,
false
)
private
val
bottomSheetBehavior
by
lazy
{
BottomSheetBehavior
.
from
(
member_bottom_sheet
)
}
private
lateinit
var
chatRoomId
:
String
private
lateinit
var
chatRoomType
:
String
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
)
}
else
{
requireNotNull
(
bundle
)
{
"no arguments supplied when the fragment was instantiated"
}
}
}
override
fun
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
?,
savedInstanceState
:
Bundle
?):
View
?
=
container
?.
inflate
(
R
.
layout
.
fragment_members
)
override
fun
onViewCreated
(
view
:
View
,
savedInstanceState
:
Bundle
?)
{
super
.
onViewCreated
(
view
,
savedInstanceState
)
(
activity
as
AppCompatActivity
).
supportActionBar
?.
title
=
""
setupRecyclerView
()
presenter
.
loadChatRoomsMembers
(
chatRoomId
,
chatRoomType
)
}
override
fun
showMembers
(
dataSet
:
List
<
MemberViewModel
>,
total
:
Long
)
{
activity
?.
apply
{
setupToolbar
(
total
)
if
(
adapter
.
itemCount
==
0
)
{
adapter
.
prependData
(
dataSet
)
if
(
dataSet
.
size
>=
60
)
{
recycler_view
.
addOnScrollListener
(
object
:
EndlessRecyclerViewScrollListener
(
linearLayoutManager
)
{
override
fun
onLoadMore
(
page
:
Int
,
totalItemsCount
:
Int
,
recyclerView
:
RecyclerView
?)
{
presenter
.
loadChatRoomsMembers
(
chatRoomId
,
chatRoomType
,
page
*
60L
)
}
})
}
}
else
{
adapter
.
appendData
(
dataSet
)
}
}
}
override
fun
showLoading
()
=
view_loading
.
setVisible
(
true
)
override
fun
hideLoading
()
=
view_loading
.
setVisible
(
false
)
override
fun
showMessage
(
resId
:
Int
)
=
showToast
(
resId
)
override
fun
showMessage
(
message
:
String
)
=
showToast
(
message
)
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
private
fun
setupRecyclerView
()
{
activity
?.
apply
{
recycler_view
.
layoutManager
=
linearLayoutManager
recycler_view
.
addItemDecoration
(
DividerItemDecoration
(
this
))
recycler_view
.
adapter
=
adapter
}
}
private
fun
showMemberDetails
(
memberViewModel
:
MemberViewModel
)
{
image_bottom_sheet_avatar
.
setImageURI
(
memberViewModel
.
avatarUri
)
text_bottom_sheet_member_name
.
content
=
memberViewModel
.
realName
text_bottom_sheet_member_username
.
content
=
"@${memberViewModel.username}"
val
memberEmail
=
memberViewModel
.
email
if
(
memberEmail
!=
null
)
{
text_member_email_address
.
textContent
=
memberEmail
}
else
{
text_email_address
.
setVisible
(
false
)
text_member_email_address
.
setVisible
(
false
)
}
text_member_utc
.
content
=
memberViewModel
.
utcOffset
.
toString
()
bottomSheetBehavior
.
state
=
BottomSheetBehavior
.
STATE_EXPANDED
}
private
fun
setupToolbar
(
totalMembers
:
Long
)
{
(
activity
as
ChatRoomActivity
).
setupToolbarTitle
(
getString
(
R
.
string
.
title_members
,
totalMembers
))
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/members/viewmodel/MemberViewModel.kt
0 → 100644
View file @
71809156
package
chat.rocket.android.members.viewmodel
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.server.domain.useRealName
import
chat.rocket.common.model.User
import
chat.rocket.core.model.Value
class
MemberViewModel
(
private
val
member
:
User
,
private
val
settings
:
Map
<
String
,
Value
<
Any
>>,
private
val
baseUrl
:
String
?)
{
val
avatarUri
:
String
?
val
displayName
:
String
val
realName
:
String
?
val
username
:
String
?
val
email
:
String
?
val
utcOffset
:
Float
?
init
{
avatarUri
=
getUserAvatar
()
displayName
=
getUserDisplayName
()
realName
=
getUserRealName
()
username
=
getUserUsername
()
email
=
getUserEmail
()
utcOffset
=
getUserUtcOffset
()
}
private
fun
getUserAvatar
():
String
?
{
val
username
=
member
.
username
?:
"?"
return
baseUrl
?.
let
{
UrlHelper
.
getAvatarUrl
(
baseUrl
,
username
)
}
}
private
fun
getUserDisplayName
():
String
{
val
username
=
member
.
username
val
realName
=
member
.
name
val
senderName
=
if
(
settings
.
useRealName
())
realName
else
username
return
senderName
?:
username
.
toString
()
}
private
fun
getUserRealName
():
String
?
=
member
.
name
private
fun
getUserUsername
():
String
?
=
member
.
username
private
fun
getUserEmail
():
String
?
=
member
.
emails
?.
get
(
0
)
?.
address
private
fun
getUserUtcOffset
():
Float
?
=
member
.
utcOffset
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/members/viewmodel/MemberViewModelMapper.kt
0 → 100644
View file @
71809156
package
chat.rocket.android.members.viewmodel
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.GetSettingsInteractor
import
chat.rocket.android.server.domain.baseUrl
import
chat.rocket.common.model.User
import
chat.rocket.core.model.Value
import
javax.inject.Inject
class
MemberViewModelMapper
@Inject
constructor
(
serverInteractor
:
GetCurrentServerInteractor
,
getSettingsInteractor
:
GetSettingsInteractor
)
{
private
var
settings
:
Map
<
String
,
Value
<
Any
>>
=
getSettingsInteractor
.
get
(
serverInteractor
.
get
()
!!
)
!!
private
val
baseUrl
=
settings
.
baseUrl
()
fun
mapToViewModelList
(
memberList
:
List
<
User
>):
List
<
MemberViewModel
>
{
return
memberList
.
map
{
MemberViewModel
(
it
,
settings
,
baseUrl
)
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/util/extensions/Animation.kt
View file @
71809156
...
...
@@ -2,6 +2,7 @@ package chat.rocket.android.util.extensions
import
android.view.View
import
android.view.ViewAnimationUtils
import
android.view.animation.AccelerateInterpolator
import
android.view.animation.DecelerateInterpolator
fun
View
.
rotateBy
(
value
:
Float
,
duration
:
Long
=
100
)
{
...
...
@@ -11,59 +12,46 @@ fun View.rotateBy(value: Float, duration: Long = 100) {
.
start
()
}
fun
View
.
fadeIn
(
start
:
Float
=
0f
,
end
:
Float
=
1f
,
duration
:
Long
=
200
)
{
// already at end alpha, just set visible and return
if
(
alpha
==
end
)
{
fun
View
.
fadeIn
(
startValue
:
Float
=
0f
,
finishValue
:
Float
=
1f
,
duration
:
Long
=
200
)
{
if
(
alpha
==
finishValue
)
{
setVisible
(
true
)
return
}
val
animation
=
animate
()
.
alpha
(
end
)
.
setDuration
(
duration
)
.
setInterpolator
(
DecelerateInterpolator
())
if
(
start
!=
alpha
)
{
animate
()
.
alpha
(
start
)
.
setDuration
(
duration
/
2
)
// half the time, so the entire animation runs on duration
.
setInterpolator
(
DecelerateInterpolator
())
.
withEndAction
{
animation
.
setDuration
(
duration
/
2
).
start
()
}.
start
()
}
else
{
animation
.
start
()
}
animate
()
.
alpha
(
startValue
)
.
setDuration
(
duration
)
.
setInterpolator
(
DecelerateInterpolator
())
.
withEndAction
({
animate
()
.
alpha
(
finishValue
)
.
setDuration
(
duration
)
.
setInterpolator
(
AccelerateInterpolator
()).
start
()
}).
start
()
setVisible
(
true
)
}
fun
View
.
fadeOut
(
start
:
Float
=
1f
,
end
:
Float
=
0f
,
duration
:
Long
=
200
)
{
if
(
alpha
==
end
)
{
fun
View
.
fadeOut
(
start
Value
:
Float
=
1f
,
finishValue
:
Float
=
0f
,
duration
:
Long
=
200
)
{
if
(
alpha
==
finishValue
)
{
setVisible
(
false
)
return
}
val
animation
=
animate
()
.
alpha
(
end
)
.
setDuration
(
duration
)
.
setInterpolator
(
DecelerateInterpolator
())
.
withEndAction
{
setVisible
(
false
)
}
animate
()
.
alpha
(
startValue
)
.
setDuration
(
duration
)
.
setInterpolator
(
DecelerateInterpolator
())
.
withEndAction
({
animate
()
.
alpha
(
finishValue
)
.
setDuration
(
duration
)
.
setInterpolator
(
AccelerateInterpolator
()).
start
()
}).
start
()
if
(
start
!=
alpha
)
{
animate
()
.
alpha
(
start
)
.
setDuration
(
duration
/
2
)
// half the time, so the entire animation runs on duration
.
setInterpolator
(
DecelerateInterpolator
())
.
withEndAction
{
animation
.
setDuration
(
duration
/
2
).
start
()
}.
start
()
}
else
{
animation
.
start
()
}
setVisible
(
false
)
}
fun
View
.
circularRevealOrUnreveal
(
centerX
:
Int
,
centerY
:
Int
,
startRadius
:
Float
,
endRadius
:
Float
,
duration
:
Long
=
200
)
{
val
anim
=
ViewAnimationUtils
.
createCircularReveal
(
this
,
centerX
,
centerY
,
startRadius
,
endRadius
)
anim
.
duration
=
duration
...
...
app/src/main/java/chat/rocket/android/util/extensions/Text.kt
View file @
71809156
...
...
@@ -3,6 +3,7 @@ package chat.rocket.android.util.extensions
import
android.text.Spannable
import
android.text.Spanned
import
android.text.TextUtils
import
android.util.Patterns
import
android.widget.EditText
import
android.widget.TextView
import
chat.rocket.android.widget.emoji.EmojiParser
...
...
@@ -31,6 +32,8 @@ fun EditText.erase() {
}
}
fun
String
.
isEmailValid
():
Boolean
=
Patterns
.
EMAIL_ADDRESS
.
matcher
(
this
).
matches
()
var
TextView
.
textContent
:
String
get
()
=
text
.
toString
()
set
(
value
)
{
...
...
app/src/main/res/drawable/ic_gitlab.xml
View file @
71809156
...
...
@@ -19,58 +19,98 @@
android:strokeWidth=
"1"
/>
<path
android:fillColor=
"#FFFFFF"
android:fillType=
"nonZero"
android:pathData=
"M121.13,18.01L119.97,21.57L117.68,28.64C117.56,29 117.04,29 116.92,28.64L114.63,21.57L107,21.57L104.71,28.64C104.59,29 104.08,29 103.96,28.64L101.66,21.57L100.5,18.01C100.4,17.68 100.51,17.33 100.79,17.12L110.82,9.84L120.84,17.12C121.12,17.33 121.23,17.68 121.13,18.01"
android:strokeColor=
"#00000000"
android:fillAlpha=
"1"
android:fillColor=
"#ffffff"
android:pathData=
"M122.13,22.99L120.97,19.43C119.6,15.19 118.83,12.83 118.68,12.36C118.56,12 118.04,12 117.92,12.36C117.77,12.83 117,15.19 115.63,19.43L108,19.43C106.63,15.19 105.86,12.83 105.71,12.36C105.59,12 105.08,12 104.96,12.36C104.81,12.83 104.04,15.19 102.66,19.43C101.96,21.57 101.58,22.75 101.5,22.99C101.4,23.32 101.51,23.67 101.79,23.88C102.46,24.37 105.8,26.79 111.82,31.16C117.83,26.79 121.17,24.37 121.84,23.88C122.12,23.67 122.23,23.32 122.13,22.99"
/>
<path
android:fillAlpha=
"0"
android:fillColor=
"#FF000000"
android:pathData=
"M122.13,22.99L120.97,19.43C119.6,15.19 118.83,12.83 118.68,12.36C118.56,12 118.04,12 117.92,12.36C117.77,12.83 117,15.19 115.63,19.43L108,19.43C106.63,15.19 105.86,12.83 105.71,12.36C105.59,12 105.08,12 104.96,12.36C104.81,12.83 104.04,15.19 102.66,19.43C101.96,21.57 101.58,22.75 101.5,22.99C101.4,23.32 101.51,23.67 101.79,23.88C102.46,24.37 105.8,26.79 111.82,31.16C117.83,26.79 121.17,24.37 121.84,23.88C122.12,23.67 122.23,23.32 122.13,22.99"
android:strokeAlpha=
"0"
android:strokeColor=
"#000000"
android:strokeWidth=
"1"
/>
<path
android:fillColor=
"#FFFFFF"
android:fillType=
"nonZero"
android:pathData=
"M110.82,9.84l0,0l3.81,11.73l-7.62,0z"
android:strokeColor=
"#00000000"
android:fillAlpha=
"1"
android:fillColor=
"#ffffff"
android:pathData=
"M111.82,31.16L111.82,31.16L115.63,19.43L108.01,19.43L111.82,31.16Z"
/>
<path
android:fillAlpha=
"0"
android:fillColor=
"#FF000000"
android:pathData=
"M111.82,31.16L111.82,31.16L115.63,19.43L108.01,19.43L111.82,31.16Z"
android:strokeAlpha=
"0"
android:strokeColor=
"#000000"
android:strokeWidth=
"1"
/>
<path
android:fillColor=
"#FFFFFF"
android:fillType=
"nonZero"
android:pathData=
"M110.82,9.84l-3.81,11.73l-5.34,0z"
android:strokeColor=
"#00000000"
android:fillAlpha=
"1"
android:fillColor=
"#ffffff"
android:pathData=
"M111.82,31.16L108.01,19.43L102.67,19.43L111.82,31.16Z"
/>
<path
android:fillAlpha=
"0"
android:fillColor=
"#FF000000"
android:pathData=
"M111.82,31.16L108.01,19.43L102.67,19.43L111.82,31.16Z"
android:strokeAlpha=
"0"
android:strokeColor=
"#000000"
android:strokeWidth=
"1"
/>
<path
android:fillColor=
"#FFFFFF"
android:fillType=
"nonZero"
android:pathData=
"M101.66,21.57L101.66,21.57L100.5,18.01C100.4,17.68 100.51,17.33 100.79,17.12L110.82,9.84L101.66,21.57L101.66,21.57Z"
android:strokeColor=
"#00000000"
android:fillAlpha=
"1"
android:fillColor=
"#ffffff"
android:pathData=
"M102.66,19.43C101.96,21.57 101.58,22.75 101.5,22.99C101.4,23.32 101.51,23.67 101.79,23.88C102.46,24.37 105.8,26.79 111.82,31.16L102.66,19.43L102.66,19.43L102.66,19.43Z"
/>
<path
android:fillAlpha=
"0"
android:fillColor=
"#FF000000"
android:pathData=
"M102.66,19.43C101.96,21.57 101.58,22.75 101.5,22.99C101.4,23.32 101.51,23.67 101.79,23.88C102.46,24.37 105.8,26.79 111.82,31.16L102.66,19.43L102.66,19.43L102.66,19.43Z"
android:strokeAlpha=
"0"
android:strokeColor=
"#000000"
android:strokeWidth=
"1"
/>
<path
android:fillColor=
"#FFFFFF"
android:fillType=
"nonZero"
android:pathData=
"M101.66,21.57L107,21.57L104.71,28.64C104.59,29 104.08,29 103.96,28.64L101.66,21.57L101.66,21.57Z"
android:strokeColor=
"#00000000"
android:fillAlpha=
"1"
android:fillColor=
"#ffffff"
android:pathData=
"M108,19.43C106.63,15.19 105.86,12.83 105.71,12.36C105.59,12 105.08,12 104.96,12.36C104.81,12.83 104.04,15.19 102.66,19.43L102.66,19.43L108,19.43Z"
/>
<path
android:fillAlpha=
"0"
android:fillColor=
"#FF000000"
android:pathData=
"M108,19.43C106.63,15.19 105.86,12.83 105.71,12.36C105.59,12 105.08,12 104.96,12.36C104.81,12.83 104.04,15.19 102.66,19.43L102.66,19.43L108,19.43Z"
android:strokeAlpha=
"0"
android:strokeColor=
"#000000"
android:strokeWidth=
"1"
/>
<path
android:fillColor=
"#FFFFFF"
android:fillType=
"nonZero"
android:pathData=
"M110.82,9.84l3.81,11.73l5.34,0z"
android:strokeColor=
"#00000000"
android:fillAlpha=
"1"
android:fillColor=
"#ffffff"
android:pathData=
"M111.82,31.16L115.63,19.43L120.97,19.43L111.82,31.16Z"
/>
<path
android:fillAlpha=
"0"
android:fillColor=
"#FF000000"
android:pathData=
"M111.82,31.16L115.63,19.43L120.97,19.43L111.82,31.16Z"
android:strokeAlpha=
"0"
android:strokeColor=
"#000000"
android:strokeWidth=
"1"
/>
<path
android:fillColor=
"#FFFFFF"
android:fillType=
"nonZero"
android:pathData=
"M119.97,21.57L119.97,21.57L121.13,18.01C121.24,17.68 121.12,17.33 120.84,17.12L110.82,9.84L119.97,21.57L119.97,21.57Z"
android:strokeColor=
"#00000000"
android:fillAlpha=
"1"
android:fillColor=
"#ffffff"
android:pathData=
"M120.97,19.43C121.67,21.57 122.05,22.75 122.13,22.99C122.24,23.32 122.12,23.67 121.84,23.88C121.17,24.37 117.83,26.79 111.82,31.16L120.97,19.43L120.97,19.43L120.97,19.43Z"
/>
<path
android:fillAlpha=
"0"
android:fillColor=
"#FF000000"
android:pathData=
"M120.97,19.43C121.67,21.57 122.05,22.75 122.13,22.99C122.24,23.32 122.12,23.67 121.84,23.88C121.17,24.37 117.83,26.79 111.82,31.16L120.97,19.43L120.97,19.43L120.97,19.43Z"
android:strokeAlpha=
"0"
android:strokeColor=
"#000000"
android:strokeWidth=
"1"
/>
<path
android:fillColor=
"#FFFFFF"
android:fillType=
"nonZero"
android:pathData=
"M119.97,21.57L114.63,21.57L116.92,28.64C117.04,29 117.56,29 117.68,28.64L119.97,21.57L119.97,21.57Z"
android:strokeColor=
"#00000000"
android:fillAlpha=
"1"
android:fillColor=
"#ffffff"
android:pathData=
"M115.63,19.43C117,15.19 117.77,12.83 117.92,12.36C118.04,12 118.56,12 118.68,12.36C118.83,12.83 119.6,15.19 120.97,19.43L120.97,19.43L115.63,19.43Z"
/>
<path
android:fillAlpha=
"0"
android:fillColor=
"#FF000000"
android:pathData=
"M115.63,19.43C117,15.19 117.77,12.83 117.92,12.36C118.04,12 118.56,12 118.68,12.36C118.83,12.83 119.6,15.19 120.97,19.43L120.97,19.43L115.63,19.43Z"
android:strokeAlpha=
"0"
android:strokeColor=
"#000000"
android:strokeWidth=
"1"
/>
</vector>
\ No newline at end of file
app/src/main/res/layout/fragment_authentication_server.xml
View file @
71809156
...
...
@@ -32,7 +32,7 @@
android:cursorVisible=
"false"
android:hint=
"@string/default_server"
android:imeOptions=
"actionDone"
android:digits=
"0123456789abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
.-/:"
android:digits=
"0123456789abcdefghijklmnopqrstuvwxyz.-/:"
android:inputType=
"textUri"
android:paddingEnd=
"0dp"
android:paddingStart=
"0dp"
/>
...
...
@@ -52,4 +52,4 @@
android:layout_alignParentBottom=
"true"
android:text=
"@string/action_connect"
/>
</RelativeLayout>
\ No newline at end of file
</RelativeLayout>
app/src/main/res/layout/fragment_members.xml
0 → 100644
View file @
71809156
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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=
"match_parent"
tools:context=
".members.ui.MembersFragment"
>
<android.support.v7.widget.RecyclerView
android:id=
"@+id/recycler_view"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
/>
<include
layout=
"@layout/member_bottom_sheet"
/>
<com.wang.avi.AVLoadingIndicatorView
android:id=
"@+id/view_loading"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
android:layout_centerInParent=
"true"
app:indicatorColor=
"@color/black"
app:indicatorName=
"BallPulseIndicator"
/>
</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
app/src/main/res/layout/item_member.xml
0 → 100644
View file @
71809156
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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:layout_marginBottom=
"6dp"
android:layout_marginEnd=
"@dimen/screen_edge_left_and_right_margins"
android:layout_marginStart=
"@dimen/screen_edge_left_and_right_margins"
android:layout_marginTop=
"6dp"
>
<include
android:id=
"@+id/layout_avatar"
layout=
"@layout/avatar"
android:layout_width=
"40dp"
android:layout_height=
"40dp"
app:layout_constraintLeft_toLeftOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
/>
<TextView
android:id=
"@+id/text_member"
style=
"@style/Sender.Name.TextView"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"16dp"
app:layout_constraintBottom_toBottomOf=
"@+id/layout_avatar"
app:layout_constraintLeft_toRightOf=
"@+id/layout_avatar"
app:layout_constraintTop_toTopOf=
"@+id/layout_avatar"
tools:text=
"Ronald Perkins"
/>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
app/src/main/res/layout/member_bottom_sheet.xml
0 → 100644
View file @
71809156
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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:id=
"@+id/member_bottom_sheet"
android:layout_width=
"match_parent"
android:layout_height=
"340dp"
app:behavior_hideable=
"true"
app:behavior_peekHeight=
"0dp"
app:layout_behavior=
"android.support.design.widget.BottomSheetBehavior"
>
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/image_bottom_sheet_avatar"
android:layout_width=
"match_parent"
android:layout_height=
"200dp"
/>
<TextView
android:id=
"@+id/text_bottom_sheet_member_name"
style=
"@style/TextAppearance.AppCompat.Title"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"16dp"
android:textColor=
"@color/white"
app:layout_constraintBottom_toTopOf=
"@+id/text_bottom_sheet_member_username"
app:layout_constraintLeft_toLeftOf=
"parent"
tools:text=
"Ronald Perkins"
/>
<TextView
android:id=
"@+id/text_bottom_sheet_member_username"
style=
"@style/Sender.Name.TextView"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginBottom=
"10dp"
android:layout_marginStart=
"16dp"
android:textColor=
"@color/white"
app:layout_constraintBottom_toBottomOf=
"@+id/image_bottom_sheet_avatar"
app:layout_constraintLeft_toLeftOf=
"parent"
tools:text=
"\@ronaldPerkins"
/>
<TextView
android:id=
"@+id/text_email_address"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"16dp"
android:layout_marginTop=
"16dp"
android:text=
"@string/msg_email_address"
app:layout_constraintLeft_toLeftOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/image_bottom_sheet_avatar"
/>
<TextView
android:id=
"@+id/text_member_email_address"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"16dp"
android:layout_marginTop=
"10dp"
android:textColor=
"@color/colorPrimaryText"
app:layout_constraintLeft_toLeftOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/text_email_address"
tools:text=
"ronald@perkins.com"
/>
<TextView
android:id=
"@+id/text_utc"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"16dp"
android:layout_marginTop=
"16dp"
android:text=
"@string/msg_utc_offset"
app:layout_constraintLeft_toLeftOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/text_member_email_address"
/>
<TextView
android:id=
"@+id/text_member_utc"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"16dp"
android:layout_marginTop=
"10dp"
android:textColor=
"@color/colorPrimaryText"
app:layout_constraintLeft_toLeftOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/text_utc"
tools:text=
"+01:00"
/>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
app/src/main/res/menu/chatroom_actions.xml
View file @
71809156
...
...
@@ -2,6 +2,11 @@
<menu
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
>
<item
android:id=
"@+id/action_members_list"
android:title=
"@string/title_members_list"
app:showAsAction=
"never"
/>
<item
android:id=
"@+id/action_pinned_messages"
android:title=
"@string/title_pinned_messages"
...
...
app/src/main/res/values-pt-rBR/strings.xml
View file @
71809156
...
...
@@ -7,6 +7,7 @@
<string
name=
"title_legal_terms"
>
Termos Legais
</string>
<string
name=
"title_chats"
>
Chats
</string>
<string
name=
"title_profile"
>
Perfil
</string>
<string
name=
"title_members"
>
Membros (%d)
</string>
<string
name=
"title_update_profile"
>
Editar perfil
</string>
<!-- Actions -->
...
...
@@ -50,6 +51,8 @@
<string
name=
"msg_content_description_show_attachment_options"
>
Mostrar opções de anexo
</string>
<string
name=
"msg_you"
>
Você
</string>
<string
name=
"msg_unknown"
>
Desconhecido
</string>
<string
name=
"msg_email_address"
>
Endereço de e-mail
</string>
<string
name=
"msg_utc_offset"
>
Deslocamento de UTC
</string>
<!-- System messages -->
<string
name=
"message_room_name_changed"
>
Nome da sala alterado para: %1$s por %2$s
</string>
...
...
@@ -78,6 +81,9 @@
<string
name=
"permission_deleting_not_allowed"
>
Remoção não permitida
</string>
<string
name=
"permission_pinning_not_allowed"
>
Fixar não permitido
</string>
<!-- Members List -->
<string
name=
"title_members_list"
>
Lista de Membros
</string>
<!-- Pinned Messages -->
<string
name=
"title_pinned_messages"
>
Mensagens Pinadas
</string>
...
...
app/src/main/res/values/strings.xml
View file @
71809156
...
...
@@ -8,6 +8,7 @@
<string
name=
"title_legal_terms"
>
Legal Terms
</string>
<string
name=
"title_chats"
>
Chats
</string>
<string
name=
"title_profile"
>
Profile
</string>
<string
name=
"title_members"
>
Members (%d)
</string>
<string
name=
"title_update_profile"
>
Update profile
</string>
<!-- Actions -->
...
...
@@ -52,6 +53,8 @@
<string
name=
"msg_content_description_show_attachment_options"
>
Show attachment options
</string>
<string
name=
"msg_you"
>
You
</string>
<string
name=
"msg_unknown"
>
Unknown
</string>
<string
name=
"msg_email_address"
>
E-mail address
</string>
<string
name=
"msg_utc_offset"
>
UTC offset
</string>
<!-- System messages -->
<string
name=
"message_room_name_changed"
>
Room name changed to: %1$s by %2$s
</string>
...
...
@@ -80,6 +83,9 @@
<string
name=
"permission_deleting_not_allowed"
>
Deleting is not allowed
</string>
<string
name=
"permission_pinning_not_allowed"
>
Pinning is not allowed
</string>
<!-- Members List -->
<string
name=
"title_members_list"
>
Members List
</string>
<!-- Pinned Messages -->
<string
name=
"title_pinned_messages"
>
Pinned Messages
</string>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment