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
55ec0626
Commit
55ec0626
authored
Jul 24, 2018
by
Filipe de Lima Brito
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adds the upload avatar feature.
From gallery or by instantly taking a photo
parent
671b9393
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
270 additions
and
100 deletions
+270
-100
ChatRoomFragment.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
+0
-1
DatabaseManager.kt
app/src/main/java/chat/rocket/android/db/DatabaseManager.kt
+2
-2
MainActivity.kt
...src/main/java/chat/rocket/android/main/ui/MainActivity.kt
+5
-1
ProfilePresenter.kt
...t/rocket/android/profile/presentation/ProfilePresenter.kt
+77
-27
ProfileView.kt
...a/chat/rocket/android/profile/presentation/ProfileView.kt
+7
-0
ProfileFragment.kt
...in/java/chat/rocket/android/profile/ui/ProfileFragment.kt
+77
-40
ic_image_black_24dp.xml
app/src/main/res/drawable/ic_image_black_24dp.xml
+10
-0
ic_link_black_24dp.xml
app/src/main/res/drawable/ic_link_black_24dp.xml
+0
-10
ic_photo_camera_black_24dp.xml
app/src/main/res/drawable/ic_photo_camera_black_24dp.xml
+13
-0
fragment_member_bottom_sheet.xml
app/src/main/res/layout/fragment_member_bottom_sheet.xml
+1
-1
fragment_profile.xml
app/src/main/res/layout/fragment_profile.xml
+17
-11
update_avatar_options.xml
app/src/main/res/layout/update_avatar_options.xml
+28
-0
strings.xml
app/src/main/res/values-es/strings.xml
+4
-3
strings.xml
app/src/main/res/values-fr/strings.xml
+4
-4
strings.xml
app/src/main/res/values-hi-rIN/strings.xml
+2
-0
strings.xml
app/src/main/res/values-pt-rBR/strings.xml
+2
-0
strings.xml
app/src/main/res/values-ru/strings.xml
+2
-0
strings.xml
app/src/main/res/values/strings.xml
+2
-0
Image.kt
...src/main/java/chat/rocket/android/util/extension/Image.kt
+17
-0
No files found.
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
View file @
55ec0626
...
@@ -12,7 +12,6 @@ import android.text.SpannableStringBuilder
...
@@ -12,7 +12,6 @@ import android.text.SpannableStringBuilder
import
android.view.KeyEvent
import
android.view.KeyEvent
import
android.view.LayoutInflater
import
android.view.LayoutInflater
import
android.view.Menu
import
android.view.Menu
import
android.view.MenuInflater
import
android.view.MenuItem
import
android.view.MenuItem
import
android.view.View
import
android.view.View
import
android.view.ViewGroup
import
android.view.ViewGroup
...
...
app/src/main/java/chat/rocket/android/db/DatabaseManager.kt
View file @
55ec0626
...
@@ -249,7 +249,7 @@ class DatabaseManager(val context: Application,
...
@@ -249,7 +249,7 @@ class DatabaseManager(val context: Application,
id
=
roomId
,
id
=
roomId
,
subscriptionId
=
id
,
subscriptionId
=
id
,
type
=
type
.
toString
(),
type
=
type
.
toString
(),
name
=
name
,
name
=
name
?:
""
,
fullname
=
fullName
?:
chatRoom
.
fullname
,
fullname
=
fullName
?:
chatRoom
.
fullname
,
userId
=
userId
?:
chatRoom
.
userId
,
userId
=
userId
?:
chatRoom
.
userId
,
readonly
=
readonly
?:
chatRoom
.
readonly
,
readonly
=
readonly
?:
chatRoom
.
readonly
,
...
@@ -330,7 +330,7 @@ class DatabaseManager(val context: Application,
...
@@ -330,7 +330,7 @@ class DatabaseManager(val context: Application,
id
=
room
.
id
,
id
=
room
.
id
,
subscriptionId
=
subscription
.
id
,
subscriptionId
=
subscription
.
id
,
type
=
room
.
type
.
toString
(),
type
=
room
.
type
.
toString
(),
name
=
room
.
name
?:
subscription
.
name
,
name
=
room
.
name
?:
subscription
.
name
?:
""
,
fullname
=
subscription
.
fullName
?:
room
.
fullName
,
fullname
=
subscription
.
fullName
?:
room
.
fullName
,
userId
=
userId
,
userId
=
userId
,
ownerId
=
room
.
user
?.
id
,
ownerId
=
room
.
user
?.
id
,
...
...
app/src/main/java/chat/rocket/android/main/ui/MainActivity.kt
View file @
55ec0626
...
@@ -132,7 +132,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
...
@@ -132,7 +132,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
text_user_name
.
text
=
userDisplayName
text_user_name
.
text
=
userDisplayName
}
}
if
(
userAvatar
!=
null
)
{
if
(
userAvatar
!=
null
)
{
image_avatar
.
setImageURI
(
userAvatar
)
setAvatar
(
userAvatar
)
}
}
if
(
serverLogo
!=
null
)
{
if
(
serverLogo
!=
null
)
{
server_logo
.
setImageURI
(
serverLogo
)
server_logo
.
setImageURI
(
serverLogo
)
...
@@ -253,6 +253,10 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
...
@@ -253,6 +253,10 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
}
}
}
}
fun
setAvatar
(
avatarUrl
:
String
)
{
headerLayout
.
image_avatar
.
setImageURI
(
avatarUrl
)
}
fun
getDrawerLayout
():
DrawerLayout
=
drawer_layout
fun
getDrawerLayout
():
DrawerLayout
=
drawer_layout
fun
openDrawer
()
=
drawer_layout
.
openDrawer
(
Gravity
.
START
)
fun
openDrawer
()
=
drawer_layout
.
openDrawer
(
Gravity
.
START
)
...
...
app/src/main/java/chat/rocket/android/profile/presentation/ProfilePresenter.kt
View file @
55ec0626
package
chat.rocket.android.profile.presentation
package
chat.rocket.android.profile.presentation
import
android.graphics.Bitmap
import
android.net.Uri
import
chat.rocket.android.chatroom.domain.UriInteractor
import
chat.rocket.android.core.behaviours.showMessage
import
chat.rocket.android.core.behaviours.showMessage
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.helper.UserHelper
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extension.compressImageAndGetByteArray
import
chat.rocket.android.util.extension.launchUI
import
chat.rocket.android.util.extension.launchUI
import
chat.rocket.android.util.extensions.avatarUrl
import
chat.rocket.android.util.extensions.avatarUrl
import
chat.rocket.android.util.retryIO
import
chat.rocket.android.util.retryIO
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.util.ifNull
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.rest.me
import
chat.rocket.core.internal.rest.setAvatar
import
chat.rocket.core.internal.rest.setAvatar
import
chat.rocket.core.internal.rest.updateProfile
import
chat.rocket.core.internal.rest.updateProfile
import
java.util.*
import
javax.inject.Inject
import
javax.inject.Inject
class
ProfilePresenter
@Inject
constructor
(
class
ProfilePresenter
@Inject
constructor
(
private
val
view
:
ProfileView
,
private
val
view
:
ProfileView
,
private
val
strategy
:
CancelStrategy
,
private
val
strategy
:
CancelStrategy
,
private
val
uriInteractor
:
UriInteractor
,
val
userHelper
:
UserHelper
,
serverInteractor
:
GetCurrentServerInteractor
,
serverInteractor
:
GetCurrentServerInteractor
,
factory
:
RocketChatClientFactory
factory
:
RocketChatClientFactory
)
{
)
{
private
val
serverUrl
=
serverInteractor
.
get
()
!!
private
val
serverUrl
=
serverInteractor
.
get
()
!!
private
val
client
:
RocketChatClient
=
factory
.
create
(
serverUrl
)
private
val
client
:
RocketChatClient
=
factory
.
create
(
serverUrl
)
private
lateinit
var
myselfId
:
String
private
val
myselfId
=
userHelper
.
user
()
?.
id
?:
""
private
var
myselfName
=
userHelper
.
user
()
?.
name
?:
""
private
var
myselfUsername
=
userHelper
.
username
()
?:
""
private
var
myselfEmailAddress
=
userHelper
.
user
()
?.
emails
?.
getOrNull
(
0
)
?.
address
?:
""
fun
loadUserProfile
()
{
fun
loadUserProfile
()
{
launchUI
(
strategy
)
{
launchUI
(
strategy
)
{
view
.
showLoading
()
view
.
showLoading
()
try
{
try
{
val
myself
=
retryIO
(
"me"
)
{
client
.
me
()
}
view
.
showProfile
(
val
id
=
myself
.
id
serverUrl
.
avatarUrl
(
myselfUsername
),
val
username
=
myself
.
username
myselfName
,
if
(
id
==
null
||
username
==
null
)
{
myselfUsername
,
view
.
showGenericErrorMessage
()
myselfEmailAddress
}
else
{
)
myselfId
=
id
val
avatarUrl
=
serverUrl
.
avatarUrl
(
username
)
val
email
=
myself
.
emails
?.
getOrNull
(
0
)
?.
address
view
.
showProfile
(
avatarUrl
,
myself
.
name
?:
""
,
myself
.
username
?:
""
,
email
)
}
}
catch
(
exception
:
RocketChatException
)
{
}
catch
(
exception
:
RocketChatException
)
{
view
.
showMessage
(
exception
)
view
.
showMessage
(
exception
)
}
finally
{
}
finally
{
...
@@ -53,18 +53,16 @@ class ProfilePresenter @Inject constructor(
...
@@ -53,18 +53,16 @@ class ProfilePresenter @Inject constructor(
}
}
}
}
fun
updateUserProfile
(
email
:
String
,
name
:
String
,
username
:
String
,
avatarUrl
:
String
=
""
)
{
fun
updateUserProfile
(
email
:
String
,
name
:
String
,
username
:
String
)
{
launchUI
(
strategy
)
{
launchUI
(
strategy
)
{
view
.
showLoading
()
view
.
showLoading
()
try
{
try
{
if
(
avatarUrl
!=
""
)
{
retryIO
{
client
.
updateProfile
(
myselfId
,
email
,
name
,
username
)
}
retryIO
{
client
.
setAvatar
(
avatarUrl
)
}
}
myselfEmailAddress
=
email
val
user
=
retryIO
{
myselfName
=
name
client
.
updateProfile
(
myselfUsername
=
username
userId
=
myselfId
,
email
=
email
,
name
=
name
,
username
=
username
)
}
view
.
showProfileUpdateSuccessfullyMessage
()
view
.
showProfileUpdateSuccessfullyMessage
()
loadUserProfile
()
loadUserProfile
()
}
catch
(
exception
:
RocketChatException
)
{
}
catch
(
exception
:
RocketChatException
)
{
...
@@ -78,4 +76,56 @@ class ProfilePresenter @Inject constructor(
...
@@ -78,4 +76,56 @@ class ProfilePresenter @Inject constructor(
}
}
}
}
}
}
fun
updateAvatar
(
uri
:
Uri
)
{
launchUI
(
strategy
)
{
view
.
showLoading
()
try
{
retryIO
{
client
.
setAvatar
(
uriInteractor
.
getFileName
(
uri
)
?:
uri
.
toString
(),
uriInteractor
.
getMimeType
(
uri
)
)
{
uriInteractor
.
getInputStream
(
uri
)
}
}
view
.
reloadUserAvatar
(
serverUrl
.
avatarUrl
(
myselfUsername
))
}
catch
(
exception
:
RocketChatException
)
{
exception
.
message
?.
let
{
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
}
}
finally
{
view
.
hideLoading
()
}
}
}
fun
preparePhotoAndUpdateAvatar
(
bitmap
:
Bitmap
)
{
launchUI
(
strategy
)
{
view
.
showLoading
()
try
{
val
byteArray
=
bitmap
.
compressImageAndGetByteArray
(
"image/png"
)
retryIO
{
client
.
setAvatar
(
UUID
.
randomUUID
().
toString
()
+
".png"
,
"image/png"
)
{
byteArray
?.
inputStream
()
}
}
view
.
reloadUserAvatar
(
serverUrl
.
avatarUrl
(
myselfUsername
))
}
catch
(
exception
:
RocketChatException
)
{
exception
.
message
?.
let
{
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
}
}
finally
{
view
.
hideLoading
()
}
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/profile/presentation/ProfileView.kt
View file @
55ec0626
...
@@ -15,6 +15,13 @@ interface ProfileView : LoadingView, MessageView {
...
@@ -15,6 +15,13 @@ interface ProfileView : LoadingView, MessageView {
*/
*/
fun
showProfile
(
avatarUrl
:
String
,
name
:
String
,
username
:
String
,
email
:
String
?)
fun
showProfile
(
avatarUrl
:
String
,
name
:
String
,
username
:
String
,
email
:
String
?)
/**
* Reloads the user avatar (after successfully updating it).
*
* @param avatarUrl The user avatar URL.
*/
fun
reloadUserAvatar
(
avatarUrl
:
String
)
/**
/**
* Shows a profile update successfully message
* Shows a profile update successfully message
*/
*/
...
...
app/src/main/java/chat/rocket/android/profile/ui/ProfileFragment.kt
View file @
55ec0626
package
chat.rocket.android.profile.ui
package
chat.rocket.android.profile.ui
import
DrawableHelper
import
DrawableHelper
import
android.app.Activity
import
android.content.Intent
import
android.graphics.Bitmap
import
android.os.Build
import
android.os.Build
import
android.os.Bundle
import
android.os.Bundle
import
androidx.fragment.app.Fragment
import
androidx.appcompat.view.ActionMode
import
android.view.*
import
android.view.*
import
androidx.appcompat.app.AppCompatActivity
import
androidx.appcompat.app.AppCompatActivity
import
androidx.appcompat.view.ActionMode
import
androidx.core.net.toUri
import
androidx.core.view.isVisible
import
androidx.fragment.app.Fragment
import
chat.rocket.android.R
import
chat.rocket.android.R
import
chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.profile.presentation.ProfilePresenter
import
chat.rocket.android.profile.presentation.ProfilePresenter
import
chat.rocket.android.profile.presentation.ProfileView
import
chat.rocket.android.profile.presentation.ProfileView
import
chat.rocket.android.util.extension.asObservable
import
chat.rocket.android.util.extension.asObservable
import
chat.rocket.android.util.extensions.*
import
chat.rocket.android.util.extension.dispatchImageSelection
import
chat.rocket.android.util.extension.dispatchTakePicture
import
chat.rocket.android.util.extensions.inflate
import
chat.rocket.android.util.extensions.showToast
import
chat.rocket.android.util.extensions.textContent
import
chat.rocket.android.util.extensions.ui
import
com.facebook.drawee.backends.pipeline.Fresco
import
dagger.android.support.AndroidSupportInjection
import
dagger.android.support.AndroidSupportInjection
import
io.reactivex.disposables.CompositeDisposable
import
io.reactivex.disposables.CompositeDisposable
import
io.reactivex.disposables.Disposable
import
io.reactivex.rxkotlin.Observables
import
io.reactivex.rxkotlin.Observables
import
kotlinx.android.synthetic.main.avatar_profile.*
import
kotlinx.android.synthetic.main.avatar_profile.*
import
kotlinx.android.synthetic.main.fragment_profile.*
import
kotlinx.android.synthetic.main.fragment_profile.*
import
kotlinx.android.synthetic.main.update_avatar_options.*
import
javax.inject.Inject
import
javax.inject.Inject
private
const
val
REQUEST_CODE_FOR_PERFORM_SAF
=
1
private
const
val
REQUEST_CODE_FOR_PERFORM_CAMERA
=
2
class
ProfileFragment
:
Fragment
(),
ProfileView
,
ActionMode
.
Callback
{
class
ProfileFragment
:
Fragment
(),
ProfileView
,
ActionMode
.
Callback
{
@Inject
@Inject
lateinit
var
presenter
:
ProfilePresenter
lateinit
var
presenter
:
ProfilePresenter
private
lateinit
var
currentName
:
String
private
var
currentName
=
""
private
lateinit
var
currentUsername
:
String
private
var
currentUsername
=
""
private
lateinit
var
currentEmail
:
String
private
var
currentEmail
=
""
private
lateinit
var
currentAvatar
:
String
private
var
actionMode
:
ActionMode
?
=
null
private
var
actionMode
:
ActionMode
?
=
null
private
val
editTextsDisposable
=
CompositeDisposable
()
private
val
editTextsDisposable
=
CompositeDisposable
()
...
@@ -50,11 +63,12 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
...
@@ -50,11 +63,12 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
super
.
onViewCreated
(
view
,
savedInstanceState
)
super
.
onViewCreated
(
view
,
savedInstanceState
)
setupToolbar
()
setupToolbar
()
setupListeners
()
if
(
Build
.
VERSION
.
SDK_INT
<=
Build
.
VERSION_CODES
.
M
)
{
if
(
Build
.
VERSION
.
SDK_INT
<=
Build
.
VERSION_CODES
.
M
)
{
tintEditTextDrawableStart
()
tintEditTextDrawableStart
()
}
}
presenter
.
loadUserProfile
()
presenter
.
loadUserProfile
()
subscribeEditTexts
()
}
}
override
fun
onDestroyView
()
{
override
fun
onDestroyView
()
{
...
@@ -62,56 +76,61 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
...
@@ -62,56 +76,61 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
unsubscribeEditTexts
()
unsubscribeEditTexts
()
}
}
override
fun
onActivityResult
(
requestCode
:
Int
,
resultCode
:
Int
,
resultData
:
Intent
?)
{
if
(
resultData
!=
null
&&
resultCode
==
Activity
.
RESULT_OK
)
{
if
(
requestCode
==
REQUEST_CODE_FOR_PERFORM_SAF
)
{
presenter
.
updateAvatar
(
resultData
.
data
)
}
else
if
(
requestCode
==
REQUEST_CODE_FOR_PERFORM_CAMERA
)
{
presenter
.
preparePhotoAndUpdateAvatar
(
resultData
.
extras
[
"data"
]
as
Bitmap
)
}
}
}
override
fun
showProfile
(
avatarUrl
:
String
,
name
:
String
,
username
:
String
,
email
:
String
?)
{
override
fun
showProfile
(
avatarUrl
:
String
,
name
:
String
,
username
:
String
,
email
:
String
?)
{
ui
{
ui
{
image_avatar
.
setImageURI
(
avatarUrl
)
image_avatar
.
setImageURI
(
avatarUrl
)
text_name
.
textContent
=
name
text_name
.
textContent
=
name
text_username
.
textContent
=
username
text_username
.
textContent
=
username
text_email
.
textContent
=
email
?:
""
text_email
.
textContent
=
email
?:
""
text_avatar_url
.
textContent
=
""
currentName
=
name
currentName
=
name
currentUsername
=
username
currentUsername
=
username
currentEmail
=
email
?:
""
currentEmail
=
email
?:
""
currentAvatar
=
avatarUrl
profile_container
.
setVisible
(
true
)
subscribeEditTexts
()
profile_container
.
isVisible
=
true
}
}
}
}
override
fun
reloadUserAvatar
(
avatarUrl
:
String
)
{
Fresco
.
getImagePipeline
().
evictFromCache
(
avatarUrl
.
toUri
())
image_avatar
.
setImageURI
(
avatarUrl
)
(
activity
as
MainActivity
).
setAvatar
(
avatarUrl
)
}
override
fun
showProfileUpdateSuccessfullyMessage
()
{
override
fun
showProfileUpdateSuccessfullyMessage
()
{
showMessage
(
getString
(
R
.
string
.
msg_profile_update_successfully
))
showMessage
(
getString
(
R
.
string
.
msg_profile_update_successfully
))
}
}
override
fun
showLoading
()
{
override
fun
showLoading
()
{
enableUserInput
(
false
)
enableUserInput
(
false
)
ui
{
ui
{
view_loading
.
isVisible
=
true
}
view_loading
.
setVisible
(
true
)
}
}
}
override
fun
hideLoading
()
{
override
fun
hideLoading
()
{
ui
{
ui
{
if
(
view_loading
!=
null
)
{
if
(
view_loading
!=
null
)
{
view_loading
.
setVisible
(
false
)
view_loading
.
isVisible
=
false
}
}
}
}
enableUserInput
(
true
)
enableUserInput
(
true
)
}
}
override
fun
showMessage
(
resId
:
Int
)
{
override
fun
showMessage
(
resId
:
Int
)
{
ui
{
ui
{
showToast
(
resId
)
}
showToast
(
resId
)
}
}
}
override
fun
showMessage
(
message
:
String
)
{
override
fun
showMessage
(
message
:
String
)
{
ui
{
ui
{
showToast
(
message
)
}
showToast
(
message
)
}
}
}
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
...
@@ -130,8 +149,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
...
@@ -130,8 +149,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
presenter
.
updateUserProfile
(
presenter
.
updateUserProfile
(
text_email
.
textContent
,
text_email
.
textContent
,
text_name
.
textContent
,
text_name
.
textContent
,
text_username
.
textContent
,
text_username
.
textContent
text_avatar_url
.
textContent
)
)
mode
.
finish
()
mode
.
finish
()
true
true
...
@@ -151,6 +169,32 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
...
@@ -151,6 +169,32 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
getString
(
R
.
string
.
title_profile
)
getString
(
R
.
string
.
title_profile
)
}
}
private
fun
setupListeners
()
{
image_avatar
.
setOnClickListener
{
showUpdateAvatarOptions
()
}
view_dim
.
setOnClickListener
{
hideUpdateAvatarOptions
()
}
button_open_gallery
.
setOnClickListener
{
dispatchImageSelection
(
REQUEST_CODE_FOR_PERFORM_SAF
)
hideUpdateAvatarOptions
()
}
button_take_photo
.
setOnClickListener
{
dispatchTakePicture
(
REQUEST_CODE_FOR_PERFORM_CAMERA
)
hideUpdateAvatarOptions
()
}
}
private
fun
showUpdateAvatarOptions
()
{
view_dim
.
isVisible
=
true
layout_update_avatar_options
.
isVisible
=
true
}
private
fun
hideUpdateAvatarOptions
()
{
layout_update_avatar_options
.
isVisible
=
false
view_dim
.
isVisible
=
false
}
private
fun
tintEditTextDrawableStart
()
{
private
fun
tintEditTextDrawableStart
()
{
(
activity
as
MainActivity
).
apply
{
(
activity
as
MainActivity
).
apply
{
val
personDrawable
=
val
personDrawable
=
...
@@ -158,14 +202,12 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
...
@@ -158,14 +202,12 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
val
atDrawable
=
DrawableHelper
.
getDrawableFromId
(
R
.
drawable
.
ic_at_black_24dp
,
this
)
val
atDrawable
=
DrawableHelper
.
getDrawableFromId
(
R
.
drawable
.
ic_at_black_24dp
,
this
)
val
emailDrawable
=
val
emailDrawable
=
DrawableHelper
.
getDrawableFromId
(
R
.
drawable
.
ic_email_black_24dp
,
this
)
DrawableHelper
.
getDrawableFromId
(
R
.
drawable
.
ic_email_black_24dp
,
this
)
val
linkDrawable
=
DrawableHelper
.
getDrawableFromId
(
R
.
drawable
.
ic_link_black_24dp
,
this
)
val
drawables
=
arrayOf
(
personDrawable
,
atDrawable
,
emailDrawable
,
linkDrawable
)
val
drawables
=
arrayOf
(
personDrawable
,
atDrawable
,
emailDrawable
)
DrawableHelper
.
wrapDrawables
(
drawables
)
DrawableHelper
.
wrapDrawables
(
drawables
)
DrawableHelper
.
tintDrawables
(
drawables
,
this
,
R
.
color
.
colorDrawableTintGrey
)
DrawableHelper
.
tintDrawables
(
drawables
,
this
,
R
.
color
.
colorDrawableTintGrey
)
DrawableHelper
.
compoundDrawables
(
DrawableHelper
.
compoundDrawables
(
arrayOf
(
text_name
,
text_username
,
text_email
,
text_avatar_url
),
arrayOf
(
text_name
,
text_username
,
text_email
),
drawables
drawables
)
)
}
}
}
}
...
@@ -174,13 +216,11 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
...
@@ -174,13 +216,11 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
editTextsDisposable
.
add
(
Observables
.
combineLatest
(
editTextsDisposable
.
add
(
Observables
.
combineLatest
(
text_name
.
asObservable
(),
text_name
.
asObservable
(),
text_username
.
asObservable
(),
text_username
.
asObservable
(),
text_email
.
asObservable
(),
text_email
.
asObservable
()
text_avatar_url
.
asObservable
()
)
{
text_name
,
text_username
,
text_email
->
)
{
text_name
,
text_username
,
text_email
,
text_avatar_url
->
return
@combineLatest
(
text_name
.
toString
()
!=
currentName
||
return
@combineLatest
(
text_name
.
toString
()
!=
currentName
||
text_username
.
toString
()
!=
currentUsername
||
text_username
.
toString
()
!=
currentUsername
||
text_email
.
toString
()
!=
currentEmail
||
text_email
.
toString
()
!=
currentEmail
)
(
text_avatar_url
.
toString
()
!=
""
&&
text_avatar_url
.
toString
()
!=
currentAvatar
))
}.
subscribe
{
isValid
->
}.
subscribe
{
isValid
->
if
(
isValid
)
{
if
(
isValid
)
{
startActionMode
()
startActionMode
()
...
@@ -190,9 +230,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
...
@@ -190,9 +230,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
})
})
}
}
private
fun
unsubscribeEditTexts
()
{
private
fun
unsubscribeEditTexts
()
=
editTextsDisposable
.
clear
()
editTextsDisposable
.
clear
()
}
private
fun
startActionMode
()
{
private
fun
startActionMode
()
{
if
(
actionMode
==
null
)
{
if
(
actionMode
==
null
)
{
...
@@ -207,7 +245,6 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
...
@@ -207,7 +245,6 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
text_username
.
isEnabled
=
value
text_username
.
isEnabled
=
value
text_username
.
isEnabled
=
value
text_username
.
isEnabled
=
value
text_email
.
isEnabled
=
value
text_email
.
isEnabled
=
value
text_avatar_url
.
isEnabled
=
value
}
}
}
}
}
}
app/src/main/res/drawable/ic_image_black_24dp.xml
0 → 100644
View file @
55ec0626
<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=
"M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z"
/>
</vector>
app/src/main/res/drawable/ic_link_black_24dp.xml
deleted
100644 → 0
View file @
671b9393
<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=
"M3.9,12c0,-1.71 1.39,-3.1 3.1,-3.1h4L11,7L7,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5h4v-1.9L7,15.1c-1.71,0 -3.1,-1.39 -3.1,-3.1zM8,13h8v-2L8,11v2zM17,7h-4v1.9h4c1.71,0 3.1,1.39 3.1,3.1s-1.39,3.1 -3.1,3.1h-4L13,17h4c2.76,0 5,-2.24 5,-5s-2.24,-5 -5,-5z"
/>
</vector>
app/src/main/res/drawable/ic_photo_camera_black_24dp.xml
0 → 100644
View file @
55ec0626
<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=
"M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"
/>
<path
android:fillColor=
"#FF000000"
android:pathData=
"M9,2L7.17,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2L9,2zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z"
/>
</vector>
app/src/main/res/layout/fragment_member_bottom_sheet.xml
View file @
55ec0626
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:layout_height=
"match_parent"
android:paddingBottom=
"16dp"
android:paddingBottom=
"16dp"
app:layout_behavior=
"
com.google.android.material.bottomsheet.BottomSheetBehavior"
>
app:layout_behavior=
"com.google.android.material.bottomsheet.BottomSheetBehavior"
>
<com.facebook.drawee.view.SimpleDraweeView
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/image_bottom_sheet_avatar"
android:id=
"@+id/image_bottom_sheet_avatar"
...
...
app/src/main/res/layout/fragment_profile.xml
View file @
55ec0626
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
<RelativeLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:id=
"@+id/relative_layout"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
xmlns:tools=
"http://schemas.android.com/tools"
android:id=
"@+id/relative_layout"
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:layout_height=
"match_parent"
android:focusableInTouchMode=
"true"
android:focusableInTouchMode=
"true"
...
@@ -48,20 +48,11 @@
...
@@ -48,20 +48,11 @@
android:id=
"@+id/text_email"
android:id=
"@+id/text_email"
style=
"@style/Profile.EditText"
style=
"@style/Profile.EditText"
android:layout_marginTop=
"16dp"
android:layout_marginTop=
"16dp"
android:layout_marginBottom=
"16dp"
android:drawableStart=
"@drawable/ic_email_black_24dp"
android:drawableStart=
"@drawable/ic_email_black_24dp"
android:hint=
"@string/msg_email"
android:hint=
"@string/msg_email"
android:inputType=
"textEmailAddress"
/>
android:inputType=
"textEmailAddress"
/>
<EditText
android:id=
"@+id/text_avatar_url"
style=
"@style/Profile.EditText"
android:layout_marginTop=
"16dp"
android:drawableStart=
"@drawable/ic_link_black_24dp"
android:hint=
"@string/msg_avatar_url"
android:inputType=
"text"
android:layout_marginBottom=
"16dp"
/>
</LinearLayout>
</LinearLayout>
</ScrollView>
</ScrollView>
<com.wang.avi.AVLoadingIndicatorView
<com.wang.avi.AVLoadingIndicatorView
...
@@ -72,4 +63,19 @@
...
@@ -72,4 +63,19 @@
app:indicatorColor=
"@color/colorBlack"
app:indicatorColor=
"@color/colorBlack"
app:indicatorName=
"BallPulseIndicator"
/>
app:indicatorName=
"BallPulseIndicator"
/>
<View
android:id=
"@+id/view_dim"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"@color/colorDim"
android:visibility=
"gone"
/>
<include
android:id=
"@+id/layout_update_avatar_options"
layout=
"@layout/update_avatar_options"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_alignParentBottom=
"true"
android:visibility=
"gone"
/>
</RelativeLayout>
</RelativeLayout>
\ No newline at end of file
app/src/main/res/layout/update_avatar_options.xml
0 → 100644
View file @
55ec0626
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:background=
"@drawable/style_attachment_options"
android:orientation=
"vertical"
>
<Button
android:id=
"@+id/button_open_gallery"
style=
"?android:attr/borderlessButtonStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:drawableStart=
"@drawable/ic_image_black_24dp"
android:drawablePadding=
"20dp"
android:gravity=
"start|center"
android:text=
"@string/action_select_photo_from_gallery"
/>
<Button
android:id=
"@+id/button_take_photo"
style=
"?android:attr/borderlessButtonStyle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:drawableStart=
"@drawable/ic_photo_camera_black_24dp"
android:drawablePadding=
"20dp"
android:gravity=
"start|center"
android:text=
"@string/action_take_photo"
/>
</LinearLayout>
\ No newline at end of file
app/src/main/res/values-es/strings.xml
View file @
55ec0626
...
@@ -36,9 +36,11 @@
...
@@ -36,9 +36,11 @@
<string
name=
"action_away"
>
Ausente
</string>
<string
name=
"action_away"
>
Ausente
</string>
<string
name=
"action_busy"
>
Ocupado
</string>
<string
name=
"action_busy"
>
Ocupado
</string>
<string
name=
"action_invisible"
>
Invisible
</string>
<string
name=
"action_invisible"
>
Invisible
</string>
<!-- TODO Add translation -->
<string
name=
"action_drawing"
>
Drawing
</string>
<!-- TODO Add translation -->
<string
name=
"action_drawing"
>
Drawing
</string>
<string
name=
"action_save_to_gallery"
>
Guardar en la galería
</string>
<string
name=
"action_save_to_gallery"
>
Guardar en la galería
</string>
<string
name=
"action_select_photo_from_gallery"
>
Select photo from gallery
</string>
<!-- TODO Add translation -->
<string
name=
"action_take_photo"
>
Select photo from gallery
</string>
<!-- TODO Add translation -->
<!-- Settings List -->
<!-- Settings List -->
<string-array
name=
"settings_actions"
>
<string-array
name=
"settings_actions"
>
...
@@ -140,7 +142,6 @@
...
@@ -140,7 +142,6 @@
<string
name=
"msg_member_not_found"
>
Miembro no encontrado
</string>
<string
name=
"msg_member_not_found"
>
Miembro no encontrado
</string>
<string
name=
"msg_channel_created_successfully"
>
Canal creado con éxito
</string>
<string
name=
"msg_channel_created_successfully"
>
Canal creado con éxito
</string>
<!-- System messages -->
<!-- System messages -->
<string
name=
"message_room_name_changed"
>
Nombre de la sala cambiado para: %1$s por %2$s
</string>
<string
name=
"message_room_name_changed"
>
Nombre de la sala cambiado para: %1$s por %2$s
</string>
<string
name=
"message_user_added_by"
>
Usuario %1$s añadido por %2$s
</string>
<string
name=
"message_user_added_by"
>
Usuario %1$s añadido por %2$s
</string>
...
...
app/src/main/res/values-fr/strings.xml
View file @
55ec0626
...
@@ -27,8 +27,7 @@
...
@@ -27,8 +27,7 @@
<string
name=
"action_search"
>
Chercher
</string>
<string
name=
"action_search"
>
Chercher
</string>
<string
name=
"action_update"
>
Mettre à jour
</string>
<string
name=
"action_update"
>
Mettre à jour
</string>
<string
name=
"action_settings"
>
Paramètres
</string>
<string
name=
"action_settings"
>
Paramètres
</string>
// TODO: Add proper translation.
<string
name=
"action_create_channel"
>
Create channel
</string>
<!-- TODO Add translation -->
<string
name=
"action_create_channel"
>
Create channel
</string>
<string
name=
"action_create"
>
Create
</string>
<string
name=
"action_create"
>
Create
</string>
<string
name=
"action_logout"
>
Se déconnecter
</string>
<string
name=
"action_logout"
>
Se déconnecter
</string>
<string
name=
"action_files"
>
Fichiers
</string>
<string
name=
"action_files"
>
Fichiers
</string>
...
@@ -40,8 +39,9 @@
...
@@ -40,8 +39,9 @@
<string
name=
"action_busy"
>
Occupé
</string>
<string
name=
"action_busy"
>
Occupé
</string>
<string
name=
"action_invisible"
>
Invisible
</string>
<string
name=
"action_invisible"
>
Invisible
</string>
<string
name=
"action_drawing"
>
Dessin
</string>
<string
name=
"action_drawing"
>
Dessin
</string>
// TODO: Add proper translation.
<string
name=
"action_save_to_gallery"
>
Save to gallery
</string>
<!-- TODO Add translation -->
<string
name=
"action_save_to_gallery"
>
Save to gallery
</string>
<string
name=
"action_select_photo_from_gallery"
>
Select photo from gallery
</string>
<!-- TODO Add translation -->
<string
name=
"action_take_photo"
>
Select photo from gallery
</string>
<!-- TODO Add translation -->
<!-- Settings List -->
<!-- Settings List -->
<string-array
name=
"settings_actions"
>
<string-array
name=
"settings_actions"
>
...
...
app/src/main/res/values-hi-rIN/strings.xml
View file @
55ec0626
...
@@ -39,6 +39,8 @@
...
@@ -39,6 +39,8 @@
<string
name=
"action_invisible"
>
अदृश्य
</string>
<string
name=
"action_invisible"
>
अदृश्य
</string>
<string
name=
"action_save_to_gallery"
>
गैलरी में सहेजें
</string>
<string
name=
"action_save_to_gallery"
>
गैलरी में सहेजें
</string>
<string
name=
"action_drawing"
>
चित्रकारी
</string>
<string
name=
"action_drawing"
>
चित्रकारी
</string>
<string
name=
"action_select_photo_from_gallery"
>
Select photo from gallery
</string>
<!-- TODO Add translation -->
<string
name=
"action_take_photo"
>
Select photo from gallery
</string>
<!-- TODO Add translation -->
<!-- Settings List -->
<!-- Settings List -->
<string-array
name=
"settings_actions"
>
<string-array
name=
"settings_actions"
>
...
...
app/src/main/res/values-pt-rBR/strings.xml
View file @
55ec0626
...
@@ -39,6 +39,8 @@
...
@@ -39,6 +39,8 @@
<string
name=
"action_invisible"
>
Invisível
</string>
<string
name=
"action_invisible"
>
Invisível
</string>
<string
name=
"action_drawing"
>
Desenhando
</string>
<string
name=
"action_drawing"
>
Desenhando
</string>
<string
name=
"action_save_to_gallery"
>
Salvar na galeria
</string>
<string
name=
"action_save_to_gallery"
>
Salvar na galeria
</string>
<string
name=
"action_select_photo_from_gallery"
>
Escolher foto da galeria
</string>
<string
name=
"action_take_photo"
>
Tirar foto
</string>
<!-- Settings List -->
<!-- Settings List -->
<string-array
name=
"settings_actions"
>
<string-array
name=
"settings_actions"
>
...
...
app/src/main/res/values-ru/strings.xml
View file @
55ec0626
...
@@ -39,6 +39,8 @@
...
@@ -39,6 +39,8 @@
<string
name=
"action_invisible"
>
Невидимый
</string>
<string
name=
"action_invisible"
>
Невидимый
</string>
<string
name=
"action_drawing"
>
Рисование
</string>
<string
name=
"action_drawing"
>
Рисование
</string>
<string
name=
"action_save_to_gallery"
>
Сохранить в галерею
</string>
<string
name=
"action_save_to_gallery"
>
Сохранить в галерею
</string>
<string
name=
"action_select_photo_from_gallery"
>
Select photo from gallery
</string>
<!-- TODO Add translation -->
<string
name=
"action_take_photo"
>
Select photo from gallery
</string>
<!-- TODO Add translation -->
<!-- Settings List -->
<!-- Settings List -->
<string-array
name=
"settings_actions"
>
<string-array
name=
"settings_actions"
>
...
...
app/src/main/res/values/strings.xml
View file @
55ec0626
...
@@ -40,6 +40,8 @@
...
@@ -40,6 +40,8 @@
<string
name=
"action_invisible"
>
Invisible
</string>
<string
name=
"action_invisible"
>
Invisible
</string>
<string
name=
"action_drawing"
>
Drawing
</string>
<string
name=
"action_drawing"
>
Drawing
</string>
<string
name=
"action_save_to_gallery"
>
Save to gallery
</string>
<string
name=
"action_save_to_gallery"
>
Save to gallery
</string>
<string
name=
"action_select_photo_from_gallery"
>
Select photo from gallery
</string>
<string
name=
"action_take_photo"
>
Take photo
</string>
<!-- Settings List -->
<!-- Settings List -->
<string-array
name=
"settings_actions"
>
<string-array
name=
"settings_actions"
>
...
...
util/src/main/java/chat/rocket/android/util/extension/Image.kt
View file @
55ec0626
package
chat.rocket.android.util.extension
package
chat.rocket.android.util.extension
import
android.content.Intent
import
android.graphics.Bitmap
import
android.graphics.Bitmap
import
android.provider.MediaStore
import
androidx.fragment.app.Fragment
import
kotlinx.coroutines.experimental.DefaultDispatcher
import
kotlinx.coroutines.experimental.DefaultDispatcher
import
kotlinx.coroutines.experimental.withContext
import
kotlinx.coroutines.experimental.withContext
import
java.io.ByteArrayInputStream
import
java.io.ByteArrayInputStream
...
@@ -61,4 +64,18 @@ fun String.getCompressFormat(): Bitmap.CompressFormat {
...
@@ -61,4 +64,18 @@ fun String.getCompressFormat(): Bitmap.CompressFormat {
this
.
contains
(
"webp"
)
->
Bitmap
.
CompressFormat
.
WEBP
this
.
contains
(
"webp"
)
->
Bitmap
.
CompressFormat
.
WEBP
else
->
Bitmap
.
CompressFormat
.
PNG
else
->
Bitmap
.
CompressFormat
.
PNG
}
}
}
fun
Fragment
.
dispatchImageSelection
(
requestCode
:
Int
)
{
val
intent
=
Intent
(
Intent
.
ACTION_GET_CONTENT
)
intent
.
type
=
"image/*"
intent
.
addCategory
(
Intent
.
CATEGORY_OPENABLE
)
startActivityForResult
(
intent
,
requestCode
)
}
fun
Fragment
.
dispatchTakePicture
(
requestCode
:
Int
)
{
val
takePictureIntent
=
Intent
(
MediaStore
.
ACTION_IMAGE_CAPTURE
)
if
(
takePictureIntent
.
resolveActivity
(
context
?.
packageManager
)
!=
null
)
{
startActivityForResult
(
takePictureIntent
,
requestCode
)
}
}
}
\ No newline at end of file
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