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
c448359d
Unverified
Commit
c448359d
authored
Jun 20, 2018
by
Lucio Maciel
Committed by
GitHub
Jun 20, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1384 from RocketChat/feature/compress-image
[NEW] Compress image
parents
18e06ae0
590aedde
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
209 additions
and
122 deletions
+209
-122
UriInteractor.kt
...java/chat/rocket/android/chatroom/domain/UriInteractor.kt
+13
-7
ChatRoomPresenter.kt
...rocket/android/chatroom/presentation/ChatRoomPresenter.kt
+152
-74
Animation.kt
...ain/java/chat/rocket/android/util/extensions/Animation.kt
+15
-9
Image.kt
...rc/main/java/chat/rocket/android/util/extensions/Image.kt
+11
-0
Ui.kt
app/src/main/java/chat/rocket/android/util/extensions/Ui.kt
+5
-16
Uri.kt
app/src/main/java/chat/rocket/android/util/extensions/Uri.kt
+13
-16
No files found.
app/src/main/java/chat/rocket/android/chatroom/domain/UriInteractor.kt
View file @
c448359d
...
...
@@ -5,26 +5,32 @@ import android.net.Uri
import
chat.rocket.android.util.extensions.*
import
javax.inject.Inject
class
UriInteractor
@Inject
constructor
(
private
val
context
:
Context
)
{
/**
*
Gets the file name from an
[Uri].
*
Returns the file name from the
[Uri].
*/
fun
getFileName
(
uri
:
Uri
):
String
?
=
uri
.
getFileName
(
context
)
/**
*
Gets the MimeType of an [Uri]
*
Returns the MimeType from the [Uri].
*/
fun
getMimeType
(
uri
:
Uri
):
String
=
uri
.
getMimeType
(
context
)
/**
*
Gets the real path of an [Uri]
*
Returns the file size from the [Uri].
*/
fun
getRealPath
(
uri
:
Uri
):
String
?
=
uri
.
getRealPathFromURI
(
context
)
fun
getFileSize
(
uri
:
Uri
)
=
uri
.
getFileSize
(
context
)
/**
* Returns the InputStream from the [Uri].
*/
fun
getInputStream
(
uri
:
Uri
)
=
uri
.
getInputStream
(
context
)
/**
* Returns the Bitmap from the [Uri].
*
* Note: It should be an image.
*/
fun
getBitmap
(
uri
:
Uri
)
=
uri
.
getBitmpap
(
context
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt
View file @
c448359d
...
...
@@ -16,21 +16,11 @@ import chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.helper.MessageHelper
import
chat.rocket.android.helper.UserHelper
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.ChatRoomsInteractor
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.GetSettingsInteractor
import
chat.rocket.android.server.domain.JobSchedulerInteractor
import
chat.rocket.android.server.domain.MessagesRepository
import
chat.rocket.android.server.domain.PermissionsInteractor
import
chat.rocket.android.server.domain.PublicSettings
import
chat.rocket.android.server.domain.RoomRepository
import
chat.rocket.android.server.domain.UsersRepository
import
chat.rocket.android.server.domain.uploadMaxFileSize
import
chat.rocket.android.server.domain.uploadMimeTypeFilter
import
chat.rocket.android.server.domain.useRealName
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.server.infraestructure.state
import
chat.rocket.android.util.extensions.avatarUrl
import
chat.rocket.android.util.extensions.getCompressFormat
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.android.util.retryIO
import
chat.rocket.common.RocketChatException
...
...
@@ -43,36 +33,22 @@ import chat.rocket.core.internal.realtime.setTypingStatus
import
chat.rocket.core.internal.realtime.socket.model.State
import
chat.rocket.core.internal.realtime.subscribeTypingStatus
import
chat.rocket.core.internal.realtime.unsubscribe
import
chat.rocket.core.internal.rest.chatRoomRoles
import
chat.rocket.core.internal.rest.commands
import
chat.rocket.core.internal.rest.deleteMessage
import
chat.rocket.core.internal.rest.getMembers
import
chat.rocket.core.internal.rest.history
import
chat.rocket.core.internal.rest.joinChat
import
chat.rocket.core.internal.rest.markAsRead
import
chat.rocket.core.internal.rest.me
import
chat.rocket.core.internal.rest.messages
import
chat.rocket.core.internal.rest.pinMessage
import
chat.rocket.core.internal.rest.runCommand
import
chat.rocket.core.internal.rest.sendMessage
import
chat.rocket.core.internal.rest.spotlight
import
chat.rocket.core.internal.rest.starMessage
import
chat.rocket.core.internal.rest.toggleReaction
import
chat.rocket.core.internal.rest.unpinMessage
import
chat.rocket.core.internal.rest.unstarMessage
import
chat.rocket.core.internal.rest.updateMessage
import
chat.rocket.core.internal.rest.uploadFile
import
chat.rocket.core.internal.rest.*
import
chat.rocket.core.model.ChatRoomRole
import
chat.rocket.core.model.Command
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.Myself
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.DefaultDispatcher
import
kotlinx.coroutines.experimental.android.UI
import
kotlinx.coroutines.experimental.async
import
kotlinx.coroutines.experimental.channels.Channel
import
kotlinx.coroutines.experimental.launch
import
kotlinx.coroutines.experimental.withContext
import
org.threeten.bp.Instant
import
timber.log.Timber
import
java.io.ByteArrayInputStream
import
java.io.ByteArrayOutputStream
import
java.io.InputStream
import
java.util.*
import
javax.inject.Inject
...
...
@@ -111,7 +87,12 @@ class ChatRoomPresenter @Inject constructor(
private
var
lastState
=
manager
.
state
private
var
typingStatusList
=
arrayListOf
<
String
>()
fun
setupChatRoom
(
roomId
:
String
,
roomName
:
String
,
roomType
:
String
,
chatRoomMessage
:
String
?
=
null
)
{
fun
setupChatRoom
(
roomId
:
String
,
roomName
:
String
,
roomType
:
String
,
chatRoomMessage
:
String
?
=
null
)
{
launchUI
(
strategy
)
{
try
{
chatRoles
=
if
(
roomTypeOf
(
roomType
)
!
is
RoomType
.
DirectMessage
)
{
...
...
@@ -130,10 +111,16 @@ class ChatRoomPresenter @Inject constructor(
}
?:
false
view
.
onRoomUpdated
(
userCanPost
,
chatIsBroadcast
,
userCanMod
)
loadMessages
(
roomId
,
roomType
)
chatRoomMessage
?.
let
{
messageHelper
.
messageIdFromPermalink
(
it
)
}
?.
let
{
messageId
->
val
name
=
messageHelper
.
roomNameFromPermalink
(
chatRoomMessage
)
citeMessage
(
name
!!
,
messageHelper
.
roomTypeFromPermalink
(
chatRoomMessage
)
!!
,
messageId
,
true
)
}
chatRoomMessage
?.
let
{
messageHelper
.
messageIdFromPermalink
(
it
)
}
?.
let
{
messageId
->
val
name
=
messageHelper
.
roomNameFromPermalink
(
chatRoomMessage
)
citeMessage
(
name
!!
,
messageHelper
.
roomTypeFromPermalink
(
chatRoomMessage
)
!!
,
messageId
,
true
)
}
}
}
}
...
...
@@ -152,8 +139,12 @@ class ChatRoomPresenter @Inject constructor(
try
{
if
(
offset
==
0L
)
{
val
localMessages
=
messagesRepository
.
getByRoomId
(
chatRoomId
)
val
oldMessages
=
mapper
.
map
(
localMessages
,
RoomUiModel
(
roles
=
chatRoles
,
isBroadcast
=
chatIsBroadcast
,
isRoom
=
true
))
val
oldMessages
=
mapper
.
map
(
localMessages
,
RoomUiModel
(
roles
=
chatRoles
,
isBroadcast
=
chatIsBroadcast
,
isRoom
=
true
)
)
if
(
oldMessages
.
isNotEmpty
())
{
view
.
showMessages
(
oldMessages
)
loadMissingMessages
()
...
...
@@ -185,14 +176,24 @@ class ChatRoomPresenter @Inject constructor(
}
}
private
suspend
fun
loadAndShowMessages
(
chatRoomId
:
String
,
chatRoomType
:
String
,
offset
:
Long
=
0
)
{
private
suspend
fun
loadAndShowMessages
(
chatRoomId
:
String
,
chatRoomType
:
String
,
offset
:
Long
=
0
)
{
val
messages
=
retryIO
(
description
=
"messages chatRoom: $chatRoomId, type: $chatRoomType, offset: $offset"
)
{
client
.
messages
(
chatRoomId
,
roomTypeOf
(
chatRoomType
),
offset
,
30
).
result
}
messagesRepository
.
saveAll
(
messages
)
view
.
showMessages
(
mapper
.
map
(
messages
,
RoomUiModel
(
roles
=
chatRoles
,
isBroadcast
=
chatIsBroadcast
,
isRoom
=
true
)))
view
.
showMessages
(
mapper
.
map
(
messages
,
RoomUiModel
(
roles
=
chatRoles
,
isBroadcast
=
chatIsBroadcast
,
isRoom
=
true
)
)
)
}
fun
sendMessage
(
chatRoomId
:
String
,
text
:
String
,
messageId
:
String
?)
{
...
...
@@ -227,8 +228,13 @@ class ChatRoomPresenter @Inject constructor(
)
try
{
messagesRepository
.
save
(
newMessage
)
view
.
showNewMessage
(
mapper
.
map
(
newMessage
,
RoomUiModel
(
roles
=
chatRoles
,
isBroadcast
=
chatIsBroadcast
)))
view
.
showNewMessage
(
mapper
.
map
(
newMessage
,
RoomUiModel
(
roles
=
chatRoles
,
isBroadcast
=
chatIsBroadcast
)
)
)
client
.
sendMessage
(
id
,
chatRoomId
,
text
)
}
catch
(
ex
:
Exception
)
{
// Ok, not very beautiful, but the backend sends us a not valid response
...
...
@@ -265,19 +271,37 @@ class ChatRoomPresenter @Inject constructor(
launchUI
(
strategy
)
{
view
.
showLoading
()
try
{
val
fileName
=
async
{
uriInteractor
.
getFileName
(
uri
)
}.
await
()
?:
uri
.
toString
()
val
mimeType
=
async
{
uriInteractor
.
getMimeType
(
uri
)
}.
await
()
val
fileSize
=
async
{
uriInteractor
.
getFileSize
(
uri
)
}.
await
()
val
maxFileSize
=
settings
.
uploadMaxFileSize
()
when
{
fileName
.
isNullOrEmpty
()
->
view
.
showInvalidFileMessage
()
fileSize
>
maxFileSize
->
view
.
showInvalidFileSize
(
fileSize
,
maxFileSize
)
else
->
{
Timber
.
d
(
"Uploading to $roomId: $fileName - $mimeType"
)
retryIO
(
"uploadFile($roomId, $fileName, $mimeType"
)
{
client
.
uploadFile
(
roomId
,
fileName
!!
,
mimeType
,
msg
,
description
=
fileName
)
{
uriInteractor
.
getInputStream
(
uri
)
withContext
(
DefaultDispatcher
)
{
val
fileName
=
uriInteractor
.
getFileName
(
uri
)
?:
uri
.
toString
()
val
fileSize
=
uriInteractor
.
getFileSize
(
uri
)
val
mimeType
=
uriInteractor
.
getMimeType
(
uri
)
val
maxFileSizeAllowed
=
settings
.
uploadMaxFileSize
()
when
{
fileName
.
isEmpty
()
->
{
view
.
showInvalidFileMessage
()
}
fileSize
>
maxFileSizeAllowed
->
{
view
.
showInvalidFileSize
(
fileSize
,
maxFileSizeAllowed
)
}
else
->
{
var
inputStream
:
InputStream
?
=
uriInteractor
.
getInputStream
(
uri
)
if
(
mimeType
.
contains
(
"image"
))
{
compressImage
(
uri
,
mimeType
)
?.
let
{
inputStream
=
it
}
}
retryIO
(
"uploadFile($roomId, $fileName, $mimeType"
)
{
client
.
uploadFile
(
roomId
,
fileName
,
mimeType
,
msg
,
description
=
fileName
)
{
inputStream
}
}
}
}
...
...
@@ -294,6 +318,25 @@ class ChatRoomPresenter @Inject constructor(
}
}
// Returns an InputStream of a compressed image.
private
suspend
fun
compressImage
(
uri
:
Uri
,
mimeType
:
String
):
InputStream
?
{
var
inputStream
:
InputStream
?
=
null
uriInteractor
.
getBitmap
(
uri
)
?.
let
{
withContext
(
DefaultDispatcher
)
{
val
byteArrayOutputStream
=
ByteArrayOutputStream
()
// TODO: Add an option the the app to the user be able to select the quality of the compressed image
val
isCompressed
=
it
.
compress
(
it
.
getCompressFormat
(
mimeType
),
70
,
byteArrayOutputStream
)
if
(
isCompressed
)
{
inputStream
=
ByteArrayInputStream
(
byteArrayOutputStream
.
toByteArray
())
}
}
}
return
inputStream
}
fun
sendTyping
()
{
launch
(
CommonPool
+
strategy
.
jobs
)
{
if
(
chatRoomId
!=
null
&&
currentLoggedUsername
!=
null
)
{
...
...
@@ -362,15 +405,23 @@ class ChatRoomPresenter @Inject constructor(
.
sortedByDescending
{
it
.
timestamp
}.
firstOrNull
()
?.
let
{
lastMessage
->
val
instant
=
Instant
.
ofEpochMilli
(
lastMessage
.
timestamp
).
toString
()
try
{
val
messages
=
retryIO
(
description
=
"history($chatRoomId, $roomType, $instant)"
)
{
client
.
history
(
chatRoomId
!!
,
roomType
,
count
=
50
,
oldest
=
instant
)
}
val
messages
=
retryIO
(
description
=
"history($chatRoomId, $roomType, $instant)"
)
{
client
.
history
(
chatRoomId
!!
,
roomType
,
count
=
50
,
oldest
=
instant
)
}
Timber
.
d
(
"History: $messages"
)
if
(
messages
.
result
.
isNotEmpty
())
{
val
models
=
mapper
.
map
(
messages
.
result
,
RoomUiModel
(
roles
=
chatRoles
,
isBroadcast
=
chatIsBroadcast
,
isRoom
=
true
))
val
models
=
mapper
.
map
(
messages
.
result
,
RoomUiModel
(
roles
=
chatRoles
,
isBroadcast
=
chatIsBroadcast
,
isRoom
=
true
)
)
messagesRepository
.
saveAll
(
messages
.
result
)
launchUI
(
strategy
)
{
...
...
@@ -440,7 +491,8 @@ class ChatRoomPresenter @Inject constructor(
val
id
=
msg
.
id
val
username
=
msg
.
sender
?.
username
?:
""
val
mention
=
if
(
mentionAuthor
&&
me
?.
username
!=
username
)
"@$username"
else
""
val
room
=
if
(
roomTypeOf
(
roomType
)
is
RoomType
.
DirectMessage
)
username
else
roomName
val
room
=
if
(
roomTypeOf
(
roomType
)
is
RoomType
.
DirectMessage
)
username
else
roomName
val
chatRoomType
=
when
(
roomTypeOf
(
roomType
))
{
is
RoomType
.
DirectMessage
->
"direct"
is
RoomType
.
PrivateGroup
->
"group"
...
...
@@ -451,8 +503,12 @@ class ChatRoomPresenter @Inject constructor(
view
.
showReplyingAction
(
username
=
getDisplayName
(
msg
.
sender
),
replyMarkdown
=
"[ ]($currentServer/$chatRoomType/$room?msg=$id) $mention "
,
quotedMessage
=
mapper
.
map
(
message
,
RoomUiModel
(
roles
=
chatRoles
,
isBroadcast
=
chatIsBroadcast
)).
last
().
preview
?.
message
?:
""
quotedMessage
=
mapper
.
map
(
message
,
RoomUiModel
(
roles
=
chatRoles
,
isBroadcast
=
chatIsBroadcast
)
).
last
().
preview
?.
message
?:
""
)
}
}
...
...
@@ -553,7 +609,12 @@ class ChatRoomPresenter @Inject constructor(
}
}
fun
loadActiveMembers
(
chatRoomId
:
String
,
chatRoomType
:
String
,
offset
:
Long
=
0
,
filterSelfOut
:
Boolean
=
false
)
{
fun
loadActiveMembers
(
chatRoomId
:
String
,
chatRoomType
:
String
,
offset
:
Long
=
0
,
filterSelfOut
:
Boolean
=
false
)
{
launchUI
(
strategy
)
{
try
{
val
members
=
retryIO
(
"getMembers($chatRoomId, $chatRoomType, $offset)"
)
{
...
...
@@ -573,8 +634,12 @@ class ChatRoomPresenter @Inject constructor(
val
found
=
members
.
firstOrNull
{
member
->
member
.
username
==
username
}
val
status
=
if
(
found
!=
null
)
found
.
status
else
UserStatus
.
Offline
()
val
searchList
=
mutableListOf
(
username
,
name
)
activeUsers
.
add
(
PeopleSuggestionUiModel
(
avatarUrl
,
username
,
username
,
name
,
status
,
true
,
searchList
))
activeUsers
.
add
(
PeopleSuggestionUiModel
(
avatarUrl
,
username
,
username
,
name
,
status
,
true
,
searchList
)
)
}
// Filter out from members list the active users.
val
others
=
members
.
filterNot
{
member
->
...
...
@@ -588,7 +653,15 @@ class ChatRoomPresenter @Inject constructor(
val
name
=
it
.
name
?:
""
val
avatarUrl
=
currentServer
.
avatarUrl
(
username
)
val
searchList
=
mutableListOf
(
username
,
name
)
PeopleSuggestionUiModel
(
avatarUrl
,
username
,
username
,
name
,
it
.
status
,
true
,
searchList
)
PeopleSuggestionUiModel
(
avatarUrl
,
username
,
username
,
name
,
it
.
status
,
true
,
searchList
)
})
view
.
populatePeopleSuggestions
(
activeUsers
)
...
...
@@ -613,8 +686,10 @@ class ChatRoomPresenter @Inject constructor(
val
name
=
it
.
name
?:
""
val
searchList
=
mutableListOf
(
username
,
name
)
it
.
emails
?.
forEach
{
email
->
searchList
.
add
(
email
.
address
)
}
PeopleSuggestionUiModel
(
currentServer
.
avatarUrl
(
username
),
username
,
username
,
name
,
it
.
status
,
false
,
searchList
)
PeopleSuggestionUiModel
(
currentServer
.
avatarUrl
(
username
),
username
,
username
,
name
,
it
.
status
,
false
,
searchList
)
}.
filterNot
{
filterSelfOut
&&
self
!=
null
&&
self
==
it
.
text
})
}
ROOMS
->
{
...
...
@@ -834,8 +909,11 @@ class ChatRoomPresenter @Inject constructor(
private
fun
updateMessage
(
streamedMessage
:
Message
)
{
launchUI
(
strategy
)
{
val
viewModelStreamedMessage
=
mapper
.
map
(
streamedMessage
,
RoomUiModel
(
roles
=
chatRoles
,
isBroadcast
=
chatIsBroadcast
))
val
viewModelStreamedMessage
=
mapper
.
map
(
streamedMessage
,
RoomUiModel
(
roles
=
chatRoles
,
isBroadcast
=
chatIsBroadcast
)
)
val
roomMessages
=
messagesRepository
.
getByRoomId
(
streamedMessage
.
roomId
)
val
index
=
roomMessages
.
indexOfFirst
{
msg
->
msg
.
id
==
streamedMessage
.
id
}
...
...
app/src/main/java/chat/rocket/android/util/extensions/Animation.kt
View file @
c448359d
...
...
@@ -8,11 +8,11 @@ import android.content.Context
import
android.os.Build
import
android.os.VibrationEffect
import
android.os.Vibrator
import
androidx.fragment.app.Fragment
import
android.view.View
import
android.view.ViewAnimationUtils
import
android.view.animation.AccelerateInterpolator
import
android.view.animation.DecelerateInterpolator
import
androidx.fragment.app.Fragment
fun
View
.
rotateBy
(
value
:
Float
,
duration
:
Long
=
100
)
{
animate
()
...
...
@@ -31,12 +31,12 @@ fun View.fadeIn(startValue: Float = 0f, finishValue: Float = 1f, duration: Long
.
alpha
(
startValue
)
.
setDuration
(
duration
/
2
)
.
setInterpolator
(
DecelerateInterpolator
())
.
withEndAction
(
{
.
withEndAction
{
animate
()
.
alpha
(
finishValue
)
.
setDuration
(
duration
/
2
)
.
setInterpolator
(
AccelerateInterpolator
()).
start
()
}
)
.
start
()
}.
start
()
setVisible
(
true
)
}
...
...
@@ -51,18 +51,25 @@ fun View.fadeOut(startValue: Float = 1f, finishValue: Float = 0f, duration: Long
.
alpha
(
startValue
)
.
setDuration
(
duration
)
.
setInterpolator
(
DecelerateInterpolator
())
.
withEndAction
(
{
.
withEndAction
{
animate
()
.
alpha
(
finishValue
)
.
setDuration
(
duration
)
.
setInterpolator
(
AccelerateInterpolator
()).
start
()
}
)
.
start
()
}.
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
)
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
if
(
startRadius
<
endRadius
)
{
...
...
@@ -74,7 +81,7 @@ fun View.circularRevealOrUnreveal(centerX: Int, centerY: Int, startRadius: Float
anim
.
start
()
}
fun
View
.
shake
(
x
:
Float
=
2F
,
num
:
Int
=
0
){
fun
View
.
shake
(
x
:
Float
=
2F
,
num
:
Int
=
0
)
{
if
(
num
==
6
)
{
this
.
translationX
=
0
.
toFloat
()
return
...
...
@@ -104,5 +111,4 @@ fun Fragment.vibrateSmartPhone() {
}
else
{
vibrator
.
vibrate
(
200
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/util/extensions/Image.kt
0 → 100644
View file @
c448359d
package
chat.rocket.android.util.extensions
import
android.graphics.Bitmap
fun
Bitmap
.
getCompressFormat
(
mimeType
:
String
):
Bitmap
.
CompressFormat
{
return
when
{
mimeType
.
contains
(
"jpeg"
)
->
Bitmap
.
CompressFormat
.
JPEG
mimeType
.
contains
(
"webp"
)
->
Bitmap
.
CompressFormat
.
WEBP
else
->
Bitmap
.
CompressFormat
.
PNG
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/util/extensions/Ui.kt
View file @
c448359d
...
...
@@ -2,17 +2,15 @@ package chat.rocket.android.util.extensions
import
android.app.Activity
import
android.content.Context
import
androidx.annotation.LayoutRes
import
androidx.annotation.StringRes
import
androidx.fragment.app.Fragment
import
androidx.appcompat.app.AppCompatActivity
import
androidx.recyclerview.widget.LinearLayoutManager
import
androidx.recyclerview.widget.RecyclerView
import
android.view.LayoutInflater
import
android.view.View
import
android.view.ViewGroup
import
android.view.inputmethod.InputMethodManager
import
android.widget.Toast
import
androidx.annotation.LayoutRes
import
androidx.annotation.StringRes
import
androidx.appcompat.app.AppCompatActivity
import
androidx.fragment.app.Fragment
import
chat.rocket.android.R
// TODO: Remove. Use KTX instead.
...
...
@@ -88,13 +86,4 @@ fun Fragment.showToast(@StringRes resource: Int, duration: Int = Toast.LENGTH_SH
showToast
(
getString
(
resource
),
duration
)
fun
Fragment
.
showToast
(
message
:
String
,
duration
:
Int
=
Toast
.
LENGTH_SHORT
)
=
activity
?.
showToast
(
message
,
duration
)
fun
RecyclerView
.
isAtBottom
():
Boolean
{
val
manager
:
RecyclerView
.
LayoutManager
?
=
layoutManager
if
(
manager
is
LinearLayoutManager
)
{
return
manager
.
findFirstVisibleItemPosition
()
==
0
}
return
false
// or true??? we can't determine the first visible item.
}
\ No newline at end of file
activity
?.
showToast
(
message
,
duration
)
\ No newline at end of file
app/src/main/java/chat/rocket/android/util/extensions/Uri.kt
View file @
c448359d
...
...
@@ -3,6 +3,7 @@ package chat.rocket.android.util.extensions
import
android.annotation.TargetApi
import
android.content.ContentResolver
import
android.content.Context
import
android.graphics.Bitmap
import
android.net.Uri
import
android.os.Build
import
android.provider.DocumentsContract
...
...
@@ -57,25 +58,17 @@ fun Uri.getMimeType(context: Context): String {
}
}
fun
Uri
.
getRealPathFromURI
(
context
:
Context
):
String
?
{
val
cursor
=
context
.
contentResolver
.
query
(
this
,
arrayOf
(
MediaStore
.
Images
.
Media
.
DATA
),
null
,
null
,
null
)
cursor
.
use
{
cursor
->
val
columnIndex
=
cursor
.
getColumnIndexOrThrow
(
MediaStore
.
Images
.
Media
.
DATA
)
cursor
.
moveToFirst
()
return
cursor
.
getString
(
columnIndex
)
}
}
@TargetApi
(
Build
.
VERSION_CODES
.
N
)
fun
Uri
.
isVirtualFile
(
context
:
Context
):
Boolean
{
if
(!
DocumentsContract
.
isDocumentUri
(
context
,
this
))
{
return
false
}
val
cursor
=
context
.
contentResolver
.
query
(
this
,
arrayOf
(
DocumentsContract
.
Document
.
COLUMN_FLAGS
),
null
,
null
,
null
)
val
cursor
=
context
.
contentResolver
.
query
(
this
,
arrayOf
(
DocumentsContract
.
Document
.
COLUMN_FLAGS
),
null
,
null
,
null
)
var
flags
=
0
if
(
cursor
.
moveToFirst
())
{
...
...
@@ -97,8 +90,8 @@ fun Uri.getInputStreamForVirtualFile(context: Context, mimeTypeFilter: String):
throw
FileNotFoundException
()
}
return
resolver
.
openTypedAssetFileDescriptor
(
this
,
openableMimeTypes
[
0
],
null
)
?.
createInputStream
()
return
resolver
.
openTypedAssetFileDescriptor
(
this
,
openableMimeTypes
[
0
],
null
)
?.
createInputStream
()
}
fun
Uri
.
getInputStream
(
context
:
Context
):
InputStream
?
{
...
...
@@ -107,4 +100,8 @@ fun Uri.getInputStream(context: Context): InputStream? {
}
return
context
.
contentResolver
.
openInputStream
(
this
)
}
\ No newline at end of file
}
fun
Uri
.
getBitmpap
(
context
:
Context
):
Bitmap
?
{
return
MediaStore
.
Images
.
Media
.
getBitmap
(
context
.
contentResolver
,
this
)
}
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