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
efab24c2
Commit
efab24c2
authored
Nov 08, 2016
by
Yusuke Iwaki
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implement User Registration
parent
1877e61d
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
666 additions
and
95 deletions
+666
-95
LoginFragment.java
.../rocket/android/fragment/server_config/LoginFragment.java
+10
-21
UserRegistrationDialogFragment.java
...ragment/server_config/UserRegistrationDialogFragment.java
+148
-0
CheckSum.java
app/src/main/java/chat/rocket/android/helper/CheckSum.java
+30
-0
MethodCallHelper.java
...ain/java/chat/rocket/android/helper/MethodCallHelper.java
+52
-0
MethodCall.java
app/src/main/java/chat/rocket/android/model/MethodCall.java
+125
-0
SyncState.java
app/src/main/java/chat/rocket/android/model/SyncState.java
+11
-0
RocketChatWebSocketThread.java
...hat/rocket/android/service/RocketChatWebSocketThread.java
+3
-1
MethodCallObserver.java
...t/rocket/android/service/observer/MethodCallObserver.java
+83
-0
RocketChatWebSocketAPI.java
...n/java/chat/rocket/android/ws/RocketChatWebSocketAPI.java
+16
-0
ic_user_registration_blue_24dp.xml
app/src/main/res/drawable/ic_user_registration_blue_24dp.xml
+9
-0
dialog_user_registration.xml
app/src/main/res/layout/dialog_user_registration.xml
+97
-0
fragment_login.xml
app/src/main/res/layout/fragment_login.xml
+80
-71
WaitingView.java
...src/main/java/chat/rocket/android/widget/WaitingView.java
+1
-1
normal_circle.xml
...t-android-widgets/src/main/res/drawable/normal_circle.xml
+1
-1
No files found.
app/src/main/java/chat/rocket/android/fragment/server_config/LoginFragment.java
View file @
efab24c2
...
@@ -6,6 +6,7 @@ import android.view.View;
...
@@ -6,6 +6,7 @@ import android.view.View;
import
android.widget.TextView
;
import
android.widget.TextView
;
import
android.widget.Toast
;
import
android.widget.Toast
;
import
chat.rocket.android.R
;
import
chat.rocket.android.R
;
import
chat.rocket.android.helper.CheckSum
;
import
chat.rocket.android.helper.LogcatIfError
;
import
chat.rocket.android.helper.LogcatIfError
;
import
chat.rocket.android.helper.TextUtils
;
import
chat.rocket.android.helper.TextUtils
;
import
chat.rocket.android.model.MeteorLoginServiceConfiguration
;
import
chat.rocket.android.model.MeteorLoginServiceConfiguration
;
...
@@ -14,9 +15,6 @@ import chat.rocket.android.model.ServerConfigCredential;
...
@@ -14,9 +15,6 @@ import chat.rocket.android.model.ServerConfigCredential;
import
chat.rocket.android.renderer.ServerConfigCredentialRenderer
;
import
chat.rocket.android.renderer.ServerConfigCredentialRenderer
;
import
io.realm.Realm
;
import
io.realm.Realm
;
import
io.realm.RealmResults
;
import
io.realm.RealmResults
;
import
java.nio.charset.Charset
;
import
java.security.MessageDigest
;
import
java.security.NoSuchAlgorithmException
;
import
java.util.List
;
import
java.util.List
;
import
jp.co.crowdworks.realm_java_helpers.RealmHelper
;
import
jp.co.crowdworks.realm_java_helpers.RealmHelper
;
import
jp.co.crowdworks.realm_java_helpers.RealmListObserver
;
import
jp.co.crowdworks.realm_java_helpers.RealmListObserver
;
...
@@ -69,11 +67,19 @@ public class LoginFragment extends AbstractServerConfigFragment {
...
@@ -69,11 +67,19 @@ public class LoginFragment extends AbstractServerConfigFragment {
.
put
(
"type"
,
ServerConfigCredential
.
TYPE_EMAIL
)
.
put
(
"type"
,
ServerConfigCredential
.
TYPE_EMAIL
)
.
put
(
"errorMessage"
,
JSONObject
.
NULL
)
.
put
(
"errorMessage"
,
JSONObject
.
NULL
)
.
put
(
"username"
,
username
.
toString
())
.
put
(
"username"
,
username
.
toString
())
.
put
(
"hashedPasswd"
,
sha256sum
(
passwd
.
toString
())))
.
put
(
"hashedPasswd"
,
CheckSum
.
sha256
(
passwd
.
toString
())))
)
)
).
continueWith
(
new
LogcatIfError
());
).
continueWith
(
new
LogcatIfError
());
});
});
final
View
btnUserRegistration
=
rootView
.
findViewById
(
R
.
id
.
btn_user_registration
);
btnUserRegistration
.
setOnClickListener
(
view
->
{
UserRegistrationDialogFragment
.
create
(
serverConfigId
,
txtUsername
.
getText
().
toString
(),
txtPasswd
.
getText
().
toString
())
.
show
(
getFragmentManager
(),
UserRegistrationDialogFragment
.
class
.
getSimpleName
());
});
showErrorIfNeeded
();
showErrorIfNeeded
();
}
}
...
@@ -102,23 +108,6 @@ public class LoginFragment extends AbstractServerConfigFragment {
...
@@ -102,23 +108,6 @@ public class LoginFragment extends AbstractServerConfigFragment {
errorShowingHandler
.
sendMessageDelayed
(
msg
,
160
);
errorShowingHandler
.
sendMessageDelayed
(
msg
,
160
);
}
}
private
static
String
sha256sum
(
String
orig
)
{
MessageDigest
messageDigest
=
null
;
try
{
messageDigest
=
MessageDigest
.
getInstance
(
"SHA-256"
);
}
catch
(
NoSuchAlgorithmException
exception
)
{
return
null
;
}
messageDigest
.
update
(
orig
.
getBytes
(
Charset
.
forName
(
"UTF-8"
)));
StringBuilder
stringBuilder
=
new
StringBuilder
();
for
(
byte
b
:
messageDigest
.
digest
())
{
stringBuilder
.
append
(
String
.
format
(
"%02x"
,
b
&
0xff
));
}
return
stringBuilder
.
toString
();
}
private
void
onRenderAuthProviders
(
List
<
MeteorLoginServiceConfiguration
>
authProviders
)
{
private
void
onRenderAuthProviders
(
List
<
MeteorLoginServiceConfiguration
>
authProviders
)
{
final
View
btnTwitter
=
rootView
.
findViewById
(
R
.
id
.
btn_login_with_twitter
);
final
View
btnTwitter
=
rootView
.
findViewById
(
R
.
id
.
btn_login_with_twitter
);
final
View
btnGitHub
=
rootView
.
findViewById
(
R
.
id
.
btn_login_with_github
);
final
View
btnGitHub
=
rootView
.
findViewById
(
R
.
id
.
btn_login_with_github
);
...
...
app/src/main/java/chat/rocket/android/fragment/server_config/UserRegistrationDialogFragment.java
0 → 100644
View file @
efab24c2
package
chat
.
rocket
.
android
.
fragment
.
server_config
;
import
android.app.Dialog
;
import
android.os.Bundle
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.Nullable
;
import
android.support.v4.app.DialogFragment
;
import
android.support.v7.app.AlertDialog
;
import
android.util.Patterns
;
import
android.view.LayoutInflater
;
import
android.view.View
;
import
android.widget.TextView
;
import
android.widget.Toast
;
import
chat.rocket.android.R
;
import
chat.rocket.android.helper.CheckSum
;
import
chat.rocket.android.helper.MethodCallHelper
;
import
chat.rocket.android.helper.TextUtils
;
import
chat.rocket.android.model.ServerConfig
;
import
chat.rocket.android.model.ServerConfigCredential
;
import
jp.co.crowdworks.realm_java_helpers_bolts.RealmHelperBolts
;
import
org.json.JSONObject
;
/**
* Dialog for user registration.
*/
public
class
UserRegistrationDialogFragment
extends
DialogFragment
{
private
String
serverConfigId
;
private
String
username
;
private
String
email
;
private
String
password
;
/**
* create UserRegistrationDialogFragment with auto-detect email/username.
*/
public
static
UserRegistrationDialogFragment
create
(
String
serverConfigId
,
String
usernameOrEmail
,
String
password
)
{
if
(
Patterns
.
EMAIL_ADDRESS
.
matcher
(
usernameOrEmail
).
matches
())
{
return
create
(
serverConfigId
,
null
,
usernameOrEmail
,
password
);
}
else
{
return
create
(
serverConfigId
,
usernameOrEmail
,
null
,
password
);
}
}
/**
* create UserRegistrationDialogFragment.
*/
public
static
UserRegistrationDialogFragment
create
(
String
serverConfigId
,
String
username
,
String
email
,
String
password
)
{
Bundle
args
=
new
Bundle
();
args
.
putString
(
"serverConfigId"
,
serverConfigId
);
if
(!
TextUtils
.
isEmpty
(
username
))
{
args
.
putString
(
"username"
,
username
);
}
if
(!
TextUtils
.
isEmpty
(
email
))
{
args
.
putString
(
"email"
,
email
);
}
if
(!
TextUtils
.
isEmpty
(
password
))
{
args
.
putString
(
"password"
,
password
);
}
UserRegistrationDialogFragment
dialog
=
new
UserRegistrationDialogFragment
();
dialog
.
setArguments
(
args
);
return
dialog
;
}
public
UserRegistrationDialogFragment
()
{
super
();
}
@Override
public
void
onCreate
(
@Nullable
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
Bundle
args
=
getArguments
();
if
(
args
!=
null
)
{
serverConfigId
=
args
.
getString
(
"serverConfigId"
);
username
=
args
.
getString
(
"username"
);
email
=
args
.
getString
(
"email"
);
password
=
args
.
getString
(
"password"
);
}
}
@NonNull
@Override
public
Dialog
onCreateDialog
(
Bundle
savedInstanceState
)
{
return
new
AlertDialog
.
Builder
(
getContext
(),
R
.
style
.
AppTheme_Dialog
)
.
setView
(
createDialogView
())
.
create
();
}
private
View
createDialogView
()
{
View
dialog
=
LayoutInflater
.
from
(
getContext
())
.
inflate
(
R
.
layout
.
dialog_user_registration
,
null
,
false
);
final
TextView
txtUsername
=
(
TextView
)
dialog
.
findViewById
(
R
.
id
.
editor_username
);
final
TextView
txtEmail
=
(
TextView
)
dialog
.
findViewById
(
R
.
id
.
editor_email
);
final
TextView
txtPasswd
=
(
TextView
)
dialog
.
findViewById
(
R
.
id
.
editor_passwd
);
if
(!
TextUtils
.
isEmpty
(
username
))
{
txtUsername
.
setText
(
username
);
}
if
(!
TextUtils
.
isEmpty
(
email
))
{
txtEmail
.
setText
(
email
);
}
if
(!
TextUtils
.
isEmpty
(
password
))
{
txtPasswd
.
setText
(
password
);
}
final
View
waitingView
=
dialog
.
findViewById
(
R
.
id
.
waiting
);
waitingView
.
setVisibility
(
View
.
GONE
);
dialog
.
findViewById
(
R
.
id
.
btn_register_user
).
setOnClickListener
(
view
->
{
view
.
setEnabled
(
false
);
waitingView
.
setVisibility
(
View
.
VISIBLE
);
username
=
txtUsername
.
getText
().
toString
();
email
=
txtEmail
.
getText
().
toString
();
password
=
txtPasswd
.
getText
().
toString
();
MethodCallHelper
.
registerUser
(
username
,
email
,
password
,
password
).
onSuccessTask
(
task
->
RealmHelperBolts
.
executeTransaction
(
realm
->
realm
.
createOrUpdateObjectFromJson
(
ServerConfig
.
class
,
new
JSONObject
()
.
put
(
"id"
,
serverConfigId
)
.
put
(
"credential"
,
new
JSONObject
()
.
put
(
"id"
,
serverConfigId
)
.
put
(
"type"
,
ServerConfigCredential
.
TYPE_EMAIL
)
.
put
(
"errorMessage"
,
JSONObject
.
NULL
)
.
put
(
"username"
,
email
)
.
put
(
"hashedPasswd"
,
CheckSum
.
sha256
(
password
)))
)
)
).
onSuccessTask
(
task
->
{
dismiss
();
return
null
;
}).
continueWith
(
task
->
{
if
(
task
.
isFaulted
())
{
Exception
exception
=
task
.
getError
();
showError
(
exception
.
getMessage
());
view
.
setEnabled
(
true
);
waitingView
.
setVisibility
(
View
.
GONE
);
}
return
null
;
});
});
return
dialog
;
}
private
void
showError
(
String
errMessage
)
{
Toast
.
makeText
(
getContext
(),
errMessage
,
Toast
.
LENGTH_SHORT
).
show
();
}
}
app/src/main/java/chat/rocket/android/helper/CheckSum.java
0 → 100644
View file @
efab24c2
package
chat
.
rocket
.
android
.
helper
;
import
java.nio.charset.Charset
;
import
java.security.MessageDigest
;
import
java.security.NoSuchAlgorithmException
;
/**
* SHA-256, MD5, ...
*/
public
class
CheckSum
{
/**
* SHA-256.
*/
public
static
String
sha256
(
String
orig
)
{
MessageDigest
messageDigest
=
null
;
try
{
messageDigest
=
MessageDigest
.
getInstance
(
"SHA-256"
);
}
catch
(
NoSuchAlgorithmException
exception
)
{
return
null
;
}
messageDigest
.
update
(
orig
.
getBytes
(
Charset
.
forName
(
"UTF-8"
)));
StringBuilder
stringBuilder
=
new
StringBuilder
();
for
(
byte
b
:
messageDigest
.
digest
())
{
stringBuilder
.
append
(
String
.
format
(
"%02x"
,
b
&
0xff
));
}
return
stringBuilder
.
toString
();
}
}
app/src/main/java/chat/rocket/android/helper/MethodCallHelper.java
0 → 100644
View file @
efab24c2
package
chat
.
rocket
.
android
.
helper
;
import
android.util.Patterns
;
import
bolts.Task
;
import
chat.rocket.android.model.MethodCall
;
import
chat.rocket.android.model.ServerConfigCredential
;
import
chat.rocket.android_ddp.DDPClientCallback
;
import
org.json.JSONArray
;
import
org.json.JSONException
;
import
org.json.JSONObject
;
import
static
android
.
icu
.
lang
.
UCharacter
.
GraphemeClusterBreak
.
T
;
/**
* Utility class for creating/handling MethodCall.
*/
public
class
MethodCallHelper
{
private
static
<
T
>
Task
<
T
>
injectErrorMessageHandler
(
Task
<
T
>
task
)
{
return
task
.
continueWithTask
(
_task
->
{
if
(
_task
.
isFaulted
())
{
Exception
exception
=
_task
.
getError
();
if
(
exception
instanceof
MethodCall
.
Error
)
{
String
errMessage
=
new
JSONObject
(
exception
.
getMessage
()).
getString
(
"message"
);
return
Task
.
forError
(
new
Exception
(
errMessage
));
}
else
{
return
Task
.
forError
(
exception
);
}
}
else
{
return
_task
;
}
});
}
/**
* Register User.
*/
public
static
Task
<
Void
>
registerUser
(
String
name
,
String
email
,
String
passwd
,
String
confirmPasswd
)
{
JSONObject
param
=
new
JSONObject
();
try
{
param
.
put
(
"name"
,
name
).
put
(
"email"
,
email
)
.
put
(
"pass"
,
passwd
).
put
(
"confirm-pass"
,
confirmPasswd
);
}
catch
(
JSONException
exception
)
{
return
Task
.
forError
(
exception
);
}
return
injectErrorMessageHandler
(
MethodCall
.
execute
(
"registerUser"
,
param
.
toString
()))
.
onSuccessTask
(
task
->
Task
.
forResult
(
null
));
// nothing to do?
}
}
app/src/main/java/chat/rocket/android/model/MethodCall.java
0 → 100644
View file @
efab24c2
package
chat
.
rocket
.
android
.
model
;
import
bolts.Task
;
import
bolts.TaskCompletionSource
;
import
chat.rocket.android.helper.LogcatIfError
;
import
chat.rocket.android.helper.TextUtils
;
import
io.realm.Realm
;
import
io.realm.RealmObject
;
import
io.realm.RealmQuery
;
import
io.realm.annotations.PrimaryKey
;
import
java.util.UUID
;
import
jp.co.crowdworks.realm_java_helpers.RealmObjectObserver
;
import
jp.co.crowdworks.realm_java_helpers_bolts.RealmHelperBolts
;
import
org.json.JSONException
;
import
org.json.JSONObject
;
@SuppressWarnings
(
"PMD.ShortVariable"
)
public
class
MethodCall
extends
RealmObject
{
@PrimaryKey
private
String
id
;
private
int
syncstate
;
private
String
name
;
private
String
paramsJson
;
private
String
resultJson
;
public
String
getId
()
{
return
id
;
}
public
void
setId
(
String
id
)
{
this
.
id
=
id
;
}
public
int
getSyncstate
()
{
return
syncstate
;
}
public
void
setSyncstate
(
int
syncstate
)
{
this
.
syncstate
=
syncstate
;
}
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
String
getParamsJson
()
{
return
paramsJson
;
}
public
void
setParamsJson
(
String
paramsJson
)
{
this
.
paramsJson
=
paramsJson
;
}
public
String
getResultJson
()
{
return
resultJson
;
}
public
void
setResultJson
(
String
resultJson
)
{
this
.
resultJson
=
resultJson
;
}
public
static
class
Error
extends
Exception
{
public
Error
(
String
message
)
{
super
(
message
);
}
public
Error
(
Throwable
exception
)
{
super
(
exception
);
}
}
public
static
Task
<
JSONObject
>
execute
(
String
name
,
String
paramsJson
)
{
final
String
newId
=
UUID
.
randomUUID
().
toString
();
TaskCompletionSource
<
JSONObject
>
task
=
new
TaskCompletionSource
<>();
RealmHelperBolts
.
executeTransaction
(
realm
->
{
MethodCall
call
=
realm
.
createObject
(
MethodCall
.
class
,
newId
);
call
.
setSyncstate
(
SyncState
.
NOT_SYNCED
);
call
.
setName
(
name
);
call
.
setParamsJson
(
paramsJson
);
return
null
;
}).
continueWith
(
_task
->
{
if
(
_task
.
isFaulted
())
{
task
.
setError
(
_task
.
getError
());
}
else
{
new
RealmObjectObserver
<
MethodCall
>()
{
@Override
protected
RealmQuery
<
MethodCall
>
query
(
Realm
realm
)
{
return
realm
.
where
(
MethodCall
.
class
).
equalTo
(
"id"
,
newId
);
}
@Override
protected
void
onChange
(
MethodCall
methodCall
)
{
int
syncstate
=
methodCall
.
getSyncstate
();
if
(
syncstate
==
SyncState
.
SYNCED
)
{
try
{
String
resultJson
=
methodCall
.
getResultJson
();
task
.
setResult
(
TextUtils
.
isEmpty
(
resultJson
)
?
null
:
new
JSONObject
(
resultJson
));
}
catch
(
JSONException
exception
)
{
task
.
setError
(
new
Error
(
exception
));
}
exit
(
methodCall
.
getId
());
}
else
if
(
syncstate
==
SyncState
.
FAILED
)
{
task
.
setError
(
new
Error
(
methodCall
.
getResultJson
()));
exit
(
methodCall
.
getId
());
}
}
private
void
exit
(
String
newId
)
{
unsub
();
remove
(
newId
).
continueWith
(
new
LogcatIfError
());
}
}.
sub
();
}
return
null
;
});
return
task
.
getTask
();
}
public
static
final
Task
<
Void
>
remove
(
String
id
)
{
return
RealmHelperBolts
.
executeTransaction
(
realm
->
realm
.
where
(
MethodCall
.
class
).
equalTo
(
"id"
,
id
).
findAll
().
deleteAllFromRealm
());
}
}
app/src/main/java/chat/rocket/android/model/SyncState.java
0 → 100644
View file @
efab24c2
package
chat
.
rocket
.
android
.
model
;
/**
* The sync status of each model.
*/
public
interface
SyncState
{
int
NOT_SYNCED
=
0
;
int
SYNCING
=
1
;
int
SYNCED
=
2
;
int
FAILED
=
3
;
}
app/src/main/java/chat/rocket/android/service/RocketChatWebSocketThread.java
View file @
efab24c2
...
@@ -11,6 +11,7 @@ import chat.rocket.android.helper.TextUtils;
...
@@ -11,6 +11,7 @@ import chat.rocket.android.helper.TextUtils;
import
chat.rocket.android.model.ServerConfig
;
import
chat.rocket.android.model.ServerConfig
;
import
chat.rocket.android.service.ddp_subscriber.LoginServiceConfigurationSubscriber
;
import
chat.rocket.android.service.ddp_subscriber.LoginServiceConfigurationSubscriber
;
import
chat.rocket.android.service.observer.LoginCredentialObserver
;
import
chat.rocket.android.service.observer.LoginCredentialObserver
;
import
chat.rocket.android.service.observer.MethodCallObserver
;
import
chat.rocket.android.ws.RocketChatWebSocketAPI
;
import
chat.rocket.android.ws.RocketChatWebSocketAPI
;
import
chat.rocket.android_ddp.DDPClientCallback
;
import
chat.rocket.android_ddp.DDPClientCallback
;
import
hugo.weaving.DebugLog
;
import
hugo.weaving.DebugLog
;
...
@@ -28,7 +29,8 @@ import timber.log.Timber;
...
@@ -28,7 +29,8 @@ import timber.log.Timber;
public
class
RocketChatWebSocketThread
extends
HandlerThread
{
public
class
RocketChatWebSocketThread
extends
HandlerThread
{
private
static
final
Class
[]
REGISTERABLE_CLASSES
=
{
private
static
final
Class
[]
REGISTERABLE_CLASSES
=
{
LoginServiceConfigurationSubscriber
.
class
,
LoginServiceConfigurationSubscriber
.
class
,
LoginCredentialObserver
.
class
LoginCredentialObserver
.
class
,
MethodCallObserver
.
class
};
};
private
final
Context
appContext
;
private
final
Context
appContext
;
private
final
String
serverConfigId
;
private
final
String
serverConfigId
;
...
...
app/src/main/java/chat/rocket/android/service/observer/MethodCallObserver.java
0 → 100644
View file @
efab24c2
package
chat
.
rocket
.
android
.
service
.
observer
;
import
android.content.Context
;
import
chat.rocket.android.helper.LogcatIfError
;
import
chat.rocket.android.model.MethodCall
;
import
chat.rocket.android.model.SyncState
;
import
chat.rocket.android.ws.RocketChatWebSocketAPI
;
import
chat.rocket.android_ddp.DDPClientCallback
;
import
io.realm.Realm
;
import
io.realm.RealmResults
;
import
java.util.List
;
import
jp.co.crowdworks.realm_java_helpers_bolts.RealmHelperBolts
;
import
org.json.JSONObject
;
/**
* Observing MethodCall record, executing RPC if needed.
*/
public
class
MethodCallObserver
extends
AbstractModelObserver
<
MethodCall
>
{
/**
* constructor.
*/
public
MethodCallObserver
(
Context
context
,
String
serverConfigId
,
RocketChatWebSocketAPI
api
)
{
super
(
context
,
serverConfigId
,
api
);
RealmHelperBolts
.
executeTransaction
(
realm
->
{
RealmResults
<
MethodCall
>
pendingMethodCalls
=
realm
.
where
(
MethodCall
.
class
)
.
equalTo
(
"syncstate"
,
SyncState
.
SYNCING
)
.
findAll
();
for
(
MethodCall
call
:
pendingMethodCalls
)
{
call
.
setSyncstate
(
SyncState
.
NOT_SYNCED
);
}
return
null
;
}).
continueWith
(
new
LogcatIfError
());
}
@Override
protected
RealmResults
<
MethodCall
>
queryItems
(
Realm
realm
)
{
return
realm
.
where
(
MethodCall
.
class
)
.
isNotNull
(
"name"
)
.
equalTo
(
"syncstate"
,
SyncState
.
NOT_SYNCED
)
.
findAll
();
}
@Override
protected
void
onCollectionChanged
(
List
<
MethodCall
>
list
)
{
if
(
list
==
null
||
list
.
isEmpty
())
{
return
;
}
MethodCall
call
=
list
.
get
(
0
);
final
String
methodCallId
=
call
.
getId
();
final
String
methodName
=
call
.
getName
();
final
String
params
=
call
.
getParamsJson
();
RealmHelperBolts
.
executeTransaction
(
realm
->
realm
.
createOrUpdateObjectFromJson
(
MethodCall
.
class
,
new
JSONObject
()
.
put
(
"id"
,
methodCallId
)
.
put
(
"syncstate"
,
SyncState
.
SYNCING
))
).
onSuccessTask
(
task
->
webSocketAPI
.
rpc
(
methodCallId
,
methodName
,
params
).
onSuccessTask
(
_task
->
RealmHelperBolts
.
executeTransaction
(
realm
->
{
JSONObject
result
=
_task
.
getResult
().
result
;
return
realm
.
createOrUpdateObjectFromJson
(
MethodCall
.
class
,
new
JSONObject
()
.
put
(
"id"
,
methodCallId
)
.
put
(
"syncstate"
,
SyncState
.
SYNCED
)
.
put
(
"resultJson"
,
result
==
null
?
null
:
result
.
toString
()));
})
)
).
continueWith
(
task
->
{
if
(
task
.
isFaulted
())
{
RealmHelperBolts
.
executeTransaction
(
realm
->
{
Exception
exception
=
task
.
getError
();
final
String
errMessage
=
(
exception
instanceof
DDPClientCallback
.
RPC
.
Error
)
?
((
DDPClientCallback
.
RPC
.
Error
)
exception
).
error
.
toString
()
:
exception
.
getMessage
();
realm
.
createOrUpdateObjectFromJson
(
MethodCall
.
class
,
new
JSONObject
()
.
put
(
"id"
,
methodCallId
)
.
put
(
"syncstate"
,
SyncState
.
FAILED
)
.
put
(
"resultJson"
,
errMessage
));
return
null
;
}).
continueWith
(
new
LogcatIfError
());
}
return
null
;
});
}
}
app/src/main/java/chat/rocket/android/ws/RocketChatWebSocketAPI.java
View file @
efab24c2
...
@@ -4,6 +4,7 @@ import android.support.annotation.Nullable;
...
@@ -4,6 +4,7 @@ import android.support.annotation.Nullable;
import
android.util.Patterns
;
import
android.util.Patterns
;
import
bolts.Task
;
import
bolts.Task
;
import
chat.rocket.android.helper.OkHttpHelper
;
import
chat.rocket.android.helper.OkHttpHelper
;
import
chat.rocket.android.helper.TextUtils
;
import
chat.rocket.android.model.ServerConfigCredential
;
import
chat.rocket.android.model.ServerConfigCredential
;
import
chat.rocket.android_ddp.DDPClient
;
import
chat.rocket.android_ddp.DDPClient
;
import
chat.rocket.android_ddp.DDPClientCallback
;
import
chat.rocket.android_ddp.DDPClientCallback
;
...
@@ -79,6 +80,21 @@ public class RocketChatWebSocketAPI {
...
@@ -79,6 +80,21 @@ public class RocketChatWebSocketAPI {
return
method
+
"-"
+
UUID
.
randomUUID
().
toString
().
replace
(
"-"
,
""
);
return
method
+
"-"
+
UUID
.
randomUUID
().
toString
().
replace
(
"-"
,
""
);
}
}
/**
* Execute raw RPC.
*/
public
Task
<
DDPClientCallback
.
RPC
>
rpc
(
String
methodCallId
,
String
methodName
,
String
params
)
{
if
(
TextUtils
.
isEmpty
(
params
))
{
return
ddpClient
.
rpc
(
methodName
,
null
,
methodCallId
);
}
try
{
return
ddpClient
.
rpc
(
methodName
,
new
JSONArray
().
put
(
new
JSONObject
(
params
)),
methodCallId
);
}
catch
(
JSONException
exception
)
{
return
Task
.
forError
(
exception
);
}
}
/**
/**
* Login with ServerConfigCredential.
* Login with ServerConfigCredential.
*/
*/
...
...
app/src/main/res/drawable/ic_user_registration_blue_24dp.xml
0 → 100644
View file @
efab24c2
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"24dp"
android:height=
"24dp"
android:viewportWidth=
"24.0"
android:viewportHeight=
"24.0"
>
<path
android:fillColor=
"#FF2D91FA"
android:pathData=
"M15,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM6,10L6,7L4,7v3L1,10v2h3v3h2v-3h3v-2L6,10zM15,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"
/>
</vector>
app/src/main/res/layout/dialog_user_registration.xml
0 → 100644
View file @
efab24c2
<?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"
android:orientation=
"vertical"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:minWidth=
"288dp"
android:padding=
"@dimen/margin_24"
>
<android.support.design.widget.TextInputLayout
android:id=
"@+id/text_input_email"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
<android.support.design.widget.TextInputEditText
android:id=
"@+id/editor_email"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:hint=
"email address"
android:imeOptions=
"actionNext"
android:inputType=
"textWebEmailAddress"
android:singleLine=
"true"
/>
</android.support.design.widget.TextInputLayout>
<Space
android:layout_width=
"wrap_content"
android:layout_height=
"@dimen/margin_8"
/>
<android.support.design.widget.TextInputLayout
android:id=
"@+id/text_input_username"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
<android.support.design.widget.TextInputEditText
android:id=
"@+id/editor_username"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:hint=
"username"
android:imeOptions=
"actionNext"
android:inputType=
"textWebEmailAddress"
android:singleLine=
"true"
/>
</android.support.design.widget.TextInputLayout>
<Space
android:layout_width=
"wrap_content"
android:layout_height=
"@dimen/margin_8"
/>
<android.support.design.widget.TextInputLayout
android:id=
"@+id/text_input_passwd"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
app:passwordToggleEnabled=
"true"
>
<android.support.design.widget.TextInputEditText
android:id=
"@+id/editor_passwd"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:hint=
"password"
android:imeOptions=
"actionNext"
android:inputType=
"textWebPassword"
android:singleLine=
"true"
/>
</android.support.design.widget.TextInputLayout>
<Space
android:layout_width=
"wrap_content"
android:layout_height=
"@dimen/margin_16"
/>
<android.support.design.widget.FloatingActionButton
android:id=
"@+id/btn_register_user"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"end|bottom"
app:elevation=
"2dp"
app:fabSize=
"mini"
app:srcCompat=
"@drawable/ic_arrow_forward_white_24dp"
/>
<chat.rocket.android.widget.WaitingView
android:id=
"@+id/waiting"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
app:dotCount=
"5"
app:dotSize=
"12dp"
android:layout_gravity=
"center"
/>
</LinearLayout>
\ No newline at end of file
app/src/main/res/layout/fragment_login.xml
View file @
efab24c2
...
@@ -12,96 +12,105 @@
...
@@ -12,96 +12,105 @@
android:layout_gravity=
"center"
android:layout_gravity=
"center"
android:background=
"@color/white"
android:background=
"@color/white"
android:minWidth=
"288dp"
android:minWidth=
"288dp"
android:orientation=
"
horizont
al"
android:orientation=
"
vertic
al"
android:padding=
"@dimen/margin_24"
android:padding=
"@dimen/margin_24"
>
>
<LinearLayout
<LinearLayout
android:layout_width=
"
0px
"
android:layout_width=
"
match_parent
"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_weight=
"1"
android:orientation=
"horizontal"
android:orientation=
"vertical"
>
>
<chat.rocket.android.widget.FontAwesomeButton
android:id=
"@+id/btn_login_with_twitter"
android:layout_width=
"48dp"
android:layout_height=
"48dp"
android:text=
"@string/fa_twitter"
android:textSize=
"16dp"
android:layout_marginEnd=
"@dimen/margin_8"
android:enabled=
"false"
/>
<chat.rocket.android.widget.FontAwesomeButton
android:id=
"@+id/btn_login_with_github"
android:layout_width=
"48dp"
android:layout_height=
"48dp"
android:text=
"@string/fa_github"
android:textSize=
"16dp"
android:layout_marginEnd=
"@dimen/margin_8"
/>
</LinearLayout>
<LinearLayout
<android.support.design.widget.TextInputLayout
android:layout_width=
"match_parent"
android:id=
"@+id/text_input_username"
android:layout_height=
"wrap_content"
android:layout_width=
"match_parent"
android:orientation=
"horizontal"
android:layout_height=
"wrap_content"
>
>
<chat.rocket.android.widget.FontAwesomeButton
android:id=
"@+id/btn_login_with_twitter"
android:layout_width=
"48dp"
android:layout_height=
"48dp"
android:text=
"@string/fa_twitter"
android:textSize=
"16dp"
android:layout_marginEnd=
"@dimen/margin_8"
android:enabled=
"false"
/>
<chat.rocket.android.widget.FontAwesomeButton
android:id=
"@+id/btn_login_with_github"
android:layout_width=
"48dp"
android:layout_height=
"48dp"
android:text=
"@string/fa_github"
android:textSize=
"16dp"
android:layout_marginEnd=
"@dimen/margin_8"
/>
</LinearLayout>
<android.support.design.widget.TextInput
Layou
t
<android.support.design.widget.TextInput
EditTex
t
android:id=
"@+id/
text_input
_username"
android:id=
"@+id/
editor
_username"
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
>
android:hint=
"username or email"
android:imeOptions=
"actionNext"
android:inputType=
"textWebEmailAddress"
android:singleLine=
"true"
/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputEditText
<Space
android:id=
"@+id/editor_username"
android:layout_width=
"wrap_content"
android:layout_width=
"match_parent"
android:layout_height=
"@dimen/margin_8"
android:layout_height=
"wrap_content"
/>
android:hint=
"username or email"
android:imeOptions=
"actionNext"
android:inputType=
"textWebEmailAddress"
android:singleLine=
"true"
/>
</android.support.design.widget.TextInputLayout>
<Space
<android.support.design.widget.TextInputLayout
android:layout_width=
"wrap_content"
android:id=
"@+id/text_input_passwd"
android:layout_height=
"@dimen/margin_8"
android:layout_width=
"match_parent"
/>
android:layout_height=
"wrap_content"
app:passwordToggleEnabled=
"true"
>
<android.support.design.widget.TextInput
Layou
t
<android.support.design.widget.TextInput
EditTex
t
android:id=
"@+id/
text_input
_passwd"
android:id=
"@+id/
editor
_passwd"
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
app:passwordToggleEnabled=
"true"
android:hint=
"password"
>
android:imeOptions=
"actionNext"
android:inputType=
"textWebPassword"
<android.support.design.widget.TextInputEditText
android:singleLine=
"true"
android:id=
"@+id/editor_passwd"
/>
android:layout_width=
"match_parent"
</android.support.design.widget.TextInputLayout>
android:layout_height=
"wrap_content"
android:hint=
"password"
android:imeOptions=
"actionNext"
android:inputType=
"textWebPassword"
android:singleLine=
"true"
/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
<Space
<Space
android:layout_width=
"
@dimen/margin_8
"
android:layout_width=
"
wrap_content
"
android:layout_height=
"
wrap_content
"
android:layout_height=
"
@dimen/margin_16
"
/>
/>
<android.support.design.widget.FloatingActionButton
<FrameLayout
android:id=
"@+id/btn_login_with_email"
android:layout_width=
"match_parent"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"end|bottom"
android:orientation=
"horizontal"
app:elevation=
"2dp"
>
app:fabSize=
"mini"
app:srcCompat=
"@drawable/ic_arrow_forward_white_24dp"
<android.support.design.widget.FloatingActionButton
/>
android:id=
"@+id/btn_user_registration"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"start|bottom"
app:elevation=
"2dp"
app:fabSize=
"mini"
app:backgroundTint=
"@color/white"
app:srcCompat=
"@drawable/ic_user_registration_blue_24dp"
/>
<android.support.design.widget.FloatingActionButton
android:id=
"@+id/btn_login_with_email"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"end|bottom"
app:elevation=
"2dp"
app:fabSize=
"normal"
app:srcCompat=
"@drawable/ic_arrow_forward_white_24dp"
/>
</FrameLayout>
</LinearLayout>
</LinearLayout>
</FrameLayout>
</FrameLayout>
\ No newline at end of file
rocket-chat-android-widgets/src/main/java/chat/rocket/android/widget/WaitingView.java
View file @
efab24c2
...
@@ -72,7 +72,7 @@ public class WaitingView extends LinearLayout {
...
@@ -72,7 +72,7 @@ public class WaitingView extends LinearLayout {
FrameLayout
frameLayout
=
new
FrameLayout
(
context
);
FrameLayout
frameLayout
=
new
FrameLayout
(
context
);
frameLayout
.
setLayoutParams
(
new
LinearLayout
.
LayoutParams
(
size
*
3
/
2
,
size
*
3
/
2
));
frameLayout
.
setLayoutParams
(
new
LinearLayout
.
LayoutParams
(
size
*
3
/
2
,
size
*
3
/
2
));
ImageView
dot
=
new
ImageView
(
context
);
ImageView
dot
=
new
ImageView
(
context
);
dot
.
setImageResource
(
R
.
drawable
.
white
_circle
);
dot
.
setImageResource
(
R
.
drawable
.
normal
_circle
);
dot
.
setLayoutParams
(
new
FrameLayout
.
LayoutParams
(
size
,
size
,
Gravity
.
CENTER
));
dot
.
setLayoutParams
(
new
FrameLayout
.
LayoutParams
(
size
,
size
,
Gravity
.
CENTER
));
frameLayout
.
addView
(
dot
);
frameLayout
.
addView
(
dot
);
addView
(
frameLayout
);
addView
(
frameLayout
);
...
...
rocket-chat-android-widgets/src/main/res/drawable/
white
_circle.xml
→
rocket-chat-android-widgets/src/main/res/drawable/
normal
_circle.xml
View file @
efab24c2
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:shape=
"oval"
>
android:shape=
"oval"
>
<solid
android:color=
"
@android:color/white
"
/>
<solid
android:color=
"
?attr/colorControlNormal
"
/>
</shape>
</shape>
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