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
8b1d9112
Commit
8b1d9112
authored
Oct 09, 2017
by
mala
Committed by
GitHub
Oct 09, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into develop
parents
2bca8302
95e001cc
Changes
35
Hide whitespace changes
Inline
Side-by-side
Showing
35 changed files
with
952 additions
and
293 deletions
+952
-293
RocketChatCache.java
app/src/main/java/chat/rocket/android/RocketChatCache.java
+4
-1
AbstractAuthedActivity.java
.../chat/rocket/android/activity/AbstractAuthedActivity.java
+1
-10
MainActivity.java
.../main/java/chat/rocket/android/activity/MainActivity.java
+2
-1
RoomActivity.kt
...in/java/chat/rocket/android/activity/room/RoomActivity.kt
+1
-3
DDPClientWrapper.java
...c/main/java/chat/rocket/android/api/DDPClientWrapper.java
+1
-1
RestApiHelper.kt
...c/main/java/chat/rocket/android/api/rest/RestApiHelper.kt
+1
-0
RocketChatAbsoluteUrl.java
...cket/android/fragment/chatroom/RocketChatAbsoluteUrl.java
+4
-0
RoomContract.java
...a/chat/rocket/android/fragment/chatroom/RoomContract.java
+13
-1
RoomFragment.java
...a/chat/rocket/android/fragment/chatroom/RoomFragment.java
+37
-21
RoomPresenter.java
.../chat/rocket/android/fragment/chatroom/RoomPresenter.java
+51
-6
RoomListContract.kt
...rocket/android/fragment/chatroom/list/RoomListContract.kt
+2
-1
RoomListFragment.kt
...rocket/android/fragment/chatroom/list/RoomListFragment.kt
+27
-2
RoomListPresenter.kt
...ocket/android/fragment/chatroom/list/RoomListPresenter.kt
+102
-20
LoginFragment.java
.../rocket/android/fragment/server_config/LoginFragment.java
+1
-1
UserRegistrationDialogFragment.java
...ragment/server_config/UserRegistrationDialogFragment.java
+2
-2
SidebarMainFragment.java
.../rocket/android/fragment/sidebar/SidebarMainFragment.java
+1
-1
UrlHelper.kt
app/src/main/java/chat/rocket/android/helper/UrlHelper.kt
+11
-10
MessageFormManager.kt
...ocket/android/layouthelper/chatroom/MessageFormManager.kt
+16
-1
MessagePopup.java
...at/rocket/android/layouthelper/chatroom/MessagePopup.java
+238
-0
RoomFileListAdapter.kt
...android/layouthelper/chatroom/list/RoomFileListAdapter.kt
+17
-7
PushNotificationHandler.java
...ava/chat/rocket/android/push/PushNotificationHandler.java
+5
-5
RocketChatWebSocketThread.java
...hat/rocket/android/service/RocketChatWebSocketThread.java
+4
-4
AbstractRocketChatCacheObserver.java
...oid/service/internal/AbstractRocketChatCacheObserver.java
+5
-5
item_room_file.xml
app/src/main/res/layout/item_room_file.xml
+14
-14
menu_room.xml
app/src/main/res/menu/menu_room.xml
+3
-3
UrlHelperTest.kt
...c/test/kotlin/chat/rocket/android/helper/UrlHelperTest.kt
+9
-12
FrescoHelper.kt
...in/java/chat/rocket/android/widget/helper/FrescoHelper.kt
+4
-0
MarkDown.java
...main/java/chat/rocket/android/widget/helper/MarkDown.java
+1
-1
MessageFormLayout.java
...chat/rocket/android/widget/message/MessageFormLayout.java
+94
-4
RocketChatMessageAttachmentsLayout.java
...id/widget/message/RocketChatMessageAttachmentsLayout.java
+19
-16
ic_close.xml
...t-chat-android-widgets/src/main/res/drawable/ic_close.xml
+8
-0
ic_reply.xml
...t-chat-android-widgets/src/main/res/drawable/ic_reply.xml
+8
-0
inline_attachment_background.xml
...ts/src/main/res/drawable/inline_attachment_background.xml
+9
-4
message_composer.xml
...-android-widgets/src/main/res/layout/message_composer.xml
+155
-54
message_inline_attachment.xml
...widgets/src/main/res/layout/message_inline_attachment.xml
+82
-82
No files found.
app/src/main/java/chat/rocket/android/RocketChatCache.java
View file @
8b1d9112
...
...
@@ -172,7 +172,10 @@ public class RocketChatCache {
}
public
Flowable
<
Optional
<
String
>>
getSelectedRoomIdPublisher
()
{
return
getValuePublisher
(
KEY_SELECTED_ROOM_ID
);
return
getValuePublisher
(
KEY_SELECTED_ROOM_ID
)
.
filter
(
Optional:
:
isPresent
)
.
map
(
Optional:
:
get
)
.
map
(
roomValue
->
Optional
.
ofNullable
(
new
JSONObject
(
roomValue
).
optString
(
getSelectedServerHostname
(),
null
)));
}
private
SharedPreferences
getSharedPreferences
()
{
...
...
app/src/main/java/chat/rocket/android/activity/AbstractAuthedActivity.java
View file @
8b1d9112
...
...
@@ -9,7 +9,6 @@ import io.reactivex.disposables.CompositeDisposable;
import
io.reactivex.schedulers.Schedulers
;
import
org.json.JSONException
;
import
org.json.JSONObject
;
import
java.util.List
;
import
chat.rocket.android.LaunchUtil
;
import
chat.rocket.android.RocketChatCache
;
...
...
@@ -196,9 +195,8 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity {
compositeDisposable
.
add
(
rocketChatCache
.
getSelectedRoomIdPublisher
()
.
filter
(
Optional:
:
isPresent
)
.
map
(
Optional:
:
get
)
.
map
(
this
::
convertStringToJsonObject
)
.
map
(
jsonObject
->
jsonObject
.
optString
(
rocketChatCache
.
getSelectedServerHostname
(),
null
))
.
subscribeOn
(
Schedulers
.
io
())
.
observeOn
(
AndroidSchedulers
.
mainThread
())
.
subscribe
(
...
...
@@ -207,11 +205,4 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity {
)
);
}
private
JSONObject
convertStringToJsonObject
(
String
json
)
throws
JSONException
{
if
(
json
==
null
)
{
return
new
JSONObject
();
}
return
new
JSONObject
(
json
);
}
}
app/src/main/java/chat/rocket/android/activity/MainActivity.java
View file @
8b1d9112
...
...
@@ -48,7 +48,8 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
private
SlidingPaneLayout
pane
;
private
MainContract
.
Presenter
presenter
;
protected
int
getLayoutContainerForFragment
()
{
@Override
public
int
getLayoutContainerForFragment
()
{
return
R
.
id
.
activity_main_container
;
}
...
...
app/src/main/java/chat/rocket/android/activity/room/RoomActivity.kt
View file @
8b1d9112
...
...
@@ -9,7 +9,6 @@ import kotlinx.android.synthetic.main.activity_room.*
class
RoomActivity
:
AppCompatActivity
()
{
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
setContentView
(
R
.
layout
.
activity_room
)
...
...
@@ -35,8 +34,7 @@ class RoomActivity : AppCompatActivity() {
}
private
fun
addFragment
(
fragment
:
Fragment
,
tag
:
String
)
{
supportFragmentManager
.
beginTransaction
()
supportFragmentManager
.
beginTransaction
()
.
add
(
R
.
id
.
fragment_container
,
fragment
,
tag
)
.
commit
()
}
...
...
app/src/main/java/chat/rocket/android/api/DDPClientWrapper.java
View file @
8b1d9112
...
...
@@ -30,7 +30,7 @@ public class DDPClientWrapper {
}
/**
*
create
new API client instance.
*
build
new API client instance.
*/
public
static
DDPClientWrapper
create
(
String
hostname
)
{
return
new
DDPClientWrapper
(
hostname
);
...
...
app/src/main/java/chat/rocket/android/api/rest/RestApiHelper.kt
View file @
8b1d9112
...
...
@@ -96,6 +96,7 @@ object RestApiHelper {
val
parsedHttpUrl
=
HttpUrl
.
parse
(
getEndpointUrlForFileList
(
roomType
,
hostname
))
?.
newBuilder
()
?.
addQueryParameter
(
"roomId"
,
roomId
)
?.
addQueryParameter
(
"sort"
,
"{\"uploadedAt\":-1}"
)
?.
addQueryParameter
(
"offset"
,
offset
)
?.
build
()
...
...
app/src/main/java/chat/rocket/android/fragment/chatroom/RocketChatAbsoluteUrl.java
View file @
8b1d9112
...
...
@@ -29,4 +29,8 @@ public class RocketChatAbsoluteUrl implements AbsoluteUrl {
public
String
getToken
()
{
return
token
;
}
public
String
getBaseUrl
()
{
return
baseUrl
;
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/fragment/chatroom/RoomContract.java
View file @
8b1d9112
...
...
@@ -2,11 +2,13 @@ package chat.rocket.android.fragment.chatroom;
import
android.support.annotation.Nullable
;
import
chat.rocket.core.models.User
;
import
java.util.List
;
import
chat.rocket.android.shared.BaseContract
;
import
chat.rocket.android.widget.AbsoluteUrl
;
import
chat.rocket.core.models.Message
;
import
chat.rocket.core.models.Room
;
import
chat.rocket.core.models.User
;
public
interface
RoomContract
{
...
...
@@ -35,6 +37,12 @@ public interface RoomContract {
void
autoloadImages
();
void
manualLoadImages
();
void
onReply
(
AbsoluteUrl
absoluteUrl
,
String
markdown
,
Message
message
);
void
onCopy
(
String
message
);
void
showMessageActions
(
Message
message
);
}
interface
Presenter
extends
BaseContract
.
Presenter
<
View
>
{
...
...
@@ -58,5 +66,9 @@ public interface RoomContract {
void
onMarkAsRead
();
void
refreshRoom
();
void
replyMessage
(
Message
message
);
void
copyMessage
(
Message
message
);
}
}
app/src/main/java/chat/rocket/android/fragment/chatroom/RoomFragment.java
View file @
8b1d9112
...
...
@@ -2,6 +2,9 @@ package chat.rocket.android.fragment.chatroom;
import
android.Manifest
;
import
android.app.Activity
;
import
android.content.ClipData
;
import
android.content.ClipboardManager
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.net.Uri
;
import
android.os.Bundle
;
...
...
@@ -26,10 +29,11 @@ import java.util.List;
import
chat.rocket.android.BackgroundLooper
;
import
chat.rocket.android.R
;
import
chat.rocket.android.RocketChatApplication
;
import
chat.rocket.android.activity.MainActivity
;
import
chat.rocket.android.activity.room.RoomActivity
;
import
chat.rocket.android.api.MethodCallHelper
;
import
chat.rocket.android.fragment.chatroom.dialog.FileUploadProgressDialogFragment
;
import
chat.rocket.android.fragment.chatroom.dialog.MessageOptionsDialogFragment
;
import
chat.rocket.android.fragment.sidebar.SidebarMainFragment
;
import
chat.rocket.android.helper.AbsoluteUrlHelper
;
import
chat.rocket.android.helper.FileUploadHelper
;
...
...
@@ -42,6 +46,7 @@ import chat.rocket.android.helper.TextUtils;
import
chat.rocket.android.layouthelper.chatroom.AbstractNewMessageIndicatorManager
;
import
chat.rocket.android.layouthelper.chatroom.MessageFormManager
;
import
chat.rocket.android.layouthelper.chatroom.MessageListAdapter
;
import
chat.rocket.android.layouthelper.chatroom.MessagePopup
;
import
chat.rocket.android.layouthelper.chatroom.ModelListAdapter
;
import
chat.rocket.android.layouthelper.chatroom.PairedMessage
;
import
chat.rocket.android.layouthelper.extra_action.AbstractExtraActionItem
;
...
...
@@ -55,6 +60,7 @@ import chat.rocket.android.renderer.RocketChatUserStatusProvider;
import
chat.rocket.android.service.ConnectivityManager
;
import
chat.rocket.android.service.temp.DeafultTempSpotlightRoomCaller
;
import
chat.rocket.android.service.temp.DefaultTempSpotlightUserCaller
;
import
chat.rocket.android.widget.AbsoluteUrl
;
import
chat.rocket.android.widget.RoomToolbar
;
import
chat.rocket.android.widget.internal.ExtraActionPickerDialogFragment
;
import
chat.rocket.android.widget.message.MessageFormLayout
;
...
...
@@ -90,7 +96,6 @@ import permissions.dispatcher.RuntimePermissions;
public
class
RoomFragment
extends
AbstractChatRoomFragment
implements
OnBackPressListener
,
ExtraActionPickerDialogFragment
.
Callback
,
ModelListAdapter
.
OnItemClickListener
<
PairedMessage
>,
ModelListAdapter
.
OnItemLongClickListener
<
PairedMessage
>,
RoomContract
.
View
{
...
...
@@ -135,7 +140,7 @@ public class RoomFragment extends AbstractChatRoomFragment implements
}
/**
*
create
fragment with roomId.
*
build
fragment with roomId.
*/
public
static
RoomFragment
create
(
String
hostname
,
String
roomId
)
{
Bundle
args
=
new
Bundle
();
...
...
@@ -202,7 +207,6 @@ public class RoomFragment extends AbstractChatRoomFragment implements
messageListAdapter
=
new
MessageListAdapter
(
getContext
(),
hostname
);
messageRecyclerView
.
setAdapter
(
messageListAdapter
);
messageListAdapter
.
setOnItemClickListener
(
this
);
messageListAdapter
.
setOnItemLongClickListener
(
this
);
LinearLayoutManager
linearLayoutManager
=
new
LinearLayoutManager
(
getContext
(),
LinearLayoutManager
.
VERTICAL
,
true
);
...
...
@@ -287,22 +291,9 @@ public class RoomFragment extends AbstractChatRoomFragment implements
super
.
onDestroyView
();
}
@Override
public
void
onItemClick
(
PairedMessage
pairedMessage
)
{
presenter
.
onMessageSelected
(
pairedMessage
.
target
);
}
@Override
public
boolean
onItemLongClick
(
PairedMessage
pairedMessage
)
{
MessageOptionsDialogFragment
messageOptionsDialogFragment
=
MessageOptionsDialogFragment
.
create
(
pairedMessage
.
target
);
messageOptionsDialogFragment
.
setOnMessageOptionSelectedListener
(
message
->
{
messageOptionsDialogFragment
.
dismiss
();
onEditMessage
(
message
);
});
messageOptionsDialogFragment
.
show
(
getChildFragmentManager
(),
"MessageOptionsDialogFragment"
);
presenter
.
onMessageSelected
(
pairedMessage
.
target
);
return
true
;
}
...
...
@@ -325,9 +316,9 @@ public class RoomFragment extends AbstractChatRoomFragment implements
case
R
.
id
.
action_favorite_messages
:
showRoomListFragment
(
R
.
id
.
action_favorite_messages
);
break
;
//
case R.id.action_file_list:
//
showRoomListFragment(R.id.action_file_list);
//
break;
case
R
.
id
.
action_file_list
:
showRoomListFragment
(
R
.
id
.
action_file_list
);
break
;
case
R
.
id
.
action_member_list
:
showRoomListFragment
(
R
.
id
.
action_member_list
);
break
;
...
...
@@ -659,6 +650,31 @@ public class RoomFragment extends AbstractChatRoomFragment implements
messageListAdapter
.
setAutoloadImages
(
false
);
}
@Override
public
void
onReply
(
AbsoluteUrl
absoluteUrl
,
String
markdown
,
Message
message
)
{
messageFormManager
.
setReply
(
absoluteUrl
,
markdown
,
message
);
}
@Override
public
void
onCopy
(
String
message
)
{
RocketChatApplication
context
=
RocketChatApplication
.
getInstance
();
ClipboardManager
clipboardManager
=
(
ClipboardManager
)
context
.
getSystemService
(
Context
.
CLIPBOARD_SERVICE
);
clipboardManager
.
setPrimaryClip
(
ClipData
.
newPlainText
(
"message"
,
message
));
}
@Override
public
void
showMessageActions
(
Message
message
)
{
Activity
context
=
getActivity
();
if
(
context
!=
null
&&
context
instanceof
MainActivity
)
{
MessagePopup
.
take
(
message
)
.
setReplyAction
(
presenter:
:
replyMessage
)
.
setEditAction
(
this
::
onEditMessage
)
.
setCopyAction
(
msg
->
onCopy
(
message
.
getMessage
()))
.
showWith
(
context
);
}
}
private
void
onEditMessage
(
Message
message
)
{
edittingMessage
=
message
;
messageFormManager
.
setEditMessage
(
message
.
getMessage
());
...
...
app/src/main/java/chat/rocket/android/fragment/chatroom/RoomPresenter.java
View file @
8b1d9112
...
...
@@ -6,15 +6,12 @@ import android.support.v4.util.Pair;
import
com.hadisatrio.optional.Optional
;
import
io.reactivex.Single
;
import
io.reactivex.android.schedulers.AndroidSchedulers
;
import
io.reactivex.disposables.Disposable
;
import
chat.rocket.android.BackgroundLooper
;
import
chat.rocket.android.api.MethodCallHelper
;
import
chat.rocket.android.helper.AbsoluteUrlHelper
;
import
chat.rocket.android.helper.LogIfError
;
import
chat.rocket.android.helper.Logger
;
import
chat.rocket.android.service.ConnectivityManagerApi
;
import
chat.rocket.android.shared.BasePresenter
;
import
chat.rocket.core.SyncState
;
import
chat.rocket.core.interactors.MessageInteractor
;
...
...
@@ -24,7 +21,9 @@ import chat.rocket.core.models.Settings;
import
chat.rocket.core.models.User
;
import
chat.rocket.core.repositories.RoomRepository
;
import
chat.rocket.core.repositories.UserRepository
;
import
chat.rocket.android.service.ConnectivityManagerApi
;
import
io.reactivex.Single
;
import
io.reactivex.android.schedulers.AndroidSchedulers
;
import
io.reactivex.disposables.Disposable
;
public
class
RoomPresenter
extends
BasePresenter
<
RoomContract
.
View
>
implements
RoomContract
.
Presenter
{
...
...
@@ -36,8 +35,9 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
private
final
AbsoluteUrlHelper
absoluteUrlHelper
;
private
final
MethodCallHelper
methodCallHelper
;
private
final
ConnectivityManagerApi
connectivityManagerApi
;
private
Room
currentRoom
;
public
RoomPresenter
(
String
roomId
,
public
RoomPresenter
(
String
roomId
,
UserRepository
userRepository
,
MessageInteractor
messageInteractor
,
RoomRepository
roomRepository
,
...
...
@@ -115,6 +115,50 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
if
(
message
.
getSyncState
()
==
SyncState
.
FAILED
)
{
view
.
showMessageSendFailure
(
message
);
}
if
(
message
.
getType
()
==
null
)
{
// If message is not a system message show applicable actions.
view
.
showMessageActions
(
message
);
}
}
@Override
public
void
replyMessage
(
Message
message
)
{
this
.
absoluteUrlHelper
.
getRocketChatAbsoluteUrl
()
.
cache
()
.
subscribeOn
(
AndroidSchedulers
.
from
(
BackgroundLooper
.
get
()))
.
observeOn
(
AndroidSchedulers
.
mainThread
())
.
subscribe
(
serverUrl
->
{
if
(
serverUrl
.
isPresent
())
{
String
baseUrl
=
serverUrl
.
get
().
getBaseUrl
();
view
.
onReply
(
serverUrl
.
get
(),
buildReplyMarkDown
(
baseUrl
,
message
),
message
);
}
},
Logger:
:
report
);
}
@Override
public
void
copyMessage
(
Message
message
)
{
view
.
onCopy
(
message
.
getMessage
());
}
private
String
buildReplyMarkDown
(
String
baseUrl
,
Message
message
)
{
if
(
currentRoom
==
null
||
message
.
getUser
()
==
null
)
{
return
""
;
}
if
(
currentRoom
.
isDirectMessage
())
{
return
String
.
format
(
"[ ](%s/direct/%s?msg=%s) "
,
baseUrl
,
message
.
getUser
().
getUsername
(),
message
.
getId
());
}
else
{
return
String
.
format
(
"[ ](%s/channel/%s?msg=%s) @%s "
,
baseUrl
,
currentRoom
.
getName
(),
message
.
getId
(),
message
.
getUser
().
getUsername
());
}
}
@Override
...
...
@@ -233,6 +277,7 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
}
private
void
processRoom
(
Room
room
)
{
this
.
currentRoom
=
room
;
view
.
render
(
room
);
if
(
room
.
isDirectMessage
())
{
...
...
app/src/main/java/chat/rocket/android/fragment/chatroom/list/RoomListContract.kt
View file @
8b1d9112
package
chat.rocket.android.fragment.chatroom.list
import
chat.rocket.core.models.Attachment
import
chat.rocket.core.models.Message
import
chat.rocket.core.models.User
...
...
@@ -32,7 +33,7 @@ interface RoomListContract {
* @param dataSet The file data set to show.
* @param total The total number of files.
*/
fun
showFileList
(
dataSet
:
ArrayList
<
String
>,
total
:
String
)
fun
showFileList
(
dataSet
:
ArrayList
<
Attachment
>,
total
:
String
)
/**
* Shows a list of members of a room.
...
...
app/src/main/java/chat/rocket/android/fragment/chatroom/list/RoomListFragment.kt
View file @
8b1d9112
...
...
@@ -9,8 +9,10 @@ import android.view.View
import
android.view.ViewGroup
import
chat.rocket.android.R
import
chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import
chat.rocket.android.layouthelper.chatroom.list.RoomFileListAdapter
import
chat.rocket.android.layouthelper.chatroom.list.RoomMemberListAdapter
import
chat.rocket.android.layouthelper.chatroom.list.RoomMessagesAdapter
import
chat.rocket.core.models.Attachment
import
chat.rocket.core.models.Message
import
chat.rocket.core.models.User
import
kotlinx.android.synthetic.main.fragment_room_list.*
...
...
@@ -84,6 +86,14 @@ class RoomListFragment : Fragment(), RoomListContract.View {
userId
,
offset
)
}
R
.
id
.
action_file_list
->
{
presenter
.
requestFileList
(
roomId
,
roomType
,
hostname
,
token
,
userId
,
offset
)
}
R
.
id
.
action_favorite_messages
->
{
presenter
.
requestFavoriteMessages
(
roomId
,
roomType
,
...
...
@@ -139,8 +149,23 @@ class RoomListFragment : Fragment(), RoomListContract.View {
}
}
// TODO (after REST api fixes)
override
fun
showFileList
(
dataSet
:
ArrayList
<
String
>,
total
:
String
)
{}
override
fun
showFileList
(
dataSet
:
ArrayList
<
Attachment
>,
total
:
String
)
{
activity
.
title
=
getString
(
R
.
string
.
fragment_room_list_file_list_title
,
total
)
if
(
recyclerView
.
adapter
==
null
)
{
recyclerView
.
adapter
=
RoomFileListAdapter
(
dataSet
)
val
linearLayoutManager
=
LinearLayoutManager
(
context
,
LinearLayoutManager
.
VERTICAL
,
false
)
recyclerView
.
layoutManager
=
linearLayoutManager
if
(
dataSet
.
size
>=
50
)
{
recyclerView
.
addOnScrollListener
(
object
:
EndlessRecyclerViewScrollListener
(
linearLayoutManager
)
{
override
fun
onLoadMore
(
page
:
Int
,
totalItemsCount
:
Int
,
recyclerView
:
RecyclerView
?)
{
loadNextDataFromApi
(
page
)
}
})
}
}
else
{
(
recyclerView
.
adapter
as
RoomFileListAdapter
).
addDataSet
(
dataSet
)
}
}
override
fun
showMemberList
(
dataSet
:
ArrayList
<
User
>,
total
:
String
)
{
activity
.
title
=
getString
(
R
.
string
.
fragment_room_list_member_list_title
,
total
)
...
...
app/src/main/java/chat/rocket/android/fragment/chatroom/list/RoomListPresenter.kt
View file @
8b1d9112
...
...
@@ -2,11 +2,13 @@ package chat.rocket.android.fragment.chatroom.list
import
android.content.Context
import
android.os.Handler
import
android.util.Log
import
chat.rocket.android.R
import
chat.rocket.android.api.rest.RestApiHelper
import
chat.rocket.android.helper.OkHttpHelper
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.core.SyncState
import
chat.rocket.core.models.Attachment
import
chat.rocket.core.models.AttachmentTitle
import
chat.rocket.core.models.Message
import
chat.rocket.core.models.User
import
okhttp3.Call
...
...
@@ -98,13 +100,43 @@ class RoomListPresenter(val context: Context, val view: RoomListContract.View) :
})
}
// TODO (after the REST api fixes)
override
fun
requestFileList
(
roomId
:
String
,
roomType
:
String
,
hostname
:
String
,
token
:
String
,
userId
:
String
,
offset
:
Int
)
{}
offset
:
Int
)
{
view
.
showWaitingView
(
true
)
OkHttpHelper
.
getClient
()
.
newCall
(
RestApiHelper
.
getRequestForFileList
(
roomId
,
roomType
,
hostname
,
token
,
userId
,
offset
.
toString
()))
.
enqueue
(
object
:
Callback
{
override
fun
onFailure
(
call
:
Call
,
e
:
IOException
)
{
if
(!
call
.
isCanceled
)
{
val
message
=
e
.
message
if
(
message
!=
null
)
{
showErrorMessage
(
message
)
}
}
}
@Throws
(
IOException
::
class
)
override
fun
onResponse
(
call
:
Call
,
response
:
Response
)
{
if
(
response
.
isSuccessful
)
{
val
result
=
response
.
body
()
?.
string
()
if
(
result
!=
null
)
{
handleFilesJson
(
result
,
hostname
)
}
}
else
{
showErrorMessage
(
response
.
message
())
}
}
})
}
override
fun
requestMemberList
(
roomId
:
String
,
roomType
:
String
,
...
...
@@ -159,27 +191,13 @@ class RoomListPresenter(val context: Context, val view: RoomListContract.View) :
val
messageJsonObject
=
messagesJSONArray
.
getJSONObject
(
it
)
val
userJsonObject
=
messageJsonObject
.
getJSONObject
(
"u"
)
val
timestampString
=
messageJsonObject
.
optString
(
"ts"
)
val
timestamp
=
if
(
timestampString
.
isBlank
())
{
0
}
else
{
Timestamp
.
valueOf
(
timestampString
.
replace
(
"T"
,
" "
).
replace
(
"Z"
,
""
)).
time
}
val
editedAtString
=
messageJsonObject
.
optString
(
"_updatedAt"
)
val
editedAt
=
if
(
editedAtString
.
isBlank
())
{
0
}
else
{
Timestamp
.
valueOf
(
editedAtString
.
replace
(
"T"
,
" "
).
replace
(
"Z"
,
""
)).
time
}
Message
.
builder
()
.
setId
(
messageJsonObject
.
optString
(
"_id"
))
.
setRoomId
(
messageJsonObject
.
optString
(
"rid"
))
.
setMessage
(
messageJsonObject
.
optString
(
"msg"
))
.
setUser
(
getUserFromJsonObject
(
userJsonObject
))
.
setTimestamp
(
timestamp
)
.
setEditedAt
(
editedAt
)
.
setTimestamp
(
getLongTimestamp
(
messageJsonObject
.
optString
(
"ts"
))
)
.
setEditedAt
(
getLongTimestamp
(
messageJsonObject
.
optString
(
"_updatedAt"
))
)
.
setGroupable
(
messageJsonObject
.
optBoolean
(
"groupable"
))
.
setSyncState
(
SyncState
.
SYNCED
)
.
build
()
...
...
@@ -202,6 +220,52 @@ class RoomListPresenter(val context: Context, val view: RoomListContract.View) :
}
}
private
fun
handleFilesJson
(
json
:
String
,
hostname
:
String
)
{
try
{
val
jsonObject
=
JSONObject
(
json
)
val
filesJsonArray
=
jsonObject
.
getJSONArray
(
"files"
)
val
total
=
filesJsonArray
.
length
()
val
dataSet
=
ArrayList
<
Attachment
>(
total
)
(
0
until
total
).
mapTo
(
dataSet
)
{
val
fileJsonObject
=
filesJsonArray
.
getJSONObject
(
it
)
val
fileLink
=
UrlHelper
.
getAttachmentLink
(
hostname
,
fileJsonObject
.
optString
(
"_id"
),
fileJsonObject
.
optString
(
"name"
))
val
attachmentTitle
=
AttachmentTitle
.
builder
()
.
setTitle
(
fileJsonObject
.
optString
(
"name"
))
.
setLink
(
fileLink
)
.
setDownloadLink
(
fileLink
)
.
build
()
val
attachment
=
Attachment
.
builder
()
val
type
=
fileJsonObject
.
optString
(
"type"
)
when
{
type
.
startsWith
(
"image"
)
->
attachment
.
setImageUrl
(
fileLink
)
type
.
startsWith
(
"audio"
)
->
attachment
.
setAudioUrl
(
fileLink
)
type
.
startsWith
(
"video"
)
->
attachment
.
setVideoUrl
(
fileLink
)
}
attachment
.
setCollapsed
(
false
)
.
setAttachmentTitle
(
attachmentTitle
)
.
setTimestamp
(
getSafeTimestamp
(
fileJsonObject
.
optString
(
"uploadedAt"
)))
.
build
()
}
if
(
dataSet
.
isEmpty
()
&&
!
hasItem
)
{
showEmptyViewMessage
(
context
.
getString
(
R
.
string
.
fragment_room_list_no_file_list_to_show
))
}
else
{
if
(
dataSet
.
isNotEmpty
())
{
hasItem
=
true
showFileList
(
dataSet
,
jsonObject
.
optString
(
"total"
))
}
}
}
catch
(
exception
:
JSONException
)
{
showInvalidRequest
()
}
}
private
fun
handleMembersJson
(
json
:
String
)
{
try
{
val
jsonObject
=
JSONObject
(
json
)
...
...
@@ -221,7 +285,7 @@ class RoomListPresenter(val context: Context, val view: RoomListContract.View) :
showMemberList
(
dataSet
,
jsonObject
.
optString
(
"total"
))
}
}
}
catch
(
exception
:
JSONException
)
{
}
catch
(
exception
:
JSONException
)
{
showInvalidRequest
()
}
}
...
...
@@ -236,6 +300,17 @@ class RoomListPresenter(val context: Context, val view: RoomListContract.View) :
.
build
()
}
private
fun
getLongTimestamp
(
timestamp
:
String
):
Long
{
return
if
(
timestamp
.
isNotBlank
())
{
Timestamp
.
valueOf
(
getSafeTimestamp
(
timestamp
)).
time
}
else
{
0
}
}
private
fun
getSafeTimestamp
(
timestamp
:
String
):
String
=
timestamp
.
replace
(
"T"
,
" "
).
replace
(
"Z"
,
""
)
private
fun
showPinnedMessageList
(
dataSet
:
ArrayList
<
Message
>,
total
:
String
)
{
mainHandler
.
post
{
view
.
showWaitingView
(
false
)
...
...
@@ -250,6 +325,13 @@ class RoomListPresenter(val context: Context, val view: RoomListContract.View) :
}
}
private
fun
showFileList
(
dataSet
:
ArrayList
<
Attachment
>,
total
:
String
)
{
mainHandler
.
post
{
view
.
showWaitingView
(
false
)
view
.
showFileList
(
dataSet
,
total
)
}
}
private
fun
showMemberList
(
dataSet
:
ArrayList
<
User
>,
total
:
String
)
{
mainHandler
.
post
{
view
.
showWaitingView
(
false
)
...
...
app/src/main/java/chat/rocket/android/fragment/server_config/LoginFragment.java
View file @
8b1d9112
...
...
@@ -100,7 +100,7 @@ public class LoginFragment extends AbstractServerConfigFragment implements Login
try
{
fragment
=
info
.
fragmentClass
.
newInstance
();
}
catch
(
Exception
exception
)
{
RCLog
.
w
(
exception
,
"failed to
create
new Fragment"
);
RCLog
.
w
(
exception
,
"failed to
build
new Fragment"
);
}
if
(
fragment
!=
null
)
{
Bundle
args
=
new
Bundle
();
...
...
app/src/main/java/chat/rocket/android/fragment/server_config/UserRegistrationDialogFragment.java
View file @
8b1d9112
...
...
@@ -30,7 +30,7 @@ public class UserRegistrationDialogFragment extends DialogFragment {
}
/**
*
create
UserRegistrationDialogFragment with auto-detect email/username.
*
build
UserRegistrationDialogFragment with auto-detect email/username.
*/
public
static
UserRegistrationDialogFragment
create
(
String
hostname
,
String
usernameOrEmail
,
String
password
)
{
...
...
@@ -42,7 +42,7 @@ public class UserRegistrationDialogFragment extends DialogFragment {
}
/**
*
create
UserRegistrationDialogFragment.
*
build
UserRegistrationDialogFragment.
*/
public
static
UserRegistrationDialogFragment
create
(
String
hostname
,
String
username
,
String
email
,
...
...
app/src/main/java/chat/rocket/android/fragment/sidebar/SidebarMainFragment.java
View file @
8b1d9112
...
...
@@ -67,7 +67,7 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain
public
SidebarMainFragment
()
{}
/**
*
create
SidebarMainFragment with hostname.
*
build
SidebarMainFragment with hostname.
*/
public
static
SidebarMainFragment
create
(
String
hostname
)
{
Bundle
args
=
new
Bundle
();
...
...
app/src/main/java/chat/rocket/android/helper/UrlHelper.kt
View file @
8b1d9112
...
...
@@ -8,7 +8,8 @@ object UrlHelper {
* @param uri The URI.
* @return The URI whit no scheme (HTTP or HTTPS)
*/
fun
removeUriScheme
(
uri
:
String
)
=
uri
.
replace
(
"http://"
,
""
).
replace
(
"https://"
,
""
)
fun
removeUriScheme
(
uri
:
String
)
=
uri
.
replace
(
"http://"
,
""
).
replace
(
"https://"
,
""
)
/**
* Returns the hostname with the security protocol (scheme) HTTPS.
...
...
@@ -17,7 +18,7 @@ object UrlHelper {
* @return The hostname with the security protocol (scheme) HTTPS.
*/
fun
getSafeHostname
(
hostname
:
String
):
String
=
"https://"
+
hostname
.
replace
(
"http://"
,
""
).
replace
(
"https://"
,
""
)
"https://"
+
removeUriScheme
(
hostname
)
/**
* Returns an URL with no spaces and inverted slashes.
...
...
@@ -25,17 +26,17 @@ object UrlHelper {
* @param url The URL.
* @return The URL with no spaces and inverted slashes.
*/
fun
getUrl
(
url
:
String
)
=
fun
get
Safe
Url
(
url
:
String
)
=
url
.
replace
(
" "
,
"%20"
).
replace
(
"\\"
,
""
)
/**
* Returns an
URL for a file
.
* Returns an
attachment link
.
*
* @param
path The path to the fil
e.
* @param
userId The user
ID.
* @param
token The token
.
* @return The
URL for a file
* @param
hostname The hostnam
e.
* @param
fileId The file
ID.
* @param
fileName The file name
.
* @return The
attachment link.
*/
fun
get
UrlForFile
(
path
:
String
,
userId
:
String
,
token
:
String
):
String
=
"https://"
+
removeUriScheme
(
getUrl
(
path
))
+
"?rc_uid=$userId"
+
"&rc_token=$token"
fun
get
AttachmentLink
(
hostname
:
String
,
fileId
:
String
,
fileName
:
String
):
String
=
getSafeUrl
(
getSafeHostname
(
hostname
)
+
"/file-upload/"
+
fileId
+
"/"
+
fileName
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/layouthelper/chatroom/MessageFormManager.kt
View file @
8b1d9112
package
chat.rocket.android.layouthelper.chatroom
import
chat.rocket.android.widget.AbsoluteUrl
import
chat.rocket.android.widget.message.MessageFormLayout
import
chat.rocket.core.models.Message
class
MessageFormManager
(
private
val
messageFormLayout
:
MessageFormLayout
,
val
callback
:
MessageFormLayout
.
ExtraActionSelectionClickListener
)
{
private
var
sendMessageCallback
:
SendMessageCallback
?
=
null
private
var
replyMarkDown
:
String
=
""
init
{
messageFormLayout
.
setExtraActionSelectionClickListener
(
callback
)
...
...
@@ -31,8 +34,20 @@ class MessageFormManager(private val messageFormLayout: MessageFormLayout, val c
messageFormLayout
.
isEnabled
=
enable
}
fun
setReply
(
absoluteUrl
:
AbsoluteUrl
,
replyMarkDown
:
String
,
message
:
Message
)
{
this
.
replyMarkDown
=
replyMarkDown
messageFormLayout
.
setReplyContent
(
absoluteUrl
,
message
)
messageFormLayout
.
setReplyCancelListener
({
this
.
replyMarkDown
=
""
messageFormLayout
.
clearReplyContent
()
messageFormLayout
.
hideKeyboard
()
})
}
private
fun
sendMessage
(
message
:
String
)
{
sendMessageCallback
?.
onSubmitText
(
message
)
val
finalMessage
=
if
(
replyMarkDown
.
isNotEmpty
())
"$replyMarkDown $message"
else
message
replyMarkDown
=
""
sendMessageCallback
?.
onSubmitText
(
finalMessage
)
}
interface
SendMessageCallback
{
...
...
app/src/main/java/chat/rocket/android/layouthelper/chatroom/MessagePopup.java
0 → 100644
View file @
8b1d9112
package
chat
.
rocket
.
android
.
layouthelper
.
chatroom
;
import
android.content.Context
;
import
android.support.annotation.NonNull
;
import
android.support.v4.util.Pair
;
import
android.support.v7.app.AlertDialog
;
import
java.util.ArrayList
;
import
java.util.List
;
import
chat.rocket.android.BackgroundLooper
;
import
chat.rocket.android.RocketChatApplication
;
import
chat.rocket.android.RocketChatCache
;
import
chat.rocket.android.helper.Logger
;
import
chat.rocket.core.interactors.EditMessageInteractor
;
import
chat.rocket.core.interactors.PermissionInteractor
;
import
chat.rocket.core.models.Message
;
import
chat.rocket.core.repositories.MessageRepository
;
import
chat.rocket.core.repositories.PermissionRepository
;
import
chat.rocket.core.repositories.PublicSettingRepository
;
import
chat.rocket.core.repositories.RoomRepository
;
import
chat.rocket.core.repositories.RoomRoleRepository
;
import
chat.rocket.core.repositories.UserRepository
;
import
chat.rocket.persistence.realm.repositories.RealmMessageRepository
;
import
chat.rocket.persistence.realm.repositories.RealmPermissionRepository
;
import
chat.rocket.persistence.realm.repositories.RealmPublicSettingRepository
;
import
chat.rocket.persistence.realm.repositories.RealmRoomRepository
;
import
chat.rocket.persistence.realm.repositories.RealmRoomRoleRepository
;
import
chat.rocket.persistence.realm.repositories.RealmUserRepository
;
import
io.reactivex.Single
;
import
io.reactivex.android.schedulers.AndroidSchedulers
;
import
io.reactivex.disposables.CompositeDisposable
;
import
io.reactivex.disposables.Disposable
;
public
class
MessagePopup
{
private
static
volatile
MessagePopup
singleton
=
null
;
private
static
final
Action
REPLY_ACTION_INFO
=
new
Action
(
"Reply"
,
null
,
true
);
private
static
final
Action
EDIT_ACTION_INFO
=
new
Action
(
"Edit"
,
null
,
true
);
private
static
final
Action
COPY_ACTION_INFO
=
new
Action
(
"Copy"
,
null
,
true
);
private
final
List
<
Action
>
defaultActions
=
new
ArrayList
<>(
3
);
private
final
List
<
Action
>
otherActions
=
new
ArrayList
<>();
private
Message
message
;
private
CompositeDisposable
compositeDisposable
=
new
CompositeDisposable
();
private
MessagePopup
(
Message
message
)
{
this
.
message
=
message
;
}
private
void
showAvailableActionsOnly
(
Context
context
)
{
RocketChatCache
cache
=
new
RocketChatCache
(
RocketChatApplication
.
getInstance
());
String
hostname
=
cache
.
getSelectedServerHostname
();
EditMessageInteractor
editMessageInteractor
=
getEditMessageInteractor
(
hostname
);
MessageRepository
messageRepository
=
new
RealmMessageRepository
(
hostname
);
Disposable
disposable
=
messageRepository
.
getById
(
singleton
.
message
.
getId
())
.
flatMap
(
it
->
{
if
(!
it
.
isPresent
())
{
return
Single
.
just
(
Pair
.<
Message
,
Boolean
>
create
(
null
,
false
));
}
Message
message
=
it
.
get
();
return
Single
.
zip
(
Single
.
just
(
message
),
editMessageInteractor
.
isAllowed
(
message
),
Pair:
:
create
);
})
.
subscribeOn
(
AndroidSchedulers
.
from
(
BackgroundLooper
.
get
()))
.
observeOn
(
AndroidSchedulers
.
mainThread
())
.
subscribe
(
pair
->
{
EDIT_ACTION_INFO
.
allowed
=
pair
.
second
;
List
<
Action
>
allActions
=
singleton
.
defaultActions
;
List
<
Action
>
allowedActions
=
new
ArrayList
<>(
3
);
for
(
int
i
=
0
;
i
<
allActions
.
size
();
i
++)
{
Action
action
=
allActions
.
get
(
i
);
if
(
action
.
allowed
)
{
allowedActions
.
add
(
action
);
}
}
allowedActions
.
addAll
(
singleton
.
otherActions
);
CharSequence
[]
items
=
new
CharSequence
[
allowedActions
.
size
()];
for
(
int
j
=
0
;
j
<
items
.
length
;
j
++)
{
items
[
j
]
=
allowedActions
.
get
(
j
).
actionName
;
}
new
AlertDialog
.
Builder
(
context
)
.
setItems
(
items
,
(
dialog
,
index
)
->
{
Action
action
=
allowedActions
.
get
(
index
);
ActionListener
actionListener
=
action
.
actionListener
;
if
(
actionListener
!=
null
)
{
actionListener
.
execute
(
singleton
.
message
);
}
})
.
setOnCancelListener
(
dialog
->
compositeDisposable
.
clear
())
.
setOnDismissListener
(
dialog1
->
compositeDisposable
.
clear
())
.
setTitle
(
"Message"
)
.
create
()
.
show
();
},
Logger:
:
report
);
compositeDisposable
.
add
(
disposable
);
}
private
void
addDefaultActions
()
{
singleton
.
defaultActions
.
add
(
REPLY_ACTION_INFO
);
singleton
.
defaultActions
.
add
(
EDIT_ACTION_INFO
);
singleton
.
defaultActions
.
add
(
COPY_ACTION_INFO
);
}
public
static
MessagePopup
take
(
Message
message
)
{
if
(
singleton
==
null
)
{
synchronized
(
MessagePopup
.
class
)
{
if
(
singleton
==
null
)
{
singleton
=
new
Builder
(
message
).
build
();
singleton
.
addDefaultActions
();
}
}
}
singleton
.
message
=
message
;
singleton
.
otherActions
.
clear
();
return
singleton
;
}
private
Action
getActionIfExists
(
Action
action
)
{
if
(
singleton
.
otherActions
.
contains
(
action
))
{
return
singleton
.
otherActions
.
get
(
singleton
.
otherActions
.
indexOf
(
action
));
}
if
(
singleton
.
defaultActions
.
contains
(
action
))
{
return
singleton
.
defaultActions
.
get
(
singleton
.
defaultActions
.
indexOf
(
action
));
}
return
null
;
}
public
MessagePopup
addAction
(
@NonNull
CharSequence
actionName
,
ActionListener
actionListener
)
{
List
<
Action
>
actions
=
singleton
.
otherActions
;
Action
newAction
=
new
Action
(
actionName
,
actionListener
,
true
);
Action
existingAction
=
getActionIfExists
(
newAction
);
if
(
existingAction
!=
null
)
{
existingAction
.
actionListener
=
actionListener
;
}
else
{
actions
.
add
(
newAction
);
}
return
singleton
;
}
public
MessagePopup
setReplyAction
(
ActionListener
actionListener
)
{
REPLY_ACTION_INFO
.
actionListener
=
actionListener
;
return
singleton
;
}
public
MessagePopup
setEditAction
(
ActionListener
actionListener
)
{
EDIT_ACTION_INFO
.
actionListener
=
actionListener
;
return
singleton
;
}
public
MessagePopup
setCopyAction
(
ActionListener
actionListener
)
{
COPY_ACTION_INFO
.
actionListener
=
actionListener
;
return
singleton
;
}
public
void
showWith
(
Context
context
)
{
showAvailableActionsOnly
(
context
);
}
private
EditMessageInteractor
getEditMessageInteractor
(
String
hostname
)
{
UserRepository
userRepository
=
new
RealmUserRepository
(
hostname
);
RoomRoleRepository
roomRoleRepository
=
new
RealmRoomRoleRepository
(
hostname
);
PermissionRepository
permissionRepository
=
new
RealmPermissionRepository
(
hostname
);
PermissionInteractor
permissionInteractor
=
new
PermissionInteractor
(
userRepository
,
roomRoleRepository
,
permissionRepository
);
MessageRepository
messageRepository
=
new
RealmMessageRepository
(
hostname
);
RoomRepository
roomRepository
=
new
RealmRoomRepository
(
hostname
);
PublicSettingRepository
publicSettingRepository
=
new
RealmPublicSettingRepository
(
hostname
);
return
new
EditMessageInteractor
(
permissionInteractor
,
userRepository
,
messageRepository
,
roomRepository
,
publicSettingRepository
);
}
private
static
class
Builder
{
private
final
Message
message
;
Builder
(
Message
message
)
{
if
(
message
==
null
)
{
throw
new
IllegalArgumentException
(
"Message must not be null"
);
}
this
.
message
=
message
;
}
public
MessagePopup
build
()
{
Message
message
=
this
.
message
;
return
new
MessagePopup
(
message
);
}
}
public
static
class
Action
{
private
CharSequence
actionName
;
private
ActionListener
actionListener
;
private
boolean
allowed
;
public
Action
(
CharSequence
actionName
,
ActionListener
actionListener
,
boolean
allowed
)
{
this
.
actionName
=
actionName
;
this
.
actionListener
=
actionListener
;
this
.
allowed
=
allowed
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
Action
that
=
(
Action
)
o
;
return
actionName
.
equals
(
that
.
actionName
);
}
@Override
public
int
hashCode
()
{
return
actionName
.
hashCode
();
}
}
public
interface
ActionListener
{
void
execute
(
Message
message
);
}
}
app/src/main/java/chat/rocket/android/layouthelper/chatroom/list/RoomFileListAdapter.kt
View file @
8b1d9112
...
...
@@ -4,14 +4,19 @@ import android.support.v7.widget.RecyclerView
import
android.view.LayoutInflater
import
android.view.View
import
android.view.ViewGroup
import
android.widget.TextView
import
chat.rocket.android.R
import
chat.rocket.android.widget.message.RocketChatMessageLayout
import
chat.rocket.android.helper.DateTime
import
chat.rocket.android.widget.message.RocketChatMessageAttachmentsLayout
import
chat.rocket.core.models.Attachment
import
kotlinx.android.synthetic.main.day.view.*
import
kotlinx.android.synthetic.main.item_room_file.view.*
import
java.sql.Timestamp
/**
* Created by Filipe de Lima Brito (filipedelimabrito@gmail.com) on 9/22/17.
*/
class
RoomFileListAdapter
(
private
var
dataSet
:
List
<
String
>)
:
RecyclerView
.
Adapter
<
RoomFileListAdapter
.
ViewHolder
>()
{
class
RoomFileListAdapter
(
private
var
dataSet
:
List
<
Attachment
>)
:
RecyclerView
.
Adapter
<
RoomFileListAdapter
.
ViewHolder
>()
{
override
fun
onCreateViewHolder
(
parent
:
ViewGroup
,
viewType
:
Int
):
ViewHolder
{
val
view
=
LayoutInflater
.
from
(
parent
.
context
).
inflate
(
R
.
layout
.
item_room_file
,
parent
,
false
)
...
...
@@ -19,17 +24,22 @@ class RoomFileListAdapter(private var dataSet: List<String>) : RecyclerView.Adap
}
override
fun
onBindViewHolder
(
holder
:
ViewHolder
,
position
:
Int
)
{
holder
.
fileNameLink
.
setText
(
dataSet
[
position
])
val
attachment
=
dataSet
[
position
]
holder
.
newDay
.
text
=
DateTime
.
fromEpocMs
(
Timestamp
.
valueOf
(
attachment
.
timestamp
).
time
,
DateTime
.
Format
.
DATE
)
holder
.
attachment
.
appendAttachmentView
(
attachment
,
true
,
false
)
}
override
fun
getItemCount
():
Int
=
dataSet
.
size
fun
setDataSet
(
dataSet
:
List
<
String
>)
{
this
.
dataSet
=
dataSet
notifyDataSetChanged
()
fun
addDataSet
(
dataSet
:
List
<
Attachment
>)
{
val
previousDataSetSize
=
this
.
dataSet
.
size
this
.
dataSet
+=
dataSet
notifyItemRangeInserted
(
previousDataSetSize
,
dataSet
.
size
)
}
class
ViewHolder
(
itemView
:
View
)
:
RecyclerView
.
ViewHolder
(
itemView
)
{
val
fileNameLink
:
RocketChatMessageLayout
=
itemView
.
fileLink
val
newDay
:
TextView
=
itemView
.
day
val
attachment
:
RocketChatMessageAttachmentsLayout
=
itemView
.
attachment
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/push/PushNotificationHandler.java
View file @
8b1d9112
...
...
@@ -88,7 +88,7 @@ public class PushNotificationHandler implements PushConstants {
if
((
message
!=
null
&&
message
.
length
()
!=
0
)
||
(
title
!=
null
&&
title
.
length
()
!=
0
))
{
Log
.
d
(
LOG_TAG
,
"
create
notification"
);
Log
.
d
(
LOG_TAG
,
"
build
notification"
);
if
(
title
==
null
||
title
.
isEmpty
())
{
extras
.
putString
(
TITLE
,
getAppName
(
context
));
...
...
@@ -191,7 +191,7 @@ public class PushNotificationHandler implements PushConstants {
private
void
createActions
(
Context
context
,
Bundle
extras
,
NotificationCompat
.
Builder
builder
,
Resources
resources
,
String
packageName
,
int
notId
)
{
Log
.
d
(
LOG_TAG
,
"
create
actions: with in-line"
);
Log
.
d
(
LOG_TAG
,
"
build
actions: with in-line"
);
String
actions
=
extras
.
getString
(
ACTIONS
);
if
(
actions
==
null
)
{
return
;
...
...
@@ -256,7 +256,7 @@ public class PushNotificationHandler implements PushConstants {
RemoteInput
remoteInput
;
if
(
inline
)
{
Log
.
d
(
LOG_TAG
,
"
create
remote input"
);
Log
.
d
(
LOG_TAG
,
"
build
remote input"
);
String
replyLabel
=
"Enter your reply here"
;
remoteInput
=
new
RemoteInput
.
Builder
(
INLINE_REPLY
)
.
setLabel
(
replyLabel
)
...
...
@@ -287,7 +287,7 @@ public class PushNotificationHandler implements PushConstants {
@RequiresApi
(
api
=
Build
.
VERSION_CODES
.
KITKAT_WATCH
)
private
void
createActions
(
Context
context
,
Bundle
extras
,
Notification
.
Builder
builder
,
Resources
resources
,
String
packageName
,
int
notId
)
{
Log
.
d
(
LOG_TAG
,
"
create
actions: with in-line"
);
Log
.
d
(
LOG_TAG
,
"
build
actions: with in-line"
);
String
actions
=
extras
.
getString
(
ACTIONS
);
if
(
actions
==
null
)
{
return
;
...
...
@@ -352,7 +352,7 @@ public class PushNotificationHandler implements PushConstants {
android
.
app
.
RemoteInput
remoteInput
;
if
(
inline
)
{
Log
.
d
(
LOG_TAG
,
"
create
remote input"
);
Log
.
d
(
LOG_TAG
,
"
build
remote input"
);
String
replyLabel
=
"Enter your reply here"
;
remoteInput
=
new
android
.
app
.
RemoteInput
.
Builder
(
INLINE_REPLY
)
.
setLabel
(
replyLabel
)
...
...
app/src/main/java/chat/rocket/android/service/RocketChatWebSocketThread.java
View file @
8b1d9112
...
...
@@ -109,7 +109,7 @@ public class RocketChatWebSocketThread extends HandlerThread {
}
/**
*
create
new Thread.
*
build
new Thread.
*/
@DebugLog
public
static
Single
<
RocketChatWebSocketThread
>
getStarted
(
Context
appContext
,
String
hostname
)
{
...
...
@@ -241,11 +241,11 @@ public class RocketChatWebSocketThread extends HandlerThread {
private
Single
<
Boolean
>
prepareDDPClient
()
{
// TODO: temporarily replaced checkIfConnectionAlive() call for this single checking if ddpClient is
// null or not. In case it is,
create
a new client, otherwise just keep connecting with existing one.
// null or not. In case it is,
build
a new client, otherwise just keep connecting with existing one.
return
Single
.
just
(
ddpClient
!=
null
)
.
doOnSuccess
(
alive
->
{
if
(!
alive
)
{
RCLog
.
d
(
"DDPClient#
create
"
);
RCLog
.
d
(
"DDPClient#
build
"
);
ddpClient
=
DDPClientWrapper
.
create
(
hostname
);
}
});
...
...
@@ -392,7 +392,7 @@ public class RocketChatWebSocketThread extends HandlerThread {
)
);
}
else
{
// if we don't have any session then just
create
the observers and register normally
// if we don't have any session then just
build
the observers and register normally
createObserversAndRegister
();
}
}
...
...
app/src/main/java/chat/rocket/android/service/internal/AbstractRocketChatCacheObserver.java
View file @
8b1d9112
...
...
@@ -4,14 +4,13 @@ import android.content.Context;
import
com.hadisatrio.optional.Optional
;
import
chat.rocket.android.log.RCLog
;
import
io.reactivex.disposables.CompositeDisposable
;
import
chat.rocket.android.RocketChatCache
;
import
chat.rocket.android.helper.TextUtils
;
import
chat.rocket.persistence.realm.models.ddp.RealmRoom
;
import
chat.rocket.persistence.realm.RealmHelper
;
import
chat.rocket.android.log.RCLog
;
import
chat.rocket.android.service.Registrable
;
import
chat.rocket.persistence.realm.RealmHelper
;
import
chat.rocket.persistence.realm.models.ddp.RealmRoom
;
import
io.reactivex.disposables.CompositeDisposable
;
public
abstract
class
AbstractRocketChatCacheObserver
implements
Registrable
{
private
final
Context
context
;
...
...
@@ -50,6 +49,7 @@ public abstract class AbstractRocketChatCacheObserver implements Registrable {
compositeDisposable
.
add
(
new
RocketChatCache
(
context
)
.
getSelectedRoomIdPublisher
()
.
filter
(
Optional:
:
isPresent
)
.
map
(
Optional:
:
get
)
.
subscribe
(
this
::
updateRoomIdWith
,
RCLog:
:
e
)
);
...
...
app/src/main/res/layout/item_room_file.xml
View file @
8b1d9112
...
...
@@ -3,20 +3,20 @@
xmlns:app=
"http://schemas.android.com/apk/res-auto"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:padding=
"@dimen/margin_16"
>
android:paddingRight=
"@dimen/margin_16"
android:paddingStart=
"@dimen/margin_16"
android:paddingLeft=
"@dimen/margin_16"
android:paddingEnd=
"@dimen/margin_16"
android:paddingBottom=
"@dimen/margin_16"
>
<chat.rocket.android.widget.message.RocketChatMessageLayout
android:id=
"@+id/fileLink"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginLeft=
"@dimen/margin_16"
android:layout_marginStart=
"@dimen/margin_16"
/>
<include
android:id=
"@+id/dayLayout"
layout=
"@layout/day"
/>
<View
android:layout_width=
"0dp"
android:layout_height=
"1dp"
android:layout_weight=
"1"
android:background=
"@color/colorDivider"
android:layout_marginTop=
"@dimen/margin_8"
app:layout_constraintTop_toBottomOf=
"@+id/fileLink"
/>
<chat.rocket.android.widget.message.RocketChatMessageAttachmentsLayout
android:id=
"@+id/attachment"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"@dimen/margin_16"
app:layout_constraintTop_toBottomOf=
"@+id/dayLayout"
/>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
app/src/main/res/menu/menu_room.xml
View file @
8b1d9112
...
...
@@ -10,9 +10,9 @@
android:title=
"@string/menu_favorite_messages"
app:showAsAction=
"never"
/>
<
!--<item android:id="@+id/action_file_list"-->
<!--android:title="@string/menu_file_list"-->
<!--app:showAsAction="never" />--
>
<
item
android:id=
"@+id/action_file_list"
android:title=
"@string/menu_file_list"
app:showAsAction=
"never"
/
>
<item
android:id=
"@+id/action_member_list"
android:title=
"@string/menu_member_list"
...
...
app/src/test/kotlin/chat/rocket/android/helper/UrlHelperTest.kt
View file @
8b1d9112
...
...
@@ -21,20 +21,17 @@ class UrlHelperTest {
@Test
fun
getUrlTest
()
{
assertEquals
(
"https://demo.rocket.chat/GENERAL/file.txt"
,
UrlHelper
.
getUrl
(
"https://demo.rocket.chat/GENERAL/file.txt"
))
assertEquals
(
"http://demo.rocket.chat/GENERAL/file.txt"
,
UrlHelper
.
getUrl
(
"http://demo.rocket.chat/GENERAL/file.txt"
))
assertEquals
(
"demo.rocket.chat/GENERAL/file.txt"
,
UrlHelper
.
getUrl
(
"demo.rocket.chat/GENERAL/file.txt"
))
assertEquals
(
"demo.rocket.chat/GENERAL/a%20sample%20file.txt"
,
UrlHelper
.
getUrl
(
"demo.rocket.chat/GENERAL/a sample file.txt"
))
assertEquals
(
"demo.rocket.chat/GENERAL/file.txt"
,
UrlHelper
.
getUrl
(
"demo.rocket.chat\\/GENERAL\\/file.txt"
))
assertEquals
(
"https://demo.rocket.chat/GENERAL/file.txt"
,
UrlHelper
.
get
Safe
Url
(
"https://demo.rocket.chat/GENERAL/file.txt"
))
assertEquals
(
"http://demo.rocket.chat/GENERAL/file.txt"
,
UrlHelper
.
get
Safe
Url
(
"http://demo.rocket.chat/GENERAL/file.txt"
))
assertEquals
(
"demo.rocket.chat/GENERAL/file.txt"
,
UrlHelper
.
get
Safe
Url
(
"demo.rocket.chat/GENERAL/file.txt"
))
assertEquals
(
"demo.rocket.chat/GENERAL/a%20sample%20file.txt"
,
UrlHelper
.
get
Safe
Url
(
"demo.rocket.chat/GENERAL/a sample file.txt"
))
assertEquals
(
"demo.rocket.chat/GENERAL/file.txt"
,
UrlHelper
.
get
Safe
Url
(
"demo.rocket.chat\\/GENERAL\\/file.txt"
))
}
@Test
fun
getUrlForFileTest
()
{
assertEquals
(
"https://demo.rocket.chat/GENERAL/file.txt?rc_uid=userId&rc_token=token"
,
UrlHelper
.
getUrlForFile
(
"https://demo.rocket.chat/GENERAL/file.txt"
,
"userId"
,
"token"
))
assertEquals
(
"https://demo.rocket.chat/GENERAL/file.txt?rc_uid=userId&rc_token=token"
,
UrlHelper
.
getUrlForFile
(
"http://demo.rocket.chat/GENERAL/file.txt"
,
"userId"
,
"token"
))
assertEquals
(
"https://demo.rocket.chat/GENERAL/file.txt?rc_uid=userId&rc_token=token"
,
UrlHelper
.
getUrlForFile
(
"demo.rocket.chat/GENERAL/file.txt"
,
"userId"
,
"token"
))
assertEquals
(
"https://demo.rocket.chat/GENERAL/a%20sample%20file.txt?rc_uid=userId&rc_token=token"
,
UrlHelper
.
getUrlForFile
(
"demo.rocket.chat/GENERAL/a sample file.txt"
,
"userId"
,
"token"
))
assertEquals
(
"https://demo.rocket.chat/GENERAL/file.txt?rc_uid=userId&rc_token=token"
,
UrlHelper
.
getUrlForFile
(
"demo.rocket.chat\\/GENERAL\\/file.txt"
,
"userId"
,
"token"
))
fun
getAttachmentLinkTest
()
{
assertEquals
(
"https://demo.rocket.chat/file-upload/aFileId/aFileName.txt"
,
UrlHelper
.
getAttachmentLink
(
"https://demo.rocket.chat"
,
"aFileId"
,
"aFileName.txt"
))
assertEquals
(
"https://demo.rocket.chat/file-upload/aFileId/aFileName.txt"
,
UrlHelper
.
getAttachmentLink
(
"http://demo.rocket.chat"
,
"aFileId"
,
"aFileName.txt"
))
assertEquals
(
"https://demo.rocket.chat/file-upload/aFileId/aFileName.txt"
,
UrlHelper
.
getAttachmentLink
(
"demo.rocket.chat"
,
"aFileId"
,
"aFileName.txt"
))
}
}
\ No newline at end of file
rocket-chat-android-widgets/src/main/java/chat/rocket/android/widget/helper/FrescoHelper.kt
View file @
8b1d9112
...
...
@@ -6,7 +6,9 @@ import android.support.graphics.drawable.VectorDrawableCompat
import
chat.rocket.android.widget.R
import
com.facebook.drawee.backends.pipeline.Fresco
import
com.facebook.drawee.drawable.ProgressBarDrawable
import
com.facebook.drawee.drawable.ScalingUtils
import
com.facebook.drawee.generic.GenericDraweeHierarchy
import
com.facebook.drawee.generic.RoundingParams
import
com.facebook.drawee.view.SimpleDraweeView
object
FrescoHelper
{
...
...
@@ -31,6 +33,8 @@ object FrescoHelper {
val
hierarchy
:
GenericDraweeHierarchy
=
draweeView
.
hierarchy
hierarchy
.
setPlaceholderImage
(
VectorDrawableCompat
.
create
(
draweeView
.
resources
,
R
.
drawable
.
image_dummy
,
null
))
hierarchy
.
setFailureImage
(
VectorDrawableCompat
.
create
(
draweeView
.
resources
,
R
.
drawable
.
image_error
,
null
))
hierarchy
.
roundingParams
=
RoundingParams
().
setCornersRadii
(
5F
,
5F
,
5F
,
5F
)
hierarchy
.
actualImageScaleType
=
ScalingUtils
.
ScaleType
.
FIT_CENTER
hierarchy
.
setProgressBarImage
(
ProgressBarDrawable
())
val
controller
=
Fresco
.
newDraweeControllerBuilder
()
...
...
rocket-chat-android-widgets/src/main/java/chat/rocket/android/widget/helper/MarkDown.java
View file @
8b1d9112
...
...
@@ -51,7 +51,7 @@ public class MarkDown {
private
static
final
Pattern
LINK_PATTERN
=
Pattern
.
compile
(
"\\[([^\\]]+)\\]\\(((?:http|https):\\/\\/[^\\)]+
)\\)"
,
Pattern
.
MULTILINE
);
"\\[(.*?)\\]\\(((https?):\\/\\/[-a-zA-Z0-9+&@#\\/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#\\/%=~_|]?
)\\)"
,
Pattern
.
MULTILINE
);
private
static
void
highlightLink1
(
SpannableString
inputText
)
{
final
Matcher
matcher
=
LINK_PATTERN
.
matcher
(
inputText
);
while
(
matcher
.
find
())
{
...
...
rocket-chat-android-widgets/src/main/java/chat/rocket/android/widget/message/MessageFormLayout.java
View file @
8b1d9112
...
...
@@ -4,6 +4,7 @@ import android.annotation.TargetApi;
import
android.content.Context
;
import
android.os.Build
;
import
android.os.Bundle
;
import
android.support.annotation.NonNull
;
import
android.support.v13.view.inputmethod.InputContentInfoCompat
;
import
android.text.Editable
;
import
android.text.TextUtils
;
...
...
@@ -15,10 +16,20 @@ import android.view.ViewGroup;
import
android.view.inputmethod.InputMethodManager
;
import
android.widget.EditText
;
import
android.widget.ImageButton
;
import
android.widget.ImageView
;
import
android.widget.LinearLayout
;
import
android.widget.RelativeLayout
;
import
android.widget.TextView
;
import
com.facebook.drawee.view.SimpleDraweeView
;
import
chat.rocket.android.widget.AbsoluteUrl
;
import
chat.rocket.android.widget.R
;
import
chat.rocket.android.widget.helper.DebouncingOnClickListener
;
import
chat.rocket.android.widget.helper.FrescoHelper
;
import
chat.rocket.core.models.Attachment
;
import
chat.rocket.core.models.AttachmentTitle
;
import
chat.rocket.core.models.Message
;
public
class
MessageFormLayout
extends
LinearLayout
{
...
...
@@ -27,6 +38,12 @@ public class MessageFormLayout extends LinearLayout {
private
ImageButton
attachButton
;
private
ImageButton
sendButton
;
private
RelativeLayout
replyBar
;
private
ImageView
replyCancelButton
;
private
SimpleDraweeView
replyThumb
;
private
TextView
replyMessageText
;
private
TextView
replyUsernameText
;
private
ExtraActionSelectionClickListener
extraActionSelectionClickListener
;
private
SubmitTextListener
submitTextListener
;
private
ImageKeyboardEditText
.
OnCommitContentListener
listener
;
...
...
@@ -65,6 +82,12 @@ public class MessageFormLayout extends LinearLayout {
}
});
replyCancelButton
=
composer
.
findViewById
(
R
.
id
.
reply_cancel
);
replyMessageText
=
composer
.
findViewById
(
R
.
id
.
reply_message
);
replyUsernameText
=
composer
.
findViewById
(
R
.
id
.
reply_username
);
replyThumb
=
composer
.
findViewById
(
R
.
id
.
reply_thumb
);
replyBar
=
composer
.
findViewById
(
R
.
id
.
reply_bar
);
sendButton
=
composer
.
findViewById
(
R
.
id
.
button_send
);
sendButton
.
setOnClickListener
(
new
DebouncingOnClickListener
()
{
...
...
@@ -73,6 +96,7 @@ public class MessageFormLayout extends LinearLayout {
String
messageText
=
getText
();
if
(
messageText
.
length
()
>
0
&&
submitTextListener
!=
null
)
{
submitTextListener
.
onSubmitText
(
messageText
);
clearReplyContent
();
}
}
});
...
...
@@ -118,6 +142,20 @@ public class MessageFormLayout extends LinearLayout {
addView
(
composer
);
}
public
void
clearReplyContent
()
{
replyBar
.
setVisibility
(
View
.
GONE
);
replyThumb
.
setVisibility
(
View
.
GONE
);
replyMessageText
.
setText
(
""
);
replyUsernameText
.
setText
(
""
);
}
public
void
showReplyThumb
()
{
replyThumb
.
setVisibility
(
View
.
VISIBLE
);
}
public
void
setReplyCancelListener
(
OnClickListener
onClickListener
)
{
replyCancelButton
.
setOnClickListener
(
onClickListener
);
}
public
EditText
getEditText
()
{
return
(
EditText
)
composer
.
findViewById
(
R
.
id
.
editor
);
}
...
...
@@ -154,10 +192,7 @@ public class MessageFormLayout extends LinearLayout {
if
(
text
.
length
()
>
0
)
{
editor
.
setSelection
(
text
.
length
());
InputMethodManager
inputMethodManager
=
(
InputMethodManager
)
editor
.
getContext
()
.
getSystemService
(
Context
.
INPUT_METHOD_SERVICE
);
editor
.
requestFocus
();
inputMethodManager
.
showSoftInput
(
editor
,
0
);
requestFocusAndShowKeyboard
();
}
}
});
...
...
@@ -173,6 +208,61 @@ public class MessageFormLayout extends LinearLayout {
this
.
listener
=
listener
;
}
public
void
setReplyContent
(
@NonNull
AbsoluteUrl
absoluteUrl
,
@NonNull
Message
message
)
{
String
text
=
message
.
getMessage
();
replyUsernameText
.
setText
(
message
.
getUser
().
getUsername
());
if
(!
TextUtils
.
isEmpty
(
text
))
{
replyMessageText
.
setText
(
text
);
}
else
{
if
(
message
.
getAttachments
()
!=
null
&&
message
.
getAttachments
().
size
()
>
0
)
{
Attachment
attachment
=
message
.
getAttachments
().
get
(
0
);
AttachmentTitle
attachmentTitle
=
attachment
.
getAttachmentTitle
();
String
imageUrl
=
null
;
if
(
attachment
.
getImageUrl
()
!=
null
)
{
imageUrl
=
absoluteUrl
.
from
(
attachment
.
getImageUrl
());
}
if
(
attachmentTitle
!=
null
)
{
text
=
attachmentTitle
.
getTitle
();
}
if
(
TextUtils
.
isEmpty
(
text
))
{
text
=
"Unknown"
;
}
if
(
imageUrl
!=
null
)
{
FrescoHelper
.
INSTANCE
.
loadImageWithCustomization
(
replyThumb
,
imageUrl
);
showReplyThumb
();
}
replyMessageText
.
setText
(
text
);
}
}
replyBar
.
setVisibility
(
View
.
VISIBLE
);
requestFocusAndShowKeyboard
();
}
public
void
hideKeyboard
()
{
final
EditText
editor
=
getEditor
();
editor
.
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
InputMethodManager
inputMethodManager
=
(
InputMethodManager
)
editor
.
getContext
()
.
getSystemService
(
Context
.
INPUT_METHOD_SERVICE
);
inputMethodManager
.
hideSoftInputFromWindow
(
editor
.
getWindowToken
(),
0
);
}
});
}
private
void
requestFocusAndShowKeyboard
()
{
final
EditText
editor
=
getEditor
();
editor
.
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
InputMethodManager
inputMethodManager
=
(
InputMethodManager
)
editor
.
getContext
()
.
getSystemService
(
Context
.
INPUT_METHOD_SERVICE
);
editor
.
requestFocus
();
inputMethodManager
.
showSoftInput
(
editor
,
0
);
}
});
}
private
void
animateHide
(
final
View
view
)
{
view
.
animate
().
scaleX
(
0
).
scaleY
(
0
).
setDuration
(
150
).
withEndAction
(
new
Runnable
()
{
@Override
...
...
rocket-chat-android-widgets/src/main/java/chat/rocket/android/widget/message/RocketChatMessageAttachmentsLayout.java
View file @
8b1d9112
...
...
@@ -71,21 +71,21 @@ public class RocketChatMessageAttachmentsLayout extends LinearLayout {
return
;
}
this
.
attachments
=
attachments
;
removeAllViews
();
for
(
int
i
=
0
,
size
=
attachments
.
size
();
i
<
size
;
i
++)
{
appendAttachmentView
(
attachments
.
get
(
i
),
autoloadImages
);
appendAttachmentView
(
attachments
.
get
(
i
),
autoloadImages
,
true
);
}
}
p
rivate
void
appendAttachmentView
(
Attachment
attachment
,
boolean
autoloadImages
)
{
p
ublic
void
appendAttachmentView
(
Attachment
attachment
,
boolean
autoloadImages
,
boolean
showAttachmentStrip
)
{
if
(
attachment
==
null
)
{
return
;
}
removeAllViews
();
View
attachmentView
=
inflater
.
inflate
(
R
.
layout
.
message_inline_attachment
,
this
,
false
);
colorizeAttachmentBar
(
attachment
,
attachmentView
);
colorizeAttachmentBar
(
attachment
,
attachmentView
,
showAttachmentStrip
);
showAuthorAttachment
(
attachment
,
attachmentView
);
showTitleAttachment
(
attachment
,
attachmentView
);
showReferenceAttachment
(
attachment
,
attachmentView
);
...
...
@@ -97,19 +97,23 @@ public class RocketChatMessageAttachmentsLayout extends LinearLayout {
addView
(
attachmentView
);
}
private
void
colorizeAttachmentBar
(
Attachment
attachment
,
View
attachmentView
)
{
private
void
colorizeAttachmentBar
(
Attachment
attachment
,
View
attachmentView
,
boolean
showAttachmentStrip
)
{
final
View
attachmentStrip
=
attachmentView
.
findViewById
(
R
.
id
.
attachment_strip
);
final
String
colorString
=
attachment
.
getColor
();
if
(
TextUtils
.
isEmpty
(
colorString
))
{
attachmentStrip
.
setBackgroundResource
(
R
.
color
.
inline_attachment_quote_line
);
return
;
}
if
(
showAttachmentStrip
)
{
final
String
colorString
=
attachment
.
getColor
();
if
(
TextUtils
.
isEmpty
(
colorString
))
{
attachmentStrip
.
setBackgroundResource
(
R
.
color
.
inline_attachment_quote_line
);
return
;
}
try
{
attachmentStrip
.
setBackgroundColor
(
Color
.
parseColor
(
colorString
));
}
catch
(
Exception
e
)
{
attachmentStrip
.
setBackgroundResource
(
R
.
color
.
inline_attachment_quote_line
);
try
{
attachmentStrip
.
setBackgroundColor
(
Color
.
parseColor
(
colorString
));
}
catch
(
Exception
e
)
{
attachmentStrip
.
setBackgroundResource
(
R
.
color
.
inline_attachment_quote_line
);
}
}
else
{
attachmentStrip
.
setVisibility
(
GONE
);
}
}
...
...
@@ -204,8 +208,7 @@ public class RocketChatMessageAttachmentsLayout extends LinearLayout {
}
}
private
void
showImageAttachment
(
Attachment
attachment
,
View
attachmentView
,
boolean
autoloadImages
)
{
private
void
showImageAttachment
(
Attachment
attachment
,
View
attachmentView
,
boolean
autoloadImages
)
{
final
View
imageContainer
=
attachmentView
.
findViewById
(
R
.
id
.
image_container
);
if
(
attachment
.
getImageUrl
()
==
null
)
{
imageContainer
.
setVisibility
(
GONE
);
...
...
rocket-chat-android-widgets/src/main/res/drawable/ic_close.xml
0 → 100644
View file @
8b1d9112
<!-- drawable/close.xml -->
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:height=
"24dp"
android:width=
"24dp"
android:viewportWidth=
"24"
android:viewportHeight=
"24"
>
<path
android:fillColor=
"#000"
android:pathData=
"M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"
/>
</vector>
\ No newline at end of file
rocket-chat-android-widgets/src/main/res/drawable/ic_reply.xml
0 → 100644
View file @
8b1d9112
<!-- drawable/reply.xml -->
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:height=
"24dp"
android:width=
"24dp"
android:viewportWidth=
"24"
android:viewportHeight=
"24"
>
<path
android:fillColor=
"#000"
android:pathData=
"M10,9V5L3,12L10,19V14.9C15,14.9 18.5,16.5 21,20C20,15 17,10 10,9Z"
/>
</vector>
\ No newline at end of file
rocket-chat-android-widgets/src/main/res/drawable/inline_attachment_background.xml
View file @
8b1d9112
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<stroke
android:color=
"@color/inline_attachment_box_outline"
android:width=
"1dp"
/>
<solid
android:color=
"@color/inline_attachment_box_background"
/>
<corners
android:radius=
"2dp"
/>
android:width=
"1dp"
android:color=
"@color/inline_attachment_box_outline"
/>
<solid
android:color=
"@color/inline_attachment_box_background"
/>
<corners
android:radius=
"2dp"
/>
</shape>
\ No newline at end of file
rocket-chat-android-widgets/src/main/res/layout/message_composer.xml
View file @
8b1d9112
<?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:minHeight=
"48dp"
android:background=
"@drawable/top_shadow"
tools:context=
"chat.rocket.android.widget.message.MessageFormLayout"
>
<chat.rocket.android.widget.message.ImageKeyboardEditText
android:id=
"@+id/editor"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginLeft=
"16dp"
android:layout_marginStart=
"16dp"
android:inputType=
"textCapSentences|textMultiLine"
android:hint=
"@string/message_composer_message_hint"
android:textSize=
"14sp"
android:minLines=
"1"
android:maxLines=
"4"
android:background=
"@null"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintLeft_toLeftOf=
"parent"
app:layout_constraintRight_toLeftOf=
"@+id/container"
app:layout_constraintBottom_toBottomOf=
"parent"
/>
<FrameLayout
android:id=
"@+id/container"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginLeft=
"16dp"
android:layout_marginStart=
"16dp"
android:layout_marginRight=
"16dp"
android:layout_marginEnd=
"16dp"
app:layout_constraintTop_toTopOf=
"@+id/editor"
app:layout_constraintRight_toRightOf=
"parent"
app:layout_constraintLeft_toRightOf=
"@+id/editor"
app:layout_constraintBottom_toBottomOf=
"@+id/editor"
>
<ImageButton
android:id=
"@+id/button_attach"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:tint=
"@color/color_icon_composer"
app:srcCompat=
"@drawable/ic_attach_file_black_24dp"
android:background=
"?attr/selectableItemBackgroundBorderless"
/>
<ImageButton
android:id=
"@+id/button_send"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:tint=
"@color/color_accent"
app:srcCompat=
"@drawable/ic_send_black_24dp"
android:background=
"?attr/selectableItemBackgroundBorderless"
/>
</FrameLayout>
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:fresco=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:background=
"@drawable/top_shadow"
android:minHeight=
"48dp"
tools:context=
"chat.rocket.android.widget.message.MessageFormLayout"
>
<RelativeLayout
android:id=
"@+id/reply_bar"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginBottom=
"8dp"
android:layout_marginEnd=
"8dp"
android:layout_marginLeft=
"8dp"
android:layout_marginRight=
"8dp"
android:layout_marginStart=
"8dp"
android:layout_marginTop=
"8dp"
android:visibility=
"gone"
app:layout_constraintBottom_toTopOf=
"@+id/keyboard_container"
app:layout_constraintLeft_toLeftOf=
"parent"
app:layout_constraintRight_toRightOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
tools:layout_editor_absoluteX=
"8dp"
tools:layout_editor_absoluteY=
"8dp"
tools:visibility=
"visible"
>
<android.support.v7.widget.AppCompatImageView
android:id=
"@+id/reply_icon"
android:layout_width=
"24dp"
android:layout_height=
"24dp"
android:layout_marginRight=
"8dp"
android:layout_marginEnd=
"8dp"
android:layout_centerVertical=
"true"
android:layout_alignParentStart=
"true"
android:layout_alignParentLeft=
"true"
android:adjustViewBounds=
"true"
app:srcCompat=
"@drawable/ic_reply"
app:tint=
"@color/color_accent"
/>
<android.support.v7.widget.AppCompatImageView
android:id=
"@+id/reply_cancel"
android:layout_width=
"24dp"
android:layout_height=
"24dp"
android:layout_marginLeft=
"8dp"
android:layout_marginStart=
"8dp"
android:layout_centerVertical=
"true"
android:layout_alignParentEnd=
"true"
android:layout_alignParentRight=
"true"
android:adjustViewBounds=
"true"
app:srcCompat=
"@drawable/ic_close"
app:tint=
"@color/color_icon_composer"
/>
<TextView
android:id=
"@+id/reply_username"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_alignBaseline=
"@id/reply_username"
android:layout_toLeftOf=
"@+id/reply_cancel"
android:layout_toStartOf=
"@id/reply_cancel"
android:layout_toRightOf=
"@+id/reply_thumb"
android:layout_toEndOf=
"@+id/reply_thumb"
android:ellipsize=
"end"
android:maxLines=
"1"
android:textColor=
"@color/color_accent"
android:textStyle=
"bold"
tools:text=
"jane.doe"
/>
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/reply_thumb"
android:layout_width=
"32dp"
android:layout_height=
"wrap_content"
android:layout_marginRight=
"4dp"
android:layout_marginEnd=
"4dp"
android:layout_toRightOf=
"@+id/reply_icon"
android:layout_toEndOf=
"@+id/reply_icon"
android:layout_alignBottom=
"@+id/reply_message"
android:layout_alignTop=
"@+id/reply_username"
android:layout_centerVertical=
"true"
android:visibility=
"gone"
fresco:actualImageScaleType=
"fitCenter"
/>
<TextView
android:id=
"@+id/reply_message"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_below=
"@id/reply_username"
android:layout_toLeftOf=
"@+id/reply_cancel"
android:layout_toStartOf=
"@id/reply_cancel"
android:layout_toRightOf=
"@+id/reply_thumb"
android:layout_toEndOf=
"@+id/reply_thumb"
android:ellipsize=
"end"
android:maxLines=
"1"
tools:text=
"Message"
/>
</RelativeLayout>
<android.support.constraint.ConstraintLayout
android:id=
"@+id/keyboard_container"
android:layout_width=
"0dp"
android:layout_height=
"48dp"
android:background=
"@drawable/top_shadow"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintLeft_toLeftOf=
"parent"
app:layout_constraintRight_toRightOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/reply_bar"
>
<chat.rocket.android.widget.message.ImageKeyboardEditText
android:id=
"@+id/editor"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginLeft=
"16dp"
android:layout_marginStart=
"16dp"
android:background=
"@null"
android:hint=
"@string/message_composer_message_hint"
android:inputType=
"textCapSentences|textMultiLine"
android:maxLines=
"4"
android:minLines=
"1"
android:textSize=
"14sp"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintLeft_toLeftOf=
"parent"
app:layout_constraintRight_toLeftOf=
"@+id/container"
app:layout_constraintTop_toTopOf=
"parent"
/>
<FrameLayout
android:id=
"@+id/container"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginEnd=
"16dp"
android:layout_marginLeft=
"16dp"
android:layout_marginRight=
"16dp"
android:layout_marginStart=
"16dp"
app:layout_constraintBottom_toBottomOf=
"@+id/editor"
app:layout_constraintLeft_toRightOf=
"@+id/editor"
app:layout_constraintRight_toRightOf=
"parent"
app:layout_constraintTop_toTopOf=
"@+id/editor"
>
<ImageButton
android:id=
"@+id/button_attach"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:background=
"?attr/selectableItemBackgroundBorderless"
android:tint=
"@color/color_icon_composer"
app:srcCompat=
"@drawable/ic_attach_file_black_24dp"
/>
<ImageButton
android:id=
"@+id/button_send"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:background=
"?attr/selectableItemBackgroundBorderless"
android:tint=
"@color/color_accent"
app:srcCompat=
"@drawable/ic_send_black_24dp"
/>
</FrameLayout>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
rocket-chat-android-widgets/src/main/res/layout/message_inline_attachment.xml
View file @
8b1d9112
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools
"
xmlns:fresco=
"http://schemas.android.com/apk/res-auto
"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:orientation=
"horizontal"
android:paddingTop
=
"4dp"
android:paddingBottom
=
"4dp"
>
xmlns:fresco=
"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:orientation=
"horizontal"
android:paddingBottom
=
"4dp"
android:paddingTop
=
"4dp"
>
<View
android:id=
"@+id/attachment_strip"
android:layout_width=
"3dp"
android:layout_height=
"match_parent"
android:layout_marginRight=
"5dp"
android:background=
"@color/inline_attachment_quote_line"
/>
android:id=
"@+id/attachment_strip"
android:layout_width=
"3dp"
android:layout_height=
"match_parent"
android:layout_marginEnd=
"5dp"
android:layout_marginRight=
"5dp"
android:background=
"@color/inline_attachment_quote_line"
/>
<LinearLayout
android:id=
"@+id/attachment_content"
android:layout_width=
"0px"
android:layout_height=
"wrap_content"
android:layout_weight=
"1"
android:orientation=
"vertical"
>
android:id=
"@+id/attachment_content"
android:layout_width=
"0px"
android:layout_height=
"wrap_content"
android:layout_weight=
"1"
android:orientation=
"vertical"
>
<LinearLayout
android:id=
"@+id/author_box"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:gravity=
"center_vertical
"
android:orientation=
"horizont
al"
android:layout_marginBottom=
"8dp
"
>
android:id=
"@+id/author_box"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginBottom=
"8dp
"
android:gravity=
"center_vertic
al"
android:orientation=
"horizontal
"
>
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/author_icon"
android:layout_width=
"16dp"
android:layout_height=
"16dp"
tools:src=
"@drawable/circle_black
"
fresco:actualImageScaleType=
"fitCenter
"
/>
android:id=
"@+id/author_icon"
android:layout_width=
"16dp"
android:layout_height=
"16dp"
fresco:actualImageScaleType=
"fitCenter
"
tools:src=
"@drawable/circle_black
"
/>
<android.support.v4.widget.Space
android:layout_width=
"8dp"
android:layout_height=
"8dp"
/>
android:layout_width=
"8dp"
android:layout_height=
"8dp"
/>
<TextView
android:id=
"@+id/author_name"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:textAppearance=
"@style/TextAppearance.RocketChat.MessageAttachment.Title.Link"
tools:text=
"Bradley Hilton"
/>
android:id=
"@+id/author_name"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:textAppearance=
"@style/TextAppearance.RocketChat.MessageAttachment.Title.Link"
tools:text=
"Bradley Hilton"
/>
<android.support.v4.widget.Space
android:layout_width=
"8dp"
android:layout_height=
"8dp"
/>
android:layout_width=
"8dp"
android:layout_height=
"8dp"
/>
<TextView
android:id=
"@+id/timestamp"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
tools:text=
"14:53"
/>
android:id=
"@+id/timestamp"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
tools:text=
"14:53"
/>
</LinearLayout>
<TextView
android:id=
"@+id/title"
android:layout_width=
"match_par
ent"
android:layout_height=
"wrap_content"
android:layout_marginBottom=
"8dp
"
android:textAppearance=
"@style/TextAppearance.RocketChat.MessageAttachment.Title
"
android:background=
"?attr/selectableItemBackground
"
tools:text=
"Attachment Example"
/>
android:id=
"@+id/title"
android:layout_width=
"wrap_cont
ent"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center
"
android:background=
"?attr/selectableItemBackground
"
android:textAppearance=
"@style/TextAppearance.RocketChat.MessageAttachment.Title
"
tools:text=
"Attachment Example"
/>
<LinearLayout
android:id=
"@+id/ref_box"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:gravity=
"center_vertical
"
android:orientation=
"horizont
al"
android:layout_marginBottom=
"8dp
"
>
android:id=
"@+id/ref_box"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginBottom=
"8dp
"
android:gravity=
"center_vertic
al"
android:orientation=
"horizontal
"
>
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/thumb"
android:layout_width=
"32dp"
android:layout_height=
"32dp"
tools:src=
"@drawable/circle_black
"
fresco:actualImageScaleType=
"fitCenter
"
/>
android:id=
"@+id/thumb"
android:layout_width=
"32dp"
android:layout_height=
"32dp"
fresco:actualImageScaleType=
"fitCenter
"
tools:src=
"@drawable/circle_black
"
/>
<android.support.v4.widget.Space
android:layout_width=
"8dp"
android:layout_height=
"8dp"
/>
android:layout_width=
"8dp"
android:layout_height=
"8dp"
/>
<TextView
android:id=
"@+id/text"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
tools:text=
"Bradley Hilton"
/>
android:id=
"@+id/text"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
tools:text=
"Bradley Hilton"
/>
</LinearLayout>
<FrameLayout
android:id=
"@+id/image_container"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
android:id=
"@+id/image_container"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
android:layout_marginTop=
"8dp"
android:padding=
"5dp"
android:background=
"@drawable/inline_attachment_background"
>
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/image"
android:layout_width=
"match_parent"
android:layout_height=
"150dp"
android:layout_marginBottom=
"8dp"
fresco:actualImageScaleType=
"fitStart"
/>
android:id=
"@+id/image"
android:layout_width=
"200dp"
android:layout_height=
"200dp"
/>
<TextView
android:id=
"@+id/image_load"
android:layout_width=
"match_parent"
android:layout_height=
"150dp"
android:gravity=
"center_horizontal|bottom"
android:paddingBottom=
"16dp"
android:text=
"@string/click_to_load"
/>
android:id=
"@+id/image_load"
android:layout_width=
"200dp"
android:layout_height=
"200dp"
android:gravity=
"center_horizontal|bottom"
android:paddingBottom=
"16dp"
android:text=
"@string/click_to_load"
/>
</FrameLayout>
<!-- audio -->
<!-- video -->
</LinearLayout>
</LinearLayout>
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