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
8876ac1e
Commit
8876ac1e
authored
Dec 17, 2016
by
Yusuke Iwaki
Browse files
Options
Browse Files
Download
Plain Diff
FIX #61 Merge branch 'upload_file' into develop
parents
c4b60e82
9cf77f45
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
1113 additions
and
20 deletions
+1113
-20
FileUploadingHelper.java
...ain/java/chat/rocket/android/api/FileUploadingHelper.java
+60
-0
MethodCallHelper.java
...c/main/java/chat/rocket/android/api/MethodCallHelper.java
+29
-10
RoomFragment.java
...a/chat/rocket/android/fragment/chatroom/RoomFragment.java
+46
-1
FileUploadProgressDialogFragment.java
...ent/chatroom/dialog/FileUploadProgressDialogFragment.java
+94
-0
InputHostnameFragment.java
...android/fragment/server_config/InputHostnameFragment.java
+5
-0
FileUploadHelper.java
...ain/java/chat/rocket/android/helper/FileUploadHelper.java
+96
-0
OkHttpHelper.java
...rc/main/java/chat/rocket/android/helper/OkHttpHelper.java
+10
-0
MessageComposerManager.java
...android/layouthelper/chatroom/MessageComposerManager.java
+26
-8
PublicSetting.java
...ain/java/chat/rocket/android/model/ddp/PublicSetting.java
+103
-0
FileUploading.java
...ava/chat/rocket/android/model/internal/FileUploading.java
+105
-0
FileUploadingRenderer.java
...a/chat/rocket/android/renderer/FileUploadingRenderer.java
+55
-0
RocketChatWebSocketThread.java
...hat/rocket/android/service/RocketChatWebSocketThread.java
+5
-1
FileUploadingToS3Observer.java
...t/android/service/observer/FileUploadingToS3Observer.java
+178
-0
FileUploadingWithUfsObserver.java
...ndroid/service/observer/FileUploadingWithUfsObserver.java
+177
-0
SessionObserver.java
...chat/rocket/android/service/observer/SessionObserver.java
+5
-0
ic_insert_photo_white_24dp.xml
app/src/main/res/drawable/ic_insert_photo_white_24dp.xml
+10
-0
progress_bar.xml
app/src/main/res/drawable/progress_bar.xml
+28
-0
dialog_file_uploading.xml
app/src/main/res/layout/dialog_file_uploading.xml
+64
-0
fragment_room_main.xml
app/src/main/res/layout/fragment_room_main.xml
+10
-0
strings.xml
app/src/main/res/values/strings.xml
+2
-0
styles.xml
app/src/main/res/values/styles.xml
+5
-0
No files found.
app/src/main/java/chat/rocket/android/api/FileUploadingHelper.java
0 → 100644
View file @
8876ac1e
package
chat
.
rocket
.
android
.
api
;
import
android.content.Context
;
import
bolts.Task
;
import
chat.rocket.android.helper.TextUtils
;
import
chat.rocket.android.realm_helper.RealmHelper
;
import
org.json.JSONArray
;
import
org.json.JSONObject
;
/**
* MethodCall for uploading file.
*/
public
class
FileUploadingHelper
extends
MethodCallHelper
{
public
FileUploadingHelper
(
Context
context
,
String
serverConfigId
)
{
super
(
context
,
serverConfigId
);
}
public
FileUploadingHelper
(
RealmHelper
realmHelper
,
DDPClientWraper
ddpClient
)
{
super
(
realmHelper
,
ddpClient
);
}
public
Task
<
JSONObject
>
uploadRequest
(
String
filename
,
long
filesize
,
String
mimeType
,
String
roomId
)
{
return
call
(
"slingshot/uploadRequest"
,
TIMEOUT_MS
,
()
->
new
JSONArray
()
.
put
(
"rocketchat-uploads"
)
.
put
(
new
JSONObject
()
.
put
(
"name"
,
filename
)
.
put
(
"size"
,
filesize
)
.
put
(
"type"
,
mimeType
))
.
put
(
new
JSONObject
().
put
(
"rid"
,
roomId
)))
.
onSuccessTask
(
CONVERT_TO_JSON_OBJECT
);
}
public
Task
<
JSONObject
>
sendFileMessage
(
String
roomId
,
String
storageType
,
JSONObject
fileObj
)
{
return
call
(
"sendFileMessage"
,
TIMEOUT_MS
,
()
->
new
JSONArray
()
.
put
(
roomId
)
.
put
(
TextUtils
.
isEmpty
(
storageType
)
?
JSONObject
.
NULL
:
storageType
)
.
put
(
fileObj
))
.
onSuccessTask
(
CONVERT_TO_JSON_OBJECT
);
}
public
Task
<
JSONObject
>
ufsCreate
(
String
filename
,
long
filesize
,
String
mimeType
,
String
store
,
String
roomId
)
{
return
call
(
"ufsCreate"
,
TIMEOUT_MS
,
()
->
new
JSONArray
().
put
(
new
JSONObject
()
.
put
(
"name"
,
filename
)
.
put
(
"size"
,
filesize
)
.
put
(
"type"
,
mimeType
)
.
put
(
"store"
,
store
)
.
put
(
"rid"
,
roomId
)
)).
onSuccessTask
(
CONVERT_TO_JSON_OBJECT
);
}
public
Task
<
JSONObject
>
ufsComplete
(
String
fileId
,
String
token
,
String
store
)
{
return
call
(
"ufsComplete"
,
TIMEOUT_MS
,
()
->
new
JSONArray
()
.
put
(
fileId
)
.
put
(
store
)
.
put
(
token
)
).
onSuccessTask
(
CONVERT_TO_JSON_OBJECT
);
}
}
app/src/main/java/chat/rocket/android/api/MethodCallHelper.java
View file @
8876ac1e
...
...
@@ -8,6 +8,7 @@ import chat.rocket.android.helper.CheckSum;
import
chat.rocket.android.helper.TextUtils
;
import
chat.rocket.android.model.SyncState
;
import
chat.rocket.android.model.ddp.Message
;
import
chat.rocket.android.model.ddp.PublicSetting
;
import
chat.rocket.android.model.ddp.RoomSubscription
;
import
chat.rocket.android.model.internal.MethodCall
;
import
chat.rocket.android.model.internal.Session
;
...
...
@@ -26,10 +27,10 @@ import org.json.JSONObject;
*/
public
class
MethodCallHelper
{
pr
ivate
final
Context
context
;
pr
ivate
final
RealmHelper
realmHelper
;
pr
ivate
final
DDPClientWraper
ddpClient
;
pr
ivate
static
final
long
TIMEOUT_MS
=
4000
;
pr
otected
final
Context
context
;
pr
otected
final
RealmHelper
realmHelper
;
pr
otected
final
DDPClientWraper
ddpClient
;
pr
otected
static
final
long
TIMEOUT_MS
=
4000
;
@Deprecated
/**
...
...
@@ -92,15 +93,15 @@ public class MethodCallHelper {
});
}
pr
ivate
interface
ParamBuilder
{
pr
otected
interface
ParamBuilder
{
JSONArray
buildParam
()
throws
JSONException
;
}
pr
ivate
Task
<
String
>
call
(
String
methodName
,
long
timeout
)
{
pr
otected
final
Task
<
String
>
call
(
String
methodName
,
long
timeout
)
{
return
injectErrorHandler
(
executeMethodCall
(
methodName
,
null
,
timeout
));
}
pr
ivate
Task
<
String
>
call
(
String
methodName
,
long
timeout
,
ParamBuilder
paramBuilder
)
{
pr
otected
final
Task
<
String
>
call
(
String
methodName
,
long
timeout
,
ParamBuilder
paramBuilder
)
{
try
{
final
JSONArray
params
=
paramBuilder
.
buildParam
();
return
injectErrorHandler
(
executeMethodCall
(
methodName
,
...
...
@@ -110,10 +111,10 @@ public class MethodCallHelper {
}
}
pr
ivate
static
final
Continuation
<
String
,
Task
<
JSONObject
>>
CONVERT_TO_JSON_OBJECT
=
pr
otected
static
final
Continuation
<
String
,
Task
<
JSONObject
>>
CONVERT_TO_JSON_OBJECT
=
task
->
Task
.
forResult
(
new
JSONObject
(
task
.
getResult
()));
pr
ivate
static
final
Continuation
<
String
,
Task
<
JSONArray
>>
CONVERT_TO_JSON_ARRAY
=
pr
otected
static
final
Continuation
<
String
,
Task
<
JSONArray
>>
CONVERT_TO_JSON_ARRAY
=
task
->
Task
.
forResult
(
new
JSONArray
(
task
.
getResult
()));
/**
...
...
@@ -321,7 +322,7 @@ public class MethodCallHelper {
/**
* Send message object.
*/
p
ublic
Task
<
JSONObject
>
sendMessage
(
final
JSONObject
messageJson
)
{
p
rivate
Task
<
JSONObject
>
sendMessage
(
final
JSONObject
messageJson
)
{
return
call
(
"sendMessage"
,
TIMEOUT_MS
,
()
->
new
JSONArray
().
put
(
messageJson
))
.
onSuccessTask
(
CONVERT_TO_JSON_OBJECT
)
.
onSuccessTask
(
task
->
Task
.
forResult
(
Message
.
customizeJson
(
task
.
getResult
())));
...
...
@@ -334,4 +335,22 @@ public class MethodCallHelper {
return
call
(
"readMessages"
,
TIMEOUT_MS
,
()
->
new
JSONArray
().
put
(
roomId
))
.
onSuccessTask
(
task
->
Task
.
forResult
(
null
));
}
public
Task
<
Void
>
getPublicSettings
()
{
return
call
(
"public-settings/get"
,
TIMEOUT_MS
)
.
onSuccessTask
(
CONVERT_TO_JSON_ARRAY
)
.
onSuccessTask
(
task
->
{
final
JSONArray
settings
=
task
.
getResult
();
for
(
int
i
=
0
;
i
<
settings
.
length
();
i
++)
{
PublicSetting
.
customizeJson
(
settings
.
getJSONObject
(
i
));
}
return
realmHelper
.
executeTransaction
(
realm
->
{
realm
.
delete
(
PublicSetting
.
class
);
realm
.
createOrUpdateAllFromJson
(
PublicSetting
.
class
,
settings
);
return
null
;
});
});
}
}
app/src/main/java/chat/rocket/android/fragment/chatroom/RoomFragment.java
View file @
8876ac1e
package
chat
.
rocket
.
android
.
fragment
.
chatroom
;
import
android.app.Activity
;
import
android.content.Intent
;
import
android.os.Bundle
;
import
android.support.annotation.Nullable
;
import
android.support.design.widget.FloatingActionButton
;
...
...
@@ -12,10 +14,13 @@ import android.support.v7.widget.RecyclerView;
import
android.view.View
;
import
chat.rocket.android.R
;
import
chat.rocket.android.api.MethodCallHelper
;
import
chat.rocket.android.fragment.chatroom.dialog.FileUploadProgressDialogFragment
;
import
chat.rocket.android.fragment.chatroom.dialog.UsersOfRoomDialogFragment
;
import
chat.rocket.android.helper.LoadMoreScrollListener
;
import
chat.rocket.android.helper.LogcatIfError
;
import
chat.rocket.android.helper.OnBackPressListener
;
import
chat.rocket.android.helper.TextUtils
;
import
chat.rocket.android.helper.FileUploadHelper
;
import
chat.rocket.android.layouthelper.chatroom.MessageComposerManager
;
import
chat.rocket.android.layouthelper.chatroom.MessageListAdapter
;
import
chat.rocket.android.layouthelper.chatroom.PairedMessage
;
...
...
@@ -45,6 +50,8 @@ import org.json.JSONObject;
public
class
RoomFragment
extends
AbstractChatRoomFragment
implements
OnBackPressListener
,
RealmModelListAdapter
.
OnItemClickListener
<
PairedMessage
>
{
private
static
final
int
RC_UPL
=
0x12
;
private
String
serverConfigId
;
private
RealmHelper
realmHelper
;
private
String
roomId
;
...
...
@@ -128,6 +135,7 @@ public class RoomFragment extends AbstractChatRoomFragment
setupSideMenu
();
setupMessageComposer
();
setupFileUploader
();
}
@Override
public
void
onItemClick
(
PairedMessage
pairedMessage
)
{
...
...
@@ -196,7 +204,7 @@ public class RoomFragment extends AbstractChatRoomFragment
final
MessageComposer
messageComposer
=
(
MessageComposer
)
rootView
.
findViewById
(
R
.
id
.
message_composer
);
messageComposerManager
=
new
MessageComposerManager
(
fabCompose
,
messageComposer
);
messageComposerManager
.
setCallback
(
messageText
->
messageComposerManager
.
set
SendMessage
Callback
(
messageText
->
realmHelper
.
executeTransaction
(
realm
->
realm
.
createOrUpdateObjectFromJson
(
Message
.
class
,
new
JSONObject
()
.
put
(
"_id"
,
UUID
.
randomUUID
().
toString
())
...
...
@@ -204,6 +212,43 @@ public class RoomFragment extends AbstractChatRoomFragment
.
put
(
"ts"
,
System
.
currentTimeMillis
())
.
put
(
"rid"
,
roomId
)
.
put
(
"msg"
,
messageText
))));
messageComposerManager
.
setVisibilityChangedListener
(
shown
->
{
FloatingActionButton
fab
=
(
FloatingActionButton
)
rootView
.
findViewById
(
R
.
id
.
fab_upload_file
);
if
(
shown
)
{
fab
.
hide
();
}
else
{
fab
.
show
();
}
});
}
private
void
setupFileUploader
()
{
rootView
.
findViewById
(
R
.
id
.
fab_upload_file
).
setOnClickListener
(
view
->
{
Intent
intent
=
new
Intent
();
intent
.
setType
(
"image/*"
);
intent
.
setAction
(
Intent
.
ACTION_GET_CONTENT
);
startActivityForResult
(
Intent
.
createChooser
(
intent
,
"Select Picture to Upload"
),
RC_UPL
);
});
}
@Override
public
void
onActivityResult
(
int
requestCode
,
int
resultCode
,
Intent
data
)
{
super
.
onActivityResult
(
requestCode
,
resultCode
,
data
);
if
(
requestCode
!=
RC_UPL
||
resultCode
!=
Activity
.
RESULT_OK
)
{
return
;
}
if
(
data
==
null
||
data
.
getData
()
==
null
)
{
return
;
}
String
uplId
=
new
FileUploadHelper
(
getContext
(),
realmHelper
)
.
requestUploading
(
roomId
,
data
.
getData
());
if
(!
TextUtils
.
isEmpty
(
uplId
))
{
FileUploadProgressDialogFragment
.
create
(
serverConfigId
,
roomId
,
uplId
)
.
show
(
getFragmentManager
(),
FileUploadProgressDialogFragment
.
class
.
getSimpleName
());
}
else
{
//show error.
}
}
private
void
onRenderRoom
(
RoomSubscription
roomSubscription
)
{
...
...
app/src/main/java/chat/rocket/android/fragment/chatroom/dialog/FileUploadProgressDialogFragment.java
0 → 100644
View file @
8876ac1e
package
chat
.
rocket
.
android
.
fragment
.
chatroom
.
dialog
;
import
android.content.DialogInterface
;
import
android.os.Bundle
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.Nullable
;
import
android.widget.ProgressBar
;
import
android.widget.TextView
;
import
android.widget.Toast
;
import
chat.rocket.android.R
;
import
chat.rocket.android.model.SyncState
;
import
chat.rocket.android.model.internal.FileUploading
;
import
chat.rocket.android.realm_helper.RealmObjectObserver
;
import
chat.rocket.android.renderer.FileUploadingRenderer
;
/**
* dialog fragment to display progress of file uploading.
*/
public
class
FileUploadProgressDialogFragment
extends
AbstractChatroomDialogFragment
{
private
String
uplId
;
private
RealmObjectObserver
<
FileUploading
>
fileUploadingObserver
;
public
FileUploadProgressDialogFragment
()
{}
public
static
FileUploadProgressDialogFragment
create
(
String
serverConfigId
,
String
roomId
,
String
uplId
)
{
Bundle
args
=
new
Bundle
();
args
.
putString
(
"serverConfigId"
,
serverConfigId
);
args
.
putString
(
"roomId"
,
roomId
);
args
.
putString
(
"uplId"
,
uplId
);
FileUploadProgressDialogFragment
fragment
=
new
FileUploadProgressDialogFragment
();
fragment
.
setArguments
(
args
);
return
fragment
;
}
@Override
protected
void
handleArgs
(
@NonNull
Bundle
args
)
{
super
.
handleArgs
(
args
);
uplId
=
args
.
getString
(
"uplId"
);
}
@Override
public
void
onCreate
(
@Nullable
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
fileUploadingObserver
=
realmHelper
.
createObjectObserver
(
realm
->
realm
.
where
(
FileUploading
.
class
).
equalTo
(
"uplId"
,
uplId
))
.
setOnUpdateListener
(
this
::
onRenderFileUploadingState
);
}
@Override
protected
int
getLayout
()
{
return
R
.
layout
.
dialog_file_uploading
;
}
@Override
protected
void
onSetupDialog
()
{
}
private
void
onRenderFileUploadingState
(
FileUploading
state
)
{
if
(
state
==
null
)
{
return
;
}
int
syncstate
=
state
.
getSyncstate
();
if
(
syncstate
==
SyncState
.
SYNCED
)
{
dismiss
();
}
else
if
(
syncstate
==
SyncState
.
FAILED
)
{
Toast
.
makeText
(
getContext
(),
state
.
getError
(),
Toast
.
LENGTH_SHORT
).
show
();
//TODO: prompt retry.
dismiss
();
}
else
{
new
FileUploadingRenderer
(
getContext
(),
state
)
.
progressInto
((
ProgressBar
)
getDialog
().
findViewById
(
R
.
id
.
progressBar
))
.
progressTextInto
(
(
TextView
)
getDialog
().
findViewById
(
R
.
id
.
txt_filesize_uploaded
),
(
TextView
)
getDialog
().
findViewById
(
R
.
id
.
txt_filesize_total
));
}
}
@Override
public
void
onResume
()
{
super
.
onResume
();
fileUploadingObserver
.
sub
();
}
@Override
public
void
onPause
()
{
fileUploadingObserver
.
unsub
();
super
.
onPause
();
}
@Override
public
void
onCancel
(
DialogInterface
dialog
)
{
//TODO: should cancel uploading? or continue with showing notification with progress?
}
}
app/src/main/java/chat/rocket/android/fragment/server_config/InputHostnameFragment.java
View file @
8876ac1e
...
...
@@ -3,6 +3,7 @@ package chat.rocket.android.fragment.server_config;
import
android.support.design.widget.Snackbar
;
import
android.widget.TextView
;
import
chat.rocket.android.R
;
import
chat.rocket.android.RocketChatCache
;
import
chat.rocket.android.helper.LogcatIfError
;
import
chat.rocket.android.helper.TextUtils
;
import
chat.rocket.android.model.ServerConfig
;
...
...
@@ -38,6 +39,10 @@ public class InputHostnameFragment extends AbstractServerConfigFragment {
final
String
hostname
=
TextUtils
.
or
(
TextUtils
.
or
(
editor
.
getText
(),
editor
.
getHint
()),
""
).
toString
();
RocketChatCache
.
get
(
getContext
()).
edit
()
.
putString
(
RocketChatCache
.
KEY_SELECTED_SERVER_CONFIG_ID
,
serverConfigId
)
.
apply
();
RealmStore
.
getDefault
().
executeTransaction
(
realm
->
realm
.
createOrUpdateObjectFromJson
(
ServerConfig
.
class
,
new
JSONObject
().
put
(
"serverConfigId"
,
serverConfigId
)
...
...
app/src/main/java/chat/rocket/android/helper/FileUploadHelper.java
0 → 100644
View file @
8876ac1e
package
chat
.
rocket
.
android
.
helper
;
import
android.content.ContentResolver
;
import
android.content.Context
;
import
android.database.Cursor
;
import
android.net.Uri
;
import
android.os.ParcelFileDescriptor
;
import
android.provider.OpenableColumns
;
import
android.support.annotation.Nullable
;
import
android.webkit.MimeTypeMap
;
import
chat.rocket.android.log.RCLog
;
import
chat.rocket.android.model.SyncState
;
import
chat.rocket.android.model.ddp.PublicSetting
;
import
chat.rocket.android.model.internal.FileUploading
;
import
chat.rocket.android.realm_helper.RealmHelper
;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.util.UUID
;
import
org.json.JSONObject
;
/**
* utility class for uploading file.
*/
public
class
FileUploadHelper
{
private
final
Context
context
;
private
final
RealmHelper
realmHelper
;
public
FileUploadHelper
(
Context
context
,
RealmHelper
realmHelper
)
{
this
.
context
=
context
;
this
.
realmHelper
=
realmHelper
;
}
/**
* requestUploading file.
* returns id for observing progress.
*/
public
@Nullable
String
requestUploading
(
String
roomId
,
Uri
uri
)
{
try
(
Cursor
cursor
=
context
.
getContentResolver
().
query
(
uri
,
null
,
null
,
null
,
null
))
{
if
(
cursor
!=
null
&&
cursor
.
moveToFirst
())
{
String
filename
=
cursor
.
getString
(
cursor
.
getColumnIndex
(
OpenableColumns
.
DISPLAY_NAME
));
long
filesize
=
cursor
.
getLong
(
cursor
.
getColumnIndex
(
OpenableColumns
.
SIZE
));
String
mimeType
=
context
.
getContentResolver
().
getType
(
uri
);
return
insertRequestRecord
(
roomId
,
uri
,
filename
,
filesize
,
mimeType
);
}
else
if
(
ContentResolver
.
SCHEME_FILE
.
equals
(
uri
.
getScheme
()))
{
String
filename
=
uri
.
getLastPathSegment
();
long
filesize
=
detectFileSizeFor
(
uri
);
String
mimeType
=
MimeTypeMap
.
getSingleton
()
.
getMimeTypeFromExtension
(
MimeTypeMap
.
getFileExtensionFromUrl
(
uri
.
toString
()));
return
insertRequestRecord
(
roomId
,
uri
,
filename
,
filesize
,
mimeType
);
}
}
return
null
;
}
private
String
insertRequestRecord
(
String
roomId
,
Uri
uri
,
String
filename
,
long
filesize
,
String
mimeType
)
{
final
String
uplId
=
UUID
.
randomUUID
().
toString
();
final
String
storageType
=
PublicSetting
.
getString
(
realmHelper
,
"FileUpload_Storage_Type"
,
null
);
realmHelper
.
executeTransaction
(
realm
->
realm
.
createOrUpdateObjectFromJson
(
FileUploading
.
class
,
new
JSONObject
()
.
put
(
"uplId"
,
uplId
)
.
put
(
"syncstate"
,
SyncState
.
NOT_SYNCED
)
.
put
(
"storageType"
,
TextUtils
.
isEmpty
(
storageType
)
?
JSONObject
.
NULL
:
storageType
)
.
put
(
"uri"
,
uri
.
toString
())
.
put
(
"filename"
,
filename
)
.
put
(
"filesize"
,
filesize
)
.
put
(
"mimeType"
,
mimeType
)
.
put
(
"roomId"
,
roomId
)
.
put
(
"error"
,
JSONObject
.
NULL
)
)
).
continueWith
(
new
LogcatIfError
());
return
uplId
;
}
private
long
detectFileSizeFor
(
Uri
uri
)
{
ParcelFileDescriptor
pfd
=
null
;
try
{
pfd
=
context
.
getContentResolver
().
openFileDescriptor
(
uri
,
"r"
);
return
Math
.
max
(
pfd
.
getStatSize
(),
0
);
}
catch
(
final
FileNotFoundException
exception
)
{
RCLog
.
w
(
exception
);
}
finally
{
if
(
pfd
!=
null
)
{
try
{
pfd
.
close
();
}
catch
(
final
IOException
e
)
{
// Do nothing.
}
}
}
return
-
1
;
}
}
app/src/main/java/chat/rocket/android/helper/OkHttpHelper.java
View file @
8876ac1e
...
...
@@ -8,8 +8,18 @@ import okhttp3.OkHttpClient;
* Helper class for OkHttp client.
*/
public
class
OkHttpHelper
{
private
static
OkHttpClient
sHttpClientForUplFile
;
private
static
OkHttpClient
sHttpClientForWS
;
public
static
OkHttpClient
getClientForUploadFile
()
{
if
(
sHttpClientForUplFile
==
null
)
{
sHttpClientForUplFile
=
new
OkHttpClient
.
Builder
()
.
addNetworkInterceptor
(
new
StethoInterceptor
())
.
build
();
}
return
sHttpClientForUplFile
;
}
/**
* acquire OkHttpClient instance for WebSocket connection.
*/
...
...
app/src/main/java/chat/rocket/android/layouthelper/chatroom/MessageComposerManager.java
View file @
8876ac1e
...
...
@@ -8,13 +8,18 @@ import chat.rocket.android.widget.message.MessageComposer;
* handling visibility of FAB-compose and MessageComposer.
*/
public
class
MessageComposerManager
{
public
interface
Callback
{
public
interface
SendMessage
Callback
{
Task
<
Void
>
onSubmit
(
String
messageText
);
}
public
interface
VisibilityChangedListener
{
void
onVisibilityChanged
(
boolean
shown
);
}
private
final
FloatingActionButton
fabCompose
;
private
final
MessageComposer
messageComposer
;
private
Callback
callback
;
private
SendMessageCallback
sendMessageCallback
;
private
VisibilityChangedListener
visibilityChangedListener
;
public
MessageComposerManager
(
FloatingActionButton
fabCompose
,
MessageComposer
messageComposer
)
{
this
.
fabCompose
=
fabCompose
;
...
...
@@ -29,9 +34,9 @@ public class MessageComposerManager {
messageComposer
.
setOnActionListener
(
new
MessageComposer
.
ActionListener
()
{
@Override
public
void
onSubmit
(
String
message
)
{
if
(
c
allback
!=
null
)
{
if
(
sendMessageC
allback
!=
null
)
{
messageComposer
.
setEnabled
(
false
);
c
allback
.
onSubmit
(
message
).
onSuccess
(
task
->
{
sendMessageC
allback
.
onSubmit
(
message
).
onSuccess
(
task
->
{
clearComposingText
();
return
null
;
}).
continueWith
(
task
->
{
...
...
@@ -49,8 +54,12 @@ public class MessageComposerManager {
setMessageComposerVisibility
(
false
);
}
public
void
setCallback
(
Callback
callback
)
{
this
.
callback
=
callback
;
public
void
setSendMessageCallback
(
SendMessageCallback
sendMessageCallback
)
{
this
.
sendMessageCallback
=
sendMessageCallback
;
}
public
void
setVisibilityChangedListener
(
VisibilityChangedListener
listener
)
{
this
.
visibilityChangedListener
=
listener
;
}
public
void
clearComposingText
()
{
...
...
@@ -60,9 +69,18 @@ public class MessageComposerManager {
private
void
setMessageComposerVisibility
(
boolean
show
)
{
if
(
show
)
{
fabCompose
.
hide
();
messageComposer
.
show
(
null
);
messageComposer
.
show
(()
->
{
if
(
visibilityChangedListener
!=
null
)
{
visibilityChangedListener
.
onVisibilityChanged
(
true
);
}
});
}
else
{
messageComposer
.
hide
(
fabCompose:
:
show
);
messageComposer
.
hide
(()
->
{
fabCompose
.
show
();
if
(
visibilityChangedListener
!=
null
)
{
visibilityChangedListener
.
onVisibilityChanged
(
false
);
}
});
}
}
...
...
app/src/main/java/chat/rocket/android/model/ddp/PublicSetting.java
0 → 100644
View file @
8876ac1e
package
chat
.
rocket
.
android
.
model
.
ddp
;
import
android.support.annotation.Nullable
;
import
chat.rocket.android.realm_helper.RealmHelper
;
import
io.realm.RealmObject
;
import
io.realm.annotations.PrimaryKey
;
import
org.json.JSONException
;
import
org.json.JSONObject
;
/**
* public setting model.
*/
@SuppressWarnings
({
"PMD.ShortClassName"
,
"PMD.ShortVariable"
,
"PMD.MethodNamingConventions"
,
"PMD.VariableNamingConventions"
})
public
class
PublicSetting
extends
RealmObject
{
@PrimaryKey
private
String
_id
;
private
String
group
;
private
String
type
;
private
String
value
;
//any type is available...!
private
long
_updatedAt
;
private
String
meta
;
//JSON
public
String
get_id
()
{
return
_id
;
}
public
void
set_id
(
String
_id
)
{
this
.
_id
=
_id
;
}
public
String
getGroup
()
{
return
group
;
}
public
void
setGroup
(
String
group
)
{
this
.
group
=
group
;
}
public
String
getType
()
{
return
type
;
}
public
void
setType
(
String
type
)
{
this
.
type
=
type
;
}
public
String
getValue
()
{
return
value
;
}
public
void
setValue
(
String
value
)
{
this
.
value
=
value
;
}
public
long
get_updatedAt
()
{
return
_updatedAt
;
}
public
void
set_updatedAt
(
long
_updatedAt
)
{
this
.
_updatedAt
=
_updatedAt
;
}
public
String
getMeta
()
{
return
meta
;
}
public
void
setMeta
(
String
meta
)
{
this
.
meta
=
meta
;
}
public
static
JSONObject
customizeJson
(
JSONObject
settingJson
)
throws
JSONException
{
if
(!
settingJson
.
isNull
(
"_updatedAt"
))
{
long
updatedAt
=
settingJson
.
getJSONObject
(
"_updatedAt"
).
getLong
(
"$date"
);
settingJson
.
remove
(
"_updatedAt"
);
settingJson
.
put
(
"_updatedAt"
,
updatedAt
);
}
return
settingJson
;
}
private
static
@Nullable
PublicSetting
get
(
RealmHelper
realmHelper
,
String
_id
)
{
return
realmHelper
.
executeTransactionForRead
(
realm
->
realm
.
where
(
PublicSetting
.
class
).
equalTo
(
"_id"
,
_id
).
findFirst
());
}
public
static
@Nullable
String
getString
(
RealmHelper
realmHelper
,
String
_id
,
String
defaultValue
)
{
PublicSetting
setting
=
get
(
realmHelper
,
_id
);
if
(
setting
!=
null
)
{
return
setting
.
getValue
();
}
return
defaultValue
;
}
public
static
@Nullable
boolean
getBoolean
(
RealmHelper
realmHelper
,
String
_id
,
boolean
defaultValue
)
{
PublicSetting
setting
=
get
(
realmHelper
,
_id
);
if
(
setting
!=
null
)
{
return
Boolean
.
parseBoolean
(
setting
.
getValue
());
}
return
defaultValue
;
}
}
app/src/main/java/chat/rocket/android/model/internal/FileUploading.java
0 → 100644
View file @
8876ac1e
package
chat
.
rocket
.
android
.
model
.
internal
;
import
io.realm.RealmObject
;
import
io.realm.annotations.PrimaryKey
;
/**
* holding statuses for uploading file.
*/
public
class
FileUploading
extends
RealmObject
{
public
static
final
String
STORAGE_TYPE_S3
=
"AmazonS3"
;
public
static
final
String
STORAGE_TYPE_GRID_FS
=
"GridFS"
;
public
static
final
String
STORAGE_TYPE_FILE_SYSTEM
=
"FileSystem"
;
@PrimaryKey
private
String
uplId
;
private
int
syncstate
;
private
String
storageType
;
private
String
uri
;
private
String
filename
;
private
long
filesize
;
private
String
mimeType
;
private
String
roomId
;
private
long
uploadedSize
;
private
String
error
;
public
String
getUplId
()
{
return
uplId
;
}
public
void
setUplId
(
String
uplId
)
{
this
.
uplId
=
uplId
;
}
public
int
getSyncstate
()
{
return
syncstate
;
}
public
void
setSyncstate
(
int
syncstate
)
{
this
.
syncstate
=
syncstate
;
}
public
String
getStorageType
()
{
return
storageType
;
}
public
void
setStorageType
(
String
storageType
)
{
this
.
storageType
=
storageType
;
}
public
String
getUri
()
{
return
uri
;
}
public
void
setUri
(
String
uri
)
{
this
.
uri
=
uri
;
}
public
String
getFilename
()
{
return
filename
;
}
public
void
setFilename
(
String
filename
)
{
this
.
filename
=
filename
;
}
public
long
getFilesize
()
{
return
filesize
;
}
public
void
setFilesize
(
long
filesize
)
{
this
.
filesize
=
filesize
;
}
public
String
getMimeType
()
{
return
mimeType
;
}
public
void
setMimeType
(
String
mimeType
)
{
this
.
mimeType
=
mimeType
;
}
public
String
getRoomId
()
{
return
roomId
;
}
public
void
setRoomId
(
String
roomId
)
{
this
.
roomId
=
roomId
;
}
public
long
getUploadedSize
()
{
return
uploadedSize
;
}
public
void
setUploadedSize
(
long
uploadedSize
)
{
this
.
uploadedSize
=
uploadedSize
;
}
public
String
getError
()
{
return
error
;
}
public
void
setError
(
String
error
)
{
this
.
error
=
error
;
}
}
app/src/main/java/chat/rocket/android/renderer/FileUploadingRenderer.java
0 → 100644
View file @
8876ac1e
package
chat
.
rocket
.
android
.
renderer
;
import
android.content.Context
;
import
android.widget.ProgressBar
;
import
android.widget.TextView
;
import
chat.rocket.android.model.internal.FileUploading
;
/**
* rendering FileUploading status.
*/
public
class
FileUploadingRenderer
extends
AbstractRenderer
<
FileUploading
>
{
public
FileUploadingRenderer
(
Context
context
,
FileUploading
object
)
{
super
(
context
,
object
);
}
public
FileUploadingRenderer
progressInto
(
ProgressBar
progressBar
)
{
if
(!
shouldHandle
(
progressBar
))
{
return
this
;
}
if
(
object
.
getFilesize
()
>=
Integer
.
MAX_VALUE
)
{
int
max
=
1000
;
int
progress
=
(
int
)
(
max
*
object
.
getUploadedSize
()
/
object
.
getFilesize
());
progressBar
.
setProgress
(
progress
);
progressBar
.
setMax
(
max
);
}
else
{
progressBar
.
setProgress
((
int
)
object
.
getUploadedSize
());
progressBar
.
setMax
((
int
)
object
.
getFilesize
());
}
return
this
;
}
public
FileUploadingRenderer
progressTextInto
(
TextView
uploadedSizeText
,
TextView
totalSizeText
)
{
if
(!
shouldHandle
(
uploadedSizeText
)
||
!
shouldHandle
(
totalSizeText
))
{
return
this
;
}
long
uploaded
=
object
.
getUploadedSize
();
long
total
=
object
.
getFilesize
();
if
(
total
<
50
*
1024
)
{
//<50KB
uploadedSizeText
.
setText
(
String
.
format
(
"%,d"
,
uploaded
));
totalSizeText
.
setText
(
String
.
format
(
"%,d"
,
total
));
}
else
if
(
total
<
8
*
1048576
)
{
//<8MB
uploadedSizeText
.
setText
(
String
.
format
(
"%,d"
,
uploaded
/
1024
));
totalSizeText
.
setText
(
String
.
format
(
"%,d KB"
,
total
/
1024
));
}
else
{
uploadedSizeText
.
setText
(
String
.
format
(
"%,d"
,
uploaded
/
1048576
));
totalSizeText
.
setText
(
String
.
format
(
"%,d MB"
,
total
/
1048576
));
}
return
this
;
}
}
app/src/main/java/chat/rocket/android/service/RocketChatWebSocketThread.java
View file @
8876ac1e
...
...
@@ -19,11 +19,13 @@ import chat.rocket.android.service.ddp.base.LoginServiceConfigurationSubscriber;
import
chat.rocket.android.service.ddp.base.UserDataSubscriber
;
import
chat.rocket.android.service.observer.CurrentUserObserver
;
import
chat.rocket.android.service.observer.GetUsersOfRoomsProcedureObserver
;
import
chat.rocket.android.service.observer.FileUploadingWithUfsObserver
;
import
chat.rocket.android.service.observer.LoadMessageProcedureObserver
;
import
chat.rocket.android.service.observer.MethodCallObserver
;
import
chat.rocket.android.service.observer.NewMessageObserver
;
import
chat.rocket.android.service.observer.NotificationItemObserver
;
import
chat.rocket.android.service.observer.ReactiveNotificationManager
;
import
chat.rocket.android.service.observer.FileUploadingToS3Observer
;
import
chat.rocket.android.service.observer.SessionObserver
;
import
chat.rocket.android.service.observer.TokenLoginObserver
;
import
chat.rocket.android_ddp.DDPClientCallback
;
...
...
@@ -49,7 +51,9 @@ public class RocketChatWebSocketThread extends HandlerThread {
NewMessageObserver
.
class
,
CurrentUserObserver
.
class
,
ReactiveNotificationManager
.
class
,
NotificationItemObserver
.
class
NotificationItemObserver
.
class
,
FileUploadingToS3Observer
.
class
,
FileUploadingWithUfsObserver
.
class
};
private
final
Context
appContext
;
private
final
String
serverConfigId
;
...
...
app/src/main/java/chat/rocket/android/service/observer/FileUploadingToS3Observer.java
0 → 100644
View file @
8876ac1e
package
chat
.
rocket
.
android
.
service
.
observer
;
import
android.content.Context
;
import
android.net.Uri
;
import
bolts.Task
;
import
chat.rocket.android.api.DDPClientWraper
;
import
chat.rocket.android.api.FileUploadingHelper
;
import
chat.rocket.android.helper.LogcatIfError
;
import
chat.rocket.android.helper.OkHttpHelper
;
import
chat.rocket.android.log.RCLog
;
import
chat.rocket.android.model.SyncState
;
import
chat.rocket.android.model.internal.FileUploading
;
import
chat.rocket.android.realm_helper.RealmHelper
;
import
io.realm.Realm
;
import
io.realm.RealmResults
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.util.List
;
import
okhttp3.MediaType
;
import
okhttp3.MultipartBody
;
import
okhttp3.Request
;
import
okhttp3.RequestBody
;
import
okhttp3.Response
;
import
okio.BufferedSink
;
import
okio.Okio
;
import
okio.Source
;
import
org.json.JSONArray
;
import
org.json.JSONObject
;
/**
* execute file uploading and requesting sendMessage with attachment.
*/
public
class
FileUploadingToS3Observer
extends
AbstractModelObserver
<
FileUploading
>
{
private
FileUploadingHelper
methodCall
;
public
FileUploadingToS3Observer
(
Context
context
,
String
hostname
,
RealmHelper
realmHelper
,
DDPClientWraper
ddpClient
)
{
super
(
context
,
hostname
,
realmHelper
,
ddpClient
);
methodCall
=
new
FileUploadingHelper
(
realmHelper
,
ddpClient
);
realmHelper
.
executeTransaction
(
realm
->
{
// resume pending operations.
RealmResults
<
FileUploading
>
pendingUploadRequests
=
realm
.
where
(
FileUploading
.
class
)
.
equalTo
(
"syncstate"
,
SyncState
.
SYNCING
)
.
equalTo
(
"storageType"
,
FileUploading
.
STORAGE_TYPE_S3
)
.
findAll
();
for
(
FileUploading
req
:
pendingUploadRequests
)
{
req
.
setSyncstate
(
SyncState
.
NOT_SYNCED
);
}
// clean up records.
realm
.
where
(
FileUploading
.
class
)
.
beginGroup
()
.
equalTo
(
"syncstate"
,
SyncState
.
SYNCED
)
.
or
()
.
equalTo
(
"syncstate"
,
SyncState
.
FAILED
)
.
endGroup
()
.
equalTo
(
"storageType"
,
FileUploading
.
STORAGE_TYPE_S3
)
.
findAll
().
deleteAllFromRealm
();
return
null
;
}).
continueWith
(
new
LogcatIfError
());
}
@Override
public
RealmResults
<
FileUploading
>
queryItems
(
Realm
realm
)
{
return
realm
.
where
(
FileUploading
.
class
)
.
equalTo
(
"syncstate"
,
SyncState
.
NOT_SYNCED
)
.
equalTo
(
"storageType"
,
FileUploading
.
STORAGE_TYPE_S3
)
.
findAll
();
}
@Override
public
void
onUpdateResults
(
List
<
FileUploading
>
results
)
{
if
(
results
.
isEmpty
())
{
return
;
}
List
<
FileUploading
>
uploadingList
=
realmHelper
.
executeTransactionForReadResults
(
realm
->
realm
.
where
(
FileUploading
.
class
).
equalTo
(
"syncstate"
,
SyncState
.
SYNCING
).
findAll
());
if
(
uploadingList
.
size
()
>=
3
)
{
// do not upload more than 3 files simultaneously
return
;
}
FileUploading
fileUploading
=
results
.
get
(
0
);
final
String
roomId
=
fileUploading
.
getRoomId
();
final
String
uplId
=
fileUploading
.
getUplId
();
final
String
filename
=
fileUploading
.
getFilename
();
final
long
filesize
=
fileUploading
.
getFilesize
();
final
String
mimeType
=
fileUploading
.
getMimeType
();
final
Uri
fileUri
=
Uri
.
parse
(
fileUploading
.
getUri
());
realmHelper
.
executeTransaction
(
realm
->
realm
.
createOrUpdateObjectFromJson
(
FileUploading
.
class
,
new
JSONObject
()
.
put
(
"uplId"
,
uplId
)
.
put
(
"syncstate"
,
SyncState
.
SYNCING
)
)
).
onSuccessTask
(
_task
->
methodCall
.
uploadRequest
(
filename
,
filesize
,
mimeType
,
roomId
)
).
onSuccessTask
(
task
->
{
final
JSONObject
info
=
task
.
getResult
();
final
String
uploadUrl
=
info
.
getString
(
"upload"
);
final
String
downloadUrl
=
info
.
getString
(
"download"
);
final
JSONArray
postDataList
=
info
.
getJSONArray
(
"postData"
);
MultipartBody
.
Builder
bodyBuilder
=
new
MultipartBody
.
Builder
()
.
setType
(
MultipartBody
.
FORM
);
for
(
int
i
=
0
;
i
<
postDataList
.
length
();
i
++)
{
JSONObject
postData
=
postDataList
.
getJSONObject
(
i
);
bodyBuilder
.
addFormDataPart
(
postData
.
getString
(
"name"
),
postData
.
getString
(
"value"
));
}
bodyBuilder
.
addFormDataPart
(
"file"
,
filename
,
new
RequestBody
()
{
private
long
numBytes
=
0
;
@Override
public
MediaType
contentType
()
{
return
MediaType
.
parse
(
mimeType
);
}
@Override
public
long
contentLength
()
throws
IOException
{
return
filesize
;
}
@Override
public
void
writeTo
(
BufferedSink
sink
)
throws
IOException
{
InputStream
inputStream
=
context
.
getContentResolver
().
openInputStream
(
fileUri
);
try
(
Source
source
=
Okio
.
source
(
inputStream
))
{
long
readBytes
;
while
((
readBytes
=
source
.
read
(
sink
.
buffer
(),
8192
))
>
0
)
{
numBytes
+=
readBytes
;
realmHelper
.
executeTransaction
(
realm
->
realm
.
createOrUpdateObjectFromJson
(
FileUploading
.
class
,
new
JSONObject
()
.
put
(
"uplId"
,
uplId
)
.
put
(
"uploadedSize"
,
numBytes
)))
.
continueWith
(
new
LogcatIfError
());
}
}
}
});
Request
request
=
new
Request
.
Builder
()
.
url
(
uploadUrl
)
.
post
(
bodyBuilder
.
build
())
.
build
();
Response
response
=
OkHttpHelper
.
getClientForUploadFile
().
newCall
(
request
).
execute
();
if
(
response
.
isSuccessful
())
{
return
Task
.
forResult
(
downloadUrl
);
}
else
{
return
Task
.
forError
(
new
Exception
(
response
.
message
()));
}
}).
onSuccessTask
(
task
->
{
String
downloadUrl
=
task
.
getResult
();
return
methodCall
.
sendFileMessage
(
roomId
,
"s3"
,
new
JSONObject
()
.
put
(
"_id"
,
Uri
.
parse
(
downloadUrl
).
getLastPathSegment
())
.
put
(
"type"
,
mimeType
)
.
put
(
"size"
,
filesize
)
.
put
(
"name"
,
filename
)
.
put
(
"url"
,
downloadUrl
)
);
}).
onSuccessTask
(
task
->
realmHelper
.
executeTransaction
(
realm
->
realm
.
createOrUpdateObjectFromJson
(
FileUploading
.
class
,
new
JSONObject
()
.
put
(
"uplId"
,
uplId
)
.
put
(
"syncstate"
,
SyncState
.
SYNCED
)
.
put
(
"error"
,
JSONObject
.
NULL
)
)
)).
continueWithTask
(
task
->
{
if
(
task
.
isFaulted
())
{
RCLog
.
w
(
task
.
getError
());
return
realmHelper
.
executeTransaction
(
realm
->
realm
.
createOrUpdateObjectFromJson
(
FileUploading
.
class
,
new
JSONObject
()
.
put
(
"uplId"
,
uplId
)
.
put
(
"syncstate"
,
SyncState
.
FAILED
)
.
put
(
"error"
,
task
.
getError
().
getMessage
())
));
}
else
{
return
Task
.
forResult
(
null
);
}
});
}
}
app/src/main/java/chat/rocket/android/service/observer/FileUploadingWithUfsObserver.java
0 → 100644
View file @
8876ac1e
package
chat
.
rocket
.
android
.
service
.
observer
;
import
android.content.Context
;
import
android.net.Uri
;
import
bolts.Task
;
import
chat.rocket.android.api.DDPClientWraper
;
import
chat.rocket.android.api.FileUploadingHelper
;
import
chat.rocket.android.helper.LogcatIfError
;
import
chat.rocket.android.helper.OkHttpHelper
;
import
chat.rocket.android.log.RCLog
;
import
chat.rocket.android.model.SyncState
;
import
chat.rocket.android.model.ddp.User
;
import
chat.rocket.android.model.internal.FileUploading
;
import
chat.rocket.android.model.internal.Session
;
import
chat.rocket.android.realm_helper.RealmHelper
;
import
io.realm.Realm
;
import
io.realm.RealmResults
;
import
java.io.InputStream
;
import
java.util.List
;
import
okhttp3.MediaType
;
import
okhttp3.Request
;
import
okhttp3.RequestBody
;
import
okhttp3.Response
;
import
org.json.JSONObject
;
/**
* execute file uploading and requesting sendMessage with attachment.
*/
public
class
FileUploadingWithUfsObserver
extends
AbstractModelObserver
<
FileUploading
>
{
private
FileUploadingHelper
methodCall
;
public
FileUploadingWithUfsObserver
(
Context
context
,
String
hostname
,
RealmHelper
realmHelper
,
DDPClientWraper
ddpClient
)
{
super
(
context
,
hostname
,
realmHelper
,
ddpClient
);
methodCall
=
new
FileUploadingHelper
(
realmHelper
,
ddpClient
);
realmHelper
.
executeTransaction
(
realm
->
{
// resume pending operations.
RealmResults
<
FileUploading
>
pendingUploadRequests
=
realm
.
where
(
FileUploading
.
class
)
.
equalTo
(
"syncstate"
,
SyncState
.
SYNCING
)
.
beginGroup
()
.
equalTo
(
"storageType"
,
FileUploading
.
STORAGE_TYPE_GRID_FS
)
.
or
()
.
equalTo
(
"storageType"
,
FileUploading
.
STORAGE_TYPE_FILE_SYSTEM
)
.
endGroup
()
.
findAll
();
for
(
FileUploading
req
:
pendingUploadRequests
)
{
req
.
setSyncstate
(
SyncState
.
NOT_SYNCED
);
}
// clean up records.
realm
.
where
(
FileUploading
.
class
)
.
beginGroup
()
.
equalTo
(
"syncstate"
,
SyncState
.
SYNCED
)
.
or
()
.
equalTo
(
"syncstate"
,
SyncState
.
FAILED
)
.
endGroup
()
.
beginGroup
()
.
equalTo
(
"storageType"
,
FileUploading
.
STORAGE_TYPE_GRID_FS
)
.
or
()
.
equalTo
(
"storageType"
,
FileUploading
.
STORAGE_TYPE_FILE_SYSTEM
)
.
endGroup
()
.
findAll
().
deleteAllFromRealm
();
return
null
;
}).
continueWith
(
new
LogcatIfError
());
}
@Override
public
RealmResults
<
FileUploading
>
queryItems
(
Realm
realm
)
{
return
realm
.
where
(
FileUploading
.
class
)
.
equalTo
(
"syncstate"
,
SyncState
.
NOT_SYNCED
)
.
beginGroup
()
.
equalTo
(
"storageType"
,
FileUploading
.
STORAGE_TYPE_GRID_FS
)
.
or
()
.
equalTo
(
"storageType"
,
FileUploading
.
STORAGE_TYPE_FILE_SYSTEM
)
.
endGroup
()
.
findAll
();
}
@Override
public
void
onUpdateResults
(
List
<
FileUploading
>
results
)
{
if
(
results
.
isEmpty
())
{
return
;
}
List
<
FileUploading
>
uploadingList
=
realmHelper
.
executeTransactionForReadResults
(
realm
->
realm
.
where
(
FileUploading
.
class
).
equalTo
(
"syncstate"
,
SyncState
.
SYNCING
).
findAll
());
if
(
uploadingList
.
size
()
>=
1
)
{
// do not upload multiple files simultaneously
return
;
}
User
currentUser
=
realmHelper
.
executeTransactionForRead
(
realm
->
User
.
queryCurrentUser
(
realm
).
findFirst
());
Session
session
=
realmHelper
.
executeTransactionForRead
(
realm
->
Session
.
queryDefaultSession
(
realm
).
findFirst
());
if
(
currentUser
==
null
||
session
==
null
)
{
return
;
}
final
String
cookie
=
String
.
format
(
"rc_uid=%s; rc_token=%s"
,
currentUser
.
get_id
(),
session
.
getToken
());
FileUploading
fileUploading
=
results
.
get
(
0
);
final
String
roomId
=
fileUploading
.
getRoomId
();
final
String
uplId
=
fileUploading
.
getUplId
();
final
String
filename
=
fileUploading
.
getFilename
();
final
long
filesize
=
fileUploading
.
getFilesize
();
final
String
mimeType
=
fileUploading
.
getMimeType
();
final
Uri
fileUri
=
Uri
.
parse
(
fileUploading
.
getUri
());
final
String
store
=
FileUploading
.
STORAGE_TYPE_GRID_FS
.
equals
(
fileUploading
.
getStorageType
())
?
"rocketchat_uploads"
:
(
FileUploading
.
STORAGE_TYPE_FILE_SYSTEM
.
equals
(
fileUploading
.
getStorageType
())
?
"fileSystem"
:
null
);
realmHelper
.
executeTransaction
(
realm
->
realm
.
createOrUpdateObjectFromJson
(
FileUploading
.
class
,
new
JSONObject
()
.
put
(
"uplId"
,
uplId
)
.
put
(
"syncstate"
,
SyncState
.
SYNCING
)
)
).
onSuccessTask
(
_task
->
methodCall
.
ufsCreate
(
filename
,
filesize
,
mimeType
,
store
,
roomId
)
).
onSuccessTask
(
task
->
{
final
JSONObject
info
=
task
.
getResult
();
final
String
fileId
=
info
.
getString
(
"fileId"
);
final
String
token
=
info
.
getString
(
"token"
);
final
String
url
=
info
.
getString
(
"url"
);
final
int
bufSize
=
16384
;
//16KB
final
byte
[]
buffer
=
new
byte
[
bufSize
];
int
offset
=
0
;
final
MediaType
contentType
=
MediaType
.
parse
(
mimeType
);
try
(
InputStream
inputStream
=
context
.
getContentResolver
().
openInputStream
(
fileUri
))
{
int
read
;
while
((
read
=
inputStream
.
read
(
buffer
))
>
0
)
{
offset
+=
read
;
double
progress
=
1.0
*
offset
/
filesize
;
Request
request
=
new
Request
.
Builder
()
.
url
(
url
+
"&progress="
+
progress
)
.
header
(
"Cookie"
,
cookie
)
.
post
(
RequestBody
.
create
(
contentType
,
buffer
,
0
,
read
))
.
build
();
Response
response
=
OkHttpHelper
.
getClientForUploadFile
().
newCall
(
request
).
execute
();
if
(
response
.
isSuccessful
())
{
final
JSONObject
obj
=
new
JSONObject
()
.
put
(
"uplId"
,
uplId
)
.
put
(
"uploadedSize"
,
offset
);
realmHelper
.
executeTransaction
(
realm
->
realm
.
createOrUpdateObjectFromJson
(
FileUploading
.
class
,
obj
));
}
else
{
return
Task
.
forError
(
new
Exception
(
response
.
message
()));
}
}
}
return
methodCall
.
ufsComplete
(
fileId
,
token
,
store
);
}).
onSuccessTask
(
task
->
methodCall
.
sendFileMessage
(
roomId
,
null
,
task
.
getResult
())
).
onSuccessTask
(
task
->
realmHelper
.
executeTransaction
(
realm
->
realm
.
createOrUpdateObjectFromJson
(
FileUploading
.
class
,
new
JSONObject
()
.
put
(
"uplId"
,
uplId
)
.
put
(
"syncstate"
,
SyncState
.
SYNCED
)
.
put
(
"error"
,
JSONObject
.
NULL
)
)
)).
continueWithTask
(
task
->
{
if
(
task
.
isFaulted
())
{
RCLog
.
w
(
task
.
getError
());
return
realmHelper
.
executeTransaction
(
realm
->
realm
.
createOrUpdateObjectFromJson
(
FileUploading
.
class
,
new
JSONObject
()
.
put
(
"uplId"
,
uplId
)
.
put
(
"syncstate"
,
SyncState
.
FAILED
)
.
put
(
"error"
,
task
.
getError
().
getMessage
())
));
}
else
{
return
Task
.
forResult
(
null
);
}
});
}
}
app/src/main/java/chat/rocket/android/service/observer/SessionObserver.java
View file @
8876ac1e
...
...
@@ -2,7 +2,9 @@ package chat.rocket.android.service.observer;
import
android.content.Context
;
import
chat.rocket.android.api.DDPClientWraper
;
import
chat.rocket.android.api.MethodCallHelper
;
import
chat.rocket.android.helper.LogcatIfError
;
import
chat.rocket.android.model.ddp.PublicSetting
;
import
chat.rocket.android.model.internal.GetUsersOfRoomsProcedure
;
import
chat.rocket.android.model.internal.LoadMessageProcedure
;
import
chat.rocket.android.model.internal.MethodCall
;
...
...
@@ -62,6 +64,8 @@ public class SessionObserver extends AbstractModelObserver<Session> {
@DebugLog
private
void
onLogin
()
{
streamNotifyMessage
.
register
();
new
MethodCallHelper
(
realmHelper
,
ddpClient
).
getPublicSettings
()
.
continueWith
(
new
LogcatIfError
());
}
@DebugLog
private
void
onLogout
()
{
...
...
@@ -69,6 +73,7 @@ public class SessionObserver extends AbstractModelObserver<Session> {
realmHelper
.
executeTransaction
(
realm
->
{
// remove all tables. ONLY INTERNAL TABLES!.
realm
.
delete
(
PublicSetting
.
class
);
realm
.
delete
(
MethodCall
.
class
);
realm
.
delete
(
LoadMessageProcedure
.
class
);
realm
.
delete
(
GetUsersOfRoomsProcedure
.
class
);
...
...
app/src/main/res/drawable/ic_insert_photo_white_24dp.xml
0 → 100644
View file @
8876ac1e
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"24dp"
android:height=
"24dp"
android:viewportWidth=
"24.0"
android:viewportHeight=
"24.0"
android:alpha=
"0.78"
>
<path
android:fillColor=
"#FFFFFFFF"
android:pathData=
"M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z"
/>
</vector>
app/src/main/res/drawable/progress_bar.xml
0 → 100644
View file @
8876ac1e
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<item
android:id=
"@android:id/background"
>
<shape>
<corners
android:radius=
"2dp"
/>
<solid
android:color=
"#12000000"
/>
</shape>
</item>
<item
android:id=
"@android:id/secondaryProgress"
>
<clip>
<shape>
<corners
android:radius=
"2dp"
/>
<solid
android:color=
"@color/colorAccent_a40"
/>
</shape>
</clip>
</item>
<item
android:id=
"@android:id/progress"
>
<clip>
<shape>
<corners
android:radius=
"2dp"
/>
<solid
android:color=
"@color/colorAccent"
/>
</shape>
</clip>
</item>
</layer-list>
app/src/main/res/layout/dialog_file_uploading.xml
0 → 100644
View file @
8876ac1e
<?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=
"wrap_content"
android:paddingStart=
"@dimen/margin_16"
android:paddingEnd=
"@dimen/margin_16"
android:paddingBottom=
"@dimen/margin_16"
android:orientation=
"vertical"
>
<FrameLayout
android:id=
"@+id/room_user_titlebar"
android:layout_width=
"match_parent"
android:layout_height=
"?attr/actionBarSize"
>
<TextView
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"start|center_vertical"
android:text=
"@string/file_uploading_title"
android:textAppearance=
"@style/TextAppearance.AppCompat.Title"
/>
</FrameLayout>
<ProgressBar
android:id=
"@+id/progressBar"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
style=
"@style/AppTheme.ProgressBar.Horizontal"
android:layout_marginTop=
"@dimen/margin_8"
android:layout_marginBottom=
"@dimen/margin_8"
tools:progress=
"12"
tools:max=
"120"
/>
<LinearLayout
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:orientation=
"horizontal"
android:layout_gravity=
"end"
android:paddingEnd=
"2dp"
>
<TextView
android:id=
"@+id/txt_filesize_uploaded"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
tools:text=
"12"
/>
<TextView
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:text=
"/"
android:layout_marginStart=
"2dp"
android:layout_marginEnd=
"2dp"
/>
<TextView
android:id=
"@+id/txt_filesize_total"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
tools:text=
"120"
/>
</LinearLayout>
</LinearLayout>
\ No newline at end of file
app/src/main/res/layout/fragment_room_main.xml
View file @
8876ac1e
...
...
@@ -20,6 +20,16 @@
android:layout_gravity=
"bottom"
android:background=
"@android:color/white"
/>
<android.support.design.widget.FloatingActionButton
android:id=
"@+id/fab_upload_file"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"start|bottom"
android:layout_margin=
"@dimen/margin_16"
app:fabSize=
"mini"
app:srcCompat=
"@drawable/ic_insert_photo_white_24dp"
/>
<android.support.design.widget.FloatingActionButton
android:id=
"@+id/fab_compose"
android:layout_width=
"wrap_content"
...
...
app/src/main/res/values/strings.xml
View file @
8876ac1e
...
...
@@ -18,6 +18,8 @@
<string
name=
"resend"
>
Resend
</string>
<string
name=
"discard"
>
Discard
</string>
<string
name=
"file_uploading_title"
>
Uploading...
</string>
<string
name=
"dialog_user_registration_email"
>
Email
</string>
<string
name=
"dialog_user_registration_username"
>
Username
</string>
<string
name=
"dialog_user_registration_password"
>
Password
</string>
...
...
app/src/main/res/values/styles.xml
View file @
8876ac1e
...
...
@@ -38,4 +38,9 @@
<item
name=
"colorControlActivated"
>
@color/colorAccentDark
</item>
<item
name=
"android:textColorHighlight"
>
@color/colorAccent_a40
</item>
</style>
<style
name=
"AppTheme.ProgressBar.Horizontal"
parent=
"Widget.AppCompat.ProgressBar.Horizontal"
>
<item
name=
"android:minHeight"
>
11dp
</item>
<item
name=
"android:progressDrawable"
>
@drawable/progress_bar
</item>
</style>
</resources>
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