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
44241c63
Commit
44241c63
authored
Sep 27, 2017
by
Rafael Kellermann Streit
Committed by
GitHub
Sep 27, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into fix/logout-single-instance
parents
cf96cd2f
9d8197a7
Changes
54
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
54 changed files
with
2421 additions
and
955 deletions
+2421
-955
build.gradle
app/build.gradle
+7
-1
OkHttpHelper.kt
...src/debug/java/chat/rocket/android/helper/OkHttpHelper.kt
+8
-0
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+5
-0
MainActivity.java
.../main/java/chat/rocket/android/activity/MainActivity.java
+0
-1
RoomActivity.kt
...in/java/chat/rocket/android/activity/room/RoomActivity.kt
+43
-0
RestApiHelper.kt
...c/main/java/chat/rocket/android/api/rest/RestApiHelper.kt
+218
-0
RocketChatAbsoluteUrl.java
...cket/android/fragment/chatroom/RocketChatAbsoluteUrl.java
+9
-1
RoomFragment.java
...a/chat/rocket/android/fragment/chatroom/RoomFragment.java
+522
-525
UsersOfRoomDialogFragment.java
...d/fragment/chatroom/dialog/UsersOfRoomDialogFragment.java
+0
-207
RoomListContract.kt
...rocket/android/fragment/chatroom/list/RoomListContract.kt
+134
-0
RoomListFragment.kt
...rocket/android/fragment/chatroom/list/RoomListFragment.kt
+188
-0
RoomListPresenter.kt
...ocket/android/fragment/chatroom/list/RoomListPresenter.kt
+266
-0
EndlessRecyclerViewScrollListener.kt
...ocket/android/helper/EndlessRecyclerViewScrollListener.kt
+111
-0
LoadMoreScrollListener.java
...va/chat/rocket/android/helper/LoadMoreScrollListener.java
+0
-44
LoadMoreScrollListener.kt
...java/chat/rocket/android/helper/LoadMoreScrollListener.kt
+30
-0
UrlHelper.kt
app/src/main/java/chat/rocket/android/helper/UrlHelper.kt
+41
-0
AbstractMessageViewHolder.java
...roid/layouthelper/chatroom/AbstractMessageViewHolder.java
+2
-2
RoomFileListAdapter.kt
...android/layouthelper/chatroom/list/RoomFileListAdapter.kt
+35
-0
RoomMemberListAdapter.kt
...droid/layouthelper/chatroom/list/RoomMemberListAdapter.kt
+69
-0
RoomMessagesAdapter.kt
...android/layouthelper/chatroom/list/RoomMessagesAdapter.kt
+90
-0
RoomUserAdapter.java
...t/android/layouthelper/chatroom/list/RoomUserAdapter.java
+1
-1
RoomUserViewHolder.java
...ndroid/layouthelper/chatroom/list/RoomUserViewHolder.java
+1
-1
PushNotificationHandler.java
...ava/chat/rocket/android/push/PushNotificationHandler.java
+44
-10
rocket_chat_notification.xml
...main/res/drawable-anydpi-v21/rocket_chat_notification.xml
+8
-17
ic_close_circle_outline_black_24dp.xml
.../main/res/drawable/ic_close_circle_outline_black_24dp.xml
+11
-0
activity_main.xml
app/src/main/res/layout-w720dp/activity_main.xml
+3
-1
fragment_room.xml
app/src/main/res/layout-w720dp/fragment_room.xml
+0
-12
activity_main.xml
app/src/main/res/layout/activity_main.xml
+3
-1
activity_room.xml
app/src/main/res/layout/activity_room.xml
+26
-0
day.xml
app/src/main/res/layout/day.xml
+30
-0
fragment_room.xml
app/src/main/res/layout/fragment_room.xml
+14
-11
fragment_room_list.xml
app/src/main/res/layout/fragment_room_list.xml
+25
-0
fragment_room_main.xml
app/src/main/res/layout/fragment_room_main.xml
+0
-21
item_room_file.xml
app/src/main/res/layout/item_room_file.xml
+22
-0
item_room_member.xml
app/src/main/res/layout/item_room_member.xml
+67
-0
item_room_message.xml
app/src/main/res/layout/item_room_message.xml
+85
-0
list_item_message_newday.xml
app/src/main/res/layout/list_item_message_newday.xml
+0
-34
list_item_normal_message.xml
app/src/main/res/layout/list_item_normal_message.xml
+1
-1
list_item_system_message.xml
app/src/main/res/layout/list_item_system_message.xml
+1
-1
room_side_menu.xml
app/src/main/res/layout/room_side_menu.xml
+0
-29
menu_room.xml
app/src/main/res/menu/menu_room.xml
+20
-0
colors.xml
app/src/main/res/values/colors.xml
+13
-8
fa_strings.xml
app/src/main/res/values/fa_strings.xml
+0
-9
message_style.xml
app/src/main/res/values/message_style.xml
+27
-0
message_styles.xml
app/src/main/res/values/message_styles.xml
+0
-11
strings.xml
app/src/main/res/values/strings.xml
+17
-0
OkHttpHelper.kt
...c/release/java/chat/rocket/android/helper/OkHttpHelper.kt
+11
-1
RestApiHelperTest.kt
.../kotlin/chat/rocket/android/api/rest/RestApiHelperTest.kt
+110
-0
UrlHelperTest.kt
...c/test/kotlin/chat/rocket/android/helper/UrlHelperTest.kt
+40
-0
build.gradle
build.gradle
+1
-1
AvatarHelper.kt
...in/java/chat/rocket/android/widget/helper/AvatarHelper.kt
+22
-4
DrawableHelper.kt
.../java/chat/rocket/android/widget/helper/DrawableHelper.kt
+32
-0
AvatarHelperTest.kt
...lin/chat/rocket/android/widget/helper/AvatarHelperTest.kt
+3
-0
User.java
...chat-core/src/main/java/chat/rocket/core/models/User.java
+5
-0
No files found.
app/build.gradle
View file @
44241c63
...
...
@@ -7,6 +7,7 @@ repositories {
}
apply
plugin:
'kotlin-android'
apply
plugin:
'kotlin-android-extensions'
apply
plugin:
'me.tatarka.retrolambda'
apply
plugin:
'com.jakewharton.hugo'
apply
plugin:
'com.github.triplet.play'
...
...
@@ -103,7 +104,10 @@ android {
manifest
.
srcFile
'src/release/AndroidManifest.xml'
}
test
.
java
.
srcDirs
+=
'src/test/kotlin'
test
{
test
.
java
.
srcDirs
+=
'src/test/kotlin'
androidTest
.
java
.
srcDirs
+=
'src/androidTest/kotlin'
}
}
}
...
...
@@ -137,6 +141,8 @@ dependencies {
compile
'com.android.support:multidex:1.0.1'
compile
"org.jetbrains.kotlin:kotlin-stdlib-jre7:$rootProject.ext.kotlinVersion"
testCompile
"org.jetbrains.kotlin:kotlin-test:$rootProject.ext.kotlinVersion"
testCompile
"org.jetbrains.kotlin:kotlin-test-junit:$rootProject.ext.kotlinVersion"
compile
"com.google.firebase:firebase-core:$playLibVersion"
compile
"com.google.firebase:firebase-crash:$playLibVersion"
...
...
app/src/debug/java/chat/rocket/android/helper/OkHttpHelper.kt
View file @
44241c63
...
...
@@ -10,6 +10,13 @@ import okhttp3.OkHttpClient
object
OkHttpHelper
{
fun
getClient
():
OkHttpClient
{
if
(
httpClient
==
null
)
{
httpClient
=
OkHttpClient
()
}
return
httpClient
?:
throw
AssertionError
(
"httpClient set to null by another thread"
)
}
fun
getClientForUploadFile
():
OkHttpClient
{
if
(
httpClientForUploadFile
==
null
)
{
httpClientForUploadFile
=
OkHttpClient
.
Builder
().
build
()
...
...
@@ -41,6 +48,7 @@ object OkHttpHelper {
return
httpClientForWS
?:
throw
AssertionError
(
"httpClientForWS set to null by another thread"
)
}
private
var
httpClient
:
OkHttpClient
?
=
null
private
var
httpClientForUploadFile
:
OkHttpClient
?
=
null
private
var
httpClientForDownloadFile
:
OkHttpClient
?
=
null
private
var
httpClientForWS
:
OkHttpClient
?
=
null
...
...
app/src/main/AndroidManifest.xml
View file @
44241c63
...
...
@@ -32,6 +32,11 @@
</intent-filter>
</activity>
<activity
android:name=
".activity.room.RoomActivity"
android:configChanges=
"orientation|screenSize"
android:windowSoftInputMode=
"adjustResize"
/>
<activity
android:name=
".activity.AddServerActivity"
android:configChanges=
"orientation|screenSize"
...
...
app/src/main/java/chat/rocket/android/activity/MainActivity.java
View file @
44241c63
...
...
@@ -48,7 +48,6 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
private
SlidingPaneLayout
pane
;
private
MainContract
.
Presenter
presenter
;
@Override
protected
int
getLayoutContainerForFragment
()
{
return
R
.
id
.
activity_main_container
;
}
...
...
app/src/main/java/chat/rocket/android/activity/room/RoomActivity.kt
0 → 100644
View file @
44241c63
package
chat.rocket.android.activity.room
import
android.os.Bundle
import
android.support.v4.app.Fragment
import
android.support.v7.app.AppCompatActivity
import
chat.rocket.android.R
import
chat.rocket.android.fragment.chatroom.list.RoomListFragment
import
kotlinx.android.synthetic.main.activity_room.*
class
RoomActivity
:
AppCompatActivity
()
{
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
setContentView
(
R
.
layout
.
activity_room
)
setSupportActionBar
(
toolbar
)
supportActionBar
?.
setDisplayHomeAsUpEnabled
(
true
)
supportActionBar
?.
setDisplayShowHomeEnabled
(
true
)
val
extras
=
intent
.
extras
val
roomListFragment
=
RoomListFragment
.
newInstance
(
extras
.
getInt
(
"actionId"
),
extras
.
getString
(
"roomId"
),
extras
.
getString
(
"roomType"
),
extras
.
getString
(
"hostname"
),
extras
.
getString
(
"token"
),
extras
.
getString
(
"userId"
))
addFragment
(
roomListFragment
,
"roomListFragment"
)
}
override
fun
onSupportNavigateUp
():
Boolean
{
onBackPressed
()
return
true
}
private
fun
addFragment
(
fragment
:
Fragment
,
tag
:
String
)
{
supportFragmentManager
.
beginTransaction
()
.
add
(
R
.
id
.
fragment_container
,
fragment
,
tag
)
.
commit
()
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/api/rest/RestApiHelper.kt
0 → 100644
View file @
44241c63
package
chat.rocket.android.api.rest
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.core.models.Room
import
okhttp3.HttpUrl
import
okhttp3.Request
/**
* Helper class for dealing with Rest API calls.
*
* @see <a href="https://rocket.chat/docs/developer-guides/rest-api">https://rocket.chat/docs/developer-guides/rest-api</a>.
*/
object
RestApiHelper
{
/**
* Returns an OkHttp3 request for pinned messages.
*
* @param roomId The ID of the room.
* @param roomType The type of the room.
* @param hostname The server hostname.
* @param token The token.
* @param userId The user Id.
* @param offset The offset to paging which specifies the first entry to return from a collection.
* @return An OkHttp3 request.
*/
fun
getRequestForPinnedMessages
(
roomId
:
String
,
roomType
:
String
,
hostname
:
String
,
token
:
String
,
userId
:
String
,
offset
:
String
):
Request
{
val
parsedHttpUrl
=
HttpUrl
.
parse
(
getEndpointUrlForMessages
(
roomType
,
hostname
))
?.
newBuilder
()
?.
addQueryParameter
(
"roomId"
,
roomId
)
?.
addQueryParameter
(
"query"
,
"{\"pinned\":true}"
)
?.
addQueryParameter
(
"offset"
,
offset
)
?.
build
()
return
Request
.
Builder
()
.
url
(
parsedHttpUrl
)
.
get
()
.
addHeader
(
"X-Auth-Token"
,
token
)
.
addHeader
(
"X-User-Id"
,
userId
)
.
build
()
}
/**
* Returns an OkHttp3 request for favorite messages.
*
* @param roomId The ID of the room.
* @param roomType The type of the room.
* @param hostname The server hostname.
* @param token The token.
* @param userId The user Id.
* @param offset The offset to paging which specifies the first entry to return from a collection.
* @return An OkHttp3 request.
*/
fun
getRequestForFavoriteMessages
(
roomId
:
String
,
roomType
:
String
,
hostname
:
String
,
token
:
String
,
userId
:
String
,
offset
:
String
):
Request
{
val
parsedHttpUrl
=
HttpUrl
.
parse
(
getEndpointUrlForMessages
(
roomType
,
hostname
))
?.
newBuilder
()
?.
addQueryParameter
(
"roomId"
,
roomId
)
?.
addQueryParameter
(
"query"
,
"{\"starred._id\":{\"\$in\":[\"$userId\"] } }"
)
?.
addQueryParameter
(
"offset"
,
offset
)
?.
build
()
return
Request
.
Builder
()
.
url
(
parsedHttpUrl
)
.
get
()
.
addHeader
(
"X-Auth-Token"
,
token
)
.
addHeader
(
"X-User-Id"
,
userId
)
.
build
()
}
/**
* Returns an OkHttp3 request for file list.
*
* @param roomId The ID of the room.
* @param roomType The type of the room.
* @param hostname The server hostname.
* @param token The token.
* @param userId The user Id.
* @param offset The offset to paging which specifies the first entry to return from a collection.
* @return An OkHttp3 request.
*/
fun
getRequestForFileList
(
roomId
:
String
,
roomType
:
String
,
hostname
:
String
,
token
:
String
,
userId
:
String
,
offset
:
String
):
Request
{
val
parsedHttpUrl
=
HttpUrl
.
parse
(
getEndpointUrlForFileList
(
roomType
,
hostname
))
?.
newBuilder
()
?.
addQueryParameter
(
"roomId"
,
roomId
)
?.
addQueryParameter
(
"offset"
,
offset
)
?.
build
()
return
Request
.
Builder
()
.
url
(
parsedHttpUrl
)
.
get
()
.
addHeader
(
"X-Auth-Token"
,
token
)
.
addHeader
(
"X-User-Id"
,
userId
)
.
build
()
}
/**
* Returns an OkHttp3 request for member list.
*
* @param roomId The ID of the room.
* @param roomType The type of the room.
* @param hostname The server hostname.
* @param token The token.
* @param userId The user Id.
* @param offset The offset to paging which specifies the first entry to return from a collection.
* @return An OkHttp3 request.
*/
fun
getRequestForMemberList
(
roomId
:
String
,
roomType
:
String
,
hostname
:
String
,
token
:
String
,
userId
:
String
,
offset
:
String
):
Request
{
val
parsedHttpUrl
=
HttpUrl
.
parse
(
getEndpointUrlForMemberList
(
roomType
,
hostname
))
?.
newBuilder
()
?.
addQueryParameter
(
"roomId"
,
roomId
)
?.
addQueryParameter
(
"offset"
,
offset
)
?.
build
()
return
Request
.
Builder
()
.
url
(
parsedHttpUrl
)
.
get
()
.
addHeader
(
"X-Auth-Token"
,
token
)
.
addHeader
(
"X-User-Id"
,
userId
)
.
build
()
}
/**
* Returns a Rest API endpoint URL for favorite or pinned messages accordingly with the room type and the server hostname.
*
* @param roomType The type of the room.
* @param hostname The server hostname.
* @return A Rest API URL endpoint.
*/
fun
getEndpointUrlForMessages
(
roomType
:
String
,
hostname
:
String
):
String
=
UrlHelper
.
getSafeHostname
(
hostname
)
+
getRestApiUrlForMessages
(
roomType
)
/**
* Returns a Rest API endpoint URL for file list accordingly with the room type and the server hostname.
*
* @param roomType The type of the room.
* @param hostname The server hostname.
* @return A Rest API URL endpoint.
*/
fun
getEndpointUrlForFileList
(
roomType
:
String
,
hostname
:
String
):
String
=
UrlHelper
.
getSafeHostname
(
hostname
)
+
getRestApiUrlForFileList
(
roomType
)
/**
* Returns a Rest API endpoint URL for member list accordingly with the room type and the server hostname.
*
* @param roomType The type of the room.
* @param hostname The server hostname.
* @return A Rest API URL endpoint.
*/
fun
getEndpointUrlForMemberList
(
roomType
:
String
,
hostname
:
String
):
String
=
UrlHelper
.
getSafeHostname
(
hostname
)
+
getRestApiUrlForMemberList
(
roomType
)
/**
* Returns the correspondent Rest API URL accordingly with the room type to get its favorite or pinned messages.
*
* @param roomType The type of the room.
* @return A Rest API URL or null if the room type does not match.
*/
fun
getRestApiUrlForMessages
(
roomType
:
String
):
String
?
{
var
restApiUrl
:
String
?
=
null
when
(
roomType
)
{
Room
.
TYPE_CHANNEL
->
restApiUrl
=
"/api/v1/channels.messages"
Room
.
TYPE_PRIVATE
->
restApiUrl
=
"/api/v1/groups.messages"
Room
.
TYPE_DIRECT_MESSAGE
->
restApiUrl
=
"/api/v1/dm.messages"
}
return
restApiUrl
}
/**
* Returns the correspondent Rest API URL accordingly with the room type to get its file list.
*
* @param roomType The type of the room.
* @return A Rest API URL or null if the room type does not match.
*/
fun
getRestApiUrlForFileList
(
roomType
:
String
):
String
?
{
var
restApiUrl
:
String
?
=
null
when
(
roomType
)
{
Room
.
TYPE_CHANNEL
->
restApiUrl
=
"/api/v1/channels.files"
Room
.
TYPE_PRIVATE
->
restApiUrl
=
"/api/v1/groups.files"
Room
.
TYPE_DIRECT_MESSAGE
->
restApiUrl
=
"/api/v1/dm.files"
}
return
restApiUrl
}
/**
* Returns the correspondent Rest API URL accordingly with the room type to get its members list.
*
* @param roomType The type of the room.
* @return A Rest API URL or null if the room type does not match.
*/
fun
getRestApiUrlForMemberList
(
roomType
:
String
):
String
?
{
var
restApiUrl
:
String
?
=
null
when
(
roomType
)
{
Room
.
TYPE_CHANNEL
->
restApiUrl
=
"/api/v1/channels.members"
Room
.
TYPE_PRIVATE
->
restApiUrl
=
"/api/v1/groups.members"
Room
.
TYPE_DIRECT_MESSAGE
->
restApiUrl
=
"/api/v1/dm.members"
}
return
restApiUrl
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/fragment/chatroom/RocketChatAbsoluteUrl.java
View file @
44241c63
...
...
@@ -21,4 +21,12 @@ public class RocketChatAbsoluteUrl implements AbsoluteUrl {
public
String
from
(
String
url
)
{
return
url
.
startsWith
(
"/"
)
?
baseUrl
+
url
+
"?rc_uid="
+
userId
+
"&rc_token="
+
token
:
url
;
}
}
public
String
getUserId
()
{
return
userId
;
}
public
String
getToken
()
{
return
token
;
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/fragment/chatroom/RoomFragment.java
View file @
44241c63
This diff is collapsed.
Click to expand it.
app/src/main/java/chat/rocket/android/fragment/chatroom/dialog/UsersOfRoomDialogFragment.java
deleted
100644 → 0
View file @
cf96cd2f
package
chat
.
rocket
.
android
.
fragment
.
chatroom
.
dialog
;
import
android.os.Bundle
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.Nullable
;
import
android.support.v7.widget.GridLayoutManager
;
import
android.support.v7.widget.RecyclerView
;
import
android.view.View
;
import
android.widget.TextView
;
import
com.hadisatrio.optional.Optional
;
import
io.reactivex.android.schedulers.AndroidSchedulers
;
import
io.reactivex.disposables.CompositeDisposable
;
import
org.json.JSONArray
;
import
org.json.JSONException
;
import
org.json.JSONObject
;
import
java.util.ArrayList
;
import
java.util.List
;
import
chat.rocket.android.BackgroundLooper
;
import
chat.rocket.android.R
;
import
chat.rocket.android.fragment.chatroom.RocketChatAbsoluteUrl
;
import
chat.rocket.android.helper.AbsoluteUrlHelper
;
import
chat.rocket.android.helper.LogIfError
;
import
chat.rocket.android.helper.Logger
;
import
chat.rocket.android.layouthelper.chatroom.dialog.RoomUserAdapter
;
import
chat.rocket.android.log.RCLog
;
import
chat.rocket.core.SyncState
;
import
chat.rocket.core.interactors.SessionInteractor
;
import
chat.rocket.persistence.realm.models.internal.GetUsersOfRoomsProcedure
;
import
chat.rocket.persistence.realm.RealmObjectObserver
;
import
chat.rocket.android.service.ConnectivityManager
;
import
chat.rocket.persistence.realm.repositories.RealmServerInfoRepository
;
import
chat.rocket.persistence.realm.repositories.RealmSessionRepository
;
import
chat.rocket.persistence.realm.repositories.RealmUserRepository
;
/**
* Dialog to show members in a room.
*/
public
class
UsersOfRoomDialogFragment
extends
AbstractChatRoomDialogFragment
{
private
String
hostname
;
private
RealmObjectObserver
<
GetUsersOfRoomsProcedure
>
procedureObserver
;
private
int
previousSyncState
;
private
CompositeDisposable
compositeDisposable
=
new
CompositeDisposable
();
public
UsersOfRoomDialogFragment
()
{
}
/**
* create UsersOfRoomDialogFragment with required parameters.
*/
public
static
UsersOfRoomDialogFragment
create
(
String
roomId
,
String
hostname
)
{
Bundle
args
=
new
Bundle
();
args
.
putString
(
"hostname"
,
hostname
);
args
.
putString
(
"roomId"
,
roomId
);
UsersOfRoomDialogFragment
fragment
=
new
UsersOfRoomDialogFragment
();
fragment
.
setArguments
(
args
);
return
fragment
;
}
@Override
public
void
onCreate
(
@Nullable
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
procedureObserver
=
realmHelper
.
createObjectObserver
(
realm
->
realm
.
where
(
GetUsersOfRoomsProcedure
.
class
).
equalTo
(
"roomId"
,
roomId
))
.
setOnUpdateListener
(
this
::
onUpdateGetUsersOfRoomProcedure
);
previousSyncState
=
SyncState
.
NOT_SYNCED
;
if
(
savedInstanceState
==
null
)
{
requestGetUsersOfRoom
();
}
}
@Override
protected
void
handleArgs
(
@NonNull
Bundle
args
)
{
super
.
handleArgs
(
args
);
hostname
=
args
.
getString
(
"hostname"
);
}
@Override
protected
int
getLayout
()
{
return
R
.
layout
.
dialog_users_of_room
;
}
@Override
protected
void
onSetupDialog
()
{
AbsoluteUrlHelper
absoluteUrlHelper
=
new
AbsoluteUrlHelper
(
hostname
,
new
RealmServerInfoRepository
(),
new
RealmUserRepository
(
hostname
),
new
SessionInteractor
(
new
RealmSessionRepository
(
hostname
))
);
compositeDisposable
.
add
(
absoluteUrlHelper
.
getRocketChatAbsoluteUrl
()
.
subscribeOn
(
AndroidSchedulers
.
from
(
BackgroundLooper
.
get
()))
.
observeOn
(
AndroidSchedulers
.
mainThread
())
.
subscribe
(
this
::
setupView
,
Logger:
:
report
)
);
}
private
void
setupView
(
Optional
<
RocketChatAbsoluteUrl
>
rocketChatAbsoluteUrlOptional
)
{
compositeDisposable
.
clear
();
if
(!
rocketChatAbsoluteUrlOptional
.
isPresent
())
{
return
;
}
RecyclerView
recyclerView
=
(
RecyclerView
)
getDialog
().
findViewById
(
R
.
id
.
recyclerview
);
recyclerView
.
setLayoutManager
(
new
GridLayoutManager
(
getContext
(),
2
));
recyclerView
.
setAdapter
(
new
RoomUserAdapter
(
getContext
(),
realmHelper
,
rocketChatAbsoluteUrlOptional
.
get
(),
hostname
));
}
private
void
requestGetUsersOfRoom
()
{
realmHelper
.
executeTransaction
(
realm
->
{
realm
.
createOrUpdateObjectFromJson
(
GetUsersOfRoomsProcedure
.
class
,
new
JSONObject
()
.
put
(
"roomId"
,
roomId
)
.
put
(
"syncstate"
,
SyncState
.
NOT_SYNCED
)
.
put
(
"showAll"
,
true
));
return
null
;
}).
onSuccessTask
(
task
->
{
ConnectivityManager
.
getInstance
(
getContext
().
getApplicationContext
())
.
keepAliveServer
();
return
task
;
}).
continueWith
(
new
LogIfError
());
}
@Override
public
void
onResume
()
{
super
.
onResume
();
procedureObserver
.
sub
();
}
@Override
public
void
onPause
()
{
procedureObserver
.
unsub
();
super
.
onPause
();
}
private
void
onUpdateGetUsersOfRoomProcedure
(
GetUsersOfRoomsProcedure
procedure
)
{
if
(
procedure
==
null
)
{
return
;
}
int
syncState
=
procedure
.
getSyncState
();
if
(
previousSyncState
!=
syncState
)
{
onSyncStateUpdated
(
syncState
);
previousSyncState
=
syncState
;
}
if
(
syncState
==
SyncState
.
SYNCED
)
{
onRenderTotalCount
(
procedure
.
getTotal
());
try
{
JSONArray
array
=
new
JSONArray
(
procedure
.
getRecords
());
ArrayList
<
String
>
users
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
array
.
length
();
i
++)
{
Object
userObject
=
array
.
get
(
i
);
if
(
userObject
instanceof
JSONObject
)
{
JSONObject
user
=
(
JSONObject
)
userObject
;
users
.
add
(
user
.
getString
(
"username"
));
}
else
{
users
.
add
((
String
)
userObject
);
}
}
onRenderUsers
(
users
);
}
catch
(
JSONException
exception
)
{
RCLog
.
e
(
exception
);
}
}
}
/**
* called only if prevSyncstate != newSyncstate.
*/
private
void
onSyncStateUpdated
(
int
newSyncState
)
{
boolean
show
=
newSyncState
==
SyncState
.
NOT_SYNCED
||
newSyncState
==
SyncState
.
SYNCING
;
getDialog
().
findViewById
(
R
.
id
.
waiting
).
setVisibility
(
show
?
View
.
VISIBLE
:
View
.
GONE
);
}
/**
* called only if syncstate = SYNCED.
*/
private
void
onRenderTotalCount
(
long
total
)
{
TextView
userCount
=
(
TextView
)
getDialog
().
findViewById
(
R
.
id
.
room_user_count
);
userCount
.
setText
(
getResources
().
getQuantityString
(
R
.
plurals
.
fmt_room_user_count
,
(
int
)
total
,
total
));
}
/**
* called only if syncstate = SYNCED.
*/
private
void
onRenderUsers
(
List
<
String
>
usernames
)
{
RecyclerView
recyclerView
=
(
RecyclerView
)
getDialog
().
findViewById
(
R
.
id
.
recyclerview
);
if
(
recyclerView
!=
null
&&
recyclerView
.
getAdapter
()
instanceof
RoomUserAdapter
)
{
((
RoomUserAdapter
)
recyclerView
.
getAdapter
()).
setUsernames
(
usernames
);
}
}
}
app/src/main/java/chat/rocket/android/fragment/chatroom/list/RoomListContract.kt
0 → 100644
View file @
44241c63
package
chat.rocket.android.fragment.chatroom.list
import
chat.rocket.core.models.Message
import
chat.rocket.core.models.User
/**
* Created by Filipe de Lima Brito (filipedelimabrito@gmail.com) on 9/22/17.
*/
interface
RoomListContract
{
interface
View
{
/**
* Shows a pinned message list of a room.
*
* @param dataSet The pinned message data set to show.
* @param total The total number of pinned messages.
*/
fun
showPinnedMessages
(
dataSet
:
ArrayList
<
Message
>,
total
:
String
)
/**
* Shows a favorite message list of a room.
*
* @param dataSet The favorite message data set to show.
* @param total The total number of favorite messages.
*/
fun
showFavoriteMessages
(
dataSet
:
ArrayList
<
Message
>,
total
:
String
)
/**
* Shows a file list of a room.
*
* @param dataSet The file data set to show.
* @param total The total number of files.
*/
fun
showFileList
(
dataSet
:
ArrayList
<
String
>,
total
:
String
)
/**
* Shows a list of members of a room.
*
* @param dataSet The member data set to show.
* @param total The total number of members.
*/
fun
showMemberList
(
dataSet
:
ArrayList
<
User
>,
total
:
String
)
/**
* Shows a message (e.g. An error or successful message after a request).
*
* @param message The message to show.
*/
fun
showMessage
(
message
:
String
)
/**
* Shows a waiting view whenever a (long) process is taken.
*
* @param shouldShow The Boolean value that indicates whether the view should be showed.
*/
fun
showWaitingView
(
shouldShow
:
Boolean
)
}
interface
Presenter
{
/**
* Requests the pinned messages of a room.
*
* @param roomId The room ID to process the request.
* @param roomType The room type to process the request.
* @param hostname The server hostname to process the request.
* @param token The token to process the request.
* @param userId The user ID to process the request.
* @param offset The offset to process the request.
*/
fun
requestPinnedMessages
(
roomId
:
String
,
roomType
:
String
,
hostname
:
String
,
token
:
String
,
userId
:
String
,
offset
:
Int
)
/**
* Requests the favorite messages of a room.
*
* @param roomId The room ID to process the request.
* @param roomType The room type to process the request.
* @param hostname The server hostname to process the request.
* @param token The token to process the request.
* @param userId The user ID to process the request.
* @param offset The offset to process the request.
*/
fun
requestFavoriteMessages
(
roomId
:
String
,
roomType
:
String
,
hostname
:
String
,
token
:
String
,
userId
:
String
,
offset
:
Int
)
/**
* Requests the file list of a room.
*
* @param roomId The room ID to process the request.
* @param roomType The room type to process the request.
* @param hostname The server hostname to process the request.
* @param token The token to process the request.
* @param userId The user ID to process the request.
* @param offset The offset to process the request.
*/
fun
requestFileList
(
roomId
:
String
,
roomType
:
String
,
hostname
:
String
,
token
:
String
,
userId
:
String
,
offset
:
Int
)
/**
* Requests the member list of a room.
*
* @param roomId The room ID to process the request.
* @param roomType The room type to process the request.
* @param hostname The server hostname to process the request.
* @param token The token to process the request.
* @param userId The user ID to process the request.
* @param offset The offset to process the request.
*/
fun
requestMemberList
(
roomId
:
String
,
roomType
:
String
,
hostname
:
String
,
token
:
String
,
userId
:
String
,
offset
:
Int
)
/**
* Immediately cancels any running request.
*/
fun
cancelRequest
()
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/fragment/chatroom/list/RoomListFragment.kt
0 → 100644
View file @
44241c63
package
chat.rocket.android.fragment.chatroom.list
import
android.os.Bundle
import
android.support.v4.app.Fragment
import
android.support.v7.widget.LinearLayoutManager
import
android.support.v7.widget.RecyclerView
import
android.view.LayoutInflater
import
android.view.View
import
android.view.ViewGroup
import
chat.rocket.android.R
import
chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import
chat.rocket.android.layouthelper.chatroom.list.RoomMemberListAdapter
import
chat.rocket.android.layouthelper.chatroom.list.RoomMessagesAdapter
import
chat.rocket.core.models.Message
import
chat.rocket.core.models.User
import
kotlinx.android.synthetic.main.fragment_room_list.*
import
java.util.*
/**
* Created by Filipe de Lima Brito (filipedelimabrito@gmail.com) on 9/22/17.
*/
class
RoomListFragment
:
Fragment
(),
RoomListContract
.
View
{
companion
object
{
fun
newInstance
(
actionId
:
Int
,
roomId
:
String
,
roomType
:
String
,
hostname
:
String
,
token
:
String
,
userId
:
String
):
RoomListFragment
{
val
args
=
Bundle
()
args
.
putInt
(
"actionId"
,
actionId
)
args
.
putString
(
"roomId"
,
roomId
)
args
.
putString
(
"roomType"
,
roomType
)
args
.
putString
(
"hostname"
,
hostname
)
args
.
putString
(
"token"
,
token
)
args
.
putString
(
"userId"
,
userId
)
val
roomFileListDialogFragment
=
RoomListFragment
()
roomFileListDialogFragment
.
arguments
=
args
return
roomFileListDialogFragment
}
}
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
activity
.
title
=
""
actionId
=
arguments
.
getInt
(
"actionId"
)
roomId
=
arguments
.
getString
(
"roomId"
)
roomType
=
arguments
.
getString
(
"roomType"
)
hostname
=
arguments
.
getString
(
"hostname"
)
token
=
arguments
.
getString
(
"token"
)
userId
=
arguments
.
getString
(
"userId"
)
}
override
fun
onCreateView
(
inflater
:
LayoutInflater
?,
container
:
ViewGroup
?,
savedInstanceState
:
Bundle
?):
View
?
=
inflater
?.
inflate
(
R
.
layout
.
fragment_room_list
,
container
,
false
)
override
fun
onViewCreated
(
view
:
View
?,
savedInstanceState
:
Bundle
?)
{
super
.
onViewCreated
(
view
,
savedInstanceState
)
presenter
=
RoomListPresenter
(
context
,
this
)
}
override
fun
onResume
()
{
super
.
onResume
()
if
(!
isDataRequested
)
{
requestData
(
0
)
isDataRequested
=
true
}
}
override
fun
onPause
()
{
super
.
onPause
()
presenter
.
cancelRequest
()
}
private
fun
requestData
(
offset
:
Int
)
{
when
(
actionId
)
{
R
.
id
.
action_pinned_messages
->
{
presenter
.
requestPinnedMessages
(
roomId
,
roomType
,
hostname
,
token
,
userId
,
offset
)
}
R
.
id
.
action_favorite_messages
->
{
presenter
.
requestFavoriteMessages
(
roomId
,
roomType
,
hostname
,
token
,
userId
,
offset
)
}
R
.
id
.
action_member_list
->
{
presenter
.
requestMemberList
(
roomId
,
roomType
,
hostname
,
token
,
userId
,
offset
)
}
}
}
override
fun
showPinnedMessages
(
dataSet
:
ArrayList
<
Message
>,
total
:
String
)
{
activity
.
title
=
getString
(
R
.
string
.
fragment_room_list_pinned_message_title
,
total
)
if
(
recyclerView
.
adapter
==
null
)
{
recyclerView
.
adapter
=
RoomMessagesAdapter
(
dataSet
,
hostname
,
context
)
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
RoomMessagesAdapter
).
addDataSet
(
dataSet
)
}
}
override
fun
showFavoriteMessages
(
dataSet
:
ArrayList
<
Message
>,
total
:
String
)
{
activity
.
title
=
getString
(
R
.
string
.
fragment_room_list_favorite_message_title
,
total
)
if
(
recyclerView
.
adapter
==
null
)
{
recyclerView
.
adapter
=
RoomMessagesAdapter
(
dataSet
,
hostname
,
context
)
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
RoomMessagesAdapter
).
addDataSet
(
dataSet
)
}
}
// TODO (after REST api fixes)
override
fun
showFileList
(
dataSet
:
ArrayList
<
String
>,
total
:
String
)
{}
override
fun
showMemberList
(
dataSet
:
ArrayList
<
User
>,
total
:
String
)
{
activity
.
title
=
getString
(
R
.
string
.
fragment_room_list_member_list_title
,
total
)
if
(
recyclerView
.
adapter
==
null
)
{
recyclerView
.
adapter
=
RoomMemberListAdapter
(
dataSet
,
hostname
,
context
)
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
RoomMemberListAdapter
).
addDataSet
(
dataSet
)
}
}
override
fun
showMessage
(
message
:
String
)
{
messageText
.
text
=
message
messageText
.
visibility
=
View
.
VISIBLE
}
override
fun
showWaitingView
(
shouldShow
:
Boolean
)
{
if
(
shouldShow
)
{
waitingView
.
visibility
=
View
.
VISIBLE
}
else
{
waitingView
.
visibility
=
View
.
GONE
}
}
private
fun
loadNextDataFromApi
(
page
:
Int
)
{
requestData
(
page
*
50
)
}
private
var
actionId
:
Int
=
0
private
lateinit
var
roomId
:
String
private
lateinit
var
roomType
:
String
private
lateinit
var
hostname
:
String
private
lateinit
var
token
:
String
private
lateinit
var
userId
:
String
private
lateinit
var
presenter
:
RoomListContract
.
Presenter
private
var
isDataRequested
:
Boolean
=
false
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/fragment/chatroom/list/RoomListPresenter.kt
0 → 100644
View file @
44241c63
This diff is collapsed.
Click to expand it.
app/src/main/java/chat/rocket/android/helper/EndlessRecyclerViewScrollListener.kt
0 → 100644
View file @
44241c63
package
chat.rocket.android.helper
import
android.support.v7.widget.GridLayoutManager
import
android.support.v7.widget.LinearLayoutManager
import
android.support.v7.widget.RecyclerView
import
android.support.v7.widget.StaggeredGridLayoutManager
/**
* Created by Filipe de Lima Brito (filipedelimabrito@gmail.com) on 9/21/17.
* Source info: https://github.com/codepath/android_guides/wiki/Endless-Scrolling-with-AdapterViews-and-RecyclerView
*/
abstract
class
EndlessRecyclerViewScrollListener
:
RecyclerView
.
OnScrollListener
{
private
var
visibleThreshold
=
5
// The minimum amount of items to have below of the current scroll position before loading more.
private
var
currentPage
=
0
// The current offset index of data loaded
private
var
previousTotalItemCount
=
0
// The total number of items in the dataset after the last load
private
var
loading
=
true
// True if we are still waiting for the last set of data to load.
private
val
startingPageIndex
=
0
// Sets the starting page index
private
var
layoutManager
:
RecyclerView
.
LayoutManager
constructor
(
layoutManager
:
LinearLayoutManager
)
{
this
.
layoutManager
=
layoutManager
}
constructor
(
layoutManager
:
GridLayoutManager
)
{
this
.
layoutManager
=
layoutManager
visibleThreshold
*=
layoutManager
.
spanCount
}
constructor
(
layoutManager
:
StaggeredGridLayoutManager
)
{
this
.
layoutManager
=
layoutManager
visibleThreshold
*=
layoutManager
.
spanCount
}
private
fun
getLastVisibleItem
(
lastVisibleItemPositions
:
IntArray
):
Int
{
var
maxSize
=
0
for
(
i
in
lastVisibleItemPositions
.
indices
)
{
if
(
i
==
0
)
{
maxSize
=
lastVisibleItemPositions
[
i
]
}
else
if
(
lastVisibleItemPositions
[
i
]
>
maxSize
)
{
maxSize
=
lastVisibleItemPositions
[
i
]
}
}
return
maxSize
}
// This happens many times a second during a scroll, so be wary of the code you place here.
// We are given a few useful parameters to help us work out if we need to load some more data,
// but first we check if we are waiting for the previous load to finish.
override
fun
onScrolled
(
view
:
RecyclerView
?,
dx
:
Int
,
dy
:
Int
)
{
var
lastVisibleItemPosition
=
0
val
totalItemCount
=
layoutManager
.
itemCount
when
(
layoutManager
)
{
is
StaggeredGridLayoutManager
->
{
val
lastVisibleItemPositions
=
(
layoutManager
as
StaggeredGridLayoutManager
).
findLastVisibleItemPositions
(
null
)
// get maximum element within the list
lastVisibleItemPosition
=
getLastVisibleItem
(
lastVisibleItemPositions
)
}
is
GridLayoutManager
->
lastVisibleItemPosition
=
(
layoutManager
as
GridLayoutManager
).
findLastVisibleItemPosition
()
is
LinearLayoutManager
->
lastVisibleItemPosition
=
(
layoutManager
as
LinearLayoutManager
).
findLastVisibleItemPosition
()
}
// If the total item count is zero and the previous isn't, assume the
// list is invalidated and should be reset back to initial state
// If it’s still loading, we check to see if the dataset count has
// changed, if so we conclude it has finished loading and update the current page
// number and total item count.
// If it isn’t currently loading, we check to see if we have breached
// the visibleThreshold and need to reload more data.
// If we do need to reload some more data, we execute onLoadMore to fetch the data.
// threshold should reflect how many total columns there are too
// If the total item count is zero and the previous isn't, assume the
// list is invalidated and should be reset back to initial state
if
(
totalItemCount
<
previousTotalItemCount
)
{
this
.
currentPage
=
this
.
startingPageIndex
this
.
previousTotalItemCount
=
totalItemCount
if
(
totalItemCount
==
0
)
{
this
.
loading
=
true
}
}
// If it’s still loading, we check to see if the dataset count has
// changed, if so we conclude it has finished loading and update the current page
// number and total item count.
if
(
loading
&&
totalItemCount
>
previousTotalItemCount
)
{
loading
=
false
previousTotalItemCount
=
totalItemCount
}
// If it isn’t currently loading, we check to see if we have breached
// the visibleThreshold and need to reload more data.
// If we do need to reload some more data, we execute onLoadMore to fetch the data.
// threshold should reflect how many total columns there are too
if
(!
loading
&&
lastVisibleItemPosition
+
visibleThreshold
>
totalItemCount
)
{
currentPage
++
onLoadMore
(
currentPage
,
totalItemCount
,
view
)
loading
=
true
}
}
// Call this method whenever performing new searches
fun
resetState
()
{
this
.
currentPage
=
this
.
startingPageIndex
this
.
previousTotalItemCount
=
0
this
.
loading
=
true
}
// Defines the process for actually loading more data based on page
abstract
fun
onLoadMore
(
page
:
Int
,
totalItemsCount
:
Int
,
recyclerView
:
RecyclerView
?)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/helper/LoadMoreScrollListener.java
deleted
100644 → 0
View file @
cf96cd2f
package
chat
.
rocket
.
android
.
helper
;
import
android.support.v7.widget.LinearLayoutManager
;
import
android.support.v7.widget.RecyclerView
;
@SuppressWarnings
(
"PMD.AbstractNaming"
)
public
abstract
class
LoadMoreScrollListener
extends
RecyclerView
.
OnScrollListener
{
private
final
LinearLayoutManager
layoutManager
;
private
final
int
loadThreshold
;
private
boolean
isLoading
;
/**
* constructor. loadThreshold is better to set to 0.4 * total.
*/
public
LoadMoreScrollListener
(
LinearLayoutManager
layoutManager
,
int
loadThreshold
)
{
this
.
layoutManager
=
layoutManager
;
this
.
loadThreshold
=
loadThreshold
;
setLoadingDone
();
}
@Override
public
void
onScrolled
(
RecyclerView
recyclerView
,
int
deltaX
,
int
deltaY
)
{
super
.
onScrolled
(
recyclerView
,
deltaX
,
deltaY
);
final
int
visibleItemCount
=
recyclerView
.
getChildCount
();
final
int
totalItemCount
=
layoutManager
.
getItemCount
();
final
int
firstVisibleItem
=
layoutManager
.
findFirstVisibleItemPosition
();
if
(!
isLoading
&&
firstVisibleItem
+
visibleItemCount
>=
totalItemCount
-
loadThreshold
&&
visibleItemCount
<
totalItemCount
&&
deltaY
<
0
)
{
isLoading
=
true
;
requestMoreItem
();
}
}
public
void
setLoadingDone
()
{
isLoading
=
false
;
}
public
abstract
void
requestMoreItem
();
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/helper/LoadMoreScrollListener.kt
0 → 100644
View file @
44241c63
package
chat.rocket.android.helper
import
android.support.v7.widget.LinearLayoutManager
import
android.support.v7.widget.RecyclerView
abstract
class
LoadMoreScrollListener
(
private
val
layoutManager
:
LinearLayoutManager
,
private
val
visibleThreshold
:
Int
)
:
RecyclerView
.
OnScrollListener
()
{
private
var
isLoading
:
Boolean
=
false
override
fun
onScrolled
(
recyclerView
:
RecyclerView
,
deltaX
:
Int
,
deltaY
:
Int
)
{
super
.
onScrolled
(
recyclerView
,
deltaX
,
deltaY
)
val
visibleItemCount
=
recyclerView
.
childCount
val
totalItemCount
=
layoutManager
.
itemCount
val
firstVisibleItem
=
layoutManager
.
findFirstVisibleItemPosition
()
if
(!
isLoading
&&
(
firstVisibleItem
+
visibleItemCount
)
>=
(
totalItemCount
-
visibleThreshold
)
&&
visibleItemCount
<
totalItemCount
&&
deltaY
<
0
)
{
isLoading
=
true
requestMoreItem
()
}
}
fun
setLoadingDone
()
{
isLoading
=
false
}
abstract
fun
requestMoreItem
()
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/helper/UrlHelper.kt
0 → 100644
View file @
44241c63
package
chat.rocket.android.helper
object
UrlHelper
{
/**
* Returns an URI whit no scheme (HTTP or HTTPS)
*
* @param uri The URI.
* @return The URI whit no scheme (HTTP or HTTPS)
*/
fun
removeUriScheme
(
uri
:
String
)
=
uri
.
replace
(
"http://"
,
""
).
replace
(
"https://"
,
""
)
/**
* Returns the hostname with the security protocol (scheme) HTTPS.
*
* @param hostname The hostname.
* @return The hostname with the security protocol (scheme) HTTPS.
*/
fun
getSafeHostname
(
hostname
:
String
):
String
=
"https://"
+
hostname
.
replace
(
"http://"
,
""
).
replace
(
"https://"
,
""
)
/**
* Returns an URL with no spaces and inverted slashes.
*
* @param url The URL.
* @return The URL with no spaces and inverted slashes.
*/
fun
getUrl
(
url
:
String
)
=
url
.
replace
(
" "
,
"%20"
).
replace
(
"\\"
,
""
)
/**
* Returns an URL for a file.
*
* @param path The path to the file.
* @param userId The user ID.
* @param token The token.
* @return The URL for a file
*/
fun
getUrlForFile
(
path
:
String
,
userId
:
String
,
token
:
String
):
String
=
"https://"
+
removeUriScheme
(
getUrl
(
path
))
+
"?rc_uid=$userId"
+
"&rc_token=$token"
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/layouthelper/chatroom/AbstractMessageViewHolder.java
View file @
44241c63
...
...
@@ -34,8 +34,8 @@ public abstract class AbstractMessageViewHolder extends ModelViewHolder<PairedMe
subUsername
=
itemView
.
findViewById
(
R
.
id
.
sub_username
);
timestamp
=
itemView
.
findViewById
(
R
.
id
.
timestamp
);
userAndTimeContainer
=
itemView
.
findViewById
(
R
.
id
.
user_and_timestamp_container
);
newDayContainer
=
itemView
.
findViewById
(
R
.
id
.
newday_c
ontainer
);
newDayText
=
itemView
.
findViewById
(
R
.
id
.
newday_text
);
newDayContainer
=
itemView
.
findViewById
(
R
.
id
.
dayC
ontainer
);
newDayText
=
itemView
.
findViewById
(
R
.
id
.
day
);
this
.
absoluteUrl
=
absoluteUrl
;
this
.
hostname
=
hostname
;
}
...
...
app/src/main/java/chat/rocket/android/layouthelper/chatroom/list/RoomFileListAdapter.kt
0 → 100644
View file @
44241c63
package
chat.rocket.android.layouthelper.chatroom.list
import
android.support.v7.widget.RecyclerView
import
android.view.LayoutInflater
import
android.view.View
import
android.view.ViewGroup
import
chat.rocket.android.R
import
chat.rocket.android.widget.message.RocketChatMessageLayout
import
kotlinx.android.synthetic.main.item_room_file.view.*
/**
* Created by Filipe de Lima Brito (filipedelimabrito@gmail.com) on 9/22/17.
*/
class
RoomFileListAdapter
(
private
var
dataSet
:
List
<
String
>)
:
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
)
return
ViewHolder
(
view
)
}
override
fun
onBindViewHolder
(
holder
:
ViewHolder
,
position
:
Int
)
{
holder
.
fileNameLink
.
setText
(
dataSet
[
position
])
}
override
fun
getItemCount
():
Int
=
dataSet
.
size
fun
setDataSet
(
dataSet
:
List
<
String
>)
{
this
.
dataSet
=
dataSet
notifyDataSetChanged
()
}
class
ViewHolder
(
itemView
:
View
)
:
RecyclerView
.
ViewHolder
(
itemView
)
{
val
fileNameLink
:
RocketChatMessageLayout
=
itemView
.
fileLink
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/layouthelper/chatroom/list/RoomMemberListAdapter.kt
0 → 100644
View file @
44241c63
package
chat.rocket.android.layouthelper.chatroom.list
import
android.content.Context
import
android.graphics.drawable.Drawable
import
android.support.graphics.drawable.VectorDrawableCompat
import
android.support.v7.widget.RecyclerView
import
android.view.LayoutInflater
import
android.view.View
import
android.view.ViewGroup
import
android.widget.ImageView
import
android.widget.TextView
import
chat.rocket.android.R
import
chat.rocket.android.widget.RocketChatAvatar
import
chat.rocket.android.widget.helper.AvatarHelper
import
chat.rocket.android.widget.helper.DrawableHelper
import
chat.rocket.core.models.User
import
kotlinx.android.synthetic.main.item_room_member.view.*
/**
* Created by Filipe de Lima Brito (filipedelimabrito@gmail.com) on 9/22/17.
*/
class
RoomMemberListAdapter
(
private
var
dataSet
:
List
<
User
>,
private
val
hostname
:
String
,
private
val
context
:
Context
)
:
RecyclerView
.
Adapter
<
RoomMemberListAdapter
.
ViewHolder
>()
{
override
fun
onCreateViewHolder
(
parent
:
ViewGroup
,
viewType
:
Int
):
ViewHolder
{
val
view
=
LayoutInflater
.
from
(
parent
.
context
).
inflate
(
R
.
layout
.
item_room_member
,
parent
,
false
)
return
ViewHolder
(
view
)
}
override
fun
onBindViewHolder
(
holder
:
ViewHolder
,
position
:
Int
)
{
val
user
=
dataSet
[
position
]
holder
.
name
.
text
=
user
.
name
val
userStatusDrawable
:
Drawable
?
=
VectorDrawableCompat
.
create
(
context
.
resources
,
chat
.
rocket
.
android
.
widget
.
R
.
drawable
.
ic_user_status_black_24dp
,
null
)
DrawableHelper
.
wrapDrawable
(
userStatusDrawable
)
when
(
user
.
status
)
{
User
.
STATUS_ONLINE
->
DrawableHelper
.
tintDrawable
(
userStatusDrawable
,
context
,
chat
.
rocket
.
android
.
widget
.
R
.
color
.
color_user_status_online
)
User
.
STATUS_BUSY
->
DrawableHelper
.
tintDrawable
(
userStatusDrawable
,
context
,
chat
.
rocket
.
android
.
widget
.
R
.
color
.
color_user_status_busy
)
User
.
STATUS_AWAY
->
DrawableHelper
.
tintDrawable
(
userStatusDrawable
,
context
,
chat
.
rocket
.
android
.
widget
.
R
.
color
.
color_user_status_away
)
User
.
STATUS_OFFLINE
->
DrawableHelper
.
tintDrawable
(
userStatusDrawable
,
context
,
chat
.
rocket
.
android
.
widget
.
R
.
color
.
color_user_status_offline
)
}
holder
.
status
.
setImageDrawable
(
userStatusDrawable
)
val
username
=
user
.
username
if
(
username
!=
null
)
{
holder
.
username
.
text
=
context
.
getString
(
R
.
string
.
username
,
username
)
val
placeholderDrawable
=
AvatarHelper
.
getTextDrawable
(
username
,
holder
.
userAvatar
.
context
)
holder
.
userAvatar
.
loadImage
(
AvatarHelper
.
getUri
(
hostname
,
username
),
placeholderDrawable
)
}
else
{
holder
.
userAvatar
.
visibility
=
View
.
GONE
holder
.
username
.
visibility
=
View
.
GONE
}
}
override
fun
getItemCount
():
Int
=
dataSet
.
size
fun
addDataSet
(
dataSet
:
List
<
User
>)
{
val
previousDataSetSize
=
this
.
dataSet
.
size
this
.
dataSet
+=
dataSet
notifyItemRangeInserted
(
previousDataSetSize
,
dataSet
.
size
)
}
class
ViewHolder
(
itemView
:
View
)
:
RecyclerView
.
ViewHolder
(
itemView
)
{
val
userAvatar
:
RocketChatAvatar
=
itemView
.
userAvatar
val
name
:
TextView
=
itemView
.
name
val
status
:
ImageView
=
itemView
.
status
val
username
:
TextView
=
itemView
.
username
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/layouthelper/chatroom/list/RoomMessagesAdapter.kt
0 → 100644
View file @
44241c63
package
chat.rocket.android.layouthelper.chatroom.list
import
android.content.Context
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.helper.DateTime
import
chat.rocket.android.widget.RocketChatAvatar
import
chat.rocket.android.widget.helper.AvatarHelper
import
chat.rocket.android.widget.message.RocketChatMessageAttachmentsLayout
import
chat.rocket.android.widget.message.RocketChatMessageLayout
import
chat.rocket.android.widget.message.RocketChatMessageUrlsLayout
import
chat.rocket.core.models.Message
import
kotlinx.android.synthetic.main.day.view.*
import
kotlinx.android.synthetic.main.item_room_message.view.*
/**
* Created by Filipe de Lima Brito (filipedelimabrito@gmail.com) on 9/22/17.
*/
class
RoomMessagesAdapter
(
private
var
dataSet
:
List
<
Message
>,
private
val
hostname
:
String
,
private
val
context
:
Context
)
:
RecyclerView
.
Adapter
<
RoomMessagesAdapter
.
ViewHolder
>()
{
override
fun
onCreateViewHolder
(
parent
:
ViewGroup
,
viewType
:
Int
):
ViewHolder
{
val
view
=
LayoutInflater
.
from
(
parent
.
context
).
inflate
(
R
.
layout
.
item_room_message
,
parent
,
false
)
return
ViewHolder
(
view
)
}
override
fun
onBindViewHolder
(
holder
:
ViewHolder
,
position
:
Int
)
{
val
message
=
dataSet
[
position
]
holder
.
newDay
.
text
=
DateTime
.
fromEpocMs
(
message
.
timestamp
,
DateTime
.
Format
.
DATE
)
val
user
=
message
.
user
if
(
user
!=
null
)
{
if
(
user
.
name
.
isNullOrBlank
())
{
holder
.
name
.
visibility
=
View
.
GONE
}
else
{
holder
.
name
.
text
=
message
.
user
?.
name
}
val
username
=
user
.
username
if
(
username
!=
null
)
{
val
placeholderDrawable
=
AvatarHelper
.
getTextDrawable
(
username
,
holder
.
userAvatar
.
context
)
holder
.
userAvatar
.
loadImage
(
AvatarHelper
.
getUri
(
hostname
,
username
),
placeholderDrawable
)
holder
.
username
.
text
=
context
.
getString
(
R
.
string
.
username
,
username
)
}
else
{
holder
.
userAvatar
.
visibility
=
View
.
GONE
holder
.
username
.
visibility
=
View
.
GONE
}
}
holder
.
messageBody
.
setText
(
message
.
message
)
val
webContents
=
message
.
webContents
if
(
webContents
==
null
||
webContents
.
isEmpty
())
{
holder
.
messageUrl
.
visibility
=
View
.
GONE
}
else
{
holder
.
messageUrl
.
setUrls
(
message
.
webContents
,
true
)
}
val
attachments
=
message
.
attachments
if
(
attachments
==
null
||
attachments
.
isEmpty
())
{
holder
.
messageAttachment
.
visibility
=
View
.
GONE
}
else
{
// holder.messageAttachment.setAbsoluteUrl(absoluteUrl)
// holder.messageAttachment.setAttachments(attachments, true)
// holder.messageAttachment.visibility = View.VISIBLE
}
}
override
fun
getItemCount
():
Int
=
dataSet
.
size
fun
addDataSet
(
dataSet
:
List
<
Message
>)
{
val
previousDataSetSize
=
this
.
dataSet
.
size
this
.
dataSet
+=
dataSet
notifyItemRangeInserted
(
previousDataSetSize
,
dataSet
.
size
)
}
class
ViewHolder
(
itemView
:
View
)
:
RecyclerView
.
ViewHolder
(
itemView
)
{
val
newDay
:
TextView
=
itemView
.
day
val
userAvatar
:
RocketChatAvatar
=
itemView
.
userAvatar
val
username
:
TextView
=
itemView
.
username
val
name
:
TextView
=
itemView
.
name
val
messageBody
:
RocketChatMessageLayout
=
itemView
.
messageBody
val
messageUrl
:
RocketChatMessageUrlsLayout
=
itemView
.
messageUrl
val
messageAttachment
:
RocketChatMessageAttachmentsLayout
=
itemView
.
messageAttachment
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/layouthelper/chatroom/
dialog
/RoomUserAdapter.java
→
app/src/main/java/chat/rocket/android/layouthelper/chatroom/
list
/RoomUserAdapter.java
View file @
44241c63
package
chat
.
rocket
.
android
.
layouthelper
.
chatroom
.
dialog
;
package
chat
.
rocket
.
android
.
layouthelper
.
chatroom
.
list
;
import
android.content.Context
;
import
android.support.v7.widget.RecyclerView
;
...
...
app/src/main/java/chat/rocket/android/layouthelper/chatroom/
dialog
/RoomUserViewHolder.java
→
app/src/main/java/chat/rocket/android/layouthelper/chatroom/
list
/RoomUserViewHolder.java
View file @
44241c63
package
chat
.
rocket
.
android
.
layouthelper
.
chatroom
.
dialog
;
package
chat
.
rocket
.
android
.
layouthelper
.
chatroom
.
list
;
import
android.support.v7.widget.RecyclerView
;
import
android.view.View
;
...
...
app/src/main/java/chat/rocket/android/push/PushNotificationHandler.java
View file @
44241c63
...
...
@@ -39,6 +39,7 @@ import java.util.Random;
import
chat.rocket.android.activity.MainActivity
;
import
chat.rocket.android.helper.ServerPolicyHelper
;
import
chat.rocket.android.service.ConnectivityManager
;
import
chat.rocket.android.widget.helper.AvatarHelper
;
import
chat.rocket.core.models.ServerInfo
;
public
class
PushNotificationHandler
implements
PushConstants
{
...
...
@@ -497,7 +498,7 @@ public class PushNotificationHandler implements PushConstants {
setNotification
(
notId
,
""
);
NotificationCompat
.
BigPictureStyle
bigPicture
=
new
NotificationCompat
.
BigPictureStyle
();
bigPicture
.
bigPicture
(
getBitmapFromURL
(
extras
.
getString
(
PICTURE
)));
bigPicture
.
bigPicture
(
getBitmapFromURL
(
extras
.
getString
(
PICTURE
)
,
null
,
null
));
bigPicture
.
setBigContentTitle
(
fromHtml
(
extras
.
getString
(
TITLE
)));
bigPicture
.
setSummaryText
(
fromHtml
(
extras
.
getString
(
SUMMARY_TEXT
)));
...
...
@@ -566,7 +567,7 @@ public class PushNotificationHandler implements PushConstants {
setNotification
(
notId
,
""
);
Notification
.
BigPictureStyle
bigPicture
=
new
Notification
.
BigPictureStyle
();
bigPicture
.
bigPicture
(
getBitmapFromURL
(
extras
.
getString
(
PICTURE
)));
bigPicture
.
bigPicture
(
getBitmapFromURL
(
extras
.
getString
(
PICTURE
)
,
null
,
null
));
bigPicture
.
setBigContentTitle
(
fromHtml
(
extras
.
getString
(
TITLE
)));
bigPicture
.
setSummaryText
(
fromHtml
(
extras
.
getString
(
SUMMARY_TEXT
)));
...
...
@@ -726,13 +727,22 @@ public class PushNotificationHandler implements PushConstants {
private
void
setNotificationLargeIcon
(
Context
context
,
Bundle
extras
,
String
packageName
,
Resources
resources
,
NotificationCompat
.
Builder
builder
)
{
String
gcmLargeIcon
=
extras
.
getString
(
IMAGE
);
// from gcm
String
hostname
=
getHostname
(
extras
);
String
username
=
getSenderUsername
(
extras
);
String
gcmLargeIcon
;
if
(
username
!=
null
&&
!
username
.
isEmpty
())
{
gcmLargeIcon
=
"https://"
+
hostname
+
"/avatar/"
+
username
;
}
else
{
gcmLargeIcon
=
extras
.
getString
(
IMAGE
);
// from gcm
}
if
(
gcmLargeIcon
==
null
||
""
.
equals
(
gcmLargeIcon
))
{
return
;
}
if
(
gcmLargeIcon
.
startsWith
(
"http://"
)
||
gcmLargeIcon
.
startsWith
(
"https://"
))
{
builder
.
setLargeIcon
(
getBitmapFromURL
(
gcmLargeIcon
));
builder
.
setLargeIcon
(
getBitmapFromURL
(
gcmLargeIcon
,
username
,
context
));
Log
.
d
(
LOG_TAG
,
"using remote large-icon from gcm"
);
}
else
{
AssetManager
assetManager
=
context
.
getAssets
();
...
...
@@ -757,13 +767,22 @@ public class PushNotificationHandler implements PushConstants {
private
void
setNotificationLargeIcon
(
Context
context
,
Bundle
extras
,
String
packageName
,
Resources
resources
,
Notification
.
Builder
builder
)
{
String
gcmLargeIcon
=
extras
.
getString
(
IMAGE
);
// from gcm
String
hostname
=
getHostname
(
extras
);
String
username
=
getSenderUsername
(
extras
);
String
gcmLargeIcon
;
if
(
username
!=
null
&&
!
username
.
isEmpty
())
{
gcmLargeIcon
=
"https://"
+
hostname
+
"/avatar/"
+
username
;
}
else
{
gcmLargeIcon
=
extras
.
getString
(
IMAGE
);
// from gcm
}
if
(
gcmLargeIcon
==
null
||
""
.
equals
(
gcmLargeIcon
))
{
return
;
}
if
(
gcmLargeIcon
.
startsWith
(
"http://"
)
||
gcmLargeIcon
.
startsWith
(
"https://"
))
{
builder
.
setLargeIcon
(
getBitmapFromURL
(
gcmLargeIcon
));
builder
.
setLargeIcon
(
getBitmapFromURL
(
gcmLargeIcon
,
username
,
context
));
Log
.
d
(
LOG_TAG
,
"using remote large-icon from gcm"
);
}
else
{
AssetManager
assetManager
=
context
.
getAssets
();
...
...
@@ -854,17 +873,23 @@ public class PushNotificationHandler implements PushConstants {
intent
.
putExtra
(
NOT_ID
,
notId
);
}
public
Bitmap
getBitmapFromURL
(
String
strURL
)
{
public
Bitmap
getBitmapFromURL
(
String
strURL
,
String
username
,
Context
context
)
{
try
{
URL
url
=
new
URL
(
strURL
);
HttpURLConnection
connection
=
(
HttpURLConnection
)
url
.
openConnection
();
connection
.
setDoInput
(
true
);
connection
.
connect
();
InputStream
input
=
connection
.
getInputStream
();
return
BitmapFactory
.
decodeStream
(
input
);
Bitmap
bitmap
=
BitmapFactory
.
decodeStream
(
input
);
if
(
bitmap
==
null
&&
username
!=
null
&&
context
!=
null
)
{
return
AvatarHelper
.
INSTANCE
.
getTextBitmap
(
username
,
context
);
}
return
bitmap
;
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
return
null
;
e
.
printStackTrace
();
return
null
;
}
}
...
...
@@ -937,6 +962,15 @@ public class PushNotificationHandler implements PushConstants {
}
}
private
String
getSenderUsername
(
Bundle
extras
)
{
try
{
JSONObject
jsonObject
=
new
JSONObject
(
extras
.
getString
(
"ejson"
,
"[]"
));
return
jsonObject
.
getJSONObject
(
"sender"
).
optString
(
"username"
);
}
catch
(
JSONException
e
)
{
return
null
;
}
}
private
boolean
isValidHostname
(
Context
context
,
String
hostname
)
{
final
List
<
ServerInfo
>
serverInfoList
=
ConnectivityManager
.
getInstance
(
context
.
getApplicationContext
()).
getServerList
();
...
...
app/src/main/res/drawable-anydpi-v21/rocket_chat_notification.xml
View file @
44241c63
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:height
=
"24dp"
android:viewportHeight=
"48.0
"
android:viewportWidth
=
"48.0"
android:width=
"24dp
"
>
android:width
=
"24dp"
android:height=
"24dp
"
android:viewportHeight
=
"48.0"
android:viewportWidth=
"48.0
"
>
<path
android:fillColor=
"#A3000000"
android:pathData=
"M44.99,23.47C44.99,21.42 44.38,19.45 43.16,17.62C42.07,15.97 40.54,14.52 38.62,13.29C34.91,10.92 30.03,9.62 24.88,9.62C23.16,9.62 21.47,9.77 19.82,10.05C18.8,9.1 17.61,8.24 16.35,7.57C9.6,4.3 4,7.49 4,7.49C4,7.49 9.21,11.76 8.36,15.49C6.03,17.8 4.77,20.58 4.77,23.47C4.77,23.48 4.77,23.49 4.77,23.5C4.77,23.51 4.77,23.51 4.77,23.52C4.77,26.42 6.03,29.2 8.36,31.5C9.21,35.24 4,39.5 4,39.5C4,39.5 9.6,42.69 16.35,39.43C17.61,38.75 18.8,37.89 19.82,36.94C21.47,37.23 23.16,37.37 24.88,37.37C30.03,37.37 34.91,36.07 38.62,33.7C40.54,32.48 42.07,31.02 43.16,29.38C44.38,27.55 44.99,25.58 44.99,23.53C44.99,23.52 44.99,23.51 44.99,23.5L44.99,23.47ZM24.88,12.53C34.41,12.53 42.14,17.45 42.14,23.52C42.14,29.6 34.41,34.52 24.88,34.52C22.76,34.52 20.73,34.28 18.85,33.83C16.94,36.12 12.74,39.31 8.67,38.28C9.99,36.86 11.96,34.45 11.54,30.5C9.09,28.6 7.63,26.17 7.63,23.52C7.63,17.45 15.35,12.53 24.88,12.53Z"
android:strokeColor=
"#00000000"
android:strokeWidth=
"1"
/>
android:fillColor=
"#FFFFFFFF"
android:pathData=
"M44.99,23.47C44.99,21.42 44.38,19.45 43.16,17.62C42.07,15.97 40.54,14.52 38.62,13.29C34.91,10.92 30.03,9.62 24.88,9.62C23.16,9.62 21.47,9.77 19.82,10.05C18.8,9.1 17.61,8.24 16.35,7.57C9.6,4.3 4,7.49 4,7.49C4,7.49 9.21,11.76 8.36,15.49C6.03,17.8 4.77,20.58 4.77,23.47C4.77,23.48 4.77,23.49 4.77,23.5C4.77,23.51 4.77,23.51 4.77,23.52C4.77,26.42 6.03,29.2 8.36,31.5C9.21,35.24 4,39.5 4,39.5C4,39.5 9.6,42.69 16.35,39.43C17.61,38.75 18.8,37.89 19.82,36.94C21.47,37.23 23.16,37.37 24.88,37.37C30.03,37.37 34.91,36.07 38.62,33.7C40.54,32.48 42.07,31.02 43.16,29.38C44.38,27.55 44.99,25.58 44.99,23.53C44.99,23.52 44.99,23.51 44.99,23.5L44.99,23.47ZM24.88,12.53C34.41,12.53 42.14,17.45 42.14,23.52C42.14,29.6 34.41,34.52 24.88,34.52C22.76,34.52 20.73,34.28 18.85,33.83C16.94,36.12 12.74,39.31 8.67,38.28C9.99,36.86 11.96,34.45 11.54,30.5C9.09,28.6 7.63,26.17 7.63,23.52C7.63,17.45 15.35,12.53 24.88,12.53Z"
/>
<path
android:fillColor=
"#A3000000"
android:pathData=
"M24.88,26.17C26.15,26.17 27.17,25.14 27.17,23.88C27.17,22.61 26.15,21.59 24.88,21.59C23.62,21.59 22.59,22.61 22.59,23.88C22.59,25.14 23.62,26.17 24.88,26.17ZM32.85,26.17C34.12,26.17 35.14,25.14 35.14,23.88C35.14,22.61 34.12,21.59 32.85,21.59C31.59,21.59 30.56,22.61 30.56,23.88C30.56,25.14 31.59,26.17 32.85,26.17ZM16.91,26.17C18.18,26.17 19.2,25.14 19.2,23.88C19.2,22.62 18.18,21.59 16.91,21.59C15.65,21.59 14.62,22.62 14.62,23.88C14.62,25.14 15.65,26.17 16.91,26.17L16.91,26.17Z"
android:strokeColor=
"#00000000"
android:strokeWidth=
"1"
/>
<path
android:fillColor=
"#33000000"
android:pathData=
"M24.88,33.08C22.76,33.08 20.73,32.86 18.85,32.48C17.17,34.23 13.69,36.59 10.1,36.5C9.62,37.22 9.11,37.8 8.67,38.28C12.74,39.31 16.94,36.12 18.85,33.83C20.73,34.28 22.76,34.52 24.88,34.52C34.34,34.52 42.01,29.68 42.13,23.67C42.01,28.88 34.34,33.08 24.88,33.08L24.88,33.08Z"
android:strokeColor=
"#00000000"
android:strokeWidth=
"1"
/>
android:fillColor=
"#FFFFFFFF"
android:pathData=
"M24.88,26.17C26.15,26.17 27.17,25.14 27.17,23.88C27.17,22.61 26.15,21.59 24.88,21.59C23.62,21.59 22.59,22.61 22.59,23.88C22.59,25.14 23.62,26.17 24.88,26.17ZM32.85,26.17C34.12,26.17 35.14,25.14 35.14,23.88C35.14,22.61 34.12,21.59 32.85,21.59C31.59,21.59 30.56,22.61 30.56,23.88C30.56,25.14 31.59,26.17 32.85,26.17ZM16.91,26.17C18.18,26.17 19.2,25.14 19.2,23.88C19.2,22.62 18.18,21.59 16.91,21.59C15.65,21.59 14.62,22.62 14.62,23.88C14.62,25.14 15.65,26.17 16.91,26.17L16.91,26.17Z"
/>
</vector>
app/src/main/res/drawable/ic_close_circle_outline_black_24dp.xml
0 → 100644
View file @
44241c63
<!-- drawable/close_circle_outline.xml -->
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"24dp"
android:height=
"24dp"
android:viewportHeight=
"24"
android:viewportWidth=
"24"
>
<path
android:fillColor=
"#FF000000"
android:pathData=
"M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2C6.47,2 2,6.47 2,12C2,17.53 6.47,22 12,22C17.53,22 22,17.53 22,12C22,6.47 17.53,2 12,2M14.59,8L12,10.59L9.41,8L8,9.41L10.59,12L8,14.59L9.41,16L12,13.41L14.59,16L16,14.59L13.41,12L16,9.41L14.59,8Z"
/>
</vector>
\ No newline at end of file
app/src/main/res/layout-w720dp/activity_main.xml
View file @
44241c63
...
...
@@ -17,7 +17,9 @@
<chat.rocket.android.widget.RoomToolbar
android:id=
"@+id/activity_main_toolbar"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
/>
android:layout_height=
"wrap_content"
app:theme=
"@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme=
"@style/ThemeOverlay.AppCompat.Light"
/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
...
...
app/src/main/res/layout-w720dp/fragment_room.xml
deleted
100644 → 0
View file @
cf96cd2f
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:orientation=
"horizontal"
tools:context=
"chat.rocket.android.fragment.chatroom.RoomFragment"
>
<include
layout=
"@layout/fragment_room_main"
/>
<include
layout=
"@layout/room_side_menu"
/>
</LinearLayout>
\ No newline at end of file
app/src/main/res/layout/activity_main.xml
View file @
44241c63
...
...
@@ -18,7 +18,9 @@
<chat.rocket.android.widget.RoomToolbar
android:id=
"@+id/activity_main_toolbar"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
/>
android:layout_height=
"wrap_content"
app:theme=
"@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme=
"@style/ThemeOverlay.AppCompat.Light"
/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
...
...
app/src/main/res/layout/activity_room.xml
0 → 100644
View file @
44241c63
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:orientation=
"vertical"
tools:context=
"chat.rocket.android.activity.room.RoomActivity"
>
<android.support.design.widget.AppBarLayout
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
<android.support.v7.widget.Toolbar
android:id=
"@+id/toolbar"
android:layout_width=
"match_parent"
android:layout_height=
"?attr/actionBarSize"
app:theme=
"@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme=
"@style/ThemeOverlay.AppCompat.Light"
/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id=
"@+id/fragment_container"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
/>
</LinearLayout>
\ No newline at end of file
app/src/main/res/layout/day.xml
0 → 100644
View file @
44241c63
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:id=
"@+id/dayContainer"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:gravity=
"center_vertical"
android:orientation=
"horizontal"
>
<View
android:layout_width=
"0px"
android:layout_height=
"1dp"
android:layout_weight=
"1"
android:background=
"@color/colorDivider"
/>
<TextView
android:id=
"@+id/day"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginLeft=
"16dp"
android:layout_marginRight=
"16dp"
android:textAppearance=
"@style/TextAppearance.RocketChat.Message.Day"
tools:text=
"2016/01/23"
/>
<View
android:layout_width=
"0px"
android:layout_height=
"1dp"
android:layout_weight=
"1"
android:background=
"@color/colorDivider"
/>
</LinearLayout>
\ No newline at end of file
app/src/main/res/layout/fragment_room.xml
View file @
44241c63
<?xml version="1.0" encoding="utf-8"?>
<
android.support.v4.widget.Drawer
Layout
xmlns:android=
"http://schemas.android.com/apk/res/android"
<
Relative
Layout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:id=
"@+id/
drawer_l
ayout"
android:id=
"@+id/
messageListRelativeL
ayout"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"@android:color/white"
tools:context=
"chat.rocket.android.fragment.chatroom.RoomFragment"
>
<include
layout=
"@layout/fragment_room_main"
/>
<FrameLayout
<android.support.v7.widget.RecyclerView
android:id=
"@+id/messageRecyclerView"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:layout_gravity=
"end"
android:clickable=
"true"
android:theme=
"@style/AppTheme.Dark"
>
android:scrollbars=
"vertical"
android:layout_above=
"@+id/messageComposer"
/>
<include
layout=
"@layout/room_side_menu"
/>
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
\ No newline at end of file
<chat.rocket.android.widget.message.MessageFormLayout
android:id=
"@+id/messageComposer"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_alignParentBottom=
"true"
android:theme=
"@style/Theme.AppCompat.Light"
/>
</RelativeLayout>
\ No newline at end of file
app/src/main/res/layout/fragment_room_list.xml
0 → 100644
View file @
44241c63
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:orientation=
"vertical"
>
<chat.rocket.android.widget.WaitingView
android:id=
"@+id/waitingView"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_centerInParent=
"true"
/>
<TextView
android:id=
"@+id/messageText"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_centerInParent=
"true"
android:visibility=
"gone"
/>
<android.support.v7.widget.RecyclerView
android:id=
"@+id/recyclerView"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:scrollbars=
"vertical"
/>
</RelativeLayout>
\ No newline at end of file
app/src/main/res/layout/fragment_room_main.xml
deleted
100644 → 0
View file @
cf96cd2f
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:id=
"@+id/messageListRelativeLayout"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"@android:color/white"
>
<android.support.v7.widget.RecyclerView
android:id=
"@+id/messageRecyclerView"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:scrollbars=
"vertical"
android:layout_above=
"@+id/messageComposer"
/>
<chat.rocket.android.widget.message.MessageFormLayout
android:id=
"@+id/messageComposer"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_alignParentBottom=
"true"
android:theme=
"@style/Theme.AppCompat.Light"
/>
</RelativeLayout>
\ No newline at end of file
app/src/main/res/layout/item_room_file.xml
0 → 100644
View file @
44241c63
<?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"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:padding=
"@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"
/>
<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"
/>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
app/src/main/res/layout/item_room_member.xml
0 → 100644
View file @
44241c63
<?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:paddingTop=
"@dimen/margin_16"
android:paddingRight=
"@dimen/margin_16"
android:paddingStart=
"@dimen/margin_16"
android:paddingLeft=
"@dimen/margin_16"
android:paddingEnd=
"@dimen/margin_16"
>
<chat.rocket.android.widget.RocketChatAvatar
android:id=
"@+id/userAvatar"
android:layout_width=
"40dp"
android:layout_height=
"40dp"
android:layout_marginTop=
"4dp"
app:layout_constraintTop_toTopOf=
"parent"
/>
<android.support.constraint.ConstraintLayout
android:id=
"@+id/container"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginLeft=
"@dimen/margin_16"
android:layout_marginStart=
"@dimen/margin_16"
app:layout_constraintLeft_toRightOf=
"@+id/userAvatar"
>
<ImageView
android:id=
"@+id/status"
android:layout_width=
"8dp"
android:layout_height=
"8dp"
app:layout_constraintTop_toTopOf=
"@+id/name"
app:layout_constraintBottom_toBottomOf=
"@+id/name"
app:srcCompat=
"@drawable/ic_user_status_black_24dp"
/>
<TextView
android:id=
"@+id/name"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginLeft=
"4dp"
android:layout_marginStart=
"4dp"
android:ellipsize=
"end"
android:maxLines=
"1"
android:textAppearance=
"@style/TextAppearance.RocketChat.Message.Name"
app:layout_constraintLeft_toRightOf=
"@+id/status"
tools:text=
"John Doe"
/>
<TextView
android:id=
"@+id/username"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:ellipsize=
"end"
android:maxLines=
"1"
android:textAppearance=
"@style/TextAppearance.RocketChat.Message.Username"
app:layout_constraintTop_toBottomOf=
"@+id/name"
app:layout_constraintLeft_toLeftOf=
"@+id/name"
tools:text=
"\@john.doe"
/>
</android.support.constraint.ConstraintLayout>
<View
android:layout_width=
"0dp"
android:layout_height=
"1dp"
android:layout_weight=
"1"
android:background=
"@color/colorDivider"
android:layout_marginTop=
"20dp"
app:layout_constraintTop_toBottomOf=
"@+id/container"
/>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
app/src/main/res/layout/item_room_message.xml
0 → 100644
View file @
44241c63
<?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:paddingRight=
"@dimen/margin_16"
android:paddingStart=
"@dimen/margin_16"
android:paddingLeft=
"@dimen/margin_16"
android:paddingEnd=
"@dimen/margin_16"
android:paddingBottom=
"@dimen/margin_16"
>
<include
android:id=
"@+id/dayLayout"
layout=
"@layout/day"
/>
<chat.rocket.android.widget.RocketChatAvatar
android:id=
"@+id/userAvatar"
android:layout_width=
"40dp"
android:layout_height=
"40dp"
android:layout_marginTop=
"20dp"
app:layout_constraintTop_toBottomOf=
"@+id/dayLayout"
/>
<android.support.constraint.ConstraintLayout
android:id=
"@+id/userContainer"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"@dimen/margin_16"
android:layout_marginLeft=
"@dimen/margin_16"
android:layout_marginStart=
"@dimen/margin_16"
app:layout_constraintTop_toBottomOf=
"@+id/dayLayout"
app:layout_constraintLeft_toRightOf=
"@+id/userAvatar"
>
<TextView
android:id=
"@+id/name"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:ellipsize=
"end"
android:maxLines=
"1"
android:textAppearance=
"@style/TextAppearance.RocketChat.Message.Name"
tools:text=
"John Doe"
/>
<TextView
android:id=
"@+id/username"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:ellipsize=
"end"
android:maxLines=
"1"
android:textAppearance=
"@style/TextAppearance.RocketChat.Message.Username"
app:layout_constraintLeft_toLeftOf=
"@+id/name"
app:layout_constraintTop_toBottomOf=
"@+id/name"
tools:text=
"\@john.doe"
/>
</android.support.constraint.ConstraintLayout>
<android.support.constraint.ConstraintLayout
android:id=
"@+id/messageContainer"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"10dp"
android:layout_marginLeft=
"@dimen/margin_16"
android:layout_marginStart=
"@dimen/margin_16"
app:layout_constraintTop_toBottomOf=
"@+id/userContainer"
app:layout_constraintLeft_toRightOf=
"@+id/userAvatar"
app:layout_constraintRight_toRightOf=
"parent"
>
<chat.rocket.android.widget.message.RocketChatMessageLayout
android:id=
"@+id/messageBody"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
/>
<chat.rocket.android.widget.message.RocketChatMessageUrlsLayout
android:id=
"@+id/messageUrl"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
app:layout_constraintLeft_toLeftOf=
"@+id/messageBody"
app:layout_constraintTop_toBottomOf=
"@+id/messageBody"
/>
<chat.rocket.android.widget.message.RocketChatMessageAttachmentsLayout
android:id=
"@+id/messageAttachment"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
app:layout_constraintLeft_toLeftOf=
"@+id/messageUrl"
app:layout_constraintTop_toBottomOf=
"@+id/messageUrl"
/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
app/src/main/res/layout/list_item_message_newday.xml
deleted
100644 → 0
View file @
cf96cd2f
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:id=
"@+id/newday_container"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_margin=
"16dp"
android:gravity=
"center_vertical"
android:orientation=
"horizontal"
>
<View
android:layout_width=
"0px"
android:layout_height=
"1dp"
android:layout_weight=
"1"
android:background=
"@color/newday_color"
/>
<TextView
android:id=
"@+id/newday_text"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginLeft=
"16dp"
android:layout_marginRight=
"16dp"
android:textColor=
"@color/newday_text_color"
android:textSize=
"8sp"
android:textStyle=
"bold"
tools:text=
"2016/01/23"
/>
<View
android:layout_width=
"0px"
android:layout_height=
"1dp"
android:layout_weight=
"1"
android:background=
"@color/newday_color"
/>
</LinearLayout>
\ No newline at end of file
app/src/main/res/layout/list_item_normal_message.xml
View file @
44241c63
...
...
@@ -7,7 +7,7 @@
android:orientation=
"vertical"
android:theme=
"@style/AppTheme"
>
<include
layout=
"@layout/
list_item_message_new
day"
/>
<include
layout=
"@layout/day"
/>
<FrameLayout
android:layout_width=
"match_parent"
...
...
app/src/main/res/layout/list_item_system_message.xml
View file @
44241c63
...
...
@@ -7,7 +7,7 @@
android:orientation=
"vertical"
android:theme=
"@style/AppTheme"
>
<include
layout=
"@layout/
list_item_message_new
day"
/>
<include
layout=
"@layout/day"
/>
<FrameLayout
android:layout_width=
"match_parent"
...
...
app/src/main/res/layout/room_side_menu.xml
deleted
100644 → 0
View file @
cf96cd2f
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:id=
"@+id/room_side_menu"
android:layout_width=
"48dp"
android:layout_height=
"match_parent"
android:layout_gravity=
"end"
android:orientation=
"vertical"
>
<io.github.yusukeiwaki.android.widget.FontAwesomeButton
android:layout_width=
"48dp"
android:layout_height=
"48dp"
android:enabled=
"false"
android:text=
"@string/fa_search"
android:textSize=
"24dp"
/>
<io.github.yusukeiwaki.android.widget.FontAwesomeButton
android:id=
"@+id/btn_users"
android:layout_width=
"48dp"
android:layout_height=
"48dp"
android:text=
"@string/fa_users"
android:textSize=
"24dp"
/>
<io.github.yusukeiwaki.android.widget.FontAwesomeButton
android:layout_width=
"48dp"
android:layout_height=
"48dp"
android:enabled=
"false"
android:text=
"@string/fa_at"
android:textSize=
"24dp"
/>
</LinearLayout>
\ No newline at end of file
app/src/main/res/menu/menu_room.xml
0 → 100644
View file @
44241c63
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
>
<item
android:id=
"@+id/action_pinned_messages"
android:title=
"@string/menu_pinned_messages"
app:showAsAction=
"never"
/>
<item
android:id=
"@+id/action_favorite_messages"
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_member_list"
android:title=
"@string/menu_member_list"
app:showAsAction=
"never"
/>
</menu>
\ No newline at end of file
app/src/main/res/values/colors.xml
View file @
44241c63
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color
name=
"colorPrimary"
>
#044b76
</color>
<color
name=
"colorPrimaryDark"
>
#FF04436a
</color>
<color
name=
"colorAccent"
>
#FF2D91FA
</color>
<color
name=
"colorAccentLight"
>
#FF6CB1FA
</color>
<color
name=
"colorAccentDark"
>
#FF287DD7
</color>
<color
name=
"colorAccent_a40"
>
#662D91FA
</color>
<color
name=
"textColorLink"
>
#008ce3
</color>
<color
name=
"colorRed400"
>
#FFEF5350
</color>
<color
name=
"colorPrimary"
>
#044b76
</color>
<color
name=
"colorPrimaryDark"
>
#FF04436a
</color>
<color
name=
"colorAccent"
>
#FF2D91FA
</color>
<color
name=
"colorAccentLight"
>
#FF6CB1FA
</color>
<color
name=
"colorAccentDark"
>
#FF287DD7
</color>
<color
name=
"colorAccent_a40"
>
#662D91FA
</color>
<color
name=
"textColorLink"
>
#008ce3
</color>
<color
name=
"colorRed400"
>
#FFEF5350
</color>
<color
name=
"colorPrimaryTextDark"
>
#DE000000
</color>
<color
name=
"colorSecondaryTextDark"
>
#8A000000
</color>
<color
name=
"colorDivider"
>
#1F000000
</color>
</resources>
\ No newline at end of file
app/src/main/res/values/fa_strings.xml
View file @
44241c63
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string
name=
"fa_chevron_down"
translatable=
"false"
>

</string>
<string
name=
"fa_twitter"
translatable=
"false"
>

</string>
<string
name=
"fa_github"
translatable=
"false"
>

</string>
<string
name=
"fa_google"
translatable=
"false"
>

</string>
<string
name=
"fa_facebook_official"
translatable=
"false"
>

</string>
<string
name=
"fa_plus"
translatable=
"false"
>

</string>
<string
name=
"fa_sign_out"
translatable=
"false"
>

</string>
<string
name=
"fa_search"
translatable=
"false"
>

</string>
<string
name=
"fa_users"
translatable=
"false"
>

</string>
<string
name=
"fa_at"
translatable=
"false"
>

</string>
</resources>
\ No newline at end of file
app/src/main/res/values/message_style.xml
0 → 100644
View file @
44241c63
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style
name=
"TextAppearance.RocketChat.Message.Day"
parent=
"TextAppearance.AppCompat"
>
<item
name=
"android:textSize"
>
12sp
</item>
<item
name=
"android:textColor"
>
@color/colorPrimaryTextDark
</item>
</style>
<style
name=
"TextAppearance.RocketChat.Message.SubUsername"
parent=
"TextAppearance.AppCompat.Body1"
>
<item
name=
"android:textColor"
>
#5f000000
</item>
</style>
<style
name=
"TextAppearance.RocketChat.Message.Name"
parent=
"TextAppearance.AppCompat.Body1"
>
<item
name=
"android:textColor"
>
@color/colorPrimaryTextDark
</item>
<item
name=
"android:fontFamily"
>
sans-serif-condensed
</item>
<item
name=
"android:textSize"
>
16sp
</item>
<item
name=
"android:maxLines"
>
1
</item>
<item
name=
"android:ellipsize"
>
end
</item>
</style>
<style
name=
"TextAppearance.RocketChat.Message.Username"
parent=
"TextAppearance.AppCompat.Body2"
>
<item
name=
"android:textColor"
>
@color/colorSecondaryTextDark
</item>
<item
name=
"android:fontFamily"
>
sans-serif-condensed
</item>
<item
name=
"android:textSize"
>
14sp
</item>
<item
name=
"android:maxLines"
>
1
</item>
<item
name=
"android:ellipsize"
>
end
</item>
</style>
</resources>
\ No newline at end of file
app/src/main/res/values/message_styles.xml
deleted
100644 → 0
View file @
cf96cd2f
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color
name=
"newday_color"
>
#e0e0e0
</color>
<color
name=
"newday_text_color"
>
#444444
</color>
<style
name=
"TextAppearance.RocketChat.Message.Username"
parent=
"TextAppearance.AppCompat.Body2"
>
<item
name=
"android:textColor"
>
#bb000000
</item>
</style>
<style
name=
"TextAppearance.RocketChat.Message.SubUsername"
parent=
"TextAppearance.AppCompat.Body1"
>
<item
name=
"android:textColor"
>
#5f000000
</item>
</style>
</resources>
\ No newline at end of file
app/src/main/res/values/strings.xml
View file @
44241c63
...
...
@@ -13,6 +13,16 @@
<string
name=
"dialog_add_channel_private"
>
private
</string>
<string
name=
"dialog_add_channel_read_only"
>
read only
</string>
<string
name=
"fragment_room_list_pinned_message_title"
>
Pinned Messages (%s)
</string>
<string
name=
"fragment_room_list_favorite_message_title"
>
Favorite Messages (%s)
</string>
<string
name=
"fragment_room_list_file_list_title"
>
File list (%s)
</string>
<string
name=
"fragment_room_list_member_list_title"
>
Member list (%s)
</string>
<string
name=
"fragment_room_list_could_not_load_your_request"
>
Could not load your request.\nResponse was: %s
</string>
<string
name=
"fragment_room_list_no_pinned_message_to_show"
>
No pinned message to show
</string>
<string
name=
"fragment_room_list_no_favorite_message_to_show"
>
No favorite message to show
</string>
<string
name=
"fragment_room_list_no_file_list_to_show"
>
No file list to show
</string>
<string
name=
"fragment_room_list_no_member_list_to_show"
>
No member list to show
</string>
<string
name=
"start_of_conversation"
>
Start of conversation
</string>
<string
name=
"users_of_room_title"
>
Members List
</string>
<plurals
name=
"fmt_room_user_count"
>
...
...
@@ -36,6 +46,7 @@
<string
name=
"dialog_user_registration_email"
>
Email
</string>
<string
name=
"dialog_user_registration_username"
>
Username
</string>
<string
name=
"sub_username"
>
\@%s
</string>
<string
name=
"username"
>
\@%s
</string>
<string
name=
"dialog_user_registration_password"
>
Password
</string>
<string
name=
"fragment_home_welcome_message"
>
Welcome to Rocket.Chat.Android\nSelect a channel from the drawer.
</string>
<string
name=
"fragment_input_hostname_hostname"
>
Hostname
</string>
...
...
@@ -68,5 +79,11 @@
<string
name=
"edit_message"
>
Edit message
</string>
<string
name=
"message_options_no_message_info"
>
Ooops. Something\'s up!
</string>
<string
name=
"message_options_no_permissions_info"
>
You have no permissions
</string>
<string
name=
"menu_pinned_messages"
>
Pinned messages
</string>
<string
name=
"menu_favorite_messages"
>
Favorite messages
</string>
<string
name=
"menu_file_list"
>
File list
</string>
<string
name=
"menu_member_list"
>
Member list
</string>
<string
name=
"add_new_team"
>
Add new Team
</string>
</resources>
app/src/release/java/chat/rocket/android/helper/OkHttpHelper.kt
View file @
44241c63
...
...
@@ -9,6 +9,13 @@ import okhttp3.OkHttpClient
object
OkHttpHelper
{
fun
getClient
():
OkHttpClient
{
if
(
httpClient
==
null
)
{
httpClient
=
OkHttpClient
()
}
return
httpClient
?:
throw
AssertionError
(
"httpClient set to null by another thread"
)
}
fun
getClientForUploadFile
():
OkHttpClient
{
if
(
httpClientForUploadFile
==
null
)
{
httpClientForUploadFile
=
OkHttpClient
.
Builder
().
build
()
...
...
@@ -19,6 +26,8 @@ object OkHttpHelper {
fun
getClientForDownloadFile
(
context
:
Context
):
OkHttpClient
{
if
(
httpClientForDownloadFile
==
null
)
{
httpClientForDownloadFile
=
OkHttpClient
.
Builder
()
.
followRedirects
(
true
)
.
followSslRedirects
(
true
)
.
addInterceptor
(
CookieInterceptor
(
DefaultCookieProvider
(
RocketChatCache
(
context
))))
.
build
()
}
...
...
@@ -37,7 +46,8 @@ object OkHttpHelper {
return
httpClientForWS
?:
throw
AssertionError
(
"httpClientForWS set to null by another thread"
)
}
private
var
httpClient
:
OkHttpClient
?
=
null
private
var
httpClientForUploadFile
:
OkHttpClient
?
=
null
private
var
httpClientForDownloadFile
:
OkHttpClient
?
=
null
private
var
httpClientForWS
:
OkHttpClient
?
=
null
}
\ No newline at end of file
}
app/src/test/kotlin/chat/rocket/android/api/rest/RestApiHelperTest.kt
0 → 100644
View file @
44241c63
This diff is collapsed.
Click to expand it.
app/src/test/kotlin/chat/rocket/android/helper/UrlHelperTest.kt
0 → 100644
View file @
44241c63
package
chat.rocket.android.helper
import
org.junit.Test
import
kotlin.test.assertEquals
class
UrlHelperTest
{
@Test
fun
removeUriSchemeTest
()
{
assertEquals
(
"demo.rocket.chat"
,
UrlHelper
.
removeUriScheme
(
"https://demo.rocket.chat"
))
assertEquals
(
"demo.rocket.chat"
,
UrlHelper
.
removeUriScheme
(
"http://demo.rocket.chat"
))
assertEquals
(
"demo.rocket.chat"
,
UrlHelper
.
removeUriScheme
(
"demo.rocket.chat"
))
}
@Test
fun
getSafeHostnameTest
()
{
assertEquals
(
"https://demo.rocket.chat"
,
UrlHelper
.
getSafeHostname
(
"https://demo.rocket.chat"
))
assertEquals
(
"https://demo.rocket.chat"
,
UrlHelper
.
getSafeHostname
(
"http://demo.rocket.chat"
))
assertEquals
(
"https://demo.rocket.chat"
,
UrlHelper
.
getSafeHostname
(
"demo.rocket.chat"
))
}
@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"
))
}
@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"
))
}
}
\ No newline at end of file
build.gradle
View file @
44241c63
...
...
@@ -22,7 +22,7 @@ ext {
buildToolsVersion
=
"26.0.0"
supportLibraryVersion
=
"25.4.0"
constraintLayoutVersion
=
"1.0.2"
kotlinVersion
=
"1.1.4-
2
"
kotlinVersion
=
"1.1.4-
3
"
okHttpVersion
=
"3.9.0"
}
...
...
rocket-chat-android-widgets/src/main/java/chat/rocket/android/widget/helper/AvatarHelper.kt
View file @
44241c63
package
chat.rocket.android.widget.helper
import
android.content.Context
import
android.graphics.Bitmap
import
android.graphics.Typeface
import
android.graphics.drawable.Drawable
import
chat.rocket.android.widget.AbsoluteUrl
import
com.amulyakhare.textdrawable.TextDrawable
import
java.net.URLEncoder
/**
* Created by Filipe de Lima Brito (filipedelimabrito@gmail.com) on 8/02/17.
*/
object
AvatarHelper
{
/**
...
...
@@ -45,6 +49,7 @@ object AvatarHelper {
* @param username The username.
* @param context The context.
* @return A drawable with username initials.
* @see getTextBitmap
* @see getUsernameInitials
*/
fun
getTextDrawable
(
username
:
String
,
context
:
Context
):
Drawable
{
...
...
@@ -57,6 +62,19 @@ object AvatarHelper {
.
buildRoundRect
(
getUsernameInitials
(
username
),
getUserAvatarBackgroundColor
(
username
),
round
)
}
/**
* Returns a bitmap with username initials.
*
* @param username The username.
* @param context The context.
* @return A bitmap with username initials.
* @see getTextDrawable
*/
fun
getTextBitmap
(
username
:
String
,
context
:
Context
):
Bitmap
{
val
textDrawable
=
getTextDrawable
(
username
,
context
)
return
DrawableHelper
.
getBitmapFromDrawable
(
textDrawable
,
96
,
96
)
}
/**
* Returns a string with the username initials. For example: username John.Doe returns JD initials.
*
...
...
@@ -70,15 +88,15 @@ object AvatarHelper {
val
splitUsername
=
username
.
split
(
"."
)
val
splitCount
=
splitUsername
.
size
if
(
splitCount
>
1
&&
splitUsername
[
0
].
isNotEmpty
()
&&
splitUsername
[
splitCount
-
1
].
isNotEmpty
())
{
return
if
(
splitCount
>
1
&&
splitUsername
[
0
].
isNotEmpty
()
&&
splitUsername
[
splitCount
-
1
].
isNotEmpty
())
{
val
firstInitial
=
splitUsername
[
0
].
substring
(
0
,
1
)
val
secondInitial
=
splitUsername
[
splitCount
-
1
].
substring
(
0
,
1
)
return
(
firstInitial
+
secondInitial
).
toUpperCase
()
(
firstInitial
+
secondInitial
).
toUpperCase
()
}
else
{
if
(
username
.
length
>
1
)
{
return
username
.
substring
(
0
,
2
).
toUpperCase
()
username
.
substring
(
0
,
2
).
toUpperCase
()
}
else
{
return
username
.
substring
(
0
,
1
).
toUpperCase
()
username
.
substring
(
0
,
1
).
toUpperCase
()
}
}
}
...
...
rocket-chat-android-widgets/src/main/java/chat/rocket/android/widget/helper/DrawableHelper.kt
View file @
44241c63
package
chat.rocket.android.widget.helper
import
android.content.Context
import
android.graphics.Bitmap
import
android.graphics.Canvas
import
android.graphics.drawable.BitmapDrawable
import
android.graphics.drawable.Drawable
import
android.support.v4.content.ContextCompat
import
android.support.v4.graphics.drawable.DrawableCompat
/**
* Created by Filipe de Lima Brito (filipedelimabrito@gmail.com) on 8/29/17.
*/
object
DrawableHelper
{
/**
* Returns a bitmap from drawable.
*
* @param drawable The drawable to get the bitmap.
* @return A bitmap.
*/
fun
getBitmapFromDrawable
(
drawable
:
Drawable
,
intrinsicWidth
:
Int
=
1
,
intrinsicHeight
:
Int
=
1
):
Bitmap
{
if
(
drawable
is
BitmapDrawable
)
{
return
drawable
.
bitmap
}
val
textDrawableIntrinsicWidth
=
drawable
.
intrinsicWidth
var
textDrawableIntrinsicHeight
=
drawable
.
intrinsicHeight
val
width
=
if
(
textDrawableIntrinsicWidth
>
0
)
textDrawableIntrinsicWidth
else
intrinsicWidth
val
height
=
if
(
textDrawableIntrinsicHeight
>
0
)
textDrawableIntrinsicHeight
else
intrinsicHeight
val
bitmap
=
Bitmap
.
createBitmap
(
width
,
height
,
Bitmap
.
Config
.
ARGB_8888
)
val
canvas
=
Canvas
(
bitmap
)
drawable
.
setBounds
(
0
,
0
,
canvas
.
width
,
canvas
.
height
)
drawable
.
draw
(
canvas
)
return
bitmap
}
/**
* Wraps a drawable to be used for example for tinting.
*
...
...
rocket-chat-android-widgets/src/test/kotlin/chat/rocket/android/widget/helper/AvatarHelperTest.kt
View file @
44241c63
...
...
@@ -2,6 +2,9 @@ import chat.rocket.android.widget.helper.AvatarHelper
import
org.junit.Test
import
kotlin.test.assertEquals
/**
* Created by Filipe de Lima Brito (filipedelimabrito@gmail.com) on 8/2/17.
*/
class
AvatarHelperTest
{
@Test
...
...
rocket-chat-core/src/main/java/chat/rocket/core/models/User.java
View file @
44241c63
...
...
@@ -15,6 +15,9 @@ public abstract class User {
public
abstract
String
getId
();
@Nullable
public
abstract
String
getName
();
@Nullable
public
abstract
String
getUsername
();
...
...
@@ -38,6 +41,8 @@ public abstract class User {
public
abstract
Builder
setId
(
String
id
);
public
abstract
Builder
setName
(
String
name
);
public
abstract
Builder
setUsername
(
String
username
);
public
abstract
Builder
setStatus
(
String
status
);
...
...
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