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
6007fd56
Commit
6007fd56
authored
Nov 05, 2016
by
Yusuke Iwaki
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
reformat with SquareAndroid plugin for Android Studio (google-java-formatter didn't work properly!)
parent
352f0c01
Changes
60
Hide whitespace changes
Inline
Side-by-side
Showing
60 changed files
with
1552 additions
and
1601 deletions
+1552
-1601
build.gradle
app/build.gradle
+41
-41
lint.xml
app/lint.xml
+3
-3
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+24
-21
LaunchUtil.java
app/src/main/java/chat/rocket/android/LaunchUtil.java
+9
-10
RocketChatApplication.java
.../main/java/chat/rocket/android/RocketChatApplication.java
+12
-17
AbstractAuthedActivity.java
.../chat/rocket/android/activity/AbstractAuthedActivity.java
+41
-51
AbstractFragmentActivity.java
...hat/rocket/android/activity/AbstractFragmentActivity.java
+23
-23
MainActivity.java
.../main/java/chat/rocket/android/activity/MainActivity.java
+10
-12
ServerConfigActivity.java
...va/chat/rocket/android/activity/ServerConfigActivity.java
+120
-130
AbstractFragment.java
...n/java/chat/rocket/android/fragment/AbstractFragment.java
+18
-18
AbstractServerConfigFragment.java
.../fragment/server_config/AbstractServerConfigFragment.java
+13
-15
ConnectingToHostFragment.java
...roid/fragment/server_config/ConnectingToHostFragment.java
+5
-7
InputHostnameFragment.java
...android/fragment/server_config/InputHostnameFragment.java
+61
-73
LogcatIfError.java
...c/main/java/chat/rocket/android/helper/LogcatIfError.java
+5
-6
OkHttpHelper.java
...rc/main/java/chat/rocket/android/helper/OkHttpHelper.java
+11
-15
OnBackPressListener.java
.../java/chat/rocket/android/helper/OnBackPressListener.java
+6
-6
TextUtils.java
app/src/main/java/chat/rocket/android/helper/TextUtils.java
+19
-16
MeteorLoginServiceConfiguration.java
...rocket/android/model/MeteorLoginServiceConfiguration.java
+7
-8
ServerConfig.java
...src/main/java/chat/rocket/android/model/ServerConfig.java
+87
-95
Registerable.java
...c/main/java/chat/rocket/android/service/Registerable.java
+12
-12
RocketChatService.java
...n/java/chat/rocket/android/service/RocketChatService.java
+75
-83
RocketChatWebSocketThread.java
...hat/rocket/android/service/RocketChatWebSocketThread.java
+164
-172
AbstractDDPDocEventSubscriber.java
...service/ddp_subscriber/AbstractDDPDocEventSubscriber.java
+123
-125
LoginServiceConfigurationSubscriber.java
...e/ddp_subscriber/LoginServiceConfigurationSubscriber.java
+12
-16
AbstractModelObserver.java
...ocket/android/service/observer/AbstractModelObserver.java
+14
-18
AbstractCustomFontTextView.java
.../chat/rocket/android/view/AbstractCustomFontTextView.java
+27
-25
FontAwesomeTextView.java
...in/java/chat/rocket/android/view/FontAwesomeTextView.java
+12
-13
FontelloTextView.java
.../main/java/chat/rocket/android/view/FontelloTextView.java
+12
-13
TypefaceHelper.java
...rc/main/java/chat/rocket/android/view/TypefaceHelper.java
+19
-22
WaitingView.java
app/src/main/java/chat/rocket/android/view/WaitingView.java
+92
-96
RocketChatWebSocketAPI.java
...n/java/chat/rocket/android/ws/RocketChatWebSocketAPI.java
+50
-54
ic_arrow_forward_white_24dp.xml
app/src/main/res/drawable/ic_arrow_forward_white_24dp.xml
+7
-7
selector_text_color_link.xml
app/src/main/res/drawable/selector_text_color_link.xml
+2
-2
userstatus_away.xml
app/src/main/res/drawable/userstatus_away.xml
+6
-3
userstatus_busy.xml
app/src/main/res/drawable/userstatus_busy.xml
+6
-3
userstatus_offline.xml
app/src/main/res/drawable/userstatus_offline.xml
+6
-3
userstatus_online.xml
app/src/main/res/drawable/userstatus_online.xml
+6
-3
white_circle.xml
app/src/main/res/drawable/white_circle.xml
+1
-1
activity_main.xml
app/src/main/res/layout-w720dp/activity_main.xml
+28
-24
activity_main.xml
app/src/main/res/layout/activity_main.xml
+29
-23
avatar_container_large.xml
app/src/main/res/layout/avatar_container_large.xml
+25
-19
avatar_container_normal.xml
app/src/main/res/layout/avatar_container_normal.xml
+25
-19
fragment_input_hostname.xml
app/src/main/res/layout/fragment_input_hostname.xml
+48
-39
fragment_wait_for_connection.xml
app/src/main/res/layout/fragment_wait_for_connection.xml
+7
-5
sidebar.xml
app/src/main/res/layout/sidebar.xml
+51
-44
simple_screen.xml
app/src/main/res/layout/simple_screen.xml
+2
-1
colors.xml
app/src/main/res/values/colors.xml
+9
-9
dimens.xml
app/src/main/res/values/dimens.xml
+4
-4
fa_strings.xml
app/src/main/res/values/fa_strings.xml
+1
-1
margin_dimens.xml
app/src/main/res/values/margin_dimens.xml
+3
-3
strings.xml
app/src/main/res/values/strings.xml
+1
-1
styles.xml
app/src/main/res/values/styles.xml
+41
-41
user_status_colors.xml
app/src/main/res/values/user_status_colors.xml
+8
-8
waiting_view_attrs.xml
app/src/main/res/values/waiting_view_attrs.xml
+5
-5
build.gradle
build.gradle
+19
-19
checkstyle-suppressions.xml
config/quality/checkstyle/checkstyle-suppressions.xml
+0
-8
android-exclude-filter.xml
config/quality/findbugs/android-exclude-filter.xml
+13
-13
pmd-ruleset.xml
config/quality/pmd/pmd-ruleset.xml
+19
-19
quality.gradle
config/quality/quality.gradle
+53
-54
gradle.properties
gradle.properties
+0
-4
No files found.
app/build.gradle
View file @
6007fd56
...
...
@@ -5,56 +5,56 @@ apply plugin: 'com.jakewharton.hugo'
apply
from:
'../config/quality/quality.gradle'
android
{
compileSdkVersion
25
buildToolsVersion
"25.0.0"
defaultConfig
{
applicationId
"chat.rocket.android"
minSdkVersion
17
targetSdkVersion
25
versionCode
1
versionName
"1.0"
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
vectorDrawables
.
useSupportLibrary
=
true
}
buildTypes
{
release
{
minifyEnabled
false
proguardFiles
getDefaultProguardFile
(
'proguard-android.txt'
),
'proguard-rules.pro'
}
}
compileOptions
{
sourceCompatibility
JavaVersion
.
VERSION_1_8
targetCompatibility
JavaVersion
.
VERSION_1_8
}
lintOptions
{
//avoiding okio error: https://github.com/square/okhttp/issues/896
lintConfig
file
(
"lint.xml"
)
compileSdkVersion
25
buildToolsVersion
"25.0.0"
defaultConfig
{
applicationId
"chat.rocket.android"
minSdkVersion
17
targetSdkVersion
25
versionCode
1
versionName
"1.0"
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
vectorDrawables
.
useSupportLibrary
=
true
}
buildTypes
{
release
{
minifyEnabled
false
proguardFiles
getDefaultProguardFile
(
'proguard-android.txt'
),
'proguard-rules.pro'
}
}
compileOptions
{
sourceCompatibility
JavaVersion
.
VERSION_1_8
targetCompatibility
JavaVersion
.
VERSION_1_8
}
lintOptions
{
//avoiding okio error: https://github.com/square/okhttp/issues/896
lintConfig
file
(
"lint.xml"
)
}
}
repositories
{
mavenCentral
()
maven
{
url
'https://github.com/YusukeIwaki/realm-java-helpers/raw/master/repo'
}
maven
{
url
'https://github.com/uPhyca/stetho-realm/raw/master/maven-repo'
}
maven
{
url
'https://github.com/RocketChat/Android-DDP/raw/master/repository'
}
mavenCentral
()
maven
{
url
'https://github.com/YusukeIwaki/realm-java-helpers/raw/master/repo'
}
maven
{
url
'https://github.com/uPhyca/stetho-realm/raw/master/maven-repo'
}
maven
{
url
'https://github.com/RocketChat/Android-DDP/raw/master/repository'
}
}
dependencies
{
compile
fileTree
(
dir:
'libs'
,
include:
[
'*.jar'
])
compile
'com.android.support:appcompat-v7:25.0.0'
compile
'com.android.support:design:25.0.0'
compile
'jp.co.crowdworks:realm-java-helpers:0.0.7'
compile
'jp.co.crowdworks:realm-java-helpers-bolts:0.0.7'
compile
fileTree
(
dir:
'libs'
,
include:
[
'*.jar'
])
compile
'com.android.support:appcompat-v7:25.0.0'
compile
'com.android.support:design:25.0.0'
compile
'jp.co.crowdworks:realm-java-helpers:0.0.7'
compile
'jp.co.crowdworks:realm-java-helpers-bolts:0.0.7'
compile
'com.squareup.okhttp3:okhttp:3.4.1'
compile
'com.squareup.okhttp3:okhttp:3.4.1'
compile
'com.facebook.stetho:stetho:1.4.1'
compile
'com.facebook.stetho:stetho-okhttp3:1.4.1'
compile
'com.uphyca:stetho_realm:2.0.0'
compile
'com.facebook.stetho:stetho:1.4.1'
compile
'com.facebook.stetho:stetho-okhttp3:1.4.1'
compile
'com.uphyca:stetho_realm:2.0.0'
compile
'chat.rocket:android-ddp:0.0.5'
compile
'chat.rocket:android-ddp:0.0.5'
compile
'com.jakewharton.timber:timber:4.3.1'
compile
'com.jakewharton.rxbinding:rxbinding:0.4.0'
compile
'com.jakewharton.timber:timber:4.3.1'
compile
'com.jakewharton.rxbinding:rxbinding:0.4.0'
}
app/lint.xml
View file @
6007fd56
<lint>
<issue
id=
"InvalidPackage"
>
<ignore
regexp=
"okio.*jar"
/>
</issue>
<issue
id=
"InvalidPackage"
>
<ignore
regexp=
"okio.*jar"
/>
</issue>
</lint>
\ No newline at end of file
app/src/main/AndroidManifest.xml
View file @
6007fd56
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
package=
"chat.rocket.android"
>
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.ACCESS_NETWORK_STATE"
/>
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.ACCESS_NETWORK_STATE"
/>
<application
android:allowBackup=
"true
"
android:icon=
"@mipmap/ic_launcher
"
android:label=
"@string/app_name
"
android:supportsRtl=
"tru
e"
android:theme=
"@style/AppThem
e"
android:name=
".RocketChatApplication
"
>
<application
android:name=
".RocketChatApplication
"
android:allowBackup=
"true
"
android:icon=
"@mipmap/ic_launcher
"
android:label=
"@string/app_nam
e"
android:supportsRtl=
"tru
e"
android:theme=
"@style/AppTheme
"
>
<activity
android:name=
".activity.MainActivity"
android:windowSoftInputMode=
"adjustResize"
>
<intent-filter>
<action
android:name=
"android.intent.action.MAIN"
/>
<category
android:name=
"android.intent.category.DEFAULT"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
</intent-filter>
</activity>
<activity
android:name=
".activity.MainActivity"
android:windowSoftInputMode=
"adjustResize"
>
<intent-filter>
<action
android:name=
"android.intent.action.MAIN"
/>
<activity
android:name=
".activity.ServerConfigActivity"
android:windowSoftInputMode=
"adjustResize"
/>
<category
android:name=
"android.intent.category.DEFAULT"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
</intent-filter>
</activity>
<service
android:name=
".service.RocketChatService"
/>
</application>
<activity
android:name=
".activity.ServerConfigActivity"
android:windowSoftInputMode=
"adjustResize"
/>
<service
android:name=
".service.RocketChatService"
/>
</application>
</manifest>
app/src/main/java/chat/rocket/android/LaunchUtil.java
View file @
6007fd56
...
...
@@ -2,20 +2,19 @@ package chat.rocket.android;
import
android.content.Context
;
import
android.content.Intent
;
import
chat.rocket.android.activity.ServerConfigActivity
;
/**
* utility class for launching Activity
*/
public
class
LaunchUtil
{
/**
* launch ServerConfigActivity with proper flags.
*/
public
static
void
showServerConfigActivity
(
Context
context
,
String
serverCondigId
)
{
Intent
intent
=
new
Intent
(
context
,
ServerConfigActivity
.
class
);
intent
.
setFlags
(
Intent
.
FLAG_ACTIVITY_REORDER_TO_FRONT
|
Intent
.
FLAG_ACTIVITY_CLEAR_TOP
);
intent
.
putExtra
(
"id"
,
serverCondigId
);
context
.
startActivity
(
intent
);
}
/**
* launch ServerConfigActivity with proper flags.
*/
public
static
void
showServerConfigActivity
(
Context
context
,
String
serverCondigId
)
{
Intent
intent
=
new
Intent
(
context
,
ServerConfigActivity
.
class
);
intent
.
setFlags
(
Intent
.
FLAG_ACTIVITY_REORDER_TO_FRONT
|
Intent
.
FLAG_ACTIVITY_CLEAR_TOP
);
intent
.
putExtra
(
"id"
,
serverCondigId
);
context
.
startActivity
(
intent
);
}
}
app/src/main/java/chat/rocket/android/RocketChatApplication.java
View file @
6007fd56
package
chat
.
rocket
.
android
;
import
android.app.Application
;
import
com.facebook.stetho.Stetho
;
import
com.uphyca.stetho_realm.RealmInspectorModulesProvider
;
import
io.realm.Realm
;
import
io.realm.RealmConfiguration
;
import
timber.log.Timber
;
...
...
@@ -13,23 +11,20 @@ import timber.log.Timber;
* Customized Application-class for Rocket.Chat
*/
public
class
RocketChatApplication
extends
Application
{
@Override
public
void
onCreate
()
{
super
.
onCreate
();
@Override
public
void
onCreate
()
{
super
.
onCreate
();
Timber
.
plant
(
new
Timber
.
DebugTree
());
Timber
.
plant
(
new
Timber
.
DebugTree
());
Realm
.
init
(
this
);
Realm
.
setDefaultConfiguration
(
new
RealmConfiguration
.
Builder
()
.
deleteRealmIfMigrationNeeded
()
.
build
());
Realm
.
init
(
this
);
Realm
.
setDefaultConfiguration
(
new
RealmConfiguration
.
Builder
().
deleteRealmIfMigrationNeeded
().
build
());
Stetho
.
initialize
(
Stetho
.
newInitializerBuilder
(
this
)
.
enableDumpapp
(
Stetho
.
defaultDumperPluginsProvider
(
this
))
.
enableWebKitInspector
(
RealmInspectorModulesProvider
.
builder
(
this
).
build
())
.
build
());
Stetho
.
initialize
(
Stetho
.
newInitializerBuilder
(
this
)
.
enableDumpapp
(
Stetho
.
defaultDumperPluginsProvider
(
this
))
.
enableWebKitInspector
(
RealmInspectorModulesProvider
.
builder
(
this
).
build
())
.
build
());
//TODO: add periodic trigger for RocketChatService.keepalive(this) here!
}
//TODO: add periodic trigger for RocketChatService.keepalive(this) here!
}
}
app/src/main/java/chat/rocket/android/activity/AbstractAuthedActivity.java
View file @
6007fd56
package
chat
.
rocket
.
android
.
activity
;
import
android.support.v7.app.AppCompatActivity
;
import
java.util.List
;
import
java.util.UUID
;
import
chat.rocket.android.helper.LogcatIfError
;
import
chat.rocket.android.model.ServerConfig
;
import
chat.rocket.android.service.RocketChatService
;
import
io.realm.Realm
;
import
io.realm.RealmResults
;
import
java.util.List
;
import
java.util.UUID
;
import
jp.co.crowdworks.realm_java_helpers.RealmListObserver
;
import
jp.co.crowdworks.realm_java_helpers_bolts.RealmHelperBolts
;
abstract
class
AbstractAuthedActivity
extends
AppCompatActivity
{
private
RealmListObserver
<
ServerConfig
>
mInsertEmptyRecordIfNoConfigurationExists
=
new
RealmListObserver
<
ServerConfig
>()
{
@Override
protected
RealmResults
<
ServerConfig
>
queryItems
(
Realm
realm
)
{
return
realm
.
where
(
ServerConfig
.
class
).
findAll
();
}
@Override
protected
void
onCollectionChanged
(
List
<
ServerConfig
>
list
)
{
if
(
list
.
isEmpty
())
{
final
String
newId
=
UUID
.
randomUUID
().
toString
();
RealmHelperBolts
.
executeTransaction
(
realm
->
realm
.
createObject
(
ServerConfig
.
class
,
newId
))
.
continueWith
(
new
LogcatIfError
());
}
}
};
private
RealmListObserver
<
ServerConfig
>
mShowConfigActivityIfNeeded
=
new
RealmListObserver
<
ServerConfig
>()
{
@Override
protected
RealmResults
<
ServerConfig
>
queryItems
(
Realm
realm
)
{
return
ServerConfig
.
queryLoginRequiredConnections
(
realm
).
findAll
();
}
@Override
protected
void
onCollectionChanged
(
List
<
ServerConfig
>
list
)
{
ServerConfigActivity
.
launchFor
(
AbstractAuthedActivity
.
this
,
list
);
}
};
@Override
protected
void
onResume
()
{
super
.
onResume
();
RocketChatService
.
keepalive
(
this
);
mInsertEmptyRecordIfNoConfigurationExists
.
sub
();
mShowConfigActivityIfNeeded
.
sub
();
}
@Override
protected
void
onPause
()
{
mShowConfigActivityIfNeeded
.
unsub
();
mInsertEmptyRecordIfNoConfigurationExists
.
unsub
();
super
.
onPause
();
}
private
RealmListObserver
<
ServerConfig
>
serverConfigEmptinessObserver
=
new
RealmListObserver
<
ServerConfig
>()
{
@Override
protected
RealmResults
<
ServerConfig
>
queryItems
(
Realm
realm
)
{
return
realm
.
where
(
ServerConfig
.
class
).
findAll
();
}
@Override
protected
void
onCollectionChanged
(
List
<
ServerConfig
>
list
)
{
if
(
list
.
isEmpty
())
{
final
String
newId
=
UUID
.
randomUUID
().
toString
();
RealmHelperBolts
.
executeTransaction
(
realm
->
realm
.
createObject
(
ServerConfig
.
class
,
newId
))
.
continueWith
(
new
LogcatIfError
());
}
}
};
private
RealmListObserver
<
ServerConfig
>
loginRequiredServerConfigObserver
=
new
RealmListObserver
<
ServerConfig
>()
{
@Override
protected
RealmResults
<
ServerConfig
>
queryItems
(
Realm
realm
)
{
return
ServerConfig
.
queryLoginRequiredConnections
(
realm
).
findAll
();
}
@Override
protected
void
onCollectionChanged
(
List
<
ServerConfig
>
list
)
{
ServerConfigActivity
.
launchFor
(
AbstractAuthedActivity
.
this
,
list
);
}
};
@Override
protected
void
onResume
()
{
super
.
onResume
();
RocketChatService
.
keepalive
(
this
);
serverConfigEmptinessObserver
.
sub
();
loginRequiredServerConfigObserver
.
sub
();
}
@Override
protected
void
onPause
()
{
loginRequiredServerConfigObserver
.
unsub
();
serverConfigEmptinessObserver
.
unsub
();
super
.
onPause
();
}
}
app/src/main/java/chat/rocket/android/activity/AbstractFragmentActivity.java
View file @
6007fd56
...
...
@@ -3,34 +3,34 @@ package chat.rocket.android.activity;
import
android.support.annotation.IdRes
;
import
android.support.v4.app.Fragment
;
import
android.support.v7.app.AppCompatActivity
;
import
chat.rocket.android.helper.OnBackPressListener
;
abstract
class
AbstractFragmentActivity
extends
AppCompatActivity
{
protected
abstract
@IdRes
int
getLayoutContainerForFragment
();
@Override
public
void
onBackPressed
()
{
Fragment
fragment
=
getSupportFragmentManager
().
findFragmentById
(
getLayoutContainerForFragment
());
protected
abstract
@IdRes
int
getLayoutContainerForFragment
();
if
(
fragment
instanceof
OnBackPressListener
&&
((
OnBackPressListener
)
fragment
).
onBackPressed
())
{
//consumed. do nothing.
}
else
super
.
onBackPressed
();
}
protected
void
showFragment
(
Fragment
fragment
)
{
getSupportFragmentManager
().
beginTransaction
()
.
replace
(
getLayoutContainerForFragment
(),
fragment
)
.
commit
();
}
@Override
public
void
onBackPressed
()
{
Fragment
fragment
=
getSupportFragmentManager
().
findFragmentById
(
getLayoutContainerForFragment
());
protected
void
showFragmentWithBackStack
(
Fragment
fragment
)
{
getSupportFragmentManager
().
beginTransaction
()
.
replace
(
getLayoutContainerForFragment
(),
fragment
)
.
addToBackStack
(
null
)
.
commit
();
if
(
fragment
instanceof
OnBackPressListener
&&
((
OnBackPressListener
)
fragment
).
onBackPressed
())
{
//consumed. do nothing.
}
else
{
super
.
onBackPressed
();
}
}
protected
void
showFragment
(
Fragment
fragment
)
{
getSupportFragmentManager
().
beginTransaction
()
.
replace
(
getLayoutContainerForFragment
(),
fragment
)
.
commit
();
}
protected
void
showFragmentWithBackStack
(
Fragment
fragment
)
{
getSupportFragmentManager
().
beginTransaction
()
.
replace
(
getLayoutContainerForFragment
(),
fragment
)
.
addToBackStack
(
null
)
.
commit
();
}
}
app/src/main/java/chat/rocket/android/activity/MainActivity.java
View file @
6007fd56
...
...
@@ -2,7 +2,6 @@ package chat.rocket.android.activity;
import
android.os.Bundle
;
import
android.support.annotation.Nullable
;
import
chat.rocket.android.R
;
import
chat.rocket.android.helper.LogcatIfError
;
import
chat.rocket.android.model.ServerConfig
;
...
...
@@ -12,18 +11,17 @@ import jp.co.crowdworks.realm_java_helpers_bolts.RealmHelperBolts;
* Entry-point for Rocket.Chat.Android application.
*/
public
class
MainActivity
extends
AbstractAuthedActivity
{
@Override
protected
void
onCreate
(
@Nullable
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
setContentView
(
R
.
layout
.
activity_main
);
@Override
protected
void
onCreate
(
@Nullable
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
setContentView
(
R
.
layout
.
activity_main
);
if
(
savedInstanceState
==
null
)
{
RealmHelperBolts
.
executeTransaction
(
realm
->
{
for
(
ServerConfig
config:
ServerConfig
.
queryActiveConnections
(
realm
).
findAll
())
{
config
.
setTokenVerified
(
false
);
}
return
null
;
}).
continueWith
(
new
LogcatIfError
());
if
(
savedInstanceState
==
null
)
{
RealmHelperBolts
.
executeTransaction
(
realm
->
{
for
(
ServerConfig
config
:
ServerConfig
.
queryActiveConnections
(
realm
).
findAll
())
{
config
.
setTokenVerified
(
false
);
}
return
null
;
}).
continueWith
(
new
LogcatIfError
());
}
}
}
app/src/main/java/chat/rocket/android/activity/ServerConfigActivity.java
View file @
6007fd56
...
...
@@ -5,9 +5,6 @@ import android.content.Intent;
import
android.os.Bundle
;
import
android.support.annotation.Nullable
;
import
android.support.v4.app.Fragment
;
import
java.util.List
;
import
chat.rocket.android.LaunchUtil
;
import
chat.rocket.android.R
;
import
chat.rocket.android.fragment.server_config.ConnectingToHostFragment
;
...
...
@@ -19,6 +16,7 @@ import chat.rocket.android.service.RocketChatService;
import
io.realm.Realm
;
import
io.realm.RealmList
;
import
io.realm.RealmQuery
;
import
java.util.List
;
import
jp.co.crowdworks.realm_java_helpers.RealmObjectObserver
;
/**
...
...
@@ -26,165 +24,157 @@ import jp.co.crowdworks.realm_java_helpers.RealmObjectObserver;
*/
public
class
ServerConfigActivity
extends
AbstractFragmentActivity
{
@Override
protected
int
getLayoutContainerForFragment
()
{
return
R
.
id
.
content
;
}
private
String
mServerConfigId
;
private
RealmObjectObserver
<
ServerConfig
>
mServerConfigObserver
=
new
RealmObjectObserver
<
ServerConfig
>()
{
@Override
protected
RealmQuery
<
ServerConfig
>
query
(
Realm
realm
)
{
return
realm
.
where
(
ServerConfig
.
class
).
equalTo
(
"id"
,
mServerConfigId
);
}
@Override
protected
void
onChange
(
ServerConfig
config
)
{
onRenderServerConfig
(
config
);
}
};
/**
* Start the ServerConfigActivity with considering the priority of ServerConfig in the list.
*/
public
static
boolean
launchFor
(
Context
context
,
List
<
ServerConfig
>
configList
)
{
for
(
ServerConfig
config:
configList
)
{
if
(
TextUtils
.
isEmpty
(
config
.
getHostname
()))
{
return
launchFor
(
context
,
config
);
}
else
if
(!
TextUtils
.
isEmpty
(
config
.
getConnectionError
()))
{
return
launchFor
(
context
,
config
);
}
}
for
(
ServerConfig
config:
configList
)
{
if
(
config
.
getAuthProviders
().
isEmpty
())
{
return
launchFor
(
context
,
config
);
}
private
String
mServerConfigId
;
private
RealmObjectObserver
<
ServerConfig
>
mServerConfigObserver
=
new
RealmObjectObserver
<
ServerConfig
>()
{
@Override
protected
RealmQuery
<
ServerConfig
>
query
(
Realm
realm
)
{
return
realm
.
where
(
ServerConfig
.
class
).
equalTo
(
"id"
,
mServerConfigId
);
}
for
(
ServerConfig
config:
configList
)
{
if
(
TextUtils
.
isEmpty
(
config
.
getSelectedProviderName
()))
{
return
launchFor
(
context
,
config
);
}
@Override
protected
void
onChange
(
ServerConfig
config
)
{
onRenderServerConfig
(
config
);
}
};
/**
* Start the ServerConfigActivity with considering the priority of ServerConfig in the list.
*/
public
static
boolean
launchFor
(
Context
context
,
List
<
ServerConfig
>
configList
)
{
for
(
ServerConfig
config
:
configList
)
{
if
(
TextUtils
.
isEmpty
(
config
.
getHostname
()))
{
return
launchFor
(
context
,
config
);
}
else
if
(!
TextUtils
.
isEmpty
(
config
.
getConnectionError
()))
{
return
launchFor
(
context
,
config
);
}
}
for
(
ServerConfig
config
:
configList
)
{
if
(
TextUtils
.
isEmpty
(
config
.
getToken
()
))
{
return
launchFor
(
context
,
config
);
}
}
for
(
ServerConfig
config
:
configList
)
{
if
(
config
.
getAuthProviders
().
isEmpty
(
))
{
return
launchFor
(
context
,
config
);
}
}
for
(
ServerConfig
config
:
configList
)
{
if
(!
config
.
isTokenVerified
(
))
{
return
launchFor
(
context
,
config
);
}
}
for
(
ServerConfig
config
:
configList
)
{
if
(
TextUtils
.
isEmpty
(
config
.
getSelectedProviderName
()
))
{
return
launchFor
(
context
,
config
);
}
}
return
false
;
for
(
ServerConfig
config
:
configList
)
{
if
(
TextUtils
.
isEmpty
(
config
.
getToken
()))
{
return
launchFor
(
context
,
config
);
}
}
private
static
boolean
launchFor
(
Context
context
,
ServerConfig
config
)
{
LaunchUtil
.
showServerConfigActivity
(
context
,
config
.
getId
());
return
true
;
for
(
ServerConfig
config
:
configList
)
{
if
(!
config
.
isTokenVerified
())
{
return
launchFor
(
context
,
config
);
}
}
return
false
;
}
@Override
protected
void
onCreate
(
@Nullable
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
private
static
boolean
launchFor
(
Context
context
,
ServerConfig
config
)
{
LaunchUtil
.
showServerConfigActivity
(
context
,
config
.
getId
());
return
true
;
}
Intent
intent
=
getIntent
();
if
(
intent
==
null
||
intent
.
getExtras
()
==
null
)
{
finish
();
return
;
}
@Override
protected
int
getLayoutContainerForFragment
()
{
return
R
.
id
.
content
;
}
mServerConfigId
=
intent
.
getStringExtra
(
"id"
);
if
(
TextUtils
.
isEmpty
(
mServerConfigId
))
{
finish
();
return
;
}
@Override
protected
void
onCreate
(
@Nullable
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
setContentView
(
R
.
layout
.
simple_screen
);
Intent
intent
=
getIntent
();
if
(
intent
==
null
||
intent
.
getExtras
()
==
null
)
{
finish
();
return
;
}
@Override
protected
void
onResume
()
{
super
.
onResume
();
RocketChatService
.
keepalive
(
this
);
mServerConfigObserver
.
sub
();
mServerConfigId
=
intent
.
getStringExtra
(
"id"
);
if
(
TextUtils
.
isEmpty
(
mServerConfigId
))
{
finish
();
return
;
}
@Override
protected
void
onPause
()
{
mServerConfigObserver
.
unsub
();
super
.
onPause
();
}
setContentView
(
R
.
layout
.
simple_screen
);
}
private
void
onRenderServerConfig
(
ServerConfig
config
)
{
if
(
config
==
null
)
{
finish
(
);
return
;
}
@Override
protected
void
onResume
(
)
{
super
.
onResume
();
RocketChatService
.
keepalive
(
this
);
mServerConfigObserver
.
sub
()
;
}
if
(
config
.
isTokenVerified
()
)
{
finish
();
return
;
}
@Override
protected
void
onPause
(
)
{
mServerConfigObserver
.
unsub
();
super
.
onPause
()
;
}
final
String
token
=
config
.
getToken
();
if
(!
TextUtils
.
isEmpty
(
token
))
{
return
;
}
private
void
onRenderServerConfig
(
ServerConfig
config
)
{
if
(
config
==
null
)
{
finish
();
return
;
}
final
String
selectedProviderName
=
config
.
getSelectedProviderName
();
if
(!
TextUtils
.
isEmpty
(
selectedProviderName
))
{
if
(
config
.
isTokenVerified
())
{
finish
();
return
;
}
return
;
}
final
String
token
=
config
.
getToken
();
if
(!
TextUtils
.
isEmpty
(
token
))
{
return
;
}
RealmList
<
MeteorLoginServiceConfiguration
>
providers
=
config
.
getAuthProviders
();
if
(!
providers
.
isEmpty
(
))
{
final
String
selectedProviderName
=
config
.
getSelectedProviderName
();
if
(!
TextUtils
.
isEmpty
(
selectedProviderName
))
{
return
;
}
return
;
}
final
String
error
=
config
.
getConnectionError
();
String
hostname
=
config
.
getHostname
();
if
(!
TextUtils
.
isEmpty
(
hostname
)
&&
TextUtils
.
isEmpty
(
error
))
{
showFragment
(
new
ConnectingToHostFragment
());
return
;
}
RealmList
<
MeteorLoginServiceConfiguration
>
providers
=
config
.
getAuthProviders
();
if
(!
providers
.
isEmpty
())
{
showFragment
(
new
InputHostnameFragment
())
;
return
;
}
@Override
protected
void
showFragment
(
Fragment
fragment
)
{
injectIdArgTo
(
fragment
);
super
.
showFragment
(
fragment
);
final
String
error
=
config
.
getConnectionError
();
String
hostname
=
config
.
getHostname
();
if
(!
TextUtils
.
isEmpty
(
hostname
)
&&
TextUtils
.
isEmpty
(
error
))
{
showFragment
(
new
ConnectingToHostFragment
());
return
;
}
@Override
protected
void
showFragmentWithBackStack
(
Fragment
fragment
)
{
injectIdArgTo
(
fragment
);
super
.
showFragmentWithBackStack
(
fragment
);
}
showFragment
(
new
InputHostnameFragment
());
}
private
void
injectIdArgTo
(
Fragment
fragment
)
{
Bundle
args
=
fragment
.
getArguments
();
if
(
args
==
null
)
args
=
new
Bundle
();
args
.
putString
(
"id"
,
mServerConfigId
);
fragment
.
setArguments
(
args
);
}
@Override
protected
void
showFragment
(
Fragment
fragment
)
{
injectIdArgTo
(
fragment
);
super
.
showFragment
(
fragment
);
}
@Override
public
void
onBackPressed
()
{
if
(
ServerConfig
.
hasActiveConnection
())
{
super
.
onBackPressed
();
}
else
{
moveTaskToBack
(
true
);
}
@Override
protected
void
showFragmentWithBackStack
(
Fragment
fragment
)
{
injectIdArgTo
(
fragment
);
super
.
showFragmentWithBackStack
(
fragment
);
}
private
void
injectIdArgTo
(
Fragment
fragment
)
{
Bundle
args
=
fragment
.
getArguments
();
if
(
args
==
null
)
{
args
=
new
Bundle
();
}
args
.
putString
(
"id"
,
mServerConfigId
);
fragment
.
setArguments
(
args
);
}
@Override
public
void
onBackPressed
()
{
if
(
ServerConfig
.
hasActiveConnection
())
{
super
.
onBackPressed
();
}
else
{
moveTaskToBack
(
true
);
}
}
}
app/src/main/java/chat/rocket/android/fragment/AbstractFragment.java
View file @
6007fd56
...
...
@@ -12,25 +12,25 @@ import android.view.ViewGroup;
* Fragment base class for this Application.
*/
public
abstract
class
AbstractFragment
extends
Fragment
{
protected
View
mRootView
;
protected
abstract
@LayoutRes
int
getLayout
();
protected
abstract
void
onSetupView
();
protected
View
mRootView
;
@Nullable
@Override
public
View
onCreateView
(
LayoutInflater
inflater
,
@Nullable
ViewGroup
container
,
@Nullable
Bundle
savedInstanceState
)
{
mRootView
=
inflater
.
inflate
(
getLayout
(),
container
,
false
);
onSetupView
();
return
mRootView
;
}
protected
abstract
@LayoutRes
int
getLayout
();
protected
abstract
void
onSetupView
();
@Nullable
@Override
public
View
onCreateView
(
LayoutInflater
inflater
,
@Nullable
ViewGroup
container
,
@Nullable
Bundle
savedInstanceState
)
{
mRootView
=
inflater
.
inflate
(
getLayout
(),
container
,
false
);
onSetupView
();
return
mRootView
;
}
protected
void
finish
()
{
if
(
getFragmentManager
().
getBackStackEntryCount
()
==
0
)
{
getActivity
().
finish
();
}
else
{
getFragmentManager
().
popBackStack
();
}
protected
void
finish
()
{
if
(
getFragmentManager
().
getBackStackEntryCount
()
==
0
)
{
getActivity
().
finish
();
}
else
{
getFragmentManager
().
popBackStack
();
}
}
}
app/src/main/java/chat/rocket/android/fragment/server_config/AbstractServerConfigFragment.java
View file @
6007fd56
...
...
@@ -2,27 +2,25 @@ package chat.rocket.android.fragment.server_config;
import
android.os.Bundle
;
import
android.support.annotation.Nullable
;
import
chat.rocket.android.fragment.AbstractFragment
;
import
chat.rocket.android.helper.TextUtils
;
abstract
class
AbstractServerConfigFragment
extends
AbstractFragment
{
protected
String
mServerConfigId
;
protected
String
mServerConfigId
;
@Override
public
void
onCreate
(
@Nullable
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
@Override
public
void
onCreate
(
@Nullable
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
Bundle
args
=
getArguments
();
if
(
args
==
null
)
{
finish
();
return
;
}
Bundle
args
=
getArguments
();
if
(
args
==
null
)
{
finish
();
return
;
}
mServerConfigId
=
args
.
getString
(
"id"
);
if
(
TextUtils
.
isEmpty
(
mServerConfigId
))
{
finish
();
return
;
}
mServerConfigId
=
args
.
getString
(
"id"
);
if
(
TextUtils
.
isEmpty
(
mServerConfigId
))
{
finish
();
return
;
}
}
}
app/src/main/java/chat/rocket/android/fragment/server_config/ConnectingToHostFragment.java
View file @
6007fd56
...
...
@@ -6,13 +6,11 @@ import chat.rocket.android.R;
* Just showing "connecting..." screen.
*/
public
class
ConnectingToHostFragment
extends
AbstractServerConfigFragment
{
@Override
protected
int
getLayout
()
{
return
R
.
layout
.
fragment_wait_for_connection
;
}
@Override
protected
int
getLayout
()
{
return
R
.
layout
.
fragment_wait_for_connection
;
}
@Override
protected
void
onSetupView
()
{
@Override
protected
void
onSetupView
()
{
}
}
}
app/src/main/java/chat/rocket/android/fragment/server_config/InputHostnameFragment.java
View file @
6007fd56
...
...
@@ -4,9 +4,6 @@ import android.os.Handler;
import
android.os.Message
;
import
android.widget.TextView
;
import
android.widget.Toast
;
import
org.json.JSONObject
;
import
chat.rocket.android.R
;
import
chat.rocket.android.helper.LogcatIfError
;
import
chat.rocket.android.helper.TextUtils
;
...
...
@@ -15,95 +12,86 @@ import io.realm.Realm;
import
io.realm.RealmQuery
;
import
jp.co.crowdworks.realm_java_helpers.RealmObjectObserver
;
import
jp.co.crowdworks.realm_java_helpers_bolts.RealmHelperBolts
;
import
org.json.JSONObject
;
/**
* Input server host.
*/
public
class
InputHostnameFragment
extends
AbstractServerConfigFragment
{
public
InputHostnameFragment
(){}
private
Handler
mShowError
=
new
Handler
()
{
@Override
public
void
handleMessage
(
Message
msg
)
{
Toast
.
makeText
(
mRootView
.
getContext
(),
(
String
)
msg
.
obj
,
Toast
.
LENGTH_SHORT
).
show
();
}
};
RealmObjectObserver
<
ServerConfig
>
mObserver
=
new
RealmObjectObserver
<
ServerConfig
>()
{
@Override
protected
RealmQuery
<
ServerConfig
>
query
(
Realm
realm
)
{
return
realm
.
where
(
ServerConfig
.
class
).
equalTo
(
"id"
,
mServerConfigId
);
}
@Override
protected
int
getLayout
()
{
return
R
.
layout
.
fragment_input_hostname
;
@Override
protected
void
onChange
(
ServerConfig
config
)
{
onRenderServerConfig
(
config
);
}
};
RealmObjectObserver
<
ServerConfig
>
mObserver
=
new
RealmObjectObserver
<
ServerConfig
>()
{
@Override
protected
RealmQuery
<
ServerConfig
>
query
(
Realm
realm
)
{
return
realm
.
where
(
ServerConfig
.
class
).
equalTo
(
"id"
,
mServerConfigId
);
}
public
InputHostnameFragment
()
{
}
@Override
protected
void
onChange
(
ServerConfig
config
)
{
onRenderServerConfig
(
config
);
}
};
@Override
protected
int
getLayout
()
{
return
R
.
layout
.
fragment_input_hostname
;
}
@Override
protected
void
onSetupView
()
{
mRootView
.
findViewById
(
R
.
id
.
btn_connect
).
setOnClickListener
(
view
->
handleConnect
());
@Override
protected
void
onSetupView
()
{
mRootView
.
findViewById
(
R
.
id
.
btn_connect
).
setOnClickListener
(
view
->
handleConnect
());
mObserver
.
sub
();
}
mObserver
.
sub
();
}
private
void
handleConnect
()
{
final
TextView
editor
=
(
TextView
)
mRootView
.
findViewById
(
R
.
id
.
editor_hostname
);
private
void
handleConnect
()
{
final
TextView
editor
=
(
TextView
)
mRootView
.
findViewById
(
R
.
id
.
editor_hostname
);
final
String
hostname
=
TextUtils
.
or
(
TextUtils
.
or
(
editor
.
getText
(),
editor
.
getHint
()),
""
).
toString
();
final
String
hostname
=
TextUtils
.
or
(
TextUtils
.
or
(
editor
.
getText
(),
editor
.
getHint
()),
""
).
toString
();
RealmHelperBolts
.
executeTransaction
(
realm
->
realm
.
createOrUpdateObjectFromJson
(
ServerConfig
.
class
,
new
JSONObject
()
.
put
(
"id"
,
mServerConfigId
)
.
put
(
"hostname"
,
hostname
)
.
put
(
"connectionError"
,
JSONObject
.
NULL
)))
.
continueWith
(
new
LogcatIfError
());
}
RealmHelperBolts
.
executeTransaction
(
realm
->
realm
.
createOrUpdateObjectFromJson
(
ServerConfig
.
class
,
new
JSONObject
().
put
(
"id"
,
mServerConfigId
)
.
put
(
"hostname"
,
hostname
)
.
put
(
"connectionError"
,
JSONObject
.
NULL
))).
continueWith
(
new
LogcatIfError
());
}
@Override
public
void
onResume
()
{
super
.
onResume
();
mObserver
.
keepalive
();
}
@Override
public
void
onResume
()
{
super
.
onResume
();
mObserver
.
keepalive
();
}
@Override
public
void
onDestroyView
()
{
mObserver
.
unsub
();
super
.
onDestroyView
();
}
@Override
public
void
onDestroyView
()
{
mObserver
.
unsub
();
super
.
onDestroyView
();
}
private
Handler
mShowError
=
new
Handler
()
{
@Override
public
void
handleMessage
(
Message
msg
)
{
Toast
.
makeText
(
mRootView
.
getContext
(),
(
String
)
msg
.
obj
,
Toast
.
LENGTH_SHORT
).
show
();
}
};
private
void
showError
(
String
errString
)
{
mShowError
.
removeMessages
(
0
);
Message
msg
=
Message
.
obtain
(
mShowError
,
0
,
errString
);
mShowError
.
sendMessageDelayed
(
msg
,
160
);
}
private
void
showError
(
String
errString
)
{
mShowError
.
removeMessages
(
0
);
Message
msg
=
Message
.
obtain
(
mShowError
,
0
,
errString
);
mShowError
.
sendMessageDelayed
(
msg
,
160
);
}
private
void
onRenderServerConfig
(
ServerConfig
config
)
{
final
TextView
editor
=
(
TextView
)
mRootView
.
findViewById
(
R
.
id
.
editor_hostname
);
private
void
onRenderServerConfig
(
ServerConfig
config
)
{
final
TextView
editor
=
(
TextView
)
mRootView
.
findViewById
(
R
.
id
.
editor_hostname
);
if
(!
TextUtils
.
isEmpty
(
config
.
getHostname
()))
editor
.
setText
(
config
.
getHostname
());
if
(!
TextUtils
.
isEmpty
(
config
.
getConnectionError
()))
{
clearConnectionErrorAndHostname
();
showError
(
config
.
getConnectionError
());
}
if
(!
TextUtils
.
isEmpty
(
config
.
getHostname
()))
{
editor
.
setText
(
config
.
getHostname
());
}
private
void
clearConnectionErrorAndHostname
()
{
RealmHelperBolts
.
executeTransaction
(
realm
->
realm
.
createOrUpdateObjectFromJson
(
ServerConfig
.
class
,
new
JSONObject
()
.
put
(
"id"
,
mServerConfigId
)
.
put
(
"hostname"
,
JSONObject
.
NULL
)
.
put
(
"connectionError"
,
JSONObject
.
NULL
)))
.
continueWith
(
new
LogcatIfError
());
if
(!
TextUtils
.
isEmpty
(
config
.
getConnectionError
()))
{
clearConnectionErrorAndHostname
();
showError
(
config
.
getConnectionError
());
}
}
private
void
clearConnectionErrorAndHostname
()
{
RealmHelperBolts
.
executeTransaction
(
realm
->
realm
.
createOrUpdateObjectFromJson
(
ServerConfig
.
class
,
new
JSONObject
().
put
(
"id"
,
mServerConfigId
)
.
put
(
"hostname"
,
JSONObject
.
NULL
)
.
put
(
"connectionError"
,
JSONObject
.
NULL
))).
continueWith
(
new
LogcatIfError
());
}
}
app/src/main/java/chat/rocket/android/helper/LogcatIfError.java
View file @
6007fd56
...
...
@@ -8,11 +8,10 @@ import timber.log.Timber;
* Bolts-Task continuation for just logging if error occurred.
*/
public
class
LogcatIfError
implements
Continuation
{
@Override
public
Object
then
(
Task
task
)
throws
Exception
{
if
(
task
.
isFaulted
())
{
Timber
.
w
(
task
.
getError
());
}
return
task
;
@Override
public
Object
then
(
Task
task
)
throws
Exception
{
if
(
task
.
isFaulted
())
{
Timber
.
w
(
task
.
getError
());
}
return
task
;
}
}
app/src/main/java/chat/rocket/android/helper/OkHttpHelper.java
View file @
6007fd56
package
chat
.
rocket
.
android
.
helper
;
import
com.facebook.stetho.okhttp3.StethoInterceptor
;
import
java.util.concurrent.TimeUnit
;
import
okhttp3.OkHttpClient
;
/**
* Helper class for OkHttp client.
*/
public
class
OkHttpHelper
{
private
static
OkHttpClient
sHttpClientForWS
;
private
static
OkHttpClient
sHttpClientForWS
;
/**
* acquire OkHttpClient instance for WebSocket connection.
*/
public
static
OkHttpClient
getClientForWebSocket
()
{
if
(
sHttpClientForWS
==
null
)
{
sHttpClientForWS
=
new
OkHttpClient
.
Builder
()
.
readTimeout
(
0
,
TimeUnit
.
NANOSECONDS
)
.
addNetworkInterceptor
(
new
StethoInterceptor
())
.
build
();
}
return
sHttpClientForWS
;
/**
* acquire OkHttpClient instance for WebSocket connection.
*/
public
static
OkHttpClient
getClientForWebSocket
()
{
if
(
sHttpClientForWS
==
null
)
{
sHttpClientForWS
=
new
OkHttpClient
.
Builder
().
readTimeout
(
0
,
TimeUnit
.
NANOSECONDS
)
.
addNetworkInterceptor
(
new
StethoInterceptor
())
.
build
();
}
return
sHttpClientForWS
;
}
}
app/src/main/java/chat/rocket/android/helper/OnBackPressListener.java
View file @
6007fd56
...
...
@@ -5,10 +5,10 @@ package chat.rocket.android.helper;
*/
public
interface
OnBackPressListener
{
/**
* onBackPressed
*
* @return whether back is handled or not.
*/
boolean
onBackPressed
();
/**
* onBackPressed
*
* @return whether back is handled or not.
*/
boolean
onBackPressed
();
}
app/src/main/java/chat/rocket/android/helper/TextUtils.java
View file @
6007fd56
...
...
@@ -5,22 +5,25 @@ package chat.rocket.android.helper;
*/
public
class
TextUtils
{
/**
* Returns true if the string is null or 0-length.
* @param str the string to be examined
* @return true if str is null or zero length
*/
public
static
boolean
isEmpty
(
CharSequence
str
)
{
// same definition as android.text.TextUtils#isEmpty().
return
str
==
null
||
str
.
length
()
==
0
;
}
/**
* Returns true if the string is null or 0-length.
*
* @param str the string to be examined
* @return true if str is null or zero length
*/
public
static
boolean
isEmpty
(
CharSequence
str
)
{
// same definition as android.text.TextUtils#isEmpty().
return
str
==
null
||
str
.
length
()
==
0
;
}
/**
* Returns str if it is not empty; otherwise defaultValue is returned.
*/
@SuppressWarnings
(
"PMD.ShortMethodName"
)
public
static
CharSequence
or
(
CharSequence
str
,
CharSequence
defaultValue
)
{
if
(
isEmpty
(
str
))
return
defaultValue
;
return
str
;
/**
* Returns str if it is not empty; otherwise defaultValue is returned.
*/
@SuppressWarnings
(
"PMD.ShortMethodName"
)
public
static
CharSequence
or
(
CharSequence
str
,
CharSequence
defaultValue
)
{
if
(
isEmpty
(
str
))
{
return
defaultValue
;
}
return
str
;
}
}
app/src/main/java/chat/rocket/android/model/MeteorLoginServiceConfiguration.java
View file @
6007fd56
...
...
@@ -6,12 +6,11 @@ import io.realm.annotations.PrimaryKey;
/**
* subscription model for "meteor_accounts_loginServiceConfiguration"
*/
@SuppressWarnings
(
"PMD.ShortVariable"
)
public
class
MeteorLoginServiceConfiguration
extends
RealmObject
{
@PrimaryKey
private
String
id
;
private
String
service
;
private
String
consumerKey
;
//for Twitter
private
String
appId
;
//for Facebook
private
String
clientId
;
//for other auth providers
@SuppressWarnings
(
"PMD.ShortVariable"
)
public
class
MeteorLoginServiceConfiguration
extends
RealmObject
{
@PrimaryKey
private
String
id
;
private
String
service
;
private
String
consumerKey
;
//for Twitter
private
String
appId
;
//for Facebook
private
String
clientId
;
//for other auth providers
}
app/src/main/java/chat/rocket/android/model/ServerConfig.java
View file @
6007fd56
package
chat
.
rocket
.
android
.
model
;
import
org.json.JSONObject
;
import
chat.rocket.android.helper.LogcatIfError
;
import
hugo.weaving.DebugLog
;
import
io.realm.Realm
;
...
...
@@ -11,101 +9,95 @@ import io.realm.RealmQuery;
import
io.realm.annotations.PrimaryKey
;
import
jp.co.crowdworks.realm_java_helpers.RealmHelper
;
import
jp.co.crowdworks.realm_java_helpers_bolts.RealmHelperBolts
;
import
org.json.JSONObject
;
/**
* Server configuration
*/
@SuppressWarnings
(
"PMD.ShortVariable"
)
public
class
ServerConfig
extends
RealmObject
{
@PrimaryKey
private
String
id
;
private
String
hostname
;
private
String
connectionError
;
private
String
token
;
private
boolean
tokenVerified
;
private
RealmList
<
MeteorLoginServiceConfiguration
>
authProviders
;
private
String
selectedProviderName
;
public
String
getId
()
{
return
id
;
}
public
void
setId
(
String
id
)
{
this
.
id
=
id
;
}
public
String
getHostname
()
{
return
hostname
;
}
public
void
setHostname
(
String
hostname
)
{
this
.
hostname
=
hostname
;
}
public
String
getConnectionError
()
{
return
connectionError
;
}
public
void
setConnectionError
(
String
connectionError
)
{
this
.
connectionError
=
connectionError
;
}
public
String
getToken
()
{
return
token
;
}
public
void
setToken
(
String
token
)
{
this
.
token
=
token
;
}
public
boolean
isTokenVerified
()
{
return
tokenVerified
;
}
public
void
setTokenVerified
(
boolean
tokenVerified
)
{
this
.
tokenVerified
=
tokenVerified
;
}
public
RealmList
<
MeteorLoginServiceConfiguration
>
getAuthProviders
()
{
return
authProviders
;
}
public
void
setAuthProviders
(
RealmList
<
MeteorLoginServiceConfiguration
>
authProviders
)
{
this
.
authProviders
=
authProviders
;
}
public
String
getSelectedProviderName
()
{
return
selectedProviderName
;
}
public
void
setSelectedProviderName
(
String
selectedProviderName
)
{
this
.
selectedProviderName
=
selectedProviderName
;
}
public
static
RealmQuery
<
ServerConfig
>
queryLoginRequiredConnections
(
Realm
realm
)
{
return
realm
.
where
(
ServerConfig
.
class
)
.
equalTo
(
"tokenVerified"
,
false
);
}
public
static
RealmQuery
<
ServerConfig
>
queryActiveConnections
(
Realm
realm
)
{
return
realm
.
where
(
ServerConfig
.
class
)
.
isNotNull
(
"token"
);
}
public
static
boolean
hasActiveConnection
()
{
ServerConfig
config
=
RealmHelper
.
executeTransactionForRead
(
realm
->
queryActiveConnections
(
realm
).
findFirst
());
return
config
!=
null
;
}
@DebugLog
public
static
void
logError
(
String
id
,
Exception
exception
)
{
RealmHelperBolts
.
executeTransaction
(
realm
->
realm
.
createOrUpdateObjectFromJson
(
ServerConfig
.
class
,
new
JSONObject
()
.
put
(
"id"
,
id
)
.
put
(
"connectionError"
,
exception
.
getMessage
())))
.
continueWith
(
new
LogcatIfError
());
}
@SuppressWarnings
(
"PMD.ShortVariable"
)
public
class
ServerConfig
extends
RealmObject
{
@PrimaryKey
private
String
id
;
private
String
hostname
;
private
String
connectionError
;
private
String
token
;
private
boolean
tokenVerified
;
private
RealmList
<
MeteorLoginServiceConfiguration
>
authProviders
;
private
String
selectedProviderName
;
public
static
RealmQuery
<
ServerConfig
>
queryLoginRequiredConnections
(
Realm
realm
)
{
return
realm
.
where
(
ServerConfig
.
class
).
equalTo
(
"tokenVerified"
,
false
);
}
public
static
RealmQuery
<
ServerConfig
>
queryActiveConnections
(
Realm
realm
)
{
return
realm
.
where
(
ServerConfig
.
class
).
isNotNull
(
"token"
);
}
public
static
boolean
hasActiveConnection
()
{
ServerConfig
config
=
RealmHelper
.
executeTransactionForRead
(
realm
->
queryActiveConnections
(
realm
).
findFirst
());
return
config
!=
null
;
}
@DebugLog
public
static
void
logError
(
String
id
,
Exception
exception
)
{
RealmHelperBolts
.
executeTransaction
(
realm
->
realm
.
createOrUpdateObjectFromJson
(
ServerConfig
.
class
,
new
JSONObject
().
put
(
"id"
,
id
).
put
(
"connectionError"
,
exception
.
getMessage
())))
.
continueWith
(
new
LogcatIfError
());
}
public
String
getId
()
{
return
id
;
}
public
void
setId
(
String
id
)
{
this
.
id
=
id
;
}
public
String
getHostname
()
{
return
hostname
;
}
public
void
setHostname
(
String
hostname
)
{
this
.
hostname
=
hostname
;
}
public
String
getConnectionError
()
{
return
connectionError
;
}
public
void
setConnectionError
(
String
connectionError
)
{
this
.
connectionError
=
connectionError
;
}
public
String
getToken
()
{
return
token
;
}
public
void
setToken
(
String
token
)
{
this
.
token
=
token
;
}
public
boolean
isTokenVerified
()
{
return
tokenVerified
;
}
public
void
setTokenVerified
(
boolean
tokenVerified
)
{
this
.
tokenVerified
=
tokenVerified
;
}
public
RealmList
<
MeteorLoginServiceConfiguration
>
getAuthProviders
()
{
return
authProviders
;
}
public
void
setAuthProviders
(
RealmList
<
MeteorLoginServiceConfiguration
>
authProviders
)
{
this
.
authProviders
=
authProviders
;
}
public
String
getSelectedProviderName
()
{
return
selectedProviderName
;
}
public
void
setSelectedProviderName
(
String
selectedProviderName
)
{
this
.
selectedProviderName
=
selectedProviderName
;
}
}
app/src/main/java/chat/rocket/android/service/Registerable.java
View file @
6007fd56
...
...
@@ -4,18 +4,18 @@ package chat.rocket.android.service;
* interface for observer and ddp_subscription
*/
public
interface
Registerable
{
/**
* register
*/
void
register
();
/**
* register
*/
void
register
();
/**
* keepalive
*/
void
keepalive
();
/**
* keepalive
*/
void
keepalive
();
/**
* unregister
*/
void
unregister
();
/**
* unregister
*/
void
unregister
();
}
app/src/main/java/chat/rocket/android/service/RocketChatService.java
View file @
6007fd56
...
...
@@ -5,16 +5,14 @@ import android.content.Context;
import
android.content.Intent
;
import
android.os.IBinder
;
import
android.support.annotation.Nullable
;
import
java.util.HashMap
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map
;
import
bolts.Task
;
import
chat.rocket.android.model.ServerConfig
;
import
io.realm.Realm
;
import
io.realm.RealmResults
;
import
java.util.HashMap
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map
;
import
jp.co.crowdworks.realm_java_helpers.RealmListObserver
;
/**
...
...
@@ -22,94 +20,88 @@ import jp.co.crowdworks.realm_java_helpers.RealmListObserver;
*/
public
class
RocketChatService
extends
Service
{
/**
* ensure RocketChatService alive.
*/
public
static
void
keepalive
(
Context
context
)
{
context
.
startService
(
new
Intent
(
context
,
RocketChatService
.
class
));
}
/**
* force stop RocketChatService.
*/
public
static
void
kill
(
Context
context
)
{
context
.
stopService
(
new
Intent
(
context
,
RocketChatService
.
class
));
}
private
HashMap
<
String
,
RocketChatWebSocketThread
>
mWebSocketThreads
;
private
RealmListObserver
<
ServerConfig
>
mConnectionRequiredServerConfigObserver
=
new
RealmListObserver
<
ServerConfig
>()
{
@Override
protected
RealmResults
<
ServerConfig
>
queryItems
(
Realm
realm
)
{
return
realm
.
where
(
ServerConfig
.
class
)
.
isNotNull
(
"hostname"
)
.
isNull
(
"connectionError"
)
.
findAll
();
}
private
HashMap
<
String
,
RocketChatWebSocketThread
>
mWebSocketThreads
;
private
RealmListObserver
<
ServerConfig
>
mConnectionRequiredServerConfigObserver
=
new
RealmListObserver
<
ServerConfig
>()
{
@Override
protected
RealmResults
<
ServerConfig
>
queryItems
(
Realm
realm
)
{
return
realm
.
where
(
ServerConfig
.
class
)
.
isNotNull
(
"hostname"
)
.
isNull
(
"connectionError"
)
.
findAll
();
}
@Override
protected
void
onCollectionChanged
(
List
<
ServerConfig
>
list
)
{
syncWebSocketThreadsWith
(
list
);
}
};
@Override
protected
void
onCollectionChanged
(
List
<
ServerConfig
>
list
)
{
syncWebSocketThreadsWith
(
list
);
}
};
/**
* ensure RocketChatService alive.
*/
public
static
void
keepalive
(
Context
context
)
{
context
.
startService
(
new
Intent
(
context
,
RocketChatService
.
class
));
}
@Override
public
void
onCreate
()
{
super
.
onCreate
();
mWebSocketThreads
=
new
HashMap
<>();
}
/**
* force stop RocketChatService.
*/
public
static
void
kill
(
Context
context
)
{
context
.
stopService
(
new
Intent
(
context
,
RocketChatService
.
class
));
}
@Override
public
int
onStartCommand
(
Intent
intent
,
int
flags
,
int
startId
)
{
mConnectionRequiredServerConfigObserver
.
keepalive
();
return
START_STICKY
;
}
@Override
public
void
onCreate
()
{
super
.
onCreate
();
mWebSocketThreads
=
new
HashMap
<>();
}
private
void
syncWebSocketThreadsWith
(
List
<
ServerConfig
>
configList
)
{
final
Iterator
<
Map
.
Entry
<
String
,
RocketChatWebSocketThread
>>
iterator
=
mWebSocketThreads
.
entrySet
().
iterator
();
@Override
public
int
onStartCommand
(
Intent
intent
,
int
flags
,
int
startId
)
{
mConnectionRequiredServerConfigObserver
.
keepalive
();
return
START_STICKY
;
}
while
(
iterator
.
hasNext
())
{
Map
.
Entry
<
String
,
RocketChatWebSocketThread
>
entry
=
iterator
.
next
();
String
serverConfigId
=
entry
.
getKey
();
boolean
found
=
false
;
for
(
ServerConfig
config:
configList
)
{
if
(
serverConfigId
.
equals
(
config
.
getId
()))
{
found
=
true
;
break
;
}
}
if
(!
found
)
{
RocketChatWebSocketThread
.
terminate
(
entry
.
getValue
());
iterator
.
remove
();
}
}
private
void
syncWebSocketThreadsWith
(
List
<
ServerConfig
>
configList
)
{
final
Iterator
<
Map
.
Entry
<
String
,
RocketChatWebSocketThread
>>
iterator
=
mWebSocketThreads
.
entrySet
().
iterator
();
for
(
ServerConfig
config:
configList
)
{
findOrCreateWebSocketThread
(
config
).
onSuccess
(
task
->
{
RocketChatWebSocketThread
thread
=
task
.
getResult
();
thread
.
syncStateWith
(
config
);
return
null
;
});
while
(
iterator
.
hasNext
())
{
Map
.
Entry
<
String
,
RocketChatWebSocketThread
>
entry
=
iterator
.
next
();
String
serverConfigId
=
entry
.
getKey
();
boolean
found
=
false
;
for
(
ServerConfig
config
:
configList
)
{
if
(
serverConfigId
.
equals
(
config
.
getId
()))
{
found
=
true
;
break
;
}
}
if
(!
found
)
{
RocketChatWebSocketThread
.
terminate
(
entry
.
getValue
());
iterator
.
remove
();
}
}
private
Task
<
RocketChatWebSocketThread
>
findOrCreateWebSocketThread
(
final
ServerConfig
config
)
{
final
String
serverConfigId
=
config
.
getId
();
if
(
mWebSocketThreads
.
containsKey
(
serverConfigId
))
{
return
Task
.
forResult
(
mWebSocketThreads
.
get
(
serverConfigId
));
}
else
{
return
RocketChatWebSocketThread
.
getStarted
(
getApplicationContext
(),
config
)
.
onSuccessTask
(
task
->
{
mWebSocketThreads
.
put
(
serverConfigId
,
task
.
getResult
());
return
task
;
});
}
for
(
ServerConfig
config
:
configList
)
{
findOrCreateWebSocketThread
(
config
).
onSuccess
(
task
->
{
RocketChatWebSocketThread
thread
=
task
.
getResult
();
thread
.
syncStateWith
(
config
);
return
null
;
});
}
}
@Nullable
@Override
public
IBinder
onBind
(
Intent
intent
)
{
return
null
;
private
Task
<
RocketChatWebSocketThread
>
findOrCreateWebSocketThread
(
final
ServerConfig
config
)
{
final
String
serverConfigId
=
config
.
getId
();
if
(
mWebSocketThreads
.
containsKey
(
serverConfigId
))
{
return
Task
.
forResult
(
mWebSocketThreads
.
get
(
serverConfigId
));
}
else
{
return
RocketChatWebSocketThread
.
getStarted
(
getApplicationContext
(),
config
)
.
onSuccessTask
(
task
->
{
mWebSocketThreads
.
put
(
serverConfigId
,
task
.
getResult
());
return
task
;
});
}
}
@Nullable
@Override
public
IBinder
onBind
(
Intent
intent
)
{
return
null
;
}
}
app/src/main/java/chat/rocket/android/service/RocketChatWebSocketThread.java
View file @
6007fd56
...
...
@@ -3,11 +3,6 @@ package chat.rocket.android.service;
import
android.content.Context
;
import
android.os.Handler
;
import
android.os.HandlerThread
;
import
java.lang.reflect.Constructor
;
import
java.util.ArrayList
;
import
java.util.Iterator
;
import
bolts.Task
;
import
bolts.TaskCompletionSource
;
import
chat.rocket.android.helper.TextUtils
;
...
...
@@ -16,6 +11,9 @@ import chat.rocket.android.service.ddp_subscriber.LoginServiceConfigurationSubsc
import
chat.rocket.android.ws.RocketChatWebSocketAPI
;
import
chat.rocket.android_ddp.DDPClient
;
import
hugo.weaving.DebugLog
;
import
java.lang.reflect.Constructor
;
import
java.util.ArrayList
;
import
java.util.Iterator
;
import
jp.co.crowdworks.realm_java_helpers.RealmHelper
;
import
timber.log.Timber
;
...
...
@@ -23,194 +21,188 @@ import timber.log.Timber;
* Thread for handling WebSocket connection.
*/
public
class
RocketChatWebSocketThread
extends
HandlerThread
{
private
final
Context
mAppContext
;
private
final
String
mServerConfigId
;
private
RocketChatWebSocketAPI
mWebSocketAPI
;
private
boolean
mSocketExists
;
private
boolean
mListenersRegistered
;
private
RocketChatWebSocketThread
(
Context
appContext
,
String
serverConfigId
)
{
super
(
"RC_thread_"
+
serverConfigId
);
mServerConfigId
=
serverConfigId
;
mAppContext
=
appContext
;
private
static
final
Class
[]
REGISTERABLE_CLASSES
=
{
LoginServiceConfigurationSubscriber
.
class
};
private
final
Context
mAppContext
;
private
final
String
mServerConfigId
;
private
final
ArrayList
<
Registerable
>
mListeners
=
new
ArrayList
<>();
private
RocketChatWebSocketAPI
mWebSocketAPI
;
private
boolean
mSocketExists
;
private
boolean
mListenersRegistered
;
private
RocketChatWebSocketThread
(
Context
appContext
,
String
serverConfigId
)
{
super
(
"RC_thread_"
+
serverConfigId
);
mServerConfigId
=
serverConfigId
;
mAppContext
=
appContext
;
}
/**
* create new Thread.
*/
@DebugLog
public
static
Task
<
RocketChatWebSocketThread
>
getStarted
(
Context
appContext
,
ServerConfig
config
)
{
TaskCompletionSource
<
RocketChatWebSocketThread
>
task
=
new
TaskCompletionSource
<>();
new
RocketChatWebSocketThread
(
appContext
,
config
.
getId
())
{
@Override
protected
void
onLooperPrepared
()
{
try
{
super
.
onLooperPrepared
();
task
.
setResult
(
this
);
}
catch
(
Exception
exception
)
{
task
.
setError
(
exception
);
}
}
}.
start
();
return
task
.
getTask
();
}
/**
* terminate the thread
*/
@DebugLog
public
static
void
terminate
(
RocketChatWebSocketThread
thread
)
{
thread
.
quit
();
}
private
Task
<
Void
>
ensureConnection
()
{
if
(
mWebSocketAPI
==
null
||
!
mWebSocketAPI
.
isConnected
())
{
return
registerListeners
();
}
else
{
return
Task
.
forResult
(
null
);
}
/**
* create new Thread.
*/
@DebugLog
public
static
Task
<
RocketChatWebSocketThread
>
getStarted
(
Context
appContext
,
ServerConfig
config
)
{
TaskCompletionSource
<
RocketChatWebSocketThread
>
task
=
new
TaskCompletionSource
<>();
new
RocketChatWebSocketThread
(
appContext
,
config
.
getId
()){
@Override
protected
void
onLooperPrepared
()
{
try
{
super
.
onLooperPrepared
();
task
.
setResult
(
this
);
}
catch
(
Exception
exception
)
{
task
.
setError
(
exception
);
}
}
}.
start
();
return
task
.
getTask
();
}
/**
* synchronize the state of the thread with ServerConfig.
*/
@DebugLog
public
void
syncStateWith
(
ServerConfig
config
)
{
if
(
config
==
null
||
TextUtils
.
isEmpty
(
config
.
getHostname
())
||
!
TextUtils
.
isEmpty
(
config
.
getConnectionError
()))
{
quit
();
}
else
{
ensureConnection
().
continueWith
(
task
->
{
new
Handler
(
getLooper
()).
post
(
this
::
keepaliveListeners
);
return
null
;
});
}
/**
* terminate the thread
*/
@DebugLog
public
static
void
terminate
(
RocketChatWebSocketThread
thread
)
{
thread
.
quit
();
}
@Override
protected
void
onLooperPrepared
()
{
super
.
onLooperPrepared
();
registerListeners
();
}
@Override
public
boolean
quit
()
{
scheduleUnregisterListeners
();
return
super
.
quit
();
}
@Override
public
boolean
quitSafely
()
{
scheduleUnregisterListeners
();
return
super
.
quitSafely
();
}
private
void
scheduleUnregisterListeners
()
{
if
(
isAlive
())
{
new
Handler
(
getLooper
()).
post
(()
->
{
Timber
.
d
(
"thread %s: quit()"
,
Thread
.
currentThread
().
getId
());
unregisterListeners
();
});
}
}
private
Task
<
Void
>
ensureConnection
()
{
if
(
mWebSocketAPI
==
null
||
!
mWebSocketAPI
.
isConnected
())
{
return
registerListeners
();
}
else
{
return
Task
.
forResult
(
null
);
}
}
private
void
prepareWebSocket
()
{
ServerConfig
config
=
RealmHelper
.
executeTransactionForRead
(
realm
->
realm
.
where
(
ServerConfig
.
class
).
equalTo
(
"id"
,
mServerConfigId
).
findFirst
());
/**
* synchronize the state of the thread with ServerConfig.
*/
@DebugLog
public
void
syncStateWith
(
ServerConfig
config
)
{
if
(
config
==
null
||
TextUtils
.
isEmpty
(
config
.
getHostname
())
||
!
TextUtils
.
isEmpty
(
config
.
getConnectionError
()))
{
quit
();
}
else
{
ensureConnection
()
.
continueWith
(
task
->
{
new
Handler
(
getLooper
()).
post
(
this
::
keepaliveListeners
);
return
null
;
});
}
if
(
mWebSocketAPI
==
null
||
!
mWebSocketAPI
.
isConnected
())
{
mWebSocketAPI
=
RocketChatWebSocketAPI
.
create
(
config
.
getHostname
());
}
}
@Override
protected
void
onLooperPrepared
()
{
super
.
onLooperPrepared
();
registerListeners
();
@DebugLog
private
Task
<
Void
>
registerListeners
()
{
if
(
mSocketExists
)
{
return
Task
.
forResult
(
null
);
}
@Override
public
boolean
quit
()
{
scheduleUnregisterListeners
();
return
super
.
quit
();
mSocketExists
=
true
;
prepareWebSocket
();
return
mWebSocketAPI
.
connect
().
onSuccess
(
task
->
{
registerListenersActually
();
DDPClient
client
=
task
.
getResult
().
client
;
// handling WebSocket#onClose() callback.
client
.
getOnCloseCallback
().
onSuccess
(
_task
->
{
quit
();
return
null
;
});
// just for debugging.
client
.
getSubscriptionCallback
().
subscribe
(
event
->
{
Timber
.
d
(
"Callback [DEBUG] < "
+
event
);
});
return
null
;
}).
continueWith
(
task
->
{
if
(
task
.
isFaulted
())
{
ServerConfig
.
logError
(
mServerConfigId
,
task
.
getError
());
}
return
null
;
});
}
//@DebugLog
private
void
registerListenersActually
()
{
if
(
mListenersRegistered
)
{
return
;
}
mListenersRegistered
=
true
;
@Override
public
boolean
quitSafely
()
{
scheduleUnregisterListeners
();
return
super
.
quitSafely
();
}
for
(
Class
clazz
:
REGISTERABLE_CLASSES
)
{
try
{
Constructor
ctor
=
clazz
.
getConstructor
(
Context
.
class
,
RocketChatWebSocketAPI
.
class
);
Object
obj
=
ctor
.
newInstance
(
mAppContext
,
mWebSocketAPI
);
private
void
scheduleUnregisterListeners
()
{
if
(
isAlive
())
{
new
Handler
(
getLooper
()).
post
(()
->
{
Timber
.
d
(
"thread %s: quit()"
,
Thread
.
currentThread
().
getId
());
unregisterListeners
();
});
if
(
obj
instanceof
Registerable
)
{
Registerable
registerable
=
(
Registerable
)
obj
;
registerable
.
register
();
mListeners
.
add
(
registerable
);
}
}
catch
(
Exception
exception
)
{
Timber
.
w
(
exception
,
"Failed to register listeners!!"
);
}
}
}
private
static
final
Class
[]
REGISTERABLE_CLASSES
=
{
LoginServiceConfigurationSubscriber
.
class
};
private
final
ArrayList
<
Registerable
>
mListeners
=
new
ArrayList
<>();
private
void
prepareWebSocket
()
{
ServerConfig
config
=
RealmHelper
.
executeTransactionForRead
(
realm
->
realm
.
where
(
ServerConfig
.
class
)
.
equalTo
(
"id"
,
mServerConfigId
)
.
findFirst
());
if
(
mWebSocketAPI
==
null
||
!
mWebSocketAPI
.
isConnected
())
{
mWebSocketAPI
=
RocketChatWebSocketAPI
.
create
(
config
.
getHostname
());
}
//@DebugLog
private
void
keepaliveListeners
()
{
if
(!
mSocketExists
||
!
mListenersRegistered
)
{
return
;
}
@DebugLog
private
Task
<
Void
>
registerListeners
()
{
if
(
mSocketExists
)
return
Task
.
forResult
(
null
);
mSocketExists
=
true
;
prepareWebSocket
();
return
mWebSocketAPI
.
connect
().
onSuccess
(
task
->
{
registerListenersActually
();
DDPClient
client
=
task
.
getResult
().
client
;
// handling WebSocket#onClose() callback.
client
.
getOnCloseCallback
().
onSuccess
(
_task
->
{
quit
();
return
null
;
});
// just for debugging.
client
.
getSubscriptionCallback
().
subscribe
(
event
->
{
Timber
.
d
(
"Callback [DEBUG] < "
+
event
);
});
return
null
;
}).
continueWith
(
task
->
{
if
(
task
.
isFaulted
())
{
ServerConfig
.
logError
(
mServerConfigId
,
task
.
getError
());
}
return
null
;
});
for
(
Registerable
registerable
:
mListeners
)
{
registerable
.
keepalive
();
}
}
//@DebugLog
private
void
registerListenersActually
()
{
if
(
mListenersRegistered
)
return
;
mListenersRegistered
=
true
;
for
(
Class
clazz:
REGISTERABLE_CLASSES
)
{
try
{
Constructor
ctor
=
clazz
.
getConstructor
(
Context
.
class
,
RocketChatWebSocketAPI
.
class
);
Object
obj
=
ctor
.
newInstance
(
mAppContext
,
mWebSocketAPI
);
if
(
obj
instanceof
Registerable
)
{
Registerable
registerable
=
(
Registerable
)
obj
;
registerable
.
register
();
mListeners
.
add
(
registerable
);
}
}
catch
(
Exception
exception
)
{
Timber
.
w
(
exception
,
"Failed to register listeners!!"
);
}
}
//@DebugLog
private
void
unregisterListeners
()
{
if
(!
mSocketExists
||
!
mListenersRegistered
)
{
return
;
}
//@DebugLog
private
void
keepaliveListeners
(
)
{
if
(!
mSocketExists
||
!
mListenersRegistered
)
return
;
for
(
Registerable
registerable
:
mListeners
)
registerable
.
keepali
ve
();
Iterator
<
Registerable
>
iterator
=
mListeners
.
iterator
();
while
(
iterator
.
hasNext
()
)
{
Registerable
registerable
=
iterator
.
next
()
;
registerable
.
unregister
();
iterator
.
remo
ve
();
}
//@DebugLog
private
void
unregisterListeners
()
{
if
(!
mSocketExists
||
!
mListenersRegistered
)
return
;
Iterator
<
Registerable
>
iterator
=
mListeners
.
iterator
();
while
(
iterator
.
hasNext
())
{
Registerable
registerable
=
iterator
.
next
();
registerable
.
unregister
();
iterator
.
remove
();
}
if
(
mWebSocketAPI
!=
null
)
{
mWebSocketAPI
.
close
();
mWebSocketAPI
=
null
;
}
mListenersRegistered
=
false
;
mSocketExists
=
false
;
if
(
mWebSocketAPI
!=
null
)
{
mWebSocketAPI
.
close
();
mWebSocketAPI
=
null
;
}
mListenersRegistered
=
false
;
mSocketExists
=
false
;
}
}
app/src/main/java/chat/rocket/android/service/ddp_subscriber/AbstractDDPDocEventSubscriber.java
View file @
6007fd56
...
...
@@ -2,150 +2,148 @@ package chat.rocket.android.service.ddp_subscriber;
import
android.content.Context
;
import
android.text.TextUtils
;
import
org.json.JSONException
;
import
org.json.JSONObject
;
import
java.util.Iterator
;
import
chat.rocket.android.helper.LogcatIfError
;
import
chat.rocket.android.service.Registerable
;
import
chat.rocket.android.ws.RocketChatWebSocketAPI
;
import
chat.rocket.android_ddp.DDPSubscription
;
import
io.realm.Realm
;
import
io.realm.RealmObject
;
import
java.util.Iterator
;
import
jp.co.crowdworks.realm_java_helpers_bolts.RealmHelperBolts
;
import
org.json.JSONException
;
import
org.json.JSONObject
;
import
rx.Subscription
;
import
timber.log.Timber
;
abstract
class
AbstractDDPDocEventSubscriber
implements
Registerable
{
protected
final
Context
mContext
;
protected
final
RocketChatWebSocketAPI
mAPI
;
private
String
mID
;
private
Subscription
mSubscription
;
protected
AbstractDDPDocEventSubscriber
(
Context
context
,
RocketChatWebSocketAPI
api
)
{
mContext
=
context
;
mAPI
=
api
;
}
protected
abstract
String
getSubscriptionName
();
protected
abstract
String
getSubscriptionCallbackName
();
protected
abstract
Class
<?
extends
RealmObject
>
getModelClass
();
protected
JSONObject
customizeFieldJSON
(
JSONObject
json
)
{
return
json
;
}
@Override
public
void
register
()
{
mAPI
.
subscribe
(
getSubscriptionName
(),
null
).
onSuccess
(
task
->
{
mID
=
task
.
getResult
().
id
;
return
null
;
}).
continueWith
(
task
->
{
if
(
task
.
isFaulted
())
{
Timber
.
w
(
task
.
getError
(),
"DDP subscription failed."
);
protected
final
Context
mContext
;
protected
final
RocketChatWebSocketAPI
mAPI
;
private
String
mID
;
private
Subscription
mSubscription
;
protected
AbstractDDPDocEventSubscriber
(
Context
context
,
RocketChatWebSocketAPI
api
)
{
mContext
=
context
;
mAPI
=
api
;
}
protected
abstract
String
getSubscriptionName
();
protected
abstract
String
getSubscriptionCallbackName
();
protected
abstract
Class
<?
extends
RealmObject
>
getModelClass
();
protected
JSONObject
customizeFieldJSON
(
JSONObject
json
)
{
return
json
;
}
@Override
public
void
register
()
{
mAPI
.
subscribe
(
getSubscriptionName
(),
null
).
onSuccess
(
task
->
{
mID
=
task
.
getResult
().
id
;
return
null
;
}).
continueWith
(
task
->
{
if
(
task
.
isFaulted
())
{
Timber
.
w
(
task
.
getError
(),
"DDP subscription failed."
);
}
return
null
;
});
RealmHelperBolts
.
executeTransaction
(
realm
->
{
realm
.
delete
(
getModelClass
());
return
null
;
}).
onSuccess
(
task
->
{
registerSubscriptionCallback
();
return
null
;
}).
continueWith
(
new
LogcatIfError
());
}
private
void
registerSubscriptionCallback
()
{
mSubscription
=
mAPI
.
getSubscriptionCallback
()
.
filter
(
event
->
event
instanceof
DDPSubscription
.
DocEvent
)
.
cast
(
DDPSubscription
.
DocEvent
.
class
)
.
filter
(
event
->
getSubscriptionCallbackName
().
equals
(
event
.
collection
))
.
subscribe
(
docEvent
->
{
try
{
if
(
docEvent
instanceof
DDPSubscription
.
Added
.
Before
)
{
onDocumentAdded
((
DDPSubscription
.
Added
)
docEvent
);
//ignore Before
}
else
if
(
docEvent
instanceof
DDPSubscription
.
Added
)
{
onDocumentAdded
((
DDPSubscription
.
Added
)
docEvent
);
}
else
if
(
docEvent
instanceof
DDPSubscription
.
Removed
)
{
onDocumentRemoved
((
DDPSubscription
.
Removed
)
docEvent
);
}
else
if
(
docEvent
instanceof
DDPSubscription
.
Changed
)
{
onDocumentChanged
((
DDPSubscription
.
Changed
)
docEvent
);
}
else
if
(
docEvent
instanceof
DDPSubscription
.
MovedBefore
)
{
//ignore movedBefore
}
return
null
;
}
catch
(
Exception
e
)
{
Timber
.
w
(
e
,
"failed to handle subscription callback"
);
}
});
RealmHelperBolts
.
executeTransaction
(
realm
->
{
realm
.
delete
(
getModelClass
());
return
null
;
}).
onSuccess
(
task
->
{
registerSubscriptionCallback
();
return
null
;
}).
continueWith
(
new
LogcatIfError
());
}
protected
void
onDocumentAdded
(
DDPSubscription
.
Added
docEvent
)
{
RealmHelperBolts
.
executeTransaction
(
realm
->
{
onDocumentAdded
(
realm
,
docEvent
);
return
null
;
}).
continueWith
(
new
LogcatIfError
());
}
protected
void
onDocumentChanged
(
DDPSubscription
.
Changed
docEvent
)
{
RealmHelperBolts
.
executeTransaction
(
realm
->
{
onDocumentChanged
(
realm
,
docEvent
);
return
null
;
}).
continueWith
(
new
LogcatIfError
());
}
protected
void
onDocumentRemoved
(
DDPSubscription
.
Removed
docEvent
)
{
RealmHelperBolts
.
executeTransaction
(
realm
->
{
onDocumentRemoved
(
realm
,
docEvent
);
return
null
;
}).
continueWith
(
new
LogcatIfError
());
}
private
void
mergeJSON
(
JSONObject
target
,
JSONObject
src
)
throws
JSONException
{
Iterator
<
String
>
iterator
=
src
.
keys
();
while
(
iterator
.
hasNext
())
{
String
key
=
iterator
.
next
();
target
.
put
(
key
,
src
.
get
(
key
));
}
private
void
registerSubscriptionCallback
()
{
mSubscription
=
mAPI
.
getSubscriptionCallback
()
.
filter
(
event
->
event
instanceof
DDPSubscription
.
DocEvent
)
.
cast
(
DDPSubscription
.
DocEvent
.
class
)
.
filter
(
event
->
getSubscriptionCallbackName
().
equals
(
event
.
collection
))
.
subscribe
(
docEvent
->
{
try
{
if
(
docEvent
instanceof
DDPSubscription
.
Added
.
Before
)
{
onDocumentAdded
((
DDPSubscription
.
Added
)
docEvent
);
//ignore Before
}
else
if
(
docEvent
instanceof
DDPSubscription
.
Added
)
{
onDocumentAdded
((
DDPSubscription
.
Added
)
docEvent
);
}
else
if
(
docEvent
instanceof
DDPSubscription
.
Removed
)
{
onDocumentRemoved
((
DDPSubscription
.
Removed
)
docEvent
);
}
else
if
(
docEvent
instanceof
DDPSubscription
.
Changed
)
{
onDocumentChanged
((
DDPSubscription
.
Changed
)
docEvent
);
}
else
if
(
docEvent
instanceof
DDPSubscription
.
MovedBefore
)
{
//ignore movedBefore
}
}
catch
(
Exception
e
)
{
Timber
.
w
(
e
,
"failed to handle subscription callback"
);
}
});
}
protected
void
onDocumentAdded
(
DDPSubscription
.
Added
docEvent
)
{
RealmHelperBolts
.
executeTransaction
(
realm
->
{
onDocumentAdded
(
realm
,
docEvent
);
return
null
;
}).
continueWith
(
new
LogcatIfError
());
}
protected
void
onDocumentChanged
(
DDPSubscription
.
Changed
docEvent
)
{
RealmHelperBolts
.
executeTransaction
(
realm
->
{
onDocumentChanged
(
realm
,
docEvent
);
return
null
;
}).
continueWith
(
new
LogcatIfError
());
}
protected
void
onDocumentRemoved
(
DDPSubscription
.
Removed
docEvent
)
{
RealmHelperBolts
.
executeTransaction
(
realm
->
{
onDocumentRemoved
(
realm
,
docEvent
);
return
null
;
}).
continueWith
(
new
LogcatIfError
());
}
private
void
onDocumentAdded
(
Realm
realm
,
DDPSubscription
.
Added
docEvent
)
throws
JSONException
{
//executed in RealmTransaction
JSONObject
json
=
new
JSONObject
().
put
(
"id"
,
docEvent
.
docID
);
mergeJSON
(
json
,
docEvent
.
fields
);
realm
.
createOrUpdateObjectFromJson
(
getModelClass
(),
customizeFieldJSON
(
json
));
}
private
void
onDocumentChanged
(
Realm
realm
,
DDPSubscription
.
Changed
docEvent
)
throws
JSONException
{
//executed in RealmTransaction
JSONObject
json
=
new
JSONObject
().
put
(
"id"
,
docEvent
.
docID
);
for
(
int
i
=
0
;
i
<
docEvent
.
cleared
.
length
();
i
++)
{
String
fieldToDelete
=
docEvent
.
cleared
.
getString
(
i
);
json
.
remove
(
fieldToDelete
);
}
mergeJSON
(
json
,
docEvent
.
fields
);
realm
.
createOrUpdateObjectFromJson
(
getModelClass
(),
customizeFieldJSON
(
json
));
}
private
void
mergeJSON
(
JSONObject
target
,
JSONObject
src
)
throws
JSONException
{
Iterator
<
String
>
iterator
=
src
.
keys
();
while
(
iterator
.
hasNext
())
{
String
key
=
iterator
.
next
();
target
.
put
(
key
,
src
.
get
(
key
));
}
}
private
void
onDocumentRemoved
(
Realm
realm
,
DDPSubscription
.
Removed
docEvent
)
throws
JSONException
{
//executed in RealmTransaction
realm
.
where
(
getModelClass
()).
equalTo
(
"id"
,
docEvent
.
docID
).
findAll
().
deleteAllFromRealm
();
}
private
void
onDocumentAdded
(
Realm
realm
,
DDPSubscription
.
Added
docEvent
)
throws
JSONException
{
//executed in RealmTransaction
JSONObject
json
=
new
JSONObject
().
put
(
"id"
,
docEvent
.
docID
);
mergeJSON
(
json
,
docEvent
.
fields
);
realm
.
createOrUpdateObjectFromJson
(
getModelClass
(),
customizeFieldJSON
(
json
));
}
@Override
public
void
keepalive
()
{
private
void
onDocumentChanged
(
Realm
realm
,
DDPSubscription
.
Changed
docEvent
)
throws
JSONException
{
//executed in RealmTransaction
JSONObject
json
=
new
JSONObject
().
put
(
"id"
,
docEvent
.
docID
);
for
(
int
i
=
0
;
i
<
docEvent
.
cleared
.
length
();
i
++)
{
String
fieldToDelete
=
docEvent
.
cleared
.
getString
(
i
);
json
.
remove
(
fieldToDelete
);
}
mergeJSON
(
json
,
docEvent
.
fields
);
realm
.
createOrUpdateObjectFromJson
(
getModelClass
(),
customizeFieldJSON
(
json
));
}
}
private
void
onDocumentRemoved
(
Realm
realm
,
DDPSubscription
.
Removed
docEvent
)
throws
JSONException
{
//executed in RealmTransaction
realm
.
where
(
getModelClass
()).
equalTo
(
"id"
,
docEvent
.
docID
).
findAll
().
deleteAllFromRealm
();
@Override
public
void
unregister
()
{
if
(
mSubscription
!=
null
)
{
mSubscription
.
unsubscribe
();
}
@Override
public
void
keepalive
()
{
}
@Override
public
void
unregister
()
{
if
(
mSubscription
!=
null
)
mSubscription
.
unsubscribe
();
if
(!
TextUtils
.
isEmpty
(
mID
))
{
mAPI
.
unsubscribe
(
mID
).
continueWith
(
new
LogcatIfError
());
}
if
(!
TextUtils
.
isEmpty
(
mID
))
{
mAPI
.
unsubscribe
(
mID
).
continueWith
(
new
LogcatIfError
());
}
}
}
app/src/main/java/chat/rocket/android/service/ddp_subscriber/LoginServiceConfigurationSubscriber.java
View file @
6007fd56
package
chat
.
rocket
.
android
.
service
.
ddp_subscriber
;
import
android.content.Context
;
import
chat.rocket.android.model.MeteorLoginServiceConfiguration
;
import
chat.rocket.android.ws.RocketChatWebSocketAPI
;
import
io.realm.RealmObject
;
...
...
@@ -10,22 +9,19 @@ import io.realm.RealmObject;
* meteor.loginServiceConfiguration subscriber
*/
public
class
LoginServiceConfigurationSubscriber
extends
AbstractDDPDocEventSubscriber
{
public
LoginServiceConfigurationSubscriber
(
Context
context
,
RocketChatWebSocketAPI
api
)
{
super
(
context
,
api
);
}
public
LoginServiceConfigurationSubscriber
(
Context
context
,
RocketChatWebSocketAPI
api
)
{
super
(
context
,
api
);
}
@Override
protected
String
getSubscriptionName
()
{
return
"meteor.loginServiceConfiguration"
;
}
@Override
protected
String
getSubscriptionName
()
{
return
"meteor.loginServiceConfiguration"
;
}
@Override
protected
String
getSubscriptionCallbackName
()
{
return
"meteor_accounts_loginServiceConfiguration"
;
}
@Override
protected
String
getSubscriptionCallbackName
()
{
return
"meteor_accounts_loginServiceConfiguration"
;
}
@Override
protected
Class
<?
extends
RealmObject
>
getModelClass
()
{
return
MeteorLoginServiceConfiguration
.
class
;
}
@Override
protected
Class
<?
extends
RealmObject
>
getModelClass
()
{
return
MeteorLoginServiceConfiguration
.
class
;
}
}
app/src/main/java/chat/rocket/android/service/observer/AbstractModelObserver.java
View file @
6007fd56
package
chat
.
rocket
.
android
.
service
.
observer
;
import
android.content.Context
;
import
chat.rocket.android.service.Registerable
;
import
chat.rocket.android.ws.RocketChatWebSocketAPI
;
import
io.realm.RealmObject
;
import
jp.co.crowdworks.realm_java_helpers.RealmListObserver
;
abstract
class
AbstractModelObserver
<
T
extends
RealmObject
>
extends
RealmListObserver
<
T
>
implements
Registerable
{
protected
final
Context
mContext
;
protected
final
RocketChatWebSocketAPI
mAPI
;
abstract
class
AbstractModelObserver
<
T
extends
RealmObject
>
extends
RealmListObserver
<
T
>
implements
Registerable
{
protected
AbstractModelObserver
(
Context
context
,
RocketChatWebSocketAPI
api
)
{
mContext
=
context
;
mAPI
=
api
;
}
protected
final
Context
mContext
;
protected
final
RocketChatWebSocketAPI
mAPI
;
protected
AbstractModelObserver
(
Context
context
,
RocketChatWebSocketAPI
api
)
{
mContext
=
context
;
mAPI
=
api
;
}
@Override
public
void
register
()
{
sub
();
}
@Override
public
void
register
()
{
sub
();
}
@Override
public
void
unregister
()
{
unsub
();
}
@Override
public
void
unregister
()
{
unsub
();
}
}
app/src/main/java/chat/rocket/android/view/AbstractCustomFontTextView.java
View file @
6007fd56
...
...
@@ -7,34 +7,36 @@ import android.util.AttributeSet;
abstract
class
AbstractCustomFontTextView
extends
AppCompatTextView
{
protected
abstract
String
getFont
();
//CHECKSTYLE:OFF RedundantModifier
public
AbstractCustomFontTextView
(
Context
context
,
AttributeSet
attrs
,
int
defStyle
)
{
super
(
context
,
attrs
,
defStyle
);
init
();
}
//CHECKSTYLE:OFF RedundantModifier
public
AbstractCustomFontTextView
(
Context
context
,
AttributeSet
attrs
,
int
defStyle
)
{
super
(
context
,
attrs
,
defStyle
);
init
();
}
//CHECKSTYLE:ON RedundantModifier
//CHECKSTYLE:OFF RedundantModifier
public
AbstractCustomFontTextView
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
init
();
}
//CHECKSTYLE:ON RedundantModifier
//CHECKSTYLE:OFF RedundantModifier
public
AbstractCustomFontTextView
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
init
();
}
//CHECKSTYLE:ON RedundantModifier
//CHECKSTYLE:OFF RedundantModifier
public
AbstractCustomFontTextView
(
Context
context
)
{
super
(
context
);
init
();
}
//CHECKSTYLE:ON RedundantModifier
//CHECKSTYLE:OFF RedundantModifier
public
AbstractCustomFontTextView
(
Context
context
)
{
super
(
context
);
init
();
}
//CHECKSTYLE:ON RedundantModifier
protected
abstract
String
getFont
();
//CHECKSTYLE:ON RedundantModifier
private
void
init
()
{
String
font
=
getFont
();
if
(
font
!=
null
)
{
Typeface
typeface
=
TypefaceHelper
.
getTypeface
(
getContext
(),
font
);
if
(
typeface
!=
null
)
setTypeface
(
typeface
);
}
private
void
init
()
{
String
font
=
getFont
();
if
(
font
!=
null
)
{
Typeface
typeface
=
TypefaceHelper
.
getTypeface
(
getContext
(),
font
);
if
(
typeface
!=
null
)
{
setTypeface
(
typeface
);
}
}
}
}
app/src/main/java/chat/rocket/android/view/FontAwesomeTextView.java
View file @
6007fd56
...
...
@@ -7,20 +7,19 @@ import android.util.AttributeSet;
* TextView with font-awesome
*/
public
class
FontAwesomeTextView
extends
AbstractCustomFontTextView
{
public
FontAwesomeTextView
(
Context
context
,
AttributeSet
attrs
,
int
defStyle
)
{
super
(
context
,
attrs
,
defStyle
);
}
public
FontAwesomeTextView
(
Context
context
,
AttributeSet
attrs
,
int
defStyle
)
{
super
(
context
,
attrs
,
defStyle
);
}
public
FontAwesomeTextView
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
}
public
FontAwesomeTextView
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
}
public
FontAwesomeTextView
(
Context
context
)
{
super
(
context
);
}
public
FontAwesomeTextView
(
Context
context
)
{
super
(
context
);
}
@Override
protected
String
getFont
()
{
return
"fontawesome-webfont.ttf"
;
}
@Override
protected
String
getFont
()
{
return
"fontawesome-webfont.ttf"
;
}
}
app/src/main/java/chat/rocket/android/view/FontelloTextView.java
View file @
6007fd56
...
...
@@ -7,20 +7,19 @@ import android.util.AttributeSet;
* TextView with fontello
*/
public
class
FontelloTextView
extends
AbstractCustomFontTextView
{
public
FontelloTextView
(
Context
context
,
AttributeSet
attrs
,
int
defStyle
)
{
super
(
context
,
attrs
,
defStyle
);
}
public
FontelloTextView
(
Context
context
,
AttributeSet
attrs
,
int
defStyle
)
{
super
(
context
,
attrs
,
defStyle
);
}
public
FontelloTextView
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
}
public
FontelloTextView
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
}
public
FontelloTextView
(
Context
context
)
{
super
(
context
);
}
public
FontelloTextView
(
Context
context
)
{
super
(
context
);
}
@Override
protected
String
getFont
()
{
return
"fontello.ttf"
;
}
@Override
protected
String
getFont
()
{
return
"fontello.ttf"
;
}
}
app/src/main/java/chat/rocket/android/view/TypefaceHelper.java
View file @
6007fd56
...
...
@@ -3,35 +3,32 @@ package chat.rocket.android.view;
import
android.content.Context
;
import
android.graphics.Typeface
;
import
android.util.Log
;
import
java.util.Hashtable
;
/**
* Helper for reading typeface.
* ref:https://code.google.com/p/android/issues/detail?id=9904#c7
* Helper for reading typeface. ref:https://code.google.com/p/android/issues/detail?id=9904#c7
*/
public
class
TypefaceHelper
{
private
static
final
String
TAG
=
TypefaceHelper
.
class
.
getName
();
private
static
final
String
TAG
=
TypefaceHelper
.
class
.
getName
();
private
static
final
Hashtable
<
String
,
Typeface
>
CACHE
=
new
Hashtable
<
String
,
Typeface
>();
private
static
final
Hashtable
<
String
,
Typeface
>
CACHE
=
new
Hashtable
<
String
,
Typeface
>();
/**
* read font in assets directory.
*/
public
static
Typeface
getTypeface
(
Context
context
,
String
assetPath
)
{
synchronized
(
CACHE
)
{
if
(!
CACHE
.
containsKey
(
assetPath
))
{
try
{
Typeface
typeface
=
Typeface
.
createFromAsset
(
context
.
getAssets
(),
assetPath
);
CACHE
.
put
(
assetPath
,
typeface
);
}
catch
(
Exception
exception
)
{
Log
.
e
(
TAG
,
"Could not get typeface '"
+
assetPath
+
"' because "
+
exception
.
getMessage
());
return
null
;
}
}
return
CACHE
.
get
(
assetPath
);
/**
* read font in assets directory.
*/
public
static
Typeface
getTypeface
(
Context
context
,
String
assetPath
)
{
synchronized
(
CACHE
)
{
if
(!
CACHE
.
containsKey
(
assetPath
))
{
try
{
Typeface
typeface
=
Typeface
.
createFromAsset
(
context
.
getAssets
(),
assetPath
);
CACHE
.
put
(
assetPath
,
typeface
);
}
catch
(
Exception
exception
)
{
Log
.
e
(
TAG
,
"Could not get typeface '"
+
assetPath
+
"' because "
+
exception
.
getMessage
());
return
null
;
}
}
return
CACHE
.
get
(
assetPath
);
}
}
}
app/src/main/java/chat/rocket/android/view/WaitingView.java
View file @
6007fd56
...
...
@@ -11,112 +11,108 @@ import android.view.View;
import
android.widget.FrameLayout
;
import
android.widget.ImageView
;
import
android.widget.LinearLayout
;
import
java.util.ArrayList
;
import
chat.rocket.android.R
;
import
java.util.ArrayList
;
/**
* View for indicating "waiting for connection ..." and so on.
*/
public
class
WaitingView
extends
LinearLayout
{
private
ArrayList
<
View
>
mDots
;
public
WaitingView
(
Context
context
)
{
super
(
context
);
initialize
(
context
,
null
);
}
public
WaitingView
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
initialize
(
context
,
attrs
);
}
public
WaitingView
(
Context
context
,
AttributeSet
attrs
,
int
defStyleAttr
)
{
super
(
context
,
attrs
,
defStyleAttr
);
initialize
(
context
,
attrs
);
}
@TargetApi
(
Build
.
VERSION_CODES
.
LOLLIPOP
)
public
WaitingView
(
Context
context
,
AttributeSet
attrs
,
int
defStyleAttr
,
int
defStyleRes
)
{
super
(
context
,
attrs
,
defStyleAttr
,
defStyleRes
);
initialize
(
context
,
attrs
);
}
private
void
initialize
(
Context
context
,
AttributeSet
attrs
)
{
int
size
=
context
.
getResources
().
getDimensionPixelSize
(
R
.
dimen
.
def_waiting_view_dot_size
);
int
count
=
3
;
if
(
attrs
!=
null
)
{
TypedArray
array
=
context
.
getTheme
().
obtainStyledAttributes
(
attrs
,
R
.
styleable
.
WaitingView
,
0
,
0
);
size
=
array
.
getDimensionPixelSize
(
R
.
styleable
.
WaitingView_dotSize
,
size
);
count
=
array
.
getInteger
(
R
.
styleable
.
WaitingView_dotCount
,
count
);
array
.
recycle
();
}
mDots
=
new
ArrayList
<>();
setOrientation
(
HORIZONTAL
);
for
(
int
i
=
0
;
i
<
count
;
i
++)
addDot
(
context
,
size
);
addOnAttachStateChangeListener
(
new
OnAttachStateChangeListener
()
{
@Override
public
void
onViewAttachedToWindow
(
View
view
)
{
start
();
}
@Override
public
void
onViewDetachedFromWindow
(
View
view
)
{
cancel
();
}
});
private
ArrayList
<
View
>
mDots
;
public
WaitingView
(
Context
context
)
{
super
(
context
);
initialize
(
context
,
null
);
}
public
WaitingView
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
initialize
(
context
,
attrs
);
}
public
WaitingView
(
Context
context
,
AttributeSet
attrs
,
int
defStyleAttr
)
{
super
(
context
,
attrs
,
defStyleAttr
);
initialize
(
context
,
attrs
);
}
@TargetApi
(
Build
.
VERSION_CODES
.
LOLLIPOP
)
public
WaitingView
(
Context
context
,
AttributeSet
attrs
,
int
defStyleAttr
,
int
defStyleRes
)
{
super
(
context
,
attrs
,
defStyleAttr
,
defStyleRes
);
initialize
(
context
,
attrs
);
}
private
void
initialize
(
Context
context
,
AttributeSet
attrs
)
{
int
size
=
context
.
getResources
().
getDimensionPixelSize
(
R
.
dimen
.
def_waiting_view_dot_size
);
int
count
=
3
;
if
(
attrs
!=
null
)
{
TypedArray
array
=
context
.
getTheme
().
obtainStyledAttributes
(
attrs
,
R
.
styleable
.
WaitingView
,
0
,
0
);
size
=
array
.
getDimensionPixelSize
(
R
.
styleable
.
WaitingView_dotSize
,
size
);
count
=
array
.
getInteger
(
R
.
styleable
.
WaitingView_dotCount
,
count
);
array
.
recycle
();
}
private
void
addDot
(
Context
context
,
int
size
)
{
FrameLayout
frameLayout
=
new
FrameLayout
(
context
);
frameLayout
.
setLayoutParams
(
new
LinearLayoutCompat
.
LayoutParams
(
size
*
3
/
2
,
size
*
3
/
2
));
ImageView
dot
=
new
ImageView
(
context
);
dot
.
setImageResource
(
R
.
drawable
.
white_circle
);
dot
.
setLayoutParams
(
new
FrameLayout
.
LayoutParams
(
size
,
size
,
Gravity
.
CENTER
));
frameLayout
.
addView
(
dot
);
addView
(
frameLayout
);
mDots
.
add
(
dot
);
mDots
=
new
ArrayList
<>();
setOrientation
(
HORIZONTAL
);
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
addDot
(
context
,
size
);
}
private
void
start
()
{
for
(
int
i
=
0
;
i
<
mDots
.
size
();
i
++)
{
animateDot
(
mDots
.
get
(
i
),
160
*
i
,
480
,
480
);
}
addOnAttachStateChangeListener
(
new
OnAttachStateChangeListener
()
{
@Override
public
void
onViewAttachedToWindow
(
View
view
)
{
start
();
}
@Override
public
void
onViewDetachedFromWindow
(
View
view
)
{
cancel
();
}
});
}
private
void
addDot
(
Context
context
,
int
size
)
{
FrameLayout
frameLayout
=
new
FrameLayout
(
context
);
frameLayout
.
setLayoutParams
(
new
LinearLayoutCompat
.
LayoutParams
(
size
*
3
/
2
,
size
*
3
/
2
));
ImageView
dot
=
new
ImageView
(
context
);
dot
.
setImageResource
(
R
.
drawable
.
white_circle
);
dot
.
setLayoutParams
(
new
FrameLayout
.
LayoutParams
(
size
,
size
,
Gravity
.
CENTER
));
frameLayout
.
addView
(
dot
);
addView
(
frameLayout
);
mDots
.
add
(
dot
);
}
private
void
start
()
{
for
(
int
i
=
0
;
i
<
mDots
.
size
();
i
++)
{
animateDot
(
mDots
.
get
(
i
),
160
*
i
,
480
,
480
);
}
private
void
animateDot
(
final
View
dot
,
final
long
startDelay
,
final
long
duration
,
final
long
interval
)
{
dot
.
setScaleX
(
0
);
dot
.
setScaleY
(
0
);
dot
.
animate
(
)
.
scaleX
(
1
)
.
scaleY
(
1
)
.
setDuration
(
duration
)
.
setStartDelay
(
startDelay
)
.
withEndAction
(()
->
{
dot
.
animate
()
.
scaleX
(
0
).
scaleY
(
0
)
.
setDuration
(
duration
)
.
setStartDelay
(
0
)
.
withEndAction
(()
->
{
animateDot
(
dot
,
interval
,
duration
,
interval
);
})
.
start
();
})
.
start
();
}
private
void
cancel
()
{
for
(
View
dot:
mDots
)
{
dot
.
clearAnimation
();
}
}
private
void
animateDot
(
final
View
dot
,
final
long
startDelay
,
final
long
duration
,
final
long
interval
)
{
dot
.
setScaleX
(
0
);
dot
.
setScaleY
(
0
);
dot
.
animate
()
.
scaleX
(
1
)
.
scaleY
(
1
)
.
setDuration
(
duration
)
.
setStartDelay
(
startDelay
)
.
withEndAction
(()
->
{
dot
.
animate
()
.
scaleX
(
0
)
.
scaleY
(
0
)
.
setDuration
(
duration
)
.
setStartDelay
(
0
)
.
withEndAction
(()
->
{
animateDot
(
dot
,
interval
,
duration
,
interval
);
})
.
start
();
})
.
start
();
}
private
void
cancel
(
)
{
for
(
View
dot
:
mDots
)
{
dot
.
clearAnimation
();
}
}
}
app/src/main/java/chat/rocket/android/ws/RocketChatWebSocketAPI.java
View file @
6007fd56
package
chat
.
rocket
.
android
.
ws
;
import
org.json.JSONArray
;
import
java.util.UUID
;
import
bolts.Task
;
import
chat.rocket.android.helper.OkHttpHelper
;
import
chat.rocket.android_ddp.DDPClient
;
import
chat.rocket.android_ddp.DDPClientCallback
;
import
chat.rocket.android_ddp.DDPSubscription
;
import
java.util.UUID
;
import
org.json.JSONArray
;
import
rx.Observable
;
/**
* API for several POST actions.
*/
public
class
RocketChatWebSocketAPI
{
private
final
DDPClient
mDDPClient
;
private
final
String
mHostName
;
private
RocketChatWebSocketAPI
(
String
hostname
)
{
mDDPClient
=
new
DDPClient
(
OkHttpHelper
.
getClientForWebSocket
());
mHostName
=
hostname
;
}
/**
* create new API client instance.
*/
public
static
RocketChatWebSocketAPI
create
(
String
hostname
)
{
return
new
RocketChatWebSocketAPI
(
hostname
);
}
private
final
DDPClient
mDDPClient
;
private
final
String
mHostName
;
/**
* Connect to WebSocket server with DDP client.
*/
public
Task
<
DDPClientCallback
.
Connect
>
connect
()
{
return
mDDPClient
.
connect
(
"wss://"
+
mHostName
+
"/websocket"
);
}
private
RocketChatWebSocketAPI
(
String
hostname
)
{
mDDPClient
=
new
DDPClient
(
OkHttpHelper
.
getClientForWebSocket
());
mHostName
=
hostname
;
}
/**
* Returns whether DDP client is connected to WebSocket server
.
*/
public
boolean
isConnected
(
)
{
return
mDDPClient
.
isConnected
(
);
}
/**
* create new API client instance
.
*/
public
static
RocketChatWebSocketAPI
create
(
String
hostname
)
{
return
new
RocketChatWebSocketAPI
(
hostname
);
}
/**
* close connection
.
*/
public
void
close
()
{
mDDPClient
.
close
(
);
}
/**
* Connect to WebSocket server with DDP client
.
*/
public
Task
<
DDPClientCallback
.
Connect
>
connect
()
{
return
mDDPClient
.
connect
(
"wss://"
+
mHostName
+
"/websocket"
);
}
/**
* Returns whether DDP client is connected to WebSocket server.
*/
public
boolean
isConnected
()
{
return
mDDPClient
.
isConnected
();
}
/**
* Subscribe with DDP client
.
*/
public
Task
<
DDPSubscription
.
Ready
>
subscribe
(
final
String
name
,
JSONArray
param
)
{
return
mDDPClient
.
sub
(
UUID
.
randomUUID
().
toString
(),
name
,
param
);
}
/**
* close connection
.
*/
public
void
close
(
)
{
mDDPClient
.
close
(
);
}
/**
* Uns
ubscribe with DDP client.
*/
public
Task
<
DDPSubscription
.
NoSub
>
unsubscribe
(
final
String
subscriptionId
)
{
return
mDDPClient
.
unsub
(
subscriptionId
);
}
/**
* S
ubscribe with DDP client.
*/
public
Task
<
DDPSubscription
.
Ready
>
subscribe
(
final
String
name
,
JSONArray
param
)
{
return
mDDPClient
.
sub
(
UUID
.
randomUUID
().
toString
(),
name
,
param
);
}
/**
* Returns Observable for handling DDP subscription
.
*/
public
Observable
<
DDPSubscription
.
Event
>
getSubscriptionCallback
(
)
{
return
mDDPClient
.
getSubscriptionCallback
(
);
}
/**
* Unsubscribe with DDP client
.
*/
public
Task
<
DDPSubscription
.
NoSub
>
unsubscribe
(
final
String
subscriptionId
)
{
return
mDDPClient
.
unsub
(
subscriptionId
);
}
/**
* Returns Observable for handling DDP subscription.
*/
public
Observable
<
DDPSubscription
.
Event
>
getSubscriptionCallback
()
{
return
mDDPClient
.
getSubscriptionCallback
();
}
}
app/src/main/res/drawable/ic_arrow_forward_white_24dp.xml
View file @
6007fd56
<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=
"#FFFFFFFF"
android:pathData=
"M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z"
/>
android:height
=
"24dp"
android:viewportHeight=
"24.0
"
android:viewportWidth=
"24.0"
android:width=
"24dp
"
>
<path
android:fillColor=
"#FFFFFFFF"
android:pathData=
"M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z"
/>
</vector>
app/src/main/res/drawable/selector_text_color_link.xml
View file @
6007fd56
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<!--item android:state_enabled="false" android:color="@color/textColorLink" /-->
<item
android:color=
"@color/textColorLink"
/>
<!--item android:state_enabled="false" android:color="@color/textColorLink" /-->
<item
android:color=
"@color/textColorLink"
/>
</selector>
\ No newline at end of file
app/src/main/res/drawable/userstatus_away.xml
View file @
6007fd56
<?xml version="1.0" encoding="utf-8"?>
<shape
android:shape=
"oval"
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<solid
android:color=
"@color/userstatus_away"
/>
<stroke
android:width=
"1dp"
android:color=
"@color/userstatus_away_outline"
/>
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:shape=
"oval"
>
<solid
android:color=
"@color/userstatus_away"
/>
<stroke
android:color=
"@color/userstatus_away_outline"
android:width=
"1dp"
/>
</shape>
app/src/main/res/drawable/userstatus_busy.xml
View file @
6007fd56
<?xml version="1.0" encoding="utf-8"?>
<shape
android:shape=
"oval"
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<solid
android:color=
"@color/userstatus_busy"
/>
<stroke
android:width=
"1dp"
android:color=
"@color/userstatus_busy_outline"
/>
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:shape=
"oval"
>
<solid
android:color=
"@color/userstatus_busy"
/>
<stroke
android:color=
"@color/userstatus_busy_outline"
android:width=
"1dp"
/>
</shape>
app/src/main/res/drawable/userstatus_offline.xml
View file @
6007fd56
<?xml version="1.0" encoding="utf-8"?>
<shape
android:shape=
"oval"
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<solid
android:color=
"@color/userstatus_offline"
/>
<stroke
android:width=
"1dp"
android:color=
"@color/userstatus_offline_outline"
/>
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:shape=
"oval"
>
<solid
android:color=
"@color/userstatus_offline"
/>
<stroke
android:color=
"@color/userstatus_offline_outline"
android:width=
"1dp"
/>
</shape>
app/src/main/res/drawable/userstatus_online.xml
View file @
6007fd56
<?xml version="1.0" encoding="utf-8"?>
<shape
android:shape=
"oval"
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<solid
android:color=
"@color/userstatus_online"
/>
<stroke
android:width=
"1dp"
android:color=
"@color/userstatus_online_outline"
/>
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:shape=
"oval"
>
<solid
android:color=
"@color/userstatus_online"
/>
<stroke
android:color=
"@color/userstatus_online_outline"
android:width=
"1dp"
/>
</shape>
app/src/main/res/drawable/white_circle.xml
View file @
6007fd56
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:shape=
"oval"
>
<solid
android:color=
"@android:color/white"
/>
<solid
android:color=
"@android:color/white"
/>
</shape>
app/src/main/res/layout-w720dp/activity_main.xml
View file @
6007fd56
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
<LinearLayout
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=
"match_parent"
>
android:layout_height=
"match_parent"
>
<include
layout=
"@layout/sidebar"
/>
<include
layout=
"@layout/sidebar"
/>
<android.support.design.widget.CoordinatorLayout
<android.support.design.widget.CoordinatorLayout
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
<android.support.design.widget.AppBarLayout
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
android:layout_height=
"wrap_content"
>
<android.support.design.widget.AppBarLayout
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
<android.support.v7.widget.Toolbar
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:theme=
"@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme=
"@style/ThemeOverlay.AppCompat.Light"
app:title=
"@string/app_name"
/>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.Toolbar
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:theme=
"@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme=
"@style/ThemeOverlay.AppCompat.Light"
app:title=
"@string/app_name"
/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id=
"@+id/activity_main_container"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"@color/white"
app:layout_behavior=
"@string/appbar_scrolling_view_behavior"
>
</FrameLayout>
<FrameLayout
android:id=
"@+id/activity_main_container"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"@color/white"
app:layout_behavior=
"@string/appbar_scrolling_view_behavior"
>
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
</android.support.design.widget.CoordinatorLayout>
</LinearLayout>
\ No newline at end of file
app/src/main/res/layout/activity_main.xml
View file @
6007fd56
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SlidingPaneLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
<android.support.v4.widget.SlidingPaneLayout
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=
"match_parent"
>
android:layout_height=
"match_parent"
>
<include
layout=
"@layout/sidebar"
/>
<include
layout=
"@layout/sidebar"
/>
<android.support.design.widget.CoordinatorLayout
<android.support.design.widget.CoordinatorLayout
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
<android.support.design.widget.AppBarLayout
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
android:layout_height=
"wrap_content"
>
<android.support.design.widget.AppBarLayout
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
>
<android.support.v7.widget.Toolbar
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:theme=
"@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme=
"@style/ThemeOverlay.AppCompat.Light"
app:title=
"@string/app_name"
/>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.Toolbar
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:theme=
"@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme=
"@style/ThemeOverlay.AppCompat.Light"
app:title=
"@string/app_name"
/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id=
"@+id/activity_main_container"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"@color/white"
app:layout_behavior=
"@string/appbar_scrolling_view_behavior"
>
</FrameLayout>
<FrameLayout
android:id=
"@+id/activity_main_container"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"@color/white"
app:layout_behavior=
"@string/appbar_scrolling_view_behavior"
>
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
</android.support.design.widget.CoordinatorLayout>
</android.support.v4.widget.SlidingPaneLayout>
\ No newline at end of file
app/src/main/res/layout/avatar_container_large.xml
View file @
6007fd56
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"@dimen/avatar_image_size_large"
android:layout_height=
"@dimen/avatar_image_size_large"
>
android:layout_width=
"@dimen/avatar_image_size_large"
android:layout_height=
"@dimen/avatar_image_size_large"
>
<FrameLayout
android:id=
"@+id/avatar_color"
android:layout_width=
"@dimen/avatar_image_size_large"
android:layout_height=
"@dimen/avatar_image_size_large"
android:layout_gravity=
"center"
>
<TextView
android:id=
"@+id/avatar_initials"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:textSize=
"@dimen/avatar_text_size_large"
android:layout_gravity=
"center"
/>
</FrameLayout>
<FrameLayout
android:id=
"@+id/avatar_color"
android:layout_width=
"@dimen/avatar_image_size_large"
android:layout_height=
"@dimen/avatar_image_size_large"
android:layout_gravity=
"center"
>
<ImageView
android:id=
"@+id/avatar_img"
android:layout_width=
"@dimen/avatar_image_size_large"
android:layout_height=
"@dimen/avatar_image_size_large"
android:src=
"@drawable/ic_default_avatar"
android:scaleType=
"centerInside"
/>
<TextView
android:id=
"@+id/avatar_initials"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
android:textSize=
"@dimen/avatar_text_size_large"
/>
</FrameLayout>
<ImageView
android:id=
"@+id/avatar_img"
android:layout_width=
"@dimen/avatar_image_size_large"
android:layout_height=
"@dimen/avatar_image_size_large"
android:scaleType=
"centerInside"
android:src=
"@drawable/ic_default_avatar"
/>
</FrameLayout>
\ No newline at end of file
app/src/main/res/layout/avatar_container_normal.xml
View file @
6007fd56
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"@dimen/avatar_image_size_normal"
android:layout_height=
"@dimen/avatar_image_size_normal"
>
android:layout_width=
"@dimen/avatar_image_size_normal"
android:layout_height=
"@dimen/avatar_image_size_normal"
>
<FrameLayout
android:id=
"@+id/avatar_color"
android:layout_width=
"@dimen/avatar_image_size_normal"
android:layout_height=
"@dimen/avatar_image_size_normal"
android:layout_gravity=
"center"
>
<TextView
android:id=
"@+id/avatar_initials"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:textSize=
"@dimen/avatar_text_size_normal"
android:layout_gravity=
"center"
/>
</FrameLayout>
<FrameLayout
android:id=
"@+id/avatar_color"
android:layout_width=
"@dimen/avatar_image_size_normal"
android:layout_height=
"@dimen/avatar_image_size_normal"
android:layout_gravity=
"center"
>
<ImageView
android:id=
"@+id/avatar_img"
android:layout_width=
"@dimen/avatar_image_size_normal"
android:layout_height=
"@dimen/avatar_image_size_normal"
android:src=
"@drawable/ic_default_avatar"
android:scaleType=
"centerInside"
/>
<TextView
android:id=
"@+id/avatar_initials"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
android:textSize=
"@dimen/avatar_text_size_normal"
/>
</FrameLayout>
<ImageView
android:id=
"@+id/avatar_img"
android:layout_width=
"@dimen/avatar_image_size_normal"
android:layout_height=
"@dimen/avatar_image_size_normal"
android:scaleType=
"centerInside"
android:src=
"@drawable/ic_default_avatar"
/>
</FrameLayout>
\ No newline at end of file
app/src/main/res/layout/fragment_input_hostname.xml
View file @
6007fd56
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
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=
"match_parent"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
android:background=
"?attr/colorPrimaryDark"
>
android:background=
"?attr/colorPrimaryDark"
>
<LinearLayout
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
android:background=
"@color/white"
android:minWidth=
"288dp"
android:orientation=
"horizontal"
android:padding=
"@dimen/margin_24"
>
<LinearLayout
android:layout_width=
"wrap_content"
android:minWidth=
"288dp"
android:layout_width=
"0px"
android:layout_height=
"wrap_content"
android:orientation=
"horizontal"
android:background=
"@color/white"
android:padding=
"@dimen/margin_24"
android:layout_gravity=
"center"
>
<LinearLayout
android:layout_width=
"0px"
android:layout_weight=
"1"
android:layout_height=
"wrap_content"
android:orientation=
"vertical"
>
<TextView
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:text=
"hostname"
android:textAppearance=
"@style/TextAppearance.AppCompat.Caption"
/>
<EditText
android:id=
"@+id/editor_hostname"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:singleLine=
"true"
android:hint=
"demo.rocket.chat"
android:imeOptions=
"actionGo"
android:inputType=
"textWebEditText"
/>
</LinearLayout>
android:layout_weight=
"1"
android:orientation=
"vertical"
>
<Space
android:layout_width=
"@dimen/margin_8"
android:layout_height=
"wrap_content"
/>
<TextView
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:text=
"hostname"
android:textAppearance=
"@style/TextAppearance.AppCompat.Caption"
/>
<android.support.design.widget.FloatingActionButton
android:id=
"@+id/btn_connect"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
app:fabSize=
"mini"
app:srcCompat=
"@drawable/ic_arrow_forward_white_24dp"
app:elevation=
"2dp"
android:layout_gravity=
"end|bottom"
/>
<EditText
android:id=
"@+id/editor_hostname"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:hint=
"demo.rocket.chat"
android:imeOptions=
"actionGo"
android:inputType=
"textWebEditText"
android:singleLine=
"true"
/>
</LinearLayout>
<Space
android:layout_width=
"@dimen/margin_8"
android:layout_height=
"wrap_content"
/>
<android.support.design.widget.FloatingActionButton
android:id=
"@+id/btn_connect"
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"
/>
</LinearLayout>
</FrameLayout>
\ No newline at end of file
app/src/main/res/layout/fragment_wait_for_connection.xml
View file @
6007fd56
...
...
@@ -2,10 +2,12 @@
<FrameLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"?attr/colorPrimaryDark"
>
android:background=
"?attr/colorPrimaryDark"
>
<chat.rocket.android.view.WaitingView
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
/>
<chat.rocket.android.view.WaitingView
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
/>
</FrameLayout>
\ No newline at end of file
app/src/main/res/layout/sidebar.xml
View file @
6007fd56
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"288dp"
android:layout_height=
"match_parent"
android:layout_gravity=
"start"
android:background=
"?attr/colorPrimary"
android:orientation=
"vertical"
android:theme=
"@style/AppTheme.Dark"
>
android:theme=
"@style/AppTheme.Dark"
>
<LinearLayout
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:background=
"?attr/colorPrimaryDark"
android:orientation=
"vertical"
>
<LinearLayout
android:id=
"@+id/user_info_container"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:orientation=
"vertical"
android:background=
"?attr/colorPrimaryDark"
>
<LinearLayout
android:id=
"@+id/user_info_container"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:orientation=
"horizontal"
android:gravity=
"center_vertical"
android:padding=
"@dimen/margin_16"
android:background=
"?attr/selectableItemBackground"
>
android:background=
"?attr/selectableItemBackground"
android:gravity=
"center_vertical"
android:orientation=
"horizontal"
android:padding=
"@dimen/margin_16"
>
<ImageView
android:id=
"@+id/img_userstatus"
android:layout_width=
"8dp"
android:layout_height=
"8dp"
android:src=
"@drawable/userstatus_online"
/>
<ImageView
android:id=
"@+id/img_userstatus"
android:layout_width=
"8dp"
android:layout_height=
"8dp"
android:src=
"@drawable/userstatus_online"
/>
<Space
android:layout_width=
"@dimen/margin_8"
android:layout_height=
"wrap_content"
/>
<Space
android:layout_width=
"@dimen/margin_8"
android:layout_height=
"wrap_content"
/>
<include
layout=
"@layout/avatar_container_large"
/>
<include
layout=
"@layout/avatar_container_large"
/>
<FrameLayout
android:layout_width=
"0px"
android:layout_height=
"wrap_content"
android:layout_weight=
"1"
android:layout_marginLeft=
"@dimen/margin_8"
android:layout_marginRight=
"@dimen/margin_8"
>
<FrameLayout
android:layout_width=
"0px"
android:layout_height=
"wrap_content"
android:layout_marginLeft=
"@dimen/margin_8"
android:layout_marginRight=
"@dimen/margin_8"
android:layout_weight=
"1"
>
<TextView
android:id=
"@+id/txt_account_info"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:textSize=
"14sp"
android:layout_gravity=
"center_vertical"
android:text=
"John Doe"
/>
<TextView
android:id=
"@+id/txt_account_info"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center_vertical"
android:text=
"John Doe"
android:textSize=
"14sp"
/>
</FrameLayout>
</FrameLayout>
<chat.rocket.android.view.FontAwesomeTextView
android:id=
"@+id/img_user_action_toggle"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:text=
"@string/fa_chevron_down"
android:textSize=
"16dp"
/>
<chat.rocket.android.view.FontAwesomeTextView
android:id=
"@+id/img_user_action_toggle"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:text=
"@string/fa_chevron_down"
android:textSize=
"16dp"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
\ No newline at end of file
app/src/main/res/layout/simple_screen.xml
View file @
6007fd56
...
...
@@ -2,6 +2,7 @@
<FrameLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:id=
"@+id/content"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
android:layout_height=
"match_parent"
>
</FrameLayout>
\ No newline at end of file
app/src/main/res/values/colors.xml
View file @
6007fd56
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color
name=
"colorPrimary"
>
#00426B
</color>
<color
name=
"colorPrimaryDark"
>
#FF001E31
</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=
"colorPrimary"
>
#00426B
</color>
<color
name=
"colorPrimaryDark"
>
#FF001E31
</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=
"divider"
>
#FFEEEEEE
</color>
<color
name=
"divider"
>
#FFEEEEEE
</color>
<color
name=
"white"
>
#FFFEFEFF
</color>
<color
name=
"white"
>
#FFFEFEFF
</color>
</resources>
app/src/main/res/values/dimens.xml
View file @
6007fd56
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen
name=
"avatar_image_size_normal"
>
24dp
</dimen>
<dimen
name=
"avatar_image_size_large"
>
48dp
</dimen>
<dimen
name=
"avatar_text_size_normal"
>
11sp
</dimen>
<dimen
name=
"avatar_text_size_large"
>
28sp
</dimen>
<dimen
name=
"avatar_image_size_normal"
>
24dp
</dimen>
<dimen
name=
"avatar_image_size_large"
>
48dp
</dimen>
<dimen
name=
"avatar_text_size_normal"
>
11sp
</dimen>
<dimen
name=
"avatar_text_size_large"
>
28sp
</dimen>
</resources>
\ No newline at end of file
app/src/main/res/values/fa_strings.xml
View file @
6007fd56
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string
translatable=
"false"
name=
"fa_chevron_down
"
>

</string>
<string
name=
"fa_chevron_down"
translatable=
"false
"
>

</string>
</resources>
\ No newline at end of file
app/src/main/res/values/margin_dimens.xml
View file @
6007fd56
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen
name=
"margin_8"
>
8dp
</dimen>
<dimen
name=
"margin_16"
>
16dp
</dimen>
<dimen
name=
"margin_24"
>
24dp
</dimen>
<dimen
name=
"margin_8"
>
8dp
</dimen>
<dimen
name=
"margin_16"
>
16dp
</dimen>
<dimen
name=
"margin_24"
>
24dp
</dimen>
</resources>
\ No newline at end of file
app/src/main/res/values/strings.xml
View file @
6007fd56
<resources>
<string
name=
"app_name"
>
Rocket.Chat.Android
</string>
<string
name=
"app_name"
>
Rocket.Chat.Android
</string>
</resources>
app/src/main/res/values/styles.xml
View file @
6007fd56
<resources
xmlns:tools=
"http://schemas.android.com/tools"
>
<!-- Base application theme. -->
<style
name=
"AppTheme"
parent=
"Theme.AppCompat.Light.NoActionBar"
>
<item
name=
"colorPrimary"
>
@color/colorPrimary
</item>
<item
name=
"colorPrimaryDark"
>
@color/colorPrimaryDark
</item>
<item
name=
"colorAccent"
>
@color/colorAccent
</item>
<item
name=
"android:textColorLink"
>
@drawable/selector_text_color_link
</item>
<item
name=
"android:listDivider"
>
@color/divider
</item>
<item
name=
"colorControlActivated"
>
@color/colorAccentDark
</item>
<item
name=
"android:textColorHighlight"
>
@color/colorAccent_a40
</item>
<item
name=
"actionModeBackground"
>
?attr/colorPrimaryDark
</item>
<item
name=
"android:statusBarColor"
tools:targetApi=
"21"
>
?attr/colorPrimaryDark
</item>
<item
name=
"android:navigationBarColor"
tools:targetApi=
"21"
>
?attr/colorPrimaryDark
</item>
</style>
<style
name=
"AppTheme.Dark"
parent=
"Theme.AppCompat.NoActionBar"
>
<item
name=
"colorPrimary"
>
@color/colorPrimary
</item>
<item
name=
"colorPrimaryDark"
>
@color/colorPrimaryDark
</item>
<item
name=
"colorAccent"
>
@color/colorAccent
</item>
<item
name=
"android:textColorLink"
>
@drawable/selector_text_color_link
</item>
<item
name=
"android:listDivider"
>
@color/divider
</item>
<item
name=
"colorControlActivated"
>
@color/colorAccentDark
</item>
<item
name=
"android:textColorHighlight"
>
@color/colorAccent_a40
</item>
<item
name=
"actionModeBackground"
>
?attr/colorPrimaryDark
</item>
<item
name=
"android:statusBarColor"
tools:targetApi=
"21"
>
?attr/colorPrimaryDark
</item>
<item
name=
"android:navigationBarColor"
tools:targetApi=
"21"
>
?attr/colorPrimaryDark
</item>
</style>
<style
name=
"AppTheme.Dialog"
parent=
"Theme.AppCompat.Light.Dialog"
>
<item
name=
"colorPrimary"
>
@color/colorPrimary
</item>
<item
name=
"colorPrimaryDark"
>
@color/colorPrimaryDark
</item>
<item
name=
"colorAccent"
>
@color/colorAccent
</item>
<item
name=
"android:textColorLink"
>
@drawable/selector_text_color_link
</item>
<item
name=
"android:listDivider"
>
@color/divider
</item>
<item
name=
"colorControlActivated"
>
@color/colorAccentDark
</item>
<item
name=
"android:textColorHighlight"
>
@color/colorAccent_a40
</item>
</style>
<!-- Base application theme. -->
<style
name=
"AppTheme"
parent=
"Theme.AppCompat.Light.NoActionBar"
>
<item
name=
"colorPrimary"
>
@color/colorPrimary
</item>
<item
name=
"colorPrimaryDark"
>
@color/colorPrimaryDark
</item>
<item
name=
"colorAccent"
>
@color/colorAccent
</item>
<item
name=
"android:textColorLink"
>
@drawable/selector_text_color_link
</item>
<item
name=
"android:listDivider"
>
@color/divider
</item>
<item
name=
"colorControlActivated"
>
@color/colorAccentDark
</item>
<item
name=
"android:textColorHighlight"
>
@color/colorAccent_a40
</item>
<item
name=
"actionModeBackground"
>
?attr/colorPrimaryDark
</item>
<item
name=
"android:statusBarColor"
tools:targetApi=
"21"
>
?attr/colorPrimaryDark
</item>
<item
name=
"android:navigationBarColor"
tools:targetApi=
"21"
>
?attr/colorPrimaryDark
</item>
</style>
<style
name=
"AppTheme.Dark"
parent=
"Theme.AppCompat.NoActionBar"
>
<item
name=
"colorPrimary"
>
@color/colorPrimary
</item>
<item
name=
"colorPrimaryDark"
>
@color/colorPrimaryDark
</item>
<item
name=
"colorAccent"
>
@color/colorAccent
</item>
<item
name=
"android:textColorLink"
>
@drawable/selector_text_color_link
</item>
<item
name=
"android:listDivider"
>
@color/divider
</item>
<item
name=
"colorControlActivated"
>
@color/colorAccentDark
</item>
<item
name=
"android:textColorHighlight"
>
@color/colorAccent_a40
</item>
<item
name=
"actionModeBackground"
>
?attr/colorPrimaryDark
</item>
<item
name=
"android:statusBarColor"
tools:targetApi=
"21"
>
?attr/colorPrimaryDark
</item>
<item
name=
"android:navigationBarColor"
tools:targetApi=
"21"
>
?attr/colorPrimaryDark
</item>
</style>
<style
name=
"AppTheme.Dialog"
parent=
"Theme.AppCompat.Light.Dialog"
>
<item
name=
"colorPrimary"
>
@color/colorPrimary
</item>
<item
name=
"colorPrimaryDark"
>
@color/colorPrimaryDark
</item>
<item
name=
"colorAccent"
>
@color/colorAccent
</item>
<item
name=
"android:textColorLink"
>
@drawable/selector_text_color_link
</item>
<item
name=
"android:listDivider"
>
@color/divider
</item>
<item
name=
"colorControlActivated"
>
@color/colorAccentDark
</item>
<item
name=
"android:textColorHighlight"
>
@color/colorAccent_a40
</item>
</style>
</resources>
app/src/main/res/values/user_status_colors.xml
View file @
6007fd56
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color
name=
"userstatus_online"
>
#35ac19
</color>
<color
name=
"userstatus_online_outline"
>
#2c9210
</color>
<color
name=
"userstatus_away"
>
#fcb316
</color>
<color
name=
"userstatus_away_outline"
>
#e69200
</color>
<color
name=
"userstatus_busy"
>
#d30230
</color>
<color
name=
"userstatus_busy_outline"
>
#9f0030
</color>
<color
name=
"userstatus_offline"
>
#7b7b7b
</color>
<color
name=
"userstatus_offline_outline"
>
#666
</color>
<color
name=
"userstatus_online"
>
#35ac19
</color>
<color
name=
"userstatus_online_outline"
>
#2c9210
</color>
<color
name=
"userstatus_away"
>
#fcb316
</color>
<color
name=
"userstatus_away_outline"
>
#e69200
</color>
<color
name=
"userstatus_busy"
>
#d30230
</color>
<color
name=
"userstatus_busy_outline"
>
#9f0030
</color>
<color
name=
"userstatus_offline"
>
#7b7b7b
</color>
<color
name=
"userstatus_offline_outline"
>
#666
</color>
</resources>
\ No newline at end of file
app/src/main/res/values/waiting_view_attrs.xml
View file @
6007fd56
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable
name=
"WaitingView"
>
<attr
name=
"dotSize"
format=
"dimension"
/>
<attr
name=
"dotCount"
format=
"integer"
/>
</declare-styleable>
<dimen
name=
"def_waiting_view_dot_size"
>
16dp
</dimen>
<declare-styleable
name=
"WaitingView"
>
<attr
format=
"dimension"
name=
"dotSize"
/>
<attr
format=
"integer"
name=
"dotCount"
/>
</declare-styleable>
<dimen
name=
"def_waiting_view_dot_size"
>
16dp
</dimen>
</resources>
\ No newline at end of file
build.gradle
View file @
6007fd56
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript
{
repositories
{
jcenter
()
mavenCentral
()
}
dependencies
{
classpath
'com.android.tools.build:gradle:2.2.2'
repositories
{
jcenter
()
mavenCentral
()
}
dependencies
{
classpath
'com.android.tools.build:gradle:2.2.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath
'me.tatarka:gradle-retrolambda:3.3.1'
classpath
'me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2'
classpath
"io.realm:realm-gradle-plugin:2.1.1"
classpath
'com.jakewharton.hugo:hugo-plugin:1.2.1'
}
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath
'me.tatarka:gradle-retrolambda:3.3.1'
classpath
'me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2'
classpath
"io.realm:realm-gradle-plugin:2.1.1"
classpath
'com.jakewharton.hugo:hugo-plugin:1.2.1'
}
// Exclude the version that the android plugin depends on.
configurations
.
classpath
.
exclude
group:
'com.android.tools.external.lombok'
// Exclude the version that the android plugin depends on.
configurations
.
classpath
.
exclude
group:
'com.android.tools.external.lombok'
}
allprojects
{
repositories
{
jcenter
()
}
repositories
{
jcenter
()
}
}
task
clean
(
type:
Delete
)
{
delete
rootProject
.
buildDir
delete
rootProject
.
buildDir
}
config/quality/checkstyle/checkstyle-suppressions.xml
deleted
100644 → 0
View file @
352f0c01
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
<!-- suppress some checks for classes extending RealmObject -->
<suppress
checks=
"MemberName|JavadocMethod"
files=
"chat[\\/]rocket[\\/]android[\\/]model"
/>
</suppressions>
\ No newline at end of file
config/quality/findbugs/android-exclude-filter.xml
View file @
6007fd56
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
<Match>
<Class
name=
"~.*\.R\$.*"
/>
</Match>
<Match>
<Class
name=
"~.*\.Manifest\$.*"
/>
</Match>
<!-- All bugs in test classes, except for JUnit-specific bugs -->
<Match>
<Class
name=
"~.*\.*Test"
/>
<Not>
<Bug
code=
"IJU"
/>
</Not>
</Match>
<Match>
<Class
name=
"~.*\.R\$.*"
/>
</Match>
<Match>
<Class
name=
"~.*\.Manifest\$.*"
/>
</Match>
<!-- All bugs in test classes, except for JUnit-specific bugs -->
<Match>
<Class
name=
"~.*\.*Test"
/>
<Not>
<Bug
code=
"IJU"
/>
</Not>
</Match>
</FindBugsFilter>
\ No newline at end of file
config/quality/pmd/pmd-ruleset.xml
View file @
6007fd56
...
...
@@ -4,25 +4,25 @@
xsi:noNamespaceSchemaLocation=
"http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:schemaLocation=
"http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
>
<description>
Custom ruleset for Rocket.Chat.Android application
</description>
<description>
Custom ruleset for Rocket.Chat.Android application
</description>
<exclude-pattern>
.*/R.java
</exclude-pattern>
<exclude-pattern>
.*/gen/.*
</exclude-pattern>
<exclude-pattern>
.*/R.java
</exclude-pattern>
<exclude-pattern>
.*/gen/.*
</exclude-pattern>
<rule
ref=
"rulesets/java/android.xml"
/>
<rule
ref=
"rulesets/java/clone.xml"
/>
<rule
ref=
"rulesets/java/finalizers.xml"
/>
<rule
ref=
"rulesets/java/imports.xml"
>
<!-- Espresso is designed this way !-->
<exclude
name=
"TooManyStaticImports"
/>
</rule>
<rule
ref=
"rulesets/java/basic.xml"
/>
<rule
ref=
"rulesets/java/naming.xml"
>
<!--<exclude name="AbstractNaming" />-->
<exclude
name=
"LongVariable"
/>
<!--exclude name="ShortMethodName" /-->
<!--exclude name="ShortVariable" /-->
<!--<exclude name="ShortClassName" />-->
<!--<exclude name="VariableNamingConventions" />-->
</rule>
<rule
ref=
"rulesets/java/android.xml"
/>
<rule
ref=
"rulesets/java/clone.xml"
/>
<rule
ref=
"rulesets/java/finalizers.xml"
/>
<rule
ref=
"rulesets/java/imports.xml"
>
<!-- Espresso is designed this way !-->
<exclude
name=
"TooManyStaticImports"
/>
</rule>
<rule
ref=
"rulesets/java/basic.xml"
/>
<rule
ref=
"rulesets/java/naming.xml"
>
<!--<exclude name="AbstractNaming" />-->
<exclude
name=
"LongVariable"
/>
<!--exclude name="ShortMethodName" /-->
<!--exclude name="ShortVariable" /-->
<!--<exclude name="ShortClassName" />-->
<!--<exclude name="VariableNamingConventions" />-->
</rule>
</ruleset>
\ No newline at end of file
config/quality/quality.gradle
View file @
6007fd56
...
...
@@ -7,15 +7,14 @@
* - pmd
*
* The three tasks above are added as dependencies of the check task so running check will
* run all of them.
*/
* run all of them.*/
apply
plugin:
'checkstyle'
apply
plugin:
'findbugs'
apply
plugin:
'pmd'
dependencies
{
checkstyle
'com.puppycrawl.tools:checkstyle:7.2'
checkstyle
'com.puppycrawl.tools:checkstyle:7.2'
}
def
qualityConfigDir
=
"$project.rootDir/config/quality"
;
...
...
@@ -24,67 +23,67 @@ def reportsDir = "$project.buildDir/reports"
check
.
dependsOn
'checkstyle'
,
'findbugs'
,
'pmd'
task
checkstyle
(
type:
Checkstyle
,
group:
'Verification'
,
description:
'Runs code style checks'
)
{
configFile
file
(
"$qualityConfigDir/checkstyle/checkstyle-config.xml"
)
source
'src'
include
'**/*.java'
reports
{
xml
.
enabled
=
true
xml
{
destination
"$reportsDir/checkstyle/checkstyle.xml"
}
configFile
file
(
"$qualityConfigDir/checkstyle/checkstyle-config.xml"
)
source
'src'
include
'**/*.java'
reports
{
xml
.
enabled
=
true
xml
{
destination
"$reportsDir/checkstyle/checkstyle.xml"
}
}
classpath
=
files
(
)
classpath
=
files
(
)
}
task
findbugs
(
type:
FindBugs
,
group:
'Verification'
,
description:
'Inspect java bytecode for bugs'
,
dependsOn:
[
'compileDebugSources'
,
'compileReleaseSources'
])
{
ignoreFailures
=
false
effort
=
"max"
reportLevel
=
"high"
excludeFilter
=
new
File
(
"$qualityConfigDir/findbugs/android-exclude-filter.xml"
)
classes
=
files
(
"$project.rootDir/app/build/intermediates/classes"
)
source
'src'
include
'**/*.java'
exclude
'**/gen/**'
reports
{
xml
.
enabled
=
false
html
.
enabled
=
true
xml
{
destination
"$reportsDir/findbugs/findbugs.xml"
}
html
{
destination
"$reportsDir/findbugs/findbugs.html"
}
group:
'Verification'
,
description:
'Inspect java bytecode for bugs'
,
dependsOn:
[
'compileDebugSources'
,
'compileReleaseSources'
])
{
ignoreFailures
=
false
effort
=
"max"
reportLevel
=
"high"
excludeFilter
=
new
File
(
"$qualityConfigDir/findbugs/android-exclude-filter.xml"
)
classes
=
files
(
"$project.rootDir/app/build/intermediates/classes"
)
source
'src'
include
'**/*.java'
exclude
'**/gen/**'
reports
{
xml
.
enabled
=
false
html
.
enabled
=
true
xml
{
destination
"$reportsDir/findbugs/findbugs.xml"
}
html
{
destination
"$reportsDir/findbugs/findbugs.html"
}
}
classpath
=
files
()
classpath
=
files
()
}
task
pmd
(
type:
Pmd
,
group:
'Verification'
,
description:
'Inspect sourcecode for bugs'
)
{
ruleSetFiles
=
files
(
"$qualityConfigDir/pmd/pmd-ruleset.xml"
)
ignoreFailures
=
false
ruleSets
=
[]
source
'src'
include
'**/*.java'
exclude
'**/gen/**'
reports
{
xml
.
enabled
=
true
html
.
enabled
=
true
xml
{
destination
"$reportsDir/pmd/pmd.xml"
}
html
{
destination
"$reportsDir/pmd/pmd.html"
}
ruleSetFiles
=
files
(
"$qualityConfigDir/pmd/pmd-ruleset.xml"
)
ignoreFailures
=
false
ruleSets
=
[]
source
'src'
include
'**/*.java'
exclude
'**/gen/**'
reports
{
xml
.
enabled
=
true
html
.
enabled
=
true
xml
{
destination
"$reportsDir/pmd/pmd.xml"
}
html
{
destination
"$reportsDir/pmd/pmd.html"
}
}
}
gradle.properties
View file @
6007fd56
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs
=
-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
...
...
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