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
b7ec5aac
Commit
b7ec5aac
authored
Jan 16, 2017
by
Tiago Cunha
Committed by
GitHub
Jan 16, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into fix/validate-server-with-insecure-connection
parents
fb1eef05
7f855b85
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
262 additions
and
7 deletions
+262
-7
RoomFragment.java
...a/chat/rocket/android/fragment/chatroom/RoomFragment.java
+90
-4
RecyclerViewAutoScrollManager.java
.../rocket/android/helper/RecyclerViewAutoScrollManager.java
+31
-0
RecyclerViewScrolledToBottomListener.java
.../android/helper/RecyclerViewScrolledToBottomListener.java
+67
-0
ExtRealmModelListAdapter.java
...rocket/android/layouthelper/ExtRealmModelListAdapter.java
+2
-2
AbstractNewMessageIndicatorManager.java
...uthelper/chatroom/AbstractNewMessageIndicatorManager.java
+43
-0
Message.java
app/src/main/java/chat/rocket/android/model/ddp/Message.java
+1
-0
strings.xml
app/src/main/res/values/strings.xml
+3
-0
RealmModelListAdapter.java
...at/rocket/android/realm_helper/RealmModelListAdapter.java
+25
-1
No files found.
app/src/main/java/chat/rocket/android/fragment/chatroom/RoomFragment.java
View file @
b7ec5aac
...
...
@@ -6,6 +6,7 @@ import android.content.Intent;
import
android.os.Bundle
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.Nullable
;
import
android.support.design.widget.Snackbar
;
import
android.support.v4.view.GravityCompat
;
import
android.support.v4.widget.DrawerLayout
;
import
android.support.v4.widget.SlidingPaneLayout
;
...
...
@@ -27,16 +28,19 @@ import chat.rocket.android.helper.FileUploadHelper;
import
chat.rocket.android.helper.LoadMoreScrollListener
;
import
chat.rocket.android.helper.LogcatIfError
;
import
chat.rocket.android.helper.OnBackPressListener
;
import
chat.rocket.android.helper.RecyclerViewAutoScrollManager
;
import
chat.rocket.android.helper.RecyclerViewScrolledToBottomListener
;
import
chat.rocket.android.helper.TextUtils
;
import
chat.rocket.android.layouthelper.chatroom.MessageFormManager
;
import
chat.rocket.android.layouthelper.chatroom.MessageListAdapter
;
import
chat.rocket.android.layouthelper.chatroom.AbstractNewMessageIndicatorManager
;
import
chat.rocket.android.layouthelper.chatroom.PairedMessage
;
import
chat.rocket.android.layouthelper.extra_action.MessageExtraActionBehavior
;
import
chat.rocket.android.log.RCLog
;
import
chat.rocket.android.layouthelper.extra_action.upload.AudioUploadActionItem
;
import
chat.rocket.android.layouthelper.extra_action.upload.AbstractUploadActionItem
;
import
chat.rocket.android.layouthelper.extra_action.upload.AudioUploadActionItem
;
import
chat.rocket.android.layouthelper.extra_action.upload.ImageUploadActionItem
;
import
chat.rocket.android.layouthelper.extra_action.upload.VideoUploadActionItem
;
import
chat.rocket.android.log.RCLog
;
import
chat.rocket.android.model.ServerConfig
;
import
chat.rocket.android.model.SyncState
;
import
chat.rocket.android.model.ddp.Message
;
...
...
@@ -70,6 +74,10 @@ public class RoomFragment extends AbstractChatRoomFragment
private
LoadMoreScrollListener
scrollListener
;
private
RealmObjectObserver
<
LoadMessageProcedure
>
procedureObserver
;
private
MessageFormManager
messageFormManager
;
private
RecyclerViewAutoScrollManager
autoScrollManager
;
private
AbstractNewMessageIndicatorManager
newMessageIndicatorManager
;
private
Snackbar
unreadIndicator
;
private
boolean
previousUnreadMessageExists
;
public
RoomFragment
()
{
}
...
...
@@ -145,6 +153,15 @@ public class RoomFragment extends AbstractChatRoomFragment
LinearLayoutManager
layoutManager
=
new
LinearLayoutManager
(
getContext
(),
LinearLayoutManager
.
VERTICAL
,
true
);
listView
.
setLayoutManager
(
layoutManager
);
autoScrollManager
=
new
RecyclerViewAutoScrollManager
(
layoutManager
)
{
@Override
protected
void
onAutoScrollMissed
()
{
if
(
newMessageIndicatorManager
!=
null
)
{
newMessageIndicatorManager
.
updateNewMessageCount
(
getUnreadMessageCount
());
}
}
};
adapter
.
registerAdapterDataObserver
(
autoScrollManager
);
scrollListener
=
new
LoadMoreScrollListener
(
layoutManager
,
40
)
{
@Override
...
...
@@ -153,11 +170,69 @@ public class RoomFragment extends AbstractChatRoomFragment
}
};
listView
.
addOnScrollListener
(
scrollListener
);
listView
.
addOnScrollListener
(
new
RecyclerViewScrolledToBottomListener
(
layoutManager
,
1
,
this
::
markAsReadIfNeeded
));
newMessageIndicatorManager
=
new
AbstractNewMessageIndicatorManager
()
{
@Override
protected
void
onShowIndicator
(
int
count
,
boolean
onlyAlreadyShown
)
{
if
((
onlyAlreadyShown
&&
unreadIndicator
!=
null
&&
unreadIndicator
.
isShown
())
||
!
onlyAlreadyShown
)
{
unreadIndicator
=
getUnreadCountIndicatorView
(
count
);
unreadIndicator
.
show
();
}
}
@Override
protected
void
onHideIndicator
()
{
if
(
unreadIndicator
!=
null
&&
unreadIndicator
.
isShown
())
{
unreadIndicator
.
dismiss
();
}
}
};
setupSideMenu
();
setupMessageComposer
();
}
private
void
scrollToLatestMessage
()
{
RecyclerView
listView
=
(
RecyclerView
)
rootView
.
findViewById
(
R
.
id
.
recyclerview
);
if
(
listView
!=
null
)
{
listView
.
scrollToPosition
(
0
);
}
}
private
Snackbar
getUnreadCountIndicatorView
(
int
count
)
{
// TODO: replace with another custom View widget, not to hide message composer.
final
String
caption
=
getResources
().
getString
(
R
.
string
.
fmt_dialog_view_latest_message_title
,
count
);
return
Snackbar
.
make
(
rootView
,
caption
,
Snackbar
.
LENGTH_LONG
)
.
setAction
(
R
.
string
.
dialog_view_latest_message_action
,
view
->
scrollToLatestMessage
());
}
private
int
getUnreadMessageCount
()
{
RoomSubscription
room
=
realmHelper
.
executeTransactionForRead
(
realm
->
realm
.
where
(
RoomSubscription
.
class
).
equalTo
(
RoomSubscription
.
ROOM_ID
,
roomId
).
findFirst
());
if
(
room
!=
null
)
{
return
realmHelper
.
executeTransactionForReadResults
(
realm
->
realm
.
where
(
Message
.
class
)
.
equalTo
(
Message
.
ROOM_ID
,
roomId
)
.
greaterThanOrEqualTo
(
Message
.
TIMESTAMP
,
room
.
getLastSeen
())
.
notEqualTo
(
Message
.
USER_ID
,
userId
)
.
findAll
()).
size
();
}
else
{
return
0
;
}
}
@Override
public
void
onDestroyView
()
{
RecyclerView
listView
=
(
RecyclerView
)
rootView
.
findViewById
(
R
.
id
.
recyclerview
);
listView
.
getAdapter
().
unregisterAdapterDataObserver
(
autoScrollManager
);
super
.
onDestroyView
();
}
@Override
public
void
onItemClick
(
PairedMessage
pairedMessage
)
{
if
(
pairedMessage
.
target
!=
null
)
{
...
...
@@ -230,7 +305,13 @@ public class RoomFragment extends AbstractChatRoomFragment
.
put
(
Message
.
SYNC_STATE
,
SyncState
.
NOT_SYNCED
)
.
put
(
Message
.
TIMESTAMP
,
System
.
currentTimeMillis
())
.
put
(
Message
.
ROOM_ID
,
roomId
)
.
put
(
Message
.
MESSAGE
,
messageText
))));
.
put
(
Message
.
USER
,
new
JSONObject
()
.
put
(
User
.
ID
,
userId
))
.
put
(
Message
.
MESSAGE
,
messageText
)))
.
onSuccess
(
_task
->
{
scrollToLatestMessage
();
return
null
;
}));
messageFormManager
.
registerExtraActionItem
(
new
ImageUploadActionItem
());
messageFormManager
.
registerExtraActionItem
(
new
AudioUploadActionItem
());
messageFormManager
.
registerExtraActionItem
(
new
VideoUploadActionItem
());
...
...
@@ -275,6 +356,12 @@ public class RoomFragment extends AbstractChatRoomFragment
setToolbarRoomIcon
(
0
);
}
setToolbarTitle
(
roomSubscription
.
getName
());
boolean
unreadMessageExists
=
roomSubscription
.
isAlert
();
if
(
newMessageIndicatorManager
!=
null
&&
previousUnreadMessageExists
&&
!
unreadMessageExists
)
{
newMessageIndicatorManager
.
reset
();
}
previousUnreadMessageExists
=
unreadMessageExists
;
}
private
void
onUpdateLoadMessageProcedure
(
LoadMessageProcedure
procedure
)
{
...
...
@@ -346,7 +433,6 @@ public class RoomFragment extends AbstractChatRoomFragment
roomObserver
.
sub
();
procedureObserver
.
sub
();
closeSideMenuIfNeeded
();
markAsReadIfNeeded
();
}
@Override
...
...
app/src/main/java/chat/rocket/android/helper/RecyclerViewAutoScrollManager.java
0 → 100644
View file @
b7ec5aac
package
chat
.
rocket
.
android
.
helper
;
import
android.support.v7.widget.LinearLayoutManager
;
import
android.support.v7.widget.RecyclerView
;
/**
* workaround for bug https://code.google.com/p/android/issues/detail?id=174227
*/
public
class
RecyclerViewAutoScrollManager
extends
RecyclerView
.
AdapterDataObserver
{
private
final
LinearLayoutManager
linearLayoutManager
;
public
RecyclerViewAutoScrollManager
(
LinearLayoutManager
linearLayoutManager
)
{
this
.
linearLayoutManager
=
linearLayoutManager
;
}
@Override
public
void
onItemRangeInserted
(
int
positionStart
,
int
itemCount
)
{
super
.
onItemRangeInserted
(
positionStart
,
itemCount
);
if
(
linearLayoutManager
.
findFirstVisibleItemPosition
()
<=
positionStart
)
{
linearLayoutManager
.
scrollToPosition
(
positionStart
);
}
else
{
onAutoScrollMissed
();
}
}
protected
void
onAutoScrollMissed
()
{
//do nothing by default.
}
}
app/src/main/java/chat/rocket/android/helper/RecyclerViewScrolledToBottomListener.java
0 → 100644
View file @
b7ec5aac
package
chat
.
rocket
.
android
.
helper
;
import
android.os.Handler
;
import
android.support.v7.widget.LinearLayoutManager
;
import
android.support.v7.widget.RecyclerView
;
/**
* ScrollListener for detecting scrolled on the bottom of the RecyclerView.
*/
public
class
RecyclerViewScrolledToBottomListener
extends
RecyclerView
.
OnScrollListener
{
/**
* callback.
*/
public
interface
Callback
{
void
onScrolledToBottom
();
}
private
final
LinearLayoutManager
layoutManager
;
private
final
int
thresholdPosition
;
private
final
Handler
handler
;
private
final
Callback
callback
;
/**
* Trigger callback if the bottom item position > thresholdPosition.
*/
public
RecyclerViewScrolledToBottomListener
(
LinearLayoutManager
layoutManager
,
int
thresholdPosition
,
Callback
callback
)
{
this
.
layoutManager
=
layoutManager
;
this
.
thresholdPosition
=
thresholdPosition
;
this
.
callback
=
callback
;
this
.
handler
=
new
Handler
()
{
@Override
public
void
handleMessage
(
android
.
os
.
Message
msg
)
{
onScrollEnd
();
}
};
}
@Override
public
void
onScrolled
(
RecyclerView
recyclerView
,
int
deltaX
,
int
deltaY
)
{
super
.
onScrolled
(
recyclerView
,
deltaX
,
deltaY
);
handler
.
removeMessages
(
0
);
handler
.
sendEmptyMessageDelayed
(
0
,
120
);
}
private
void
onScrollEnd
()
{
if
(
layoutManager
.
getReverseLayout
())
{
if
(
layoutManager
.
findFirstVisibleItemPosition
()
<=
thresholdPosition
)
{
doCallback
();
}
}
else
{
if
(
layoutManager
.
findLastVisibleItemPosition
()
>=
thresholdPosition
)
{
doCallback
();
}
}
}
private
void
doCallback
()
{
if
(
callback
!=
null
)
{
callback
.
onScrolledToBottom
();
}
}
}
app/src/main/java/chat/rocket/android/layouthelper/ExtRealmModelListAdapter.java
View file @
b7ec5aac
...
...
@@ -38,7 +38,7 @@ public abstract class ExtRealmModelListAdapter<T extends RealmObject, VM,
notifyItemChanged
(
position
+
1
);
}
pr
otected
ListUpdateCallback
listUpdateCallback
=
new
ListUpdateCallback
()
{
pr
ivate
final
ListUpdateCallback
listUpdateCallback
=
new
ListUpdateCallback
()
{
@Override
public
void
onInserted
(
int
position
,
int
count
)
{
notifyItemRangeInserted
(
position
+
1
,
count
);
...
...
@@ -108,7 +108,7 @@ public abstract class ExtRealmModelListAdapter<T extends RealmObject, VM,
}
@Override
p
ublic
ListUpdateCallback
getListUpdateCallback
()
{
p
rotected
ListUpdateCallback
getListUpdateCallback
()
{
return
listUpdateCallback
;
}
}
app/src/main/java/chat/rocket/android/layouthelper/chatroom/AbstractNewMessageIndicatorManager.java
0 → 100644
View file @
b7ec5aac
package
chat
.
rocket
.
android
.
layouthelper
.
chatroom
;
/**
* manager class for showing "You have XX messages" indicator.
*/
public
abstract
class
AbstractNewMessageIndicatorManager
{
private
int
count
;
private
boolean
onlyAlreadyShown
;
/**
* update the number of unread message.
*/
public
void
updateNewMessageCount
(
int
count
)
{
if
(
count
>
0
)
{
this
.
count
=
count
;
update
();
onlyAlreadyShown
=
true
;
}
else
{
reset
();
}
}
/**
* Should call this method when user checked new message.
*/
public
void
reset
()
{
count
=
0
;
onlyAlreadyShown
=
false
;
update
();
}
private
void
update
()
{
if
(
count
>
0
)
{
onShowIndicator
(
count
,
onlyAlreadyShown
);
}
else
{
onHideIndicator
();
}
}
protected
abstract
void
onShowIndicator
(
int
count
,
boolean
onlyAlreadyShown
);
protected
abstract
void
onHideIndicator
();
}
app/src/main/java/chat/rocket/android/model/ddp/Message.java
View file @
b7ec5aac
...
...
@@ -25,6 +25,7 @@ public class Message extends RealmObject {
@SuppressWarnings
({
"PMD.AvoidFieldNameMatchingTypeName"
})
public
static
final
String
MESSAGE
=
"msg"
;
public
static
final
String
USER
=
"u"
;
public
static
final
String
USER_ID
=
"u._id"
;
public
static
final
String
GROUPABLE
=
"groupable"
;
public
static
final
String
ATTACHMENTS
=
"attachments"
;
public
static
final
String
URLS
=
"urls"
;
...
...
app/src/main/res/values/strings.xml
View file @
b7ec5aac
...
...
@@ -18,6 +18,9 @@
<string
name=
"resend"
>
Resend
</string>
<string
name=
"discard"
>
Discard
</string>
<string
name=
"fmt_dialog_view_latest_message_title"
>
New %d messages
</string>
<string
name=
"dialog_view_latest_message_action"
>
View
</string>
<string
name=
"file_uploading_title"
>
Uploading…
</string>
<string
name=
"dialog_user_registration_email"
>
Email
</string>
...
...
realm-helpers/src/main/java/chat/rocket/android/realm_helper/RealmModelListAdapter.java
View file @
b7ec5aac
...
...
@@ -103,7 +103,31 @@ public abstract class RealmModelListAdapter<T extends RealmObject, VM,
protected
abstract
DiffUtil
.
Callback
getDiffCallback
(
List
<
VM
>
oldData
,
List
<
VM
>
newData
);
protected
abstract
ListUpdateCallback
getListUpdateCallback
();
private
final
ListUpdateCallback
listUpdateCallback
=
new
ListUpdateCallback
()
{
@Override
public
void
onInserted
(
int
position
,
int
count
)
{
notifyItemRangeInserted
(
position
,
count
);
}
@Override
public
void
onRemoved
(
int
position
,
int
count
)
{
notifyItemRangeRemoved
(
position
,
count
);
}
@Override
public
void
onMoved
(
int
fromPosition
,
int
toPosition
)
{
notifyItemMoved
(
fromPosition
,
toPosition
);
}
@Override
public
void
onChanged
(
int
position
,
int
count
,
Object
payload
)
{
notifyItemRangeChanged
(
position
,
count
,
payload
);
}
};
protected
ListUpdateCallback
getListUpdateCallback
()
{
return
listUpdateCallback
;
}
public
void
setOnItemClickListener
(
OnItemClickListener
<
VM
>
onItemClickListener
)
{
this
.
onItemClickListener
=
onItemClickListener
;
...
...
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