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
f136cf38
Unverified
Commit
f136cf38
authored
Mar 30, 2018
by
divyanshu bhargava
Committed by
GitHub
Mar 30, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop-2.x' into lang-hindi
parents
3d2ec050
03b36264
Changes
101
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
101 changed files
with
1971 additions
and
676 deletions
+1971
-676
build.gradle
app/build.gradle
+1
-0
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+4
-0
RocketChatApplication.kt
...ain/java/chat/rocket/android/app/RocketChatApplication.kt
+188
-19
RealmMigration.kt
.../java/chat/rocket/android/app/migration/RealmMigration.kt
+59
-0
RocketChatLibraryModule.kt
...t/rocket/android/app/migration/RocketChatLibraryModule.kt
+6
-0
RocketChatServerModule.kt
...at/rocket/android/app/migration/RocketChatServerModule.kt
+7
-0
RealmBasedServerInfo.kt
...ocket/android/app/migration/model/RealmBasedServerInfo.kt
+12
-0
RealmEmail.kt
...ava/chat/rocket/android/app/migration/model/RealmEmail.kt
+12
-0
RealmPreferences.kt
...at/rocket/android/app/migration/model/RealmPreferences.kt
+40
-0
RealmPublicSetting.kt
.../rocket/android/app/migration/model/RealmPublicSetting.kt
+20
-0
RealmSession.kt
...a/chat/rocket/android/app/migration/model/RealmSession.kt
+16
-0
RealmSettings.kt
.../chat/rocket/android/app/migration/model/RealmSettings.kt
+12
-0
RealmUser.kt
...java/chat/rocket/android/app/migration/model/RealmUser.kt
+38
-0
AuthenticationModule.kt
.../rocket/android/authentication/di/AuthenticationModule.kt
+1
-2
TokenModel.kt
.../rocket/android/authentication/domain/model/TokenModel.kt
+4
-1
MemoryTokenRepository.kt
...d/authentication/infraestructure/MemoryTokenRepository.kt
+0
-16
SharedPreferencesTokenRepository.kt
...ation/infraestructure/SharedPreferencesTokenRepository.kt
+82
-0
LoginPresenter.kt
...droid/authentication/login/presentation/LoginPresenter.kt
+34
-9
AuthenticationNavigator.kt
...id/authentication/presentation/AuthenticationNavigator.kt
+11
-4
AuthenticationPresenter.kt
...id/authentication/presentation/AuthenticationPresenter.kt
+19
-13
ServerPresenter.kt
...oid/authentication/server/presentation/ServerPresenter.kt
+10
-1
ServerFragment.kt
...rocket/android/authentication/server/ui/ServerFragment.kt
+12
-4
SignupPresenter.kt
...oid/authentication/signup/presentation/SignupPresenter.kt
+24
-4
SignupFragment.kt
...rocket/android/authentication/signup/ui/SignupFragment.kt
+6
-2
TwoFAPresenter.kt
...d/authentication/twofactor/presentation/TwoFAPresenter.kt
+32
-13
TwoFAFragment.kt
...cket/android/authentication/twofactor/ui/TwoFAFragment.kt
+9
-3
AuthenticationActivity.kt
...ocket/android/authentication/ui/AuthenticationActivity.kt
+31
-11
AutoCompleteType.kt
.../chat/rocket/android/chatroom/adapter/AutoCompleteType.kt
+2
-2
MessageReactionsAdapter.kt
...ocket/android/chatroom/adapter/MessageReactionsAdapter.kt
+1
-1
ChatRoomPresenter.kt
...rocket/android/chatroom/presentation/ChatRoomPresenter.kt
+3
-3
ChatRoomFragment.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
+9
-3
PinnedMessagesFragment.kt
...chat/rocket/android/chatroom/ui/PinnedMessagesFragment.kt
+6
-2
ViewModelMapper.kt
...chat/rocket/android/chatroom/viewmodel/ViewModelMapper.kt
+9
-6
ChatRoomsPresenter.kt
...cket/android/chatrooms/presentation/ChatRoomsPresenter.kt
+1
-1
ChatRoomsFragment.kt
...ava/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
+6
-2
AppComponent.kt
app/src/main/java/chat/rocket/android/dagger/AppComponent.kt
+3
-1
ActivityBuilder.kt
...java/chat/rocket/android/dagger/module/ActivityBuilder.kt
+6
-0
AppModule.kt
.../main/java/chat/rocket/android/dagger/module/AppModule.kt
+44
-9
ReceiverBuilder.kt
...java/chat/rocket/android/dagger/module/ReceiverBuilder.kt
+13
-0
ServiceBuilder.kt
.../java/chat/rocket/android/dagger/module/ServiceBuilder.kt
+5
-0
FrescoAuthInterceptor.kt
.../java/chat/rocket/android/helper/FrescoAuthInterceptor.kt
+18
-12
UrlHelper.kt
app/src/main/java/chat/rocket/android/helper/UrlHelper.kt
+10
-0
LocalRepository.kt
...ava/chat/rocket/android/infrastructure/LocalRepository.kt
+15
-9
SharedPrefsLocalRepository.kt
...cket/android/infrastructure/SharedPrefsLocalRepository.kt
+19
-10
AccountViewHolder.kt
...ava/chat/rocket/android/main/adapter/AccountViewHolder.kt
+16
-0
AccountsAdapter.kt
.../java/chat/rocket/android/main/adapter/AccountsAdapter.kt
+54
-0
AddAccountViewHolder.kt
.../chat/rocket/android/main/adapter/AddAccountViewHolder.kt
+6
-0
MainModule.kt
app/src/main/java/chat/rocket/android/main/di/MainModule.kt
+1
-1
MainNavigator.kt
...va/chat/rocket/android/main/presentation/MainNavigator.kt
+13
-2
MainPresenter.kt
...va/chat/rocket/android/main/presentation/MainPresenter.kt
+73
-12
MainView.kt
...in/java/chat/rocket/android/main/presentation/MainView.kt
+4
-5
MainActivity.kt
...src/main/java/chat/rocket/android/main/ui/MainActivity.kt
+61
-7
NavHeaderViewModel.kt
.../chat/rocket/android/main/viewmodel/NavHeaderViewModel.kt
+8
-0
NavHeaderViewModelMapper.kt
...rocket/android/main/viewmodel/NavHeaderViewModelMapper.kt
+28
-0
MembersFragment.kt
...in/java/chat/rocket/android/members/ui/MembersFragment.kt
+6
-2
ProfileFragment.kt
...in/java/chat/rocket/android/profile/ui/ProfileFragment.kt
+9
-3
DeleteReceiver.kt
app/src/main/java/chat/rocket/android/push/DeleteReceiver.kt
+40
-0
FirebaseTokenService.kt
...ain/java/chat/rocket/android/push/FirebaseTokenService.kt
+9
-2
GcmListenerService.kt
.../main/java/chat/rocket/android/push/GcmListenerService.kt
+11
-1
GroupedPush.kt
app/src/main/java/chat/rocket/android/push/GroupedPush.kt
+15
-0
PushManager.kt
app/src/main/java/chat/rocket/android/push/PushManager.kt
+176
-394
DeleteReceiverProvider.kt
...ava/chat/rocket/android/push/di/DeleteReceiverProvider.kt
+12
-0
GcmListenerServiceProvider.kt
...chat/rocket/android/push/di/GcmListenerServiceProvider.kt
+11
-0
ChangeServerModule.kt
.../java/chat/rocket/android/server/di/ChangeServerModule.kt
+30
-0
AccountsRepository.kt
...a/chat/rocket/android/server/domain/AccountsRepository.kt
+9
-0
GetAccountInteractor.kt
...chat/rocket/android/server/domain/GetAccountInteractor.kt
+9
-0
GetAccountsInteractor.kt
...hat/rocket/android/server/domain/GetAccountsInteractor.kt
+7
-0
GetServersInteractor.java
...at/rocket/android/server/domain/GetServersInteractor.java
+0
-17
RefreshSettingsInteractor.kt
...rocket/android/server/domain/RefreshSettingsInteractor.kt
+3
-2
RemoveAccountInterector.kt
...t/rocket/android/server/domain/RemoveAccountInterector.kt
+9
-0
SaveAccountInteractor.kt
...hat/rocket/android/server/domain/SaveAccountInteractor.kt
+8
-0
SaveServerInteractor.java
...at/rocket/android/server/domain/SaveServerInteractor.java
+0
-4
ServersRepository.kt
...va/chat/rocket/android/server/domain/ServersRepository.kt
+0
-14
SettingsRepository.kt
...a/chat/rocket/android/server/domain/SettingsRepository.kt
+7
-1
TokenRepository.kt
...java/chat/rocket/android/server/domain/TokenRepository.kt
+6
-0
Account.kt
...n/java/chat/rocket/android/server/domain/model/Account.kt
+12
-0
ConnectionManagerFactory.kt
...ndroid/server/infraestructure/ConnectionManagerFactory.kt
+2
-0
RocketChatClientFactory.kt
...android/server/infraestructure/RocketChatClientFactory.kt
+4
-4
RoomServersRepository.kt
...t/android/server/infraestructure/RoomServersRepository.kt
+0
-20
SharedPreferencesAccountsRepository.kt
...er/infraestructure/SharedPreferencesAccountsRepository.kt
+55
-0
SharedPreferencesSettingsRepository.kt
...er/infraestructure/SharedPreferencesSettingsRepository.kt
+2
-4
ChangeServerNavigator.kt
...cket/android/server/presentation/ChangeServerNavigator.kt
+19
-0
ChangeServerPresenter.kt
...cket/android/server/presentation/ChangeServerPresenter.kt
+66
-0
ChangeServerView.kt
...at/rocket/android/server/presentation/ChangeServerView.kt
+7
-0
ChangeServerActivity.kt
...ava/chat/rocket/android/server/ui/ChangeServerActivity.kt
+51
-0
Animation.kt
...ain/java/chat/rocket/android/util/extensions/Animation.kt
+2
-2
RocketChatClient.kt
...a/chat/rocket/android/util/extensions/RocketChatClient.kt
+26
-0
Ui.kt
app/src/main/java/chat/rocket/android/util/extensions/Ui.kt
+14
-7
black_gradient.xml
app/src/main/res/drawable/black_gradient.xml
+12
-0
ic_add_24dp.xml
app/src/main/res/drawable/ic_add_24dp.xml
+2
-4
ic_expand_more_24dp.xml
app/src/main/res/drawable/ic_expand_more_24dp.xml
+9
-0
activity_main.xml
app/src/main/res/layout/activity_main.xml
+19
-4
fragment_authentication_server.xml
app/src/main/res/layout/fragment_authentication_server.xml
+1
-1
item_account.xml
app/src/main/res/layout/item_account.xml
+45
-0
item_add_account.xml
app/src/main/res/layout/item_add_account.xml
+34
-0
nav_header.xml
app/src/main/res/layout/nav_header.xml
+82
-0
strings.xml
app/src/main/res/values-pt-rBR/strings.xml
+1
-0
colors.xml
app/src/main/res/values/colors.xml
+2
-0
dimens.xml
app/src/main/res/values/dimens.xml
+1
-0
strings.xml
app/src/main/res/values/strings.xml
+1
-0
build.gradle
build.gradle
+1
-0
No files found.
app/build.gradle
View file @
f136cf38
...
...
@@ -3,6 +3,7 @@ apply plugin: 'io.fabric'
apply
plugin:
'kotlin-android'
apply
plugin:
'kotlin-android-extensions'
apply
plugin:
'kotlin-kapt'
apply
plugin:
'realm-android'
android
{
compileSdkVersion
versions
.
compileSdk
...
...
app/src/main/AndroidManifest.xml
View file @
f136cf38
...
...
@@ -35,6 +35,10 @@
</intent-filter>
</activity>
<activity
android:name=
".server.ui.ChangeServerActivity"
android:theme=
"@style/AuthenticationTheme"
/>
<activity
android:name=
".main.ui.MainActivity"
android:windowSoftInputMode=
"adjustResize|stateAlwaysHidden"
...
...
app/src/main/java/chat/rocket/android/app/RocketChatApplication.kt
View file @
f136cf38
This diff is collapsed.
Click to expand it.
app/src/main/java/chat/rocket/android/app/migration/RealmMigration.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.app.migration
import
chat.rocket.android.BuildConfig
import
chat.rocket.android.app.migration.model.RealmUser
import
io.realm.DynamicRealm
import
io.realm.RealmMigration
class
RealmMigration
:
RealmMigration
{
override
fun
migrate
(
dynamicRealm
:
DynamicRealm
,
oldVersion
:
Long
,
newVersion
:
Long
)
{
var
oldVersion
=
oldVersion
val
schema
=
dynamicRealm
.
schema
if
(
oldVersion
==
0L
)
{
// NOOP
oldVersion
++
}
if
(
oldVersion
==
1L
)
{
oldVersion
++
}
if
(
oldVersion
==
2L
)
{
oldVersion
++
}
if
(
oldVersion
==
3L
)
{
oldVersion
++
}
if
(
oldVersion
==
4L
)
{
oldVersion
++
}
if
(
oldVersion
==
5L
)
{
val
userSchema
=
schema
.
get
(
"RealmUser"
)
try
{
userSchema
?.
addField
(
RealmUser
.
NAME
,
String
::
class
.
java
)
}
catch
(
e
:
IllegalArgumentException
)
{
if
(
BuildConfig
.
DEBUG
)
{
e
.
printStackTrace
()
}
// ignore; it makes here if the schema for this model was already update before without migration
}
}
}
// hack around to avoid "new different configuration cannot access the same file" error
override
fun
hashCode
():
Int
{
return
37
}
override
fun
equals
(
o
:
Any
?):
Boolean
{
return
o
is
chat
.
rocket
.
android
.
app
.
migration
.
RealmMigration
}
// end hack
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/app/migration/RocketChatLibraryModule.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.app.migration
import
io.realm.annotations.RealmModule
@RealmModule
(
library
=
true
,
allClasses
=
true
)
class
RocketChatLibraryModule
\ No newline at end of file
app/src/main/java/chat/rocket/android/app/migration/RocketChatServerModule.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.app.migration
import
chat.rocket.android.app.migration.model.RealmBasedServerInfo
import
io.realm.annotations.RealmModule
@RealmModule
(
library
=
true
,
classes
=
arrayOf
(
RealmBasedServerInfo
::
class
))
class
RocketChatServerModule
\ No newline at end of file
app/src/main/java/chat/rocket/android/app/migration/model/RealmBasedServerInfo.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.app.migration.model
import
io.realm.RealmObject
import
io.realm.annotations.PrimaryKey
open
class
RealmBasedServerInfo
:
RealmObject
()
{
@PrimaryKey
@JvmField
var
hostname
:
String
?
=
null
@JvmField
var
name
:
String
?
=
null
@JvmField
var
session
:
String
?
=
null
@JvmField
var
insecure
:
Boolean
=
false
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/app/migration/model/RealmEmail.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.app.migration.model
import
io.realm.RealmObject
import
io.realm.annotations.PrimaryKey
open
class
RealmEmail
:
RealmObject
()
{
@PrimaryKey
@JvmField
var
address
:
String
?
=
null
@JvmField
var
verified
:
Boolean
=
false
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/app/migration/model/RealmPreferences.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.app.migration.model
import
io.realm.RealmObject
import
io.realm.annotations.PrimaryKey
open
class
RealmPreferences
:
RealmObject
()
{
@PrimaryKey
@JvmField
var
id
:
String
?
=
null
@JvmField
var
newRoomNotification
:
String
?
=
null
@JvmField
var
newMessageNotification
:
String
?
=
null
@JvmField
var
useEmojis
:
Boolean
=
false
@JvmField
var
convertAsciiEmoji
:
Boolean
=
false
@JvmField
var
saveMobileBandwidth
:
Boolean
=
false
@JvmField
var
collapseMediaByDefault
:
Boolean
=
false
@JvmField
var
unreadRoomsMode
:
Boolean
=
false
@JvmField
var
autoImageLoad
:
Boolean
=
false
@JvmField
var
emailNotificationMode
:
String
?
=
null
@JvmField
var
unreadAlert
:
Boolean
=
false
@JvmField
var
desktopNotificationDuration
:
Int
=
0
@JvmField
var
viewMode
:
Int
=
0
@JvmField
var
hideUsernames
:
Boolean
=
false
@JvmField
var
hideAvatars
:
Boolean
=
false
@JvmField
var
hideFlexTab
:
Boolean
=
false
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/app/migration/model/RealmPublicSetting.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.app.migration.model
import
io.realm.RealmObject
import
io.realm.annotations.PrimaryKey
open
class
RealmPublicSetting
:
RealmObject
()
{
@PrimaryKey
@JvmField
var
_id
:
String
?
=
null
@JvmField
var
group
:
String
?
=
null
@JvmField
var
type
:
String
?
=
null
@JvmField
var
value
:
String
?
=
null
@JvmField
var
_updatedAt
:
Long
=
0
@JvmField
var
meta
:
String
?
=
null
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/app/migration/model/RealmSession.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.app.migration.model
import
io.realm.RealmObject
import
io.realm.annotations.PrimaryKey
open
class
RealmSession
:
RealmObject
()
{
@JvmField
@PrimaryKey
var
sessionId
:
Int
=
0
//only 0 is used!
@JvmField
var
token
:
String
?
=
null
@JvmField
var
tokenVerified
:
Boolean
=
false
@JvmField
var
error
:
String
?
=
null
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/app/migration/model/RealmSettings.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.app.migration.model
import
io.realm.RealmObject
import
io.realm.annotations.PrimaryKey
open
class
RealmSettings
:
RealmObject
()
{
@PrimaryKey
@JvmField
var
id
:
String
?
=
null
@JvmField
var
preferences
:
RealmPreferences
?
=
null
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/app/migration/model/RealmUser.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.app.migration.model
import
io.realm.RealmList
import
io.realm.RealmObject
import
io.realm.annotations.PrimaryKey
open
class
RealmUser
:
RealmObject
()
{
companion
object
{
const
val
ID
=
"_id"
const
val
NAME
=
"name"
const
val
USERNAME
=
"username"
const
val
STATUS
=
"status"
const
val
UTC_OFFSET
=
"utcOffset"
const
val
EMAILS
=
"emails"
const
val
SETTINGS
=
"settings"
const
val
STATUS_ONLINE
=
"online"
const
val
STATUS_BUSY
=
"busy"
const
val
STATUS_AWAY
=
"away"
const
val
STATUS_OFFLINE
=
"offline"
}
@PrimaryKey
@JvmField
var
_id
:
String
?
=
null
@JvmField
var
name
:
String
?
=
null
@JvmField
var
username
:
String
?
=
null
@JvmField
var
status
:
String
?
=
null
@JvmField
var
utcOffset
:
Double
=
0
.
toDouble
()
@JvmField
var
emails
:
RealmList
<
RealmEmail
>?
=
null
@JvmField
var
settings
:
RealmSettings
?
=
null
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/di/AuthenticationModule.kt
View file @
f136cf38
package
chat.rocket.android.authentication.di
import
android.content.Context
import
chat.rocket.android.authentication.presentation.AuthenticationNavigator
import
chat.rocket.android.authentication.ui.AuthenticationActivity
import
chat.rocket.android.dagger.scope.PerActivity
...
...
@@ -12,5 +11,5 @@ class AuthenticationModule {
@Provides
@PerActivity
fun
provideAuthenticationNavigator
(
activity
:
AuthenticationActivity
,
context
:
Context
)
=
AuthenticationNavigator
(
activity
,
context
)
fun
provideAuthenticationNavigator
(
activity
:
AuthenticationActivity
)
=
AuthenticationNavigator
(
activity
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/domain/model/TokenModel.kt
View file @
f136cf38
package
chat.rocket.android.authentication.domain.model
import
chat.rocket.common.model.Token
import
se.ansman.kotshi.JsonSerializable
@JsonSerializable
data class
TokenModel
(
val
userId
:
String
,
val
authToken
:
String
)
fun
TokenModel
.
toToken
()
=
Token
(
userId
,
authToken
)
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/infraestructure/MemoryTokenRepository.kt
deleted
100644 → 0
View file @
3d2ec050
package
chat.rocket.android.authentication.infraestructure
import
chat.rocket.common.model.Token
import
chat.rocket.core.TokenRepository
class
MemoryTokenRepository
:
TokenRepository
{
var
savedToken
:
Token
?
=
null
override
fun
get
():
Token
?
{
return
savedToken
}
override
fun
save
(
token
:
Token
)
{
savedToken
=
token
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/infraestructure/SharedPreferencesTokenRepository.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.authentication.infraestructure
import
android.content.SharedPreferences
import
androidx.content.edit
import
chat.rocket.android.authentication.domain.model.TokenModel
import
chat.rocket.android.server.domain.TokenRepository
import
chat.rocket.common.model.Token
import
com.squareup.moshi.Moshi
import
timber.log.Timber
class
SharedPreferencesTokenRepository
(
private
val
prefs
:
SharedPreferences
,
moshi
:
Moshi
)
:
TokenRepository
{
private
var
servers
=
prefs
.
getStringSet
(
KEY_SERVERS
,
emptySet
()).
toMutableSet
()
private
var
currentUrl
:
String
?
=
null
private
var
currentToken
:
Token
?
=
null
private
val
adapter
=
moshi
.
adapter
<
TokenModel
>(
TokenModel
::
class
.
java
)
override
fun
get
(
url
:
String
):
Token
?
{
if
(
currentToken
!=
null
&&
url
==
currentUrl
)
{
return
currentToken
}
try
{
prefs
.
getString
(
tokenKey
(
url
),
null
)
?.
let
{
tokenStr
->
val
model
=
adapter
.
fromJson
(
tokenStr
)
model
?.
let
{
val
token
=
Token
(
model
.
userId
,
model
.
authToken
)
currentToken
=
token
currentUrl
=
url
}
}
}
catch
(
ex
:
Exception
)
{
Timber
.
d
(
ex
,
"Error parsing token for ${tokenKey(url)}"
)
ex
.
printStackTrace
()
}
return
currentToken
}
override
fun
save
(
url
:
String
,
token
:
Token
)
{
try
{
val
model
=
TokenModel
(
token
.
userId
,
token
.
authToken
)
val
str
=
adapter
.
toJson
(
model
)
servers
.
add
(
url
)
prefs
.
edit
{
putString
(
tokenKey
(
url
),
str
)
putStringSet
(
KEY_SERVERS
,
servers
)
}
currentToken
=
token
currentUrl
=
url
}
catch
(
ex
:
Exception
)
{
Timber
.
d
(
ex
,
"Error saving token for ${tokenKey(url)}"
)
ex
.
printStackTrace
()
}
}
override
fun
remove
(
url
:
String
)
{
servers
.
remove
(
url
)
prefs
.
edit
{
remove
(
url
)
putStringSet
(
KEY_SERVERS
,
servers
)
}
}
override
fun
clear
()
{
servers
.
forEach
{
server
->
prefs
.
edit
{
remove
(
server
)
}
}
servers
.
clear
()
prefs
.
edit
{
remove
(
KEY_SERVERS
)
}
}
private
fun
tokenKey
(
url
:
String
)
=
"$KEY_TOKEN$url"
}
private
const
val
KEY_TOKEN
=
"KEY_TOKEN_"
private
const
val
KEY_SERVERS
=
"KEY_SERVERS"
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/login/presentation/LoginPresenter.kt
View file @
f136cf38
package
chat.rocket.android.authentication.login.presentation
import
chat.rocket.android.authentication.domain.model.TokenModel
import
chat.rocket.android.authentication.domain.model.toToken
import
chat.rocket.android.authentication.presentation.AuthenticationNavigator
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.helper.NetworkHelper
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.domain.model.Account
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extensions.generateRandomString
import
chat.rocket.android.util.extensions.isEmailValid
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.android.util.extensions.registerPushToken
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.RocketChatTwoFactorException
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.rest.*
import
chat.rocket.core.model.Myself
import
kotlinx.coroutines.experimental.delay
import
java.util.concurrent.TimeUnit
import
javax.inject.Inject
...
...
@@ -23,13 +27,17 @@ import javax.inject.Inject
class
LoginPresenter
@Inject
constructor
(
private
val
view
:
LoginView
,
private
val
strategy
:
CancelStrategy
,
private
val
navigator
:
AuthenticationNavigator
,
private
val
multiServerRepository
:
MultiServer
TokenRepository
,
private
val
tokenRepository
:
TokenRepository
,
private
val
localRepository
:
LocalRepository
,
private
val
getAccountsInteractor
:
GetAccountsInteractor
,
private
val
settingsInteractor
:
GetSettingsInteractor
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
factory
:
RocketChatClientFactory
)
{
private
val
saveAccountInteractor
:
SaveAccountInteractor
,
private
val
factory
:
RocketChatClientFactory
)
{
// TODO - we should validate the current server when opening the app, and have a nonnull get()
private
val
client
:
RocketChatClient
=
factory
.
create
(
serverInteractor
.
get
()
!!
)
private
val
currentServer
=
serverInteractor
.
get
()
!!
private
val
client
:
RocketChatClient
=
factory
.
create
(
currentServer
)
private
var
settings
:
PublicSettings
=
settingsInteractor
.
get
(
serverInteractor
.
get
()
!!
)
fun
setupView
()
{
val
server
=
serverInteractor
.
get
()
...
...
@@ -125,7 +133,9 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
}
}
saveToken
(
server
,
TokenModel
(
token
.
userId
,
token
.
authToken
),
client
.
me
().
username
)
val
me
=
client
.
me
()
saveToken
(
server
,
TokenModel
(
token
.
userId
,
token
.
authToken
),
me
.
username
)
saveAccount
(
me
)
registerPushToken
()
navigator
.
toChatList
()
}
catch
(
exception
:
RocketChatException
)
{
...
...
@@ -163,7 +173,9 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
if
(
server
!=
null
)
{
delay
(
3
,
TimeUnit
.
SECONDS
)
val
token
=
client
.
loginWithCas
(
casToken
)
saveToken
(
server
,
TokenModel
(
token
.
userId
,
token
.
authToken
),
client
.
me
().
username
)
val
me
=
client
.
me
()
saveToken
(
server
,
TokenModel
(
token
.
userId
,
token
.
authToken
),
me
.
username
)
saveAccount
(
me
)
registerPushToken
()
navigator
.
toChatList
()
}
else
{
...
...
@@ -188,15 +200,28 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
fun
signup
()
=
navigator
.
toSignUp
()
private
suspend
fun
saveToken
(
server
:
String
,
tokenModel
:
TokenModel
,
username
:
String
?)
{
multiServerRepository
.
save
(
server
,
tokenModel
)
localRepository
.
save
(
LocalRepository
.
USERNAME_KEY
,
username
)
localRepository
.
save
(
LocalRepository
.
CURRENT_USERNAME_KEY
,
username
)
tokenRepository
.
save
(
server
,
tokenModel
.
toToken
()
)
registerPushToken
()
}
private
suspend
fun
registerPushToken
()
{
localRepository
.
get
(
LocalRepository
.
KEY_PUSH_TOKEN
)
?.
let
{
client
.
registerPushToken
(
it
)
client
.
registerPushToken
(
it
,
getAccountsInteractor
.
get
(),
factory
)
}
// TODO: Schedule push token registering when it comes up null
// TODO: When the push token is null, at some point we should receive it with
// onTokenRefresh() on FirebaseTokenService, we need to confirm it.
}
private
suspend
fun
saveAccount
(
me
:
Myself
)
{
val
icon
=
settings
.
favicon
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
}
val
logo
=
settings
.
wideTile
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
}
val
thumb
=
UrlHelper
.
getAvatarUrl
(
currentServer
,
me
.
username
!!
)
val
account
=
Account
(
currentServer
,
icon
,
logo
,
me
.
username
!!
,
thumb
)
saveAccountInteractor
.
save
(
account
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/presentation/AuthenticationNavigator.kt
View file @
f136cf38
package
chat.rocket.android.authentication.presentation
import
android.content.Context
import
android.content.Intent
import
chat.rocket.android.R
import
chat.rocket.android.authentication.login.ui.LoginFragment
import
chat.rocket.android.authentication.signup.ui.SignupFragment
import
chat.rocket.android.authentication.twofactor.ui.TwoFAFragment
import
chat.rocket.android.authentication.ui.AuthenticationActivity
import
chat.rocket.android.authentication.ui.newServerIntent
import
chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.server.ui.changeServerIntent
import
chat.rocket.android.util.extensions.addFragmentBackStack
import
chat.rocket.android.webview.ui.webViewIntent
class
AuthenticationNavigator
(
internal
val
activity
:
AuthenticationActivity
,
internal
val
context
:
Context
)
{
class
AuthenticationNavigator
(
internal
val
activity
:
AuthenticationActivity
)
{
fun
toLogin
()
{
activity
.
addFragmentBackStack
(
"LoginFragment"
,
R
.
id
.
fragment_container
)
{
...
...
@@ -32,7 +33,7 @@ class AuthenticationNavigator(internal val activity: AuthenticationActivity, int
}
fun
toWebPage
(
url
:
String
)
{
activity
.
startActivity
(
context
.
webViewIntent
(
url
))
activity
.
startActivity
(
activity
.
webViewIntent
(
url
))
activity
.
overridePendingTransition
(
R
.
anim
.
slide_up
,
R
.
anim
.
hold
)
}
...
...
@@ -41,7 +42,13 @@ class AuthenticationNavigator(internal val activity: AuthenticationActivity, int
activity
.
finish
()
}
fun
toChatList
(
serverUrl
:
String
)
{
activity
.
startActivity
(
activity
.
changeServerIntent
(
serverUrl
))
activity
.
finish
()
}
fun
toServerScreen
()
{
TODO
(
"not implemented"
)
//To change body of created functions use File | Settings | File Templates.
activity
.
startActivity
(
activity
.
newServerIntent
())
activity
.
finish
()
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/presentation/AuthenticationPresenter.kt
View file @
f136cf38
package
chat.rocket.android.authentication.presentation
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.GetAccountInteractor
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.MultiServerTokenRepository
import
chat.rocket.android.server.domain.SettingsRepository
import
chat.rocket.common.model.Token
import
chat.rocket.core.TokenRepository
import
chat.rocket.android.server.domain.TokenRepository
import
javax.inject.Inject
class
AuthenticationPresenter
@Inject
constructor
(
private
val
navigator
:
AuthenticationNavigator
,
class
AuthenticationPresenter
@Inject
constructor
(
private
val
navigator
:
AuthenticationNavigator
,
private
val
getCurrentServerInteractor
:
GetCurrentServerInteractor
,
private
val
multiServerRepository
:
MultiServerTokenRepository
,
private
val
getAccountInteractor
:
GetAccountInteractor
,
private
val
settingsRepository
:
SettingsRepository
,
private
val
tokenRepository
:
TokenRepository
)
{
fun
loadCredentials
(
callback
:
(
authenticated
:
Boolean
)
->
Unit
)
{
private
val
localRepository
:
LocalRepository
,
private
val
tokenRepository
:
TokenRepository
)
{
suspend
fun
loadCredentials
(
newServer
:
Boolean
,
callback
:
(
authenticated
:
Boolean
)
->
Unit
)
{
val
currentServer
=
getCurrentServerInteractor
.
get
()
val
serverToken
=
currentServer
?.
let
{
multiServer
Repository
.
get
(
currentServer
)
}
val
serverToken
=
currentServer
?.
let
{
token
Repository
.
get
(
currentServer
)
}
val
settings
=
currentServer
?.
let
{
settingsRepository
.
get
(
currentServer
)
}
val
account
=
currentServer
?.
let
{
getAccountInteractor
.
get
(
currentServer
)
}
account
?.
let
{
localRepository
.
save
(
LocalRepository
.
CURRENT_USERNAME_KEY
,
account
.
userName
)
}
if
(
currentServer
==
null
||
serverToken
==
null
||
settings
==
null
)
{
if
(
newServer
||
currentServer
==
null
||
serverToken
==
null
||
settings
==
null
)
{
callback
(
false
)
}
else
{
tokenRepository
.
save
(
Token
(
serverToken
.
userId
,
serverToken
.
authToken
))
callback
(
true
)
navigator
.
toChatList
()
}
...
...
app/src/main/java/chat/rocket/android/authentication/server/presentation/ServerPresenter.kt
View file @
f136cf38
...
...
@@ -4,6 +4,7 @@ import chat.rocket.android.authentication.presentation.AuthenticationNavigator
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.helper.NetworkHelper
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.server.domain.GetAccountsInteractor
import
chat.rocket.android.server.domain.RefreshSettingsInteractor
import
chat.rocket.android.server.domain.SaveCurrentServerInteractor
import
chat.rocket.android.util.extensions.launchUI
...
...
@@ -14,12 +15,20 @@ class ServerPresenter @Inject constructor(private val view: ServerView,
private
val
strategy
:
CancelStrategy
,
private
val
navigator
:
AuthenticationNavigator
,
private
val
serverInteractor
:
SaveCurrentServerInteractor
,
private
val
refreshSettingsInteractor
:
RefreshSettingsInteractor
)
{
private
val
refreshSettingsInteractor
:
RefreshSettingsInteractor
,
private
val
getAccountsInteractor
:
GetAccountsInteractor
)
{
fun
connect
(
server
:
String
)
{
if
(!
UrlHelper
.
isValidUrl
(
server
))
{
view
.
showInvalidServerUrlMessage
()
}
else
{
launchUI
(
strategy
)
{
// Check if we already have an account for this server...
val
account
=
getAccountsInteractor
.
get
().
firstOrNull
{
it
.
serverUrl
==
server
}
if
(
account
!=
null
)
{
navigator
.
toChatList
(
server
)
return
@launchUI
}
if
(
NetworkHelper
.
hasInternetAccess
())
{
view
.
showLoading
()
try
{
...
...
app/src/main/java/chat/rocket/android/authentication/server/ui/ServerFragment.kt
View file @
f136cf38
...
...
@@ -56,13 +56,21 @@ class ServerFragment : Fragment(), ServerView {
enableUserInput
(
true
)
}
override
fun
showMessage
(
resId
:
Int
)
=
showToast
(
resId
)
override
fun
showMessage
(
resId
:
Int
){
showToast
(
resId
)
}
override
fun
showMessage
(
message
:
String
)
=
showToast
(
message
)
override
fun
showMessage
(
message
:
String
)
{
showToast
(
message
)
}
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
override
fun
showGenericErrorMessage
()
{
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
}
override
fun
showNoInternetConnection
()
=
showMessage
(
getString
(
R
.
string
.
msg_no_internet_connection
))
override
fun
showNoInternetConnection
()
{
showMessage
(
getString
(
R
.
string
.
msg_no_internet_connection
))
}
private
fun
enableUserInput
(
value
:
Boolean
)
{
button_connect
.
isEnabled
=
value
...
...
app/src/main/java/chat/rocket/android/authentication/signup/presentation/SignupPresenter.kt
View file @
f136cf38
...
...
@@ -5,7 +5,9 @@ import chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.helper.NetworkHelper
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.main.viewmodel.NavHeaderViewModel
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.domain.model.Account
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.common.RocketChatException
...
...
@@ -15,6 +17,7 @@ import chat.rocket.core.internal.rest.login
import
chat.rocket.core.internal.rest.me
import
chat.rocket.core.internal.rest.registerPushToken
import
chat.rocket.core.internal.rest.signup
import
chat.rocket.core.model.Myself
import
javax.inject.Inject
class
SignupPresenter
@Inject
constructor
(
private
val
view
:
SignupView
,
...
...
@@ -22,8 +25,12 @@ class SignupPresenter @Inject constructor(private val view: SignupView,
private
val
navigator
:
AuthenticationNavigator
,
private
val
localRepository
:
LocalRepository
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
factory
:
RocketChatClientFactory
)
{
private
val
client
:
RocketChatClient
=
factory
.
create
(
serverInteractor
.
get
()
!!
)
private
val
factory
:
RocketChatClientFactory
,
private
val
saveAccountInteractor
:
SaveAccountInteractor
,
settingsInteractor
:
GetSettingsInteractor
)
{
private
val
currentServer
=
serverInteractor
.
get
()
!!
private
val
client
:
RocketChatClient
=
factory
.
create
(
currentServer
)
private
var
settings
:
PublicSettings
=
settingsInteractor
.
get
(
serverInteractor
.
get
()
!!
)
fun
signup
(
name
:
String
,
username
:
String
,
password
:
String
,
email
:
String
)
{
val
server
=
serverInteractor
.
get
()
...
...
@@ -55,7 +62,8 @@ class SignupPresenter @Inject constructor(private val view: SignupView,
// TODO This function returns a user token so should we save it?
client
.
login
(
username
,
password
)
val
me
=
client
.
me
()
localRepository
.
save
(
LocalRepository
.
USERNAME_KEY
,
me
.
username
)
localRepository
.
save
(
LocalRepository
.
CURRENT_USERNAME_KEY
,
me
.
username
)
saveAccount
(
me
)
registerPushToken
()
navigator
.
toChatList
()
}
catch
(
exception
:
RocketChatException
)
{
...
...
@@ -94,4 +102,16 @@ class SignupPresenter @Inject constructor(private val view: SignupView,
}
// TODO: Schedule push token registering when it comes up null
}
private
suspend
fun
saveAccount
(
me
:
Myself
)
{
val
icon
=
settings
.
favicon
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
}
val
logo
=
settings
.
wideTile
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
}
val
thumb
=
UrlHelper
.
getAvatarUrl
(
currentServer
,
me
.
username
!!
)
val
account
=
Account
(
currentServer
,
icon
,
logo
,
me
.
username
!!
,
thumb
)
saveAccountInteractor
.
save
(
account
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/signup/ui/SignupFragment.kt
View file @
f136cf38
...
...
@@ -97,9 +97,13 @@ class SignupFragment : Fragment(), SignupView {
enableUserInput
(
true
)
}
override
fun
showMessage
(
resId
:
Int
)
=
showToast
(
resId
)
override
fun
showMessage
(
resId
:
Int
)
{
showToast
(
resId
)
}
override
fun
showMessage
(
message
:
String
)
=
showToast
(
message
)
override
fun
showMessage
(
message
:
String
)
{
showToast
(
message
)
}
override
fun
showGenericErrorMessage
()
{
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
...
...
app/src/main/java/chat/rocket/android/authentication/twofactor/presentation/TwoFAPresenter.kt
View file @
f136cf38
package
chat.rocket.android.authentication.twofactor.presentation
import
chat.rocket.android.authentication.domain.model.TokenModel
import
chat.rocket.android.authentication.presentation.AuthenticationNavigator
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.helper.NetworkHelper
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.
GetCurrentServerInteractor
import
chat.rocket.android.server.domain.
MultiServerTokenRepository
import
chat.rocket.android.server.domain.
*
import
chat.rocket.android.server.domain.
model.Account
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.android.util.extensions.registerPushToken
import
chat.rocket.common.RocketChatAuthException
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.rest.login
import
chat.rocket.core.internal.rest.registerPushToken
import
chat.rocket.core.internal.rest.me
import
chat.rocket.core.model.Myself
import
javax.inject.Inject
class
TwoFAPresenter
@Inject
constructor
(
private
val
view
:
TwoFAView
,
private
val
strategy
:
CancelStrategy
,
private
val
navigator
:
AuthenticationNavigator
,
private
val
multiServerRepository
:
MultiServer
TokenRepository
,
private
val
tokenRepository
:
TokenRepository
,
private
val
localRepository
:
LocalRepository
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
factory
:
RocketChatClientFactory
)
{
private
val
client
:
RocketChatClient
=
factory
.
create
(
serverInteractor
.
get
()
!!
)
private
val
factory
:
RocketChatClientFactory
,
private
val
saveAccountInteractor
:
SaveAccountInteractor
,
private
val
getAccountsInteractor
:
GetAccountsInteractor
,
settingsInteractor
:
GetSettingsInteractor
)
{
private
val
currentServer
=
serverInteractor
.
get
()
!!
private
val
client
:
RocketChatClient
=
factory
.
create
(
currentServer
)
private
var
settings
:
PublicSettings
=
settingsInteractor
.
get
(
serverInteractor
.
get
()
!!
)
// TODO: If the usernameOrEmail and password was informed by the user on the previous screen, then we should pass only the pin, like this: fun authenticate(pin: EditText)
fun
authenticate
(
usernameOrEmail
:
String
,
password
:
String
,
twoFactorAuthenticationCode
:
String
)
{
...
...
@@ -45,10 +52,9 @@ class TwoFAPresenter @Inject constructor(private val view: TwoFAView,
// The token is saved via the client TokenProvider
val
token
=
client
.
login
(
usernameOrEmail
,
password
,
twoFactorAuthenticationCode
)
multiServerRepository
.
save
(
server
,
TokenModel
(
token
.
userId
,
token
.
authToken
)
)
val
me
=
client
.
me
()
saveAccount
(
me
)
tokenRepository
.
save
(
server
,
token
)
registerPushToken
()
navigator
.
toChatList
()
}
catch
(
exception
:
RocketChatException
)
{
...
...
@@ -76,8 +82,21 @@ class TwoFAPresenter @Inject constructor(private val view: TwoFAView,
private
suspend
fun
registerPushToken
()
{
localRepository
.
get
(
LocalRepository
.
KEY_PUSH_TOKEN
)
?.
let
{
client
.
registerPushToken
(
it
)
client
.
registerPushToken
(
it
,
getAccountsInteractor
.
get
(),
factory
)
}
// TODO: Schedule push token registering when it comes up null
// TODO: When the push token is null, at some point we should receive it with
// onTokenRefresh() on FirebaseTokenService, we need to confirm it.
}
private
suspend
fun
saveAccount
(
me
:
Myself
)
{
val
icon
=
settings
.
favicon
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
}
val
logo
=
settings
.
wideTile
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
}
val
thumb
=
UrlHelper
.
getAvatarUrl
(
currentServer
,
me
.
username
!!
)
val
account
=
Account
(
currentServer
,
icon
,
logo
,
me
.
username
!!
,
thumb
)
saveAccountInteractor
.
save
(
account
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/authentication/twofactor/ui/TwoFAFragment.kt
View file @
f136cf38
...
...
@@ -66,7 +66,9 @@ class TwoFAFragment : Fragment(), TwoFAView {
text_two_factor_auth
.
shake
()
}
override
fun
alertInvalidTwoFactorAuthenticationCode
()
=
showMessage
(
getString
(
R
.
string
.
msg_invalid_2fa_code
))
override
fun
alertInvalidTwoFactorAuthenticationCode
()
{
showMessage
(
getString
(
R
.
string
.
msg_invalid_2fa_code
))
}
override
fun
showLoading
()
{
enableUserInput
(
false
)
...
...
@@ -78,9 +80,13 @@ class TwoFAFragment : Fragment(), TwoFAView {
enableUserInput
(
true
)
}
override
fun
showMessage
(
resId
:
Int
)
=
showToast
(
resId
)
override
fun
showMessage
(
resId
:
Int
)
{
showToast
(
resId
)
}
override
fun
showMessage
(
message
:
String
)
=
showToast
(
message
)
override
fun
showMessage
(
message
:
String
)
{
showToast
(
message
)
}
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
...
...
app/src/main/java/chat/rocket/android/authentication/ui/AuthenticationActivity.kt
View file @
f136cf38
package
chat.rocket.android.authentication.ui
import
android.content.Context
import
android.content.Intent
import
android.os.Bundle
import
android.support.v4.app.Fragment
import
android.support.v7.app.AppCompatActivity
...
...
@@ -7,40 +9,58 @@ import chat.rocket.android.R
import
chat.rocket.android.authentication.presentation.AuthenticationPresenter
import
chat.rocket.android.authentication.server.ui.ServerFragment
import
chat.rocket.android.util.extensions.addFragment
import
chat.rocket.android.util.extensions.launchUI
import
dagger.android.AndroidInjection
import
dagger.android.AndroidInjector
import
dagger.android.DispatchingAndroidInjector
import
dagger.android.support.HasSupportFragmentInjector
import
kotlinx.coroutines.experimental.Job
import
kotlinx.coroutines.experimental.android.UI
import
kotlinx.coroutines.experimental.launch
import
javax.inject.Inject
class
AuthenticationActivity
:
AppCompatActivity
(),
HasSupportFragmentInjector
{
@Inject
lateinit
var
fragmentDispatchingAndroidInjector
:
DispatchingAndroidInjector
<
Fragment
>
@Inject
lateinit
var
presenter
:
AuthenticationPresenter
val
job
=
Job
()
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
AndroidInjection
.
inject
(
this
)
presenter
.
loadCredentials
{
authenticated
->
if
(
authenticated
)
{
// just call onCreate, and the presenter will call the navigator...
setContentView
(
R
.
layout
.
activity_authentication
)
setTheme
(
R
.
style
.
AuthenticationTheme
)
super
.
onCreate
(
savedInstanceState
)
}
else
{
launch
(
UI
+
job
)
{
val
newServer
=
intent
.
getBooleanExtra
(
INTENT_ADD_NEW_SERVER
,
false
)
presenter
.
loadCredentials
(
newServer
)
{
authenticated
->
if
(!
authenticated
)
{
showServerInput
(
savedInstanceState
)
}
}
}
}
override
fun
onDestroy
()
{
job
.
cancel
()
super
.
onDestroy
()
}
override
fun
supportFragmentInjector
():
AndroidInjector
<
Fragment
>
{
return
fragmentDispatchingAndroidInjector
}
fun
showServerInput
(
savedInstanceState
:
Bundle
?)
{
setContentView
(
R
.
layout
.
activity_authentication
)
setTheme
(
R
.
style
.
AuthenticationTheme
)
super
.
onCreate
(
savedInstanceState
)
addFragment
(
"ServerFragment"
,
R
.
id
.
fragment_container
)
{
ServerFragment
.
newInstance
()
}
}
}
const
val
INTENT_ADD_NEW_SERVER
=
"INTENT_ADD_NEW_SERVER"
fun
Context
.
newServerIntent
():
Intent
{
return
Intent
(
this
,
AuthenticationActivity
::
class
.
java
).
apply
{
putExtra
(
INTENT_ADD_NEW_SERVER
,
true
)
flags
=
Intent
.
FLAG_ACTIVITY_CLEAR_TOP
or
Intent
.
FLAG_ACTIVITY_CLEAR_TASK
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/adapter/AutoCompleteType.kt
View file @
f136cf38
...
...
@@ -2,8 +2,8 @@ package chat.rocket.android.chatroom.adapter
import
android.support.annotation.IntDef
const
val
PEOPLE
=
0
L
const
val
ROOMS
=
1
L
const
val
PEOPLE
=
0
const
val
ROOMS
=
1
@Retention
(
AnnotationRetention
.
SOURCE
)
@IntDef
(
value
=
[
PEOPLE
,
ROOMS
])
...
...
app/src/main/java/chat/rocket/android/chatroom/adapter/MessageReactionsAdapter.kt
View file @
f136cf38
...
...
@@ -97,7 +97,7 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>()
val
countTextView
=
findViewById
<
TextView
>(
R
.
id
.
text_count
)
emojiTextView
.
text
=
reaction
.
unicode
countTextView
.
text
=
reaction
.
count
.
toString
()
val
myself
=
localRepository
.
get
(
LocalRepository
.
USERNAME_KEY
)
val
myself
=
localRepository
.
get
(
LocalRepository
.
CURRENT_
USERNAME_KEY
)
if
(
reaction
.
usernames
.
contains
(
myself
))
{
val
context
=
itemView
.
context
val
resources
=
context
.
resources
...
...
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt
View file @
f136cf38
...
...
@@ -364,7 +364,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
try
{
val
members
=
client
.
getMembers
(
chatRoomId
,
roomTypeOf
(
chatRoomType
),
offset
,
50
).
result
usersRepository
.
saveAll
(
members
)
val
self
=
localRepository
.
get
(
LocalRepository
.
USERNAME_KEY
)
val
self
=
localRepository
.
get
(
LocalRepository
.
CURRENT_
USERNAME_KEY
)
// Take at most the 100 most recent messages distinguished by user. Can return less.
val
recentMessages
=
messagesRepository
.
getRecentMessages
(
chatRoomId
,
100
)
.
filterNot
{
filterSelfOut
&&
it
.
sender
?.
username
==
self
}
...
...
@@ -402,7 +402,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
}
}
fun
spotlight
(
query
:
String
,
@AutoCompleteType
type
:
Long
,
filterSelfOut
:
Boolean
=
false
)
{
fun
spotlight
(
query
:
String
,
@AutoCompleteType
type
:
Int
,
filterSelfOut
:
Boolean
=
false
)
{
launchUI
(
strategy
)
{
try
{
val
(
users
,
rooms
)
=
client
.
spotlight
(
query
)
...
...
@@ -411,7 +411,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
if
(
users
.
isNotEmpty
())
{
usersRepository
.
saveAll
(
users
)
}
val
self
=
localRepository
.
get
(
LocalRepository
.
USERNAME_KEY
)
val
self
=
localRepository
.
get
(
LocalRepository
.
CURRENT_
USERNAME_KEY
)
view
.
populatePeopleSuggestions
(
users
.
map
{
val
username
=
it
.
username
?:
""
val
name
=
it
.
name
?:
""
...
...
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
View file @
f136cf38
...
...
@@ -234,7 +234,9 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
presenter
.
uploadFile
(
chatRoomId
,
uri
,
""
)
}
override
fun
showInvalidFileMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_invalid_file
))
override
fun
showInvalidFileMessage
()
{
showMessage
(
getString
(
R
.
string
.
msg_invalid_file
))
}
override
fun
showNewMessage
(
message
:
List
<
BaseViewModel
<*
>>)
{
adapter
.
prependData
(
message
)
...
...
@@ -288,9 +290,13 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
override
fun
hideLoading
()
=
view_loading
.
setVisible
(
false
)
override
fun
showMessage
(
message
:
String
)
=
showToast
(
message
)
override
fun
showMessage
(
message
:
String
)
{
showToast
(
message
)
}
override
fun
showMessage
(
resId
:
Int
)
=
showToast
(
resId
)
override
fun
showMessage
(
resId
:
Int
)
{
showToast
(
resId
)
}
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
...
...
app/src/main/java/chat/rocket/android/chatroom/ui/PinnedMessagesFragment.kt
View file @
f136cf38
...
...
@@ -66,9 +66,13 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView {
override
fun
hideLoading
()
=
view_loading
.
setVisible
(
false
)
override
fun
showMessage
(
resId
:
Int
)
=
showToast
(
resId
)
override
fun
showMessage
(
resId
:
Int
)
{
showToast
(
resId
)
}
override
fun
showMessage
(
message
:
String
)
=
showToast
(
message
)
override
fun
showMessage
(
message
:
String
)
{
showToast
(
message
)
}
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/ViewModelMapper.kt
View file @
f136cf38
...
...
@@ -15,7 +15,6 @@ import chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.widget.emoji.EmojiParser
import
chat.rocket.core.TokenRepository
import
chat.rocket.core.model.Message
import
chat.rocket.core.model.MessageType
import
chat.rocket.core.model.Value
...
...
@@ -23,6 +22,7 @@ import chat.rocket.core.model.attachment.*
import
chat.rocket.core.model.isSystemMessage
import
chat.rocket.core.model.url.Url
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.launch
import
kotlinx.coroutines.experimental.withContext
import
okhttp3.HttpUrl
import
timber.log.Timber
...
...
@@ -32,15 +32,17 @@ import javax.inject.Inject
class
ViewModelMapper
@Inject
constructor
(
private
val
context
:
Context
,
private
val
parser
:
MessageParser
,
private
val
messagesRepository
:
MessagesRepository
,
private
val
getAccountInteractor
:
GetAccountInteractor
,
tokenRepository
:
TokenRepository
,
localRepository
:
LocalRepository
,
serverInteractor
:
GetCurrentServerInteractor
,
getSettingsInteractor
:
GetSettingsInteractor
)
{
getSettingsInteractor
:
GetSettingsInteractor
,
localRepository
:
LocalRepository
)
{
private
var
settings
:
Map
<
String
,
Value
<
Any
>>
=
getSettingsInteractor
.
get
(
serverInteractor
.
get
()
!!
)
!!
private
val
currentServer
=
serverInteractor
.
get
()
!!
private
val
settings
:
Map
<
String
,
Value
<
Any
>>
=
getSettingsInteractor
.
get
(
currentServer
)
private
val
baseUrl
=
settings
.
baseUrl
()
private
val
currentUsername
:
String
?
=
localRepository
.
get
(
LocalRepository
.
USERNAME_KEY
)
private
val
token
=
tokenRepository
.
get
(
)
private
val
token
=
tokenRepository
.
get
(
currentServer
)
private
val
currentUsername
:
String
?
=
localRepository
.
get
(
LocalRepository
.
CURRENT_USERNAME_KEY
)
suspend
fun
map
(
message
:
Message
):
List
<
BaseViewModel
<*
>>
{
return
translate
(
message
)
...
...
@@ -249,6 +251,7 @@ class ViewModelMapper @Inject constructor(private val context: Context,
val
quoteMessage
:
Message
=
quote
quoteViewModel
=
mapMessage
(
quoteMessage
)
}
return
parser
.
renderMarkdown
(
message
.
message
,
quoteViewModel
,
currentUsername
)
}
...
...
app/src/main/java/chat/rocket/android/chatrooms/presentation/ChatRoomsPresenter.kt
View file @
f136cf38
...
...
@@ -135,7 +135,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
private
fun
updateRooms
()
{
Timber
.
d
(
"Updating Rooms"
)
launch
{
launch
(
strategy
.
jobs
)
{
view
.
updateChatRooms
(
getChatRoomsInteractor
.
get
(
currentServer
))
}
}
...
...
app/src/main/java/chat/rocket/android/chatrooms/ui/ChatRoomsFragment.kt
View file @
f136cf38
...
...
@@ -110,9 +110,13 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
override
fun
hideLoading
()
=
view_loading
.
setVisible
(
false
)
override
fun
showMessage
(
resId
:
Int
)
=
showToast
(
resId
)
override
fun
showMessage
(
resId
:
Int
)
{
showToast
(
resId
)
}
override
fun
showMessage
(
message
:
String
)
=
showToast
(
message
)
override
fun
showMessage
(
message
:
String
)
{
showToast
(
message
)
}
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
...
...
app/src/main/java/chat/rocket/android/dagger/AppComponent.kt
View file @
f136cf38
...
...
@@ -4,6 +4,7 @@ import android.app.Application
import
chat.rocket.android.app.RocketChatApplication
import
chat.rocket.android.dagger.module.ActivityBuilder
import
chat.rocket.android.dagger.module.AppModule
import
chat.rocket.android.dagger.module.ReceiverBuilder
import
chat.rocket.android.dagger.module.ServiceBuilder
import
chat.rocket.android.push.FirebaseTokenService
import
dagger.BindsInstance
...
...
@@ -12,7 +13,8 @@ import dagger.android.support.AndroidSupportInjectionModule
import
javax.inject.Singleton
@Singleton
@Component
(
modules
=
[
AndroidSupportInjectionModule
::
class
,
AppModule
::
class
,
ActivityBuilder
::
class
,
ServiceBuilder
::
class
])
@Component
(
modules
=
[
AndroidSupportInjectionModule
::
class
,
AppModule
::
class
,
ActivityBuilder
::
class
,
ServiceBuilder
::
class
,
ReceiverBuilder
::
class
])
interface
AppComponent
{
@Component
.
Builder
...
...
app/src/main/java/chat/rocket/android/dagger/module/ActivityBuilder.kt
View file @
f136cf38
...
...
@@ -16,6 +16,8 @@ import chat.rocket.android.main.di.MainModule
import
chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.members.di.MembersFragmentProvider
import
chat.rocket.android.profile.di.ProfileFragmentProvider
import
chat.rocket.android.server.di.ChangeServerModule
import
chat.rocket.android.server.ui.ChangeServerActivity
import
chat.rocket.android.settings.password.di.PasswordFragmentProvider
import
chat.rocket.android.settings.password.ui.PasswordActivity
import
dagger.Module
...
...
@@ -51,4 +53,8 @@ abstract class ActivityBuilder {
@PerActivity
@ContributesAndroidInjector
(
modules
=
[
PasswordFragmentProvider
::
class
])
abstract
fun
bindPasswordActivity
():
PasswordActivity
@PerActivity
@ContributesAndroidInjector
(
modules
=
[
ChangeServerModule
::
class
])
abstract
fun
bindChangeServerActivity
():
ChangeServerActivity
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/dagger/module/AppModule.kt
View file @
f136cf38
package
chat.rocket.android.dagger.module
import
android.app.Application
import
android.app.NotificationManager
import
android.arch.persistence.room.Room
import
android.content.Context
import
android.content.SharedPreferences
import
androidx.content.systemService
import
chat.rocket.android.BuildConfig
import
chat.rocket.android.R
import
chat.rocket.android.app.RocketChatDatabase
import
chat.rocket.android.authentication.infraestructure.MemoryTokenRepository
import
chat.rocket.android.authentication.infraestructure.SharedPreferencesMultiServerTokenRepository
import
chat.rocket.android.authentication.infraestructure.SharedPreferencesTokenRepository
import
chat.rocket.android.dagger.qualifier.ForFresco
import
chat.rocket.android.helper.FrescoAuthInterceptor
import
chat.rocket.android.helper.MessageParser
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.infrastructure.SharedPrefsLocalRepository
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.infraestructure.*
import
chat.rocket.android.push.GroupedPush
import
chat.rocket.android.server.domain.AccountsRepository
import
chat.rocket.android.server.domain.ChatRoomsRepository
import
chat.rocket.android.server.domain.CurrentServerRepository
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.GetPermissionsInteractor
import
chat.rocket.android.server.domain.MessagesRepository
import
chat.rocket.android.server.domain.MultiServerTokenRepository
import
chat.rocket.android.server.domain.RoomRepository
import
chat.rocket.android.server.domain.SettingsRepository
import
chat.rocket.android.server.domain.TokenRepository
import
chat.rocket.android.server.domain.UsersRepository
import
chat.rocket.android.server.infraestructure.MemoryChatRoomsRepository
import
chat.rocket.android.server.infraestructure.MemoryMessagesRepository
import
chat.rocket.android.server.infraestructure.MemoryRoomRepository
import
chat.rocket.android.server.infraestructure.MemoryUsersRepository
import
chat.rocket.android.server.infraestructure.ServerDao
import
chat.rocket.android.server.infraestructure.SharedPreferencesAccountsRepository
import
chat.rocket.android.server.infraestructure.SharedPreferencesSettingsRepository
import
chat.rocket.android.server.infraestructure.SharedPrefsCurrentServerRepository
import
chat.rocket.android.util.AppJsonAdapterFactory
import
chat.rocket.android.util.TimberLogger
import
chat.rocket.common.internal.FallbackSealedClassJsonAdapter
import
chat.rocket.common.util.PlatformLogger
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.TokenRepository
import
com.facebook.drawee.backends.pipeline.DraweeConfig
import
com.facebook.imagepipeline.backends.okhttp3.OkHttpImagePipelineConfigFactory
import
com.facebook.imagepipeline.core.ImagePipelineConfig
...
...
@@ -110,8 +130,8 @@ class AppModule {
@Provides
@ForFresco
@Singleton
fun
provideFrescoAuthIntercepter
(
tokenRepository
:
TokenRepository
):
Interceptor
{
return
FrescoAuthInterceptor
(
tokenRepository
)
fun
provideFrescoAuthIntercepter
(
tokenRepository
:
TokenRepository
,
currentServerInteractor
:
GetCurrentServerInteractor
):
Interceptor
{
return
FrescoAuthInterceptor
(
tokenRepository
,
currentServerInteractor
)
}
@Provides
...
...
@@ -144,8 +164,8 @@ class AppModule {
@Provides
@Singleton
fun
provideTokenRepository
():
TokenRepository
{
return
MemoryTokenRepository
(
)
fun
provideTokenRepository
(
prefs
:
SharedPreferences
,
moshi
:
Moshi
):
TokenRepository
{
return
SharedPreferencesTokenRepository
(
prefs
,
moshi
)
}
@Provides
...
...
@@ -192,7 +212,10 @@ class AppModule {
@Provides
@Singleton
fun
provideMoshi
():
Moshi
{
return
Moshi
.
Builder
().
add
(
AppJsonAdapterFactory
.
INSTANCE
).
build
()
return
Moshi
.
Builder
()
.
add
(
FallbackSealedClassJsonAdapter
.
ADAPTER_FACTORY
)
.
add
(
AppJsonAdapterFactory
.
INSTANCE
)
.
build
()
}
@Provides
...
...
@@ -240,4 +263,16 @@ class AppModule {
fun
providePermissionInteractor
(
settingsRepository
:
SettingsRepository
,
serverRepository
:
CurrentServerRepository
):
GetPermissionsInteractor
{
return
GetPermissionsInteractor
(
settingsRepository
,
serverRepository
)
}
@Provides
@Singleton
fun
provideAccountsRepository
(
preferences
:
SharedPreferences
,
moshi
:
Moshi
):
AccountsRepository
=
SharedPreferencesAccountsRepository
(
preferences
,
moshi
)
@Provides
fun
provideNotificationManager
(
context
:
Context
):
NotificationManager
=
context
.
systemService
()
@Provides
@Singleton
fun
provideGroupedPush
()
=
GroupedPush
()
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/dagger/module/ReceiverBuilder.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.dagger.module
import
chat.rocket.android.push.DeleteReceiver
import
chat.rocket.android.push.di.DeleteReceiverProvider
import
dagger.Module
import
dagger.android.ContributesAndroidInjector
@Module
abstract
class
ReceiverBuilder
{
@ContributesAndroidInjector
(
modules
=
[
DeleteReceiverProvider
::
class
])
abstract
fun
bindDeleteReceiver
():
DeleteReceiver
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/dagger/module/ServiceBuilder.kt
View file @
f136cf38
package
chat.rocket.android.dagger.module
import
chat.rocket.android.push.FirebaseTokenService
import
chat.rocket.android.push.GcmListenerService
import
chat.rocket.android.push.di.FirebaseTokenServiceProvider
import
chat.rocket.android.push.di.GcmListenerServiceProvider
import
dagger.Module
import
dagger.android.ContributesAndroidInjector
...
...
@@ -9,4 +11,7 @@ import dagger.android.ContributesAndroidInjector
@ContributesAndroidInjector
(
modules
=
[
FirebaseTokenServiceProvider
::
class
])
abstract
fun
bindFirebaseTokenService
():
FirebaseTokenService
@ContributesAndroidInjector
(
modules
=
[
GcmListenerServiceProvider
::
class
])
abstract
fun
bindGcmListenerService
():
GcmListenerService
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/helper/FrescoAuthInterceptor.kt
View file @
f136cf38
package
chat.rocket.android.helper
import
chat.rocket.core.TokenRepository
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.TokenRepository
import
okhttp3.Interceptor
import
okhttp3.Response
class
FrescoAuthInterceptor
(
private
val
tokenRepository
:
TokenRepository
)
:
Interceptor
{
class
FrescoAuthInterceptor
(
private
val
tokenRepository
:
TokenRepository
,
private
val
currentServerInteractor
:
GetCurrentServerInteractor
)
:
Interceptor
{
override
fun
intercept
(
chain
:
Interceptor
.
Chain
):
Response
{
val
token
=
tokenRepository
.
get
()
var
request
=
chain
.
request
()
currentServerInteractor
.
get
()
?.
let
{
serverUrl
->
val
token
=
tokenRepository
.
get
(
serverUrl
)
token
?.
let
{
return
@let
token
?.
let
{
val
url
=
request
.
url
().
newBuilder
().
apply
{
addQueryParameter
(
"rc_uid"
,
token
.
userId
)
addQueryParameter
(
"rc_token"
,
token
.
authToken
)
...
...
@@ -18,7 +24,7 @@ class FrescoAuthInterceptor(private val tokenRepository: TokenRepository) : Inte
url
(
url
)
}.
build
()
}
}
return
chain
.
proceed
(
request
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/helper/UrlHelper.kt
View file @
f136cf38
...
...
@@ -14,6 +14,16 @@ object UrlHelper {
fun
getAvatarUrl
(
serverUrl
:
String
,
avatarName
:
String
,
format
:
String
=
"jpeg"
):
String
=
removeTrailingSlash
(
serverUrl
)
+
"/avatar/"
+
removeTrailingSlash
(
avatarName
)
+
"?format=$format"
/**
* Returns the server logo URL.
*
* @param serverUrl The server URL.
* @param favicon The faviconLarge from the server settings.
* @return The server logo URL.
*/
fun
getServerLogoUrl
(
serverUrl
:
String
,
favicon
:
String
):
String
=
removeTrailingSlash
(
serverUrl
)
+
"/$favicon"
/**
* Returns the CAS URL.
*
...
...
app/src/main/java/chat/rocket/android/infrastructure/LocalRepository.kt
View file @
f136cf38
...
...
@@ -2,18 +2,24 @@ package chat.rocket.android.infrastructure
interface
LocalRepository
{
fun
save
(
key
:
String
,
value
:
String
?)
fun
save
(
key
:
String
,
value
:
Boolean
)
fun
save
(
key
:
String
,
value
:
Int
)
fun
save
(
key
:
String
,
value
:
Long
)
fun
save
(
key
:
String
,
value
:
Float
)
fun
get
(
key
:
String
):
String
?
fun
getBoolean
(
key
:
String
):
Boolean
fun
getFloat
(
key
:
String
):
Float
fun
getInt
(
key
:
String
):
Int
fun
getLong
(
key
:
String
):
Long
fun
clear
(
key
:
String
)
fun
clearAllFromServer
(
server
:
String
)
companion
object
{
const
val
KEY_PUSH_TOKEN
=
"KEY_PUSH_TOKEN"
const
val
MIGRATION_FINISHED_KEY
=
"MIGRATION_FINISHED_KEY"
const
val
TOKEN_KEY
=
"token_"
const
val
SETTINGS_KEY
=
"settings_"
const
val
USERNAME_KEY
=
"my_username
"
const
val
CURRENT_USERNAME_KEY
=
"username_
"
}
fun
save
(
key
:
String
,
value
:
String
?)
fun
get
(
key
:
String
):
String
?
fun
clear
(
key
:
String
)
fun
clearAllFromServer
(
server
:
String
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/infrastructure/SharedPrefsLocalRepository.kt
View file @
f136cf38
...
...
@@ -3,23 +3,32 @@ package chat.rocket.android.infrastructure
import
android.content.SharedPreferences
class
SharedPrefsLocalRepository
(
private
val
preferences
:
SharedPreferences
)
:
LocalRepository
{
override
fun
getBoolean
(
key
:
String
)
=
preferences
.
getBoolean
(
key
,
false
)
override
fun
save
(
key
:
String
,
value
:
String
?)
{
preferences
.
edit
().
putString
(
key
,
value
).
apply
()
}
override
fun
getFloat
(
key
:
String
)
=
preferences
.
getFloat
(
key
,
-
1f
)
override
fun
get
(
key
:
String
):
String
?
{
return
preferences
.
getString
(
key
,
null
)
}
override
fun
getInt
(
key
:
String
)
=
preferences
.
getInt
(
key
,
-
1
)
override
fun
clear
(
key
:
String
)
{
preferences
.
edit
().
remove
(
key
).
apply
()
}
override
fun
getLong
(
key
:
String
)
=
preferences
.
getLong
(
key
,
-
1L
)
override
fun
save
(
key
:
String
,
value
:
Int
)
=
preferences
.
edit
().
putInt
(
key
,
value
).
apply
()
override
fun
save
(
key
:
String
,
value
:
Float
)
=
preferences
.
edit
().
putFloat
(
key
,
value
).
apply
()
override
fun
save
(
key
:
String
,
value
:
Long
)
=
preferences
.
edit
().
putLong
(
key
,
value
).
apply
()
override
fun
save
(
key
:
String
,
value
:
Boolean
)
=
preferences
.
edit
().
putBoolean
(
key
,
value
).
apply
()
override
fun
save
(
key
:
String
,
value
:
String
?)
=
preferences
.
edit
().
putString
(
key
,
value
).
apply
()
override
fun
get
(
key
:
String
):
String
?
=
preferences
.
getString
(
key
,
null
)
override
fun
clear
(
key
:
String
)
=
preferences
.
edit
().
remove
(
key
).
apply
()
override
fun
clearAllFromServer
(
server
:
String
)
{
clear
(
LocalRepository
.
KEY_PUSH_TOKEN
)
clear
(
LocalRepository
.
TOKEN_KEY
+
server
)
clear
(
LocalRepository
.
SETTINGS_KEY
+
server
)
clear
(
LocalRepository
.
USERNAME_KEY
+
server
)
clear
(
LocalRepository
.
CURRENT_USERNAME_KEY
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/adapter/AccountViewHolder.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.main.adapter
import
android.support.v7.widget.RecyclerView
import
android.view.View
import
chat.rocket.android.server.domain.model.Account
import
kotlinx.android.synthetic.main.item_account.view.*
class
AccountViewHolder
(
itemView
:
View
)
:
RecyclerView
.
ViewHolder
(
itemView
)
{
fun
bind
(
account
:
Account
)
{
with
(
itemView
)
{
server_logo
.
setImageURI
(
account
.
serverLogo
)
text_server_url
.
text
=
account
.
serverUrl
text_username
.
text
=
account
.
userName
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/adapter/AccountsAdapter.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.main.adapter
import
android.support.v7.widget.RecyclerView
import
android.view.ViewGroup
import
chat.rocket.android.R
import
chat.rocket.android.server.domain.model.Account
import
chat.rocket.android.util.extensions.inflate
class
AccountsAdapter
(
private
val
accounts
:
List
<
Account
>,
private
val
selector
:
AccountSelector
)
:
RecyclerView
.
Adapter
<
RecyclerView
.
ViewHolder
>()
{
override
fun
onCreateViewHolder
(
parent
:
ViewGroup
,
viewType
:
Int
):
RecyclerView
.
ViewHolder
{
return
when
(
viewType
)
{
VIEW_TYPE_ACCOUNT
->
AccountViewHolder
(
parent
.
inflate
(
R
.
layout
.
item_account
))
else
->
AddAccountViewHolder
(
parent
.
inflate
(
R
.
layout
.
item_add_account
))
}
}
override
fun
getItemCount
()
=
accounts
.
size
+
1
override
fun
getItemViewType
(
position
:
Int
)
=
if
(
position
==
accounts
.
size
)
VIEW_TYPE_ADD_ACCOUNT
else
VIEW_TYPE_ACCOUNT
override
fun
onBindViewHolder
(
holder
:
RecyclerView
.
ViewHolder
,
position
:
Int
)
{
when
(
holder
)
{
is
AccountViewHolder
->
bindAccountViewHolder
(
holder
,
position
)
is
AddAccountViewHolder
->
bindAddAccountViewHolder
(
holder
,
position
)
}
}
private
fun
bindAccountViewHolder
(
holder
:
AccountViewHolder
,
position
:
Int
)
{
val
account
=
accounts
[
position
]
holder
.
bind
(
account
)
holder
.
itemView
.
setOnClickListener
{
selector
.
onAccountSelected
(
account
.
serverUrl
)
}
}
private
fun
bindAddAccountViewHolder
(
holder
:
AddAccountViewHolder
,
position
:
Int
)
{
holder
.
itemView
.
setOnClickListener
{
selector
.
onAddedAccountSelected
()
}
}
}
interface
AccountSelector
{
fun
onAccountSelected
(
serverUrl
:
String
)
fun
onAddedAccountSelected
()
}
private
const
val
VIEW_TYPE_ACCOUNT
=
0
private
const
val
VIEW_TYPE_ADD_ACCOUNT
=
1
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/adapter/AddAccountViewHolder.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.main.adapter
import
android.support.v7.widget.RecyclerView
import
android.view.View
class
AddAccountViewHolder
(
itemView
:
View
)
:
RecyclerView
.
ViewHolder
(
itemView
)
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/di/MainModule.kt
View file @
f136cf38
...
...
@@ -16,7 +16,7 @@ class MainModule {
@Provides
@PerActivity
fun
provideMainNavigator
(
activity
:
MainActivity
,
context
:
Context
)
=
MainNavigator
(
activity
,
context
)
fun
provideMainNavigator
(
activity
:
MainActivity
)
=
MainNavigator
(
activity
)
@Provides
fun
provideMainView
(
activity
:
MainActivity
):
MainView
=
activity
...
...
app/src/main/java/chat/rocket/android/main/presentation/MainNavigator.kt
View file @
f136cf38
...
...
@@ -2,14 +2,16 @@ package chat.rocket.android.main.presentation
import
android.content.Context
import
chat.rocket.android.R
import
chat.rocket.android.authentication.ui.newServerIntent
import
chat.rocket.android.chatroom.ui.chatRoomIntent
import
chat.rocket.android.chatrooms.ui.ChatRoomsFragment
import
chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.profile.ui.ProfileFragment
import
chat.rocket.android.server.ui.changeServerIntent
import
chat.rocket.android.settings.ui.SettingsFragment
import
chat.rocket.android.util.extensions.addFragment
class
MainNavigator
(
internal
val
activity
:
MainActivity
,
internal
val
context
:
Context
)
{
class
MainNavigator
(
internal
val
activity
:
MainActivity
)
{
fun
toChatList
()
{
activity
.
addFragment
(
"ChatRoomsFragment"
,
R
.
id
.
fragment_container
)
{
...
...
@@ -35,8 +37,17 @@ class MainNavigator(internal val activity: MainActivity, internal val context: C
isChatRoomReadOnly
:
Boolean
,
chatRoomLastSeen
:
Long
,
isChatRoomSubscribed
:
Boolean
)
{
activity
.
startActivity
(
context
.
chatRoomIntent
(
chatRoomId
,
chatRoomName
,
chatRoomType
,
activity
.
startActivity
(
activity
.
chatRoomIntent
(
chatRoomId
,
chatRoomName
,
chatRoomType
,
isChatRoomReadOnly
,
chatRoomLastSeen
,
isChatRoomSubscribed
))
activity
.
overridePendingTransition
(
R
.
anim
.
open_enter
,
R
.
anim
.
open_exit
)
}
fun
toNewServer
(
serverUrl
:
String
?
=
null
)
{
activity
.
startActivity
(
activity
.
changeServerIntent
(
serverUrl
))
activity
.
finish
()
}
fun
toServerScreen
()
{
activity
.
startActivity
(
activity
.
newServerIntent
())
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/presentation/MainPresenter.kt
View file @
f136cf38
package
chat.rocket.android.main.presentation
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.main.viewmodel.NavHeaderViewModel
import
chat.rocket.android.main.viewmodel.NavHeaderViewModelMapper
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.domain.model.Account
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.android.util.extensions.registerPushToken
import
chat.rocket.common.RocketChatException
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.realtime.disconnect
import
chat.rocket.core.internal.rest.logout
import
chat.rocket.core.internal.rest.me
import
chat.rocket.core.internal.rest.registerPushToken
import
chat.rocket.core.internal.rest.unregisterPushToken
import
timber.log.Timber
import
javax.inject.Inject
class
MainPresenter
@Inject
constructor
(
private
val
view
:
MainView
,
class
MainPresenter
@Inject
constructor
(
private
val
view
:
MainView
,
private
val
strategy
:
CancelStrategy
,
private
val
navigator
:
MainNavigator
,
private
val
tokenRepository
:
TokenRepository
,
private
val
serverInteractor
:
GetCurrentServerInteractor
,
private
val
localRepository
:
LocalRepository
,
managerFactory
:
ConnectionManagerFactory
,
factory
:
RocketChatClientFactory
)
{
private
val
navHeaderMapper
:
NavHeaderViewModelMapper
,
private
val
saveAccountInteractor
:
SaveAccountInteractor
,
private
val
getAccountsInteractor
:
GetAccountsInteractor
,
private
val
removeAccountInterector
:
RemoveAccountInterector
,
private
val
factory
:
RocketChatClientFactory
,
getSettingsInteractor
:
GetSettingsInteractor
,
managerFactory
:
ConnectionManagerFactory
)
{
private
val
currentServer
=
serverInteractor
.
get
()
!!
private
val
manager
=
managerFactory
.
create
(
currentServer
)
private
val
client
:
RocketChatClient
=
factory
.
create
(
currentServer
)
private
var
settings
:
PublicSettings
=
getSettingsInteractor
.
get
(
serverInteractor
.
get
()
!!
)
fun
toChatList
()
=
navigator
.
toChatList
()
...
...
@@ -31,6 +47,32 @@ class MainPresenter @Inject constructor(private val view: MainView,
fun
toSettings
()
=
navigator
.
toSettings
()
fun
loadCurrentInfo
()
{
launchUI
(
strategy
)
{
try
{
val
me
=
client
.
me
()
val
model
=
navHeaderMapper
.
mapToViewModel
(
me
)
saveAccount
(
model
)
view
.
setupNavHeader
(
model
,
getAccountsInteractor
.
get
())
}
catch
(
ex
:
Exception
)
{
Timber
.
d
(
ex
,
"Error loading my information for navheader"
)
ex
.
message
?.
let
{
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
}
}
}
}
private
suspend
fun
saveAccount
(
me
:
NavHeaderViewModel
)
{
val
icon
=
settings
.
favicon
()
?.
let
{
UrlHelper
.
getServerLogoUrl
(
currentServer
,
it
)
}
val
account
=
Account
(
currentServer
,
icon
,
me
.
serverLogo
,
me
.
username
,
me
.
avatar
)
saveAccountInteractor
.
save
(
account
)
}
/**
* Logout from current server.
*/
...
...
@@ -39,9 +81,10 @@ class MainPresenter @Inject constructor(private val view: MainView,
try
{
clearTokens
()
client
.
logout
()
//TODO: Add the code to unsubscribe to all subscriptions.
client
.
disconnect
()
view
.
onLogout
()
disconnect
()
removeAccountInterector
.
remove
(
currentServer
)
tokenRepository
.
remove
(
currentServer
)
navigator
.
toNewServer
()
}
catch
(
exception
:
RocketChatException
)
{
exception
.
message
?.
let
{
view
.
showMessage
(
it
)
...
...
@@ -69,4 +112,22 @@ class MainPresenter @Inject constructor(private val view: MainView,
fun
disconnect
()
{
manager
.
disconnect
()
}
fun
changeServer
(
serverUrl
:
String
)
{
if
(
currentServer
!=
serverUrl
)
{
navigator
.
toNewServer
(
serverUrl
)
}
else
{
view
.
closeServerSelection
()
}
}
fun
addNewServer
()
{
navigator
.
toServerScreen
()
}
suspend
fun
refreshToken
(
token
:
String
?)
{
token
?.
let
{
client
.
registerPushToken
(
it
,
getAccountsInteractor
.
get
(),
factory
)
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/presentation/MainView.kt
View file @
f136cf38
package
chat.rocket.android.main.presentation
import
chat.rocket.android.core.behaviours.MessageView
import
chat.rocket.android.main.viewmodel.NavHeaderViewModel
import
chat.rocket.android.server.domain.model.Account
interface
MainView
:
MessageView
{
/**
* User has successfully logged out from the current server.
**/
fun
onLogout
()
fun
setupNavHeader
(
model
:
NavHeaderViewModel
,
accounts
:
List
<
Account
>)
fun
closeServerSelection
()
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/ui/MainActivity.kt
View file @
f136cf38
package
chat.rocket.android.main.ui
import
android.app.Activity
import
android.content.Intent
import
android.os.Bundle
import
android.support.v4.app.Fragment
import
android.support.v7.app.AppCompatActivity
import
android.support.v7.widget.LinearLayoutManager
import
android.view.Gravity
import
android.view.MenuItem
import
android.view.View
import
chat.rocket.android.R
import
chat.rocket.android.authentication.ui.AuthenticationActivity
import
chat.rocket.android.main.adapter.AccountSelector
import
chat.rocket.android.main.adapter.AccountsAdapter
import
chat.rocket.android.main.presentation.MainPresenter
import
chat.rocket.android.main.presentation.MainView
import
chat.rocket.android.main.viewmodel.NavHeaderViewModel
import
chat.rocket.android.server.domain.model.Account
import
chat.rocket.android.util.extensions.fadeIn
import
chat.rocket.android.util.extensions.fadeOut
import
chat.rocket.android.util.extensions.rotateBy
import
chat.rocket.android.util.extensions.showToast
import
com.google.android.gms.gcm.GoogleCloudMessaging
import
com.google.android.gms.iid.InstanceID
import
dagger.android.AndroidInjection
import
dagger.android.AndroidInjector
import
dagger.android.DispatchingAndroidInjector
...
...
@@ -19,6 +28,10 @@ import dagger.android.HasActivityInjector
import
dagger.android.support.HasSupportFragmentInjector
import
kotlinx.android.synthetic.main.activity_main.*
import
kotlinx.android.synthetic.main.app_bar.*
import
kotlinx.android.synthetic.main.nav_header.view.*
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.launch
import
timber.log.Timber
import
javax.inject.Inject
class
MainActivity
:
AppCompatActivity
(),
MainView
,
HasActivityInjector
,
HasSupportFragmentInjector
{
...
...
@@ -32,7 +45,14 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp
super
.
onCreate
(
savedInstanceState
)
setContentView
(
R
.
layout
.
activity_main
)
launch
(
CommonPool
)
{
val
token
=
InstanceID
.
getInstance
(
this
@MainActivity
).
getToken
(
getString
(
R
.
string
.
gcm_sender_id
),
GoogleCloudMessaging
.
INSTANCE_ID_SCOPE
,
null
)
Timber
.
d
(
"GCM token: $token"
)
presenter
.
refreshToken
(
token
)
}
presenter
.
connect
()
presenter
.
loadCurrentInfo
()
setupToolbar
()
setupNavigationView
()
}
...
...
@@ -52,11 +72,45 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp
}
}
override
fun
onLogout
()
{
finish
()
val
intent
=
Intent
(
this
,
AuthenticationActivity
::
class
.
java
)
intent
.
addFlags
(
Intent
.
FLAG_ACTIVITY_CLEAR_TASK
or
Intent
.
FLAG_ACTIVITY_NEW_TASK
)
startActivity
(
intent
)
override
fun
setupNavHeader
(
model
:
NavHeaderViewModel
,
accounts
:
List
<
Account
>)
{
Timber
.
d
(
"Setting up nav header: $model"
)
val
headerLayout
=
view_navigation
.
getHeaderView
(
0
)
headerLayout
.
text_name
.
text
=
model
.
username
headerLayout
.
text_server
.
text
=
model
.
server
headerLayout
.
image_avatar
.
setImageURI
(
model
.
avatar
)
headerLayout
.
server_logo
.
setImageURI
(
model
.
serverLogo
)
setupAccountsList
(
headerLayout
,
accounts
)
}
override
fun
closeServerSelection
()
{
view_navigation
.
getHeaderView
(
0
).
account_container
.
performClick
()
}
private
var
expanded
=
false
private
fun
setupAccountsList
(
header
:
View
,
accounts
:
List
<
Account
>)
{
accounts_list
.
layoutManager
=
LinearLayoutManager
(
this
)
accounts_list
.
adapter
=
AccountsAdapter
(
accounts
,
object
:
AccountSelector
{
override
fun
onAccountSelected
(
serverUrl
:
String
)
{
presenter
.
changeServer
(
serverUrl
)
}
override
fun
onAddedAccountSelected
()
{
presenter
.
addNewServer
()
}
})
header
.
account_container
.
setOnClickListener
{
header
.
account_expand
.
rotateBy
(
180f
)
if
(
expanded
)
{
accounts_list
.
fadeOut
()
}
else
{
accounts_list
.
fadeIn
()
}
expanded
=
!
expanded
}
}
override
fun
showMessage
(
resId
:
Int
)
=
showToast
(
resId
)
...
...
app/src/main/java/chat/rocket/android/main/viewmodel/NavHeaderViewModel.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.main.viewmodel
data class
NavHeaderViewModel
(
val
username
:
String
,
val
server
:
String
,
val
avatar
:
String
?,
val
serverLogo
:
String
?
)
\ No newline at end of file
app/src/main/java/chat/rocket/android/main/viewmodel/NavHeaderViewModelMapper.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.main.viewmodel
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.server.domain.*
import
chat.rocket.core.model.Myself
import
javax.inject.Inject
class
NavHeaderViewModelMapper
@Inject
constructor
(
serverInteractor
:
GetCurrentServerInteractor
,
getSettingsInteractor
:
GetSettingsInteractor
)
{
private
var
settings
:
PublicSettings
=
getSettingsInteractor
.
get
(
serverInteractor
.
get
()
!!
)
private
val
baseUrl
=
settings
.
baseUrl
()
!!
fun
mapToViewModel
(
me
:
Myself
):
NavHeaderViewModel
{
val
username
=
mapUsername
(
me
)
val
thumb
=
me
.
username
?.
let
{
UrlHelper
.
getAvatarUrl
(
baseUrl
,
it
)
}
val
image
=
settings
.
wideTile
()
?:
settings
.
faviconLarge
()
val
logo
=
image
?.
let
{
UrlHelper
.
getServerLogoUrl
(
baseUrl
,
it
)
}
return
NavHeaderViewModel
(
username
,
baseUrl
,
thumb
,
logo
)
}
private
fun
mapUsername
(
me
:
Myself
):
String
{
val
username
=
me
.
username
val
realName
=
me
.
name
val
senderName
=
if
(
settings
.
useRealName
())
realName
else
username
return
senderName
?:
username
.
toString
()
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/members/ui/MembersFragment.kt
View file @
f136cf38
...
...
@@ -90,9 +90,13 @@ class MembersFragment : Fragment(), MembersView {
override
fun
hideLoading
()
=
view_loading
.
setVisible
(
false
)
override
fun
showMessage
(
resId
:
Int
)
=
showToast
(
resId
)
override
fun
showMessage
(
resId
:
Int
)
{
showToast
(
resId
)
}
override
fun
showMessage
(
message
:
String
)
=
showToast
(
message
)
override
fun
showMessage
(
message
:
String
)
{
showToast
(
message
)
}
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
...
...
app/src/main/java/chat/rocket/android/profile/ui/ProfileFragment.kt
View file @
f136cf38
...
...
@@ -66,7 +66,9 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
listenToChanges
()
}
override
fun
showProfileUpdateSuccessfullyMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_profile_update_successfully
))
override
fun
showProfileUpdateSuccessfullyMessage
()
{
showMessage
(
getString
(
R
.
string
.
msg_profile_update_successfully
))
}
override
fun
showLoading
()
{
enableUserInput
(
false
)
...
...
@@ -78,9 +80,13 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
enableUserInput
(
true
)
}
override
fun
showMessage
(
resId
:
Int
)
=
showToast
(
resId
)
override
fun
showMessage
(
resId
:
Int
)
{
showToast
(
resId
)
}
override
fun
showMessage
(
message
:
String
)
=
showToast
(
message
)
override
fun
showMessage
(
message
:
String
)
{
showToast
(
message
)
}
override
fun
showGenericErrorMessage
()
=
showMessage
(
getString
(
R
.
string
.
msg_generic_error
))
...
...
app/src/main/java/chat/rocket/android/push/DeleteReceiver.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.push
import
android.content.BroadcastReceiver
import
android.content.Context
import
android.content.Intent
import
dagger.android.AndroidInjection
import
javax.inject.Inject
/**
* BroadcastReceiver for dismissed notifications.
*/
class
DeleteReceiver
:
BroadcastReceiver
()
{
@Inject
lateinit
var
groupedPushes
:
GroupedPush
override
fun
onReceive
(
context
:
Context
,
intent
:
Intent
)
{
AndroidInjection
.
inject
(
this
,
context
)
val
notId
=
intent
.
extras
?.
getInt
(
EXTRA_NOT_ID
)
val
host
=
intent
.
extras
?.
getString
(
EXTRA_HOSTNAME
)
if
(
host
!=
null
&&
notId
!=
null
)
{
clearNotificationsByHostAndNotificationId
(
host
,
notId
)
}
}
/**
* Clear notifications by the host they belong to and its unique id.
*/
fun
clearNotificationsByHostAndNotificationId
(
host
:
String
,
notificationId
:
Int
)
{
if
(
groupedPushes
.
hostToPushMessageList
.
isNotEmpty
())
{
val
notifications
=
groupedPushes
.
hostToPushMessageList
[
host
]
notifications
?.
let
{
notifications
.
removeAll
{
it
.
notificationId
.
toInt
()
==
notificationId
}
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/push/FirebaseTokenService.kt
View file @
f136cf38
...
...
@@ -2,6 +2,8 @@ package chat.rocket.android.push
import
chat.rocket.android.R
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.common.RocketChatException
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.rest.registerPushToken
...
...
@@ -16,14 +18,16 @@ import javax.inject.Inject
class
FirebaseTokenService
:
FirebaseInstanceIdService
()
{
@Inject
lateinit
var
client
:
RocketChatClient
lateinit
var
factory
:
RocketChatClientFactory
@Inject
lateinit
var
getCurrentServerInteractor
:
GetCurrentServerInteractor
@Inject
lateinit
var
localRepository
:
LocalRepository
override
fun
onCreate
()
{
super
.
onCreate
()
AndroidInjection
.
inject
(
this
)
;
AndroidInjection
.
inject
(
this
)
}
override
fun
onTokenRefresh
()
{
...
...
@@ -31,11 +35,14 @@ class FirebaseTokenService : FirebaseInstanceIdService() {
// default push gateway. We should register this project's own project sender id into it.
val
gcmToken
=
InstanceID
.
getInstance
(
this
)
.
getToken
(
getString
(
R
.
string
.
gcm_sender_id
),
GoogleCloudMessaging
.
INSTANCE_ID_SCOPE
,
null
)
val
currentServer
=
getCurrentServerInteractor
.
get
()
!!
val
client
=
factory
.
create
(
currentServer
)
gcmToken
?.
let
{
localRepository
.
save
(
LocalRepository
.
KEY_PUSH_TOKEN
,
gcmToken
)
launch
{
try
{
Timber
.
d
(
"Registering push token: $gcmToken for ${client.url}"
)
client
.
registerPushToken
(
gcmToken
)
}
catch
(
ex
:
RocketChatException
)
{
Timber
.
e
(
ex
)
...
...
app/src/main/java/chat/rocket/android/push/GcmListenerService.kt
View file @
f136cf38
...
...
@@ -2,12 +2,22 @@ package chat.rocket.android.push
import
android.os.Bundle
import
com.google.android.gms.gcm.GcmListenerService
import
dagger.android.AndroidInjection
import
javax.inject.Inject
class
GcmListenerService
:
GcmListenerService
()
{
@Inject
lateinit
var
pushManager
:
PushManager
override
fun
onCreate
()
{
super
.
onCreate
()
AndroidInjection
.
inject
(
this
)
}
override
fun
onMessageReceived
(
from
:
String
?,
data
:
Bundle
?)
{
data
?.
let
{
PushManager
.
handle
(
this
,
data
)
pushManager
.
handle
(
data
)
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/push/GroupedPush.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.push
import
java.util.concurrent.atomic.AtomicInteger
import
javax.inject.Singleton
typealias
TupleGroupIdMessageCount
=
Pair
<
Int
,
AtomicInteger
>
class
GroupedPush
{
// Notifications received from the same server are grouped in a single bundled notification.
// This map associates a host to a group id.
val
groupMap
=
HashMap
<
String
,
TupleGroupIdMessageCount
>()
// Map a hostname to a list of push messages that pertain to it.
val
hostToPushMessageList
=
HashMap
<
String
,
MutableList
<
PushMessage
>>()
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/push/PushManager.kt
View file @
f136cf38
This diff is collapsed.
Click to expand it.
app/src/main/java/chat/rocket/android/push/di/DeleteReceiverProvider.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.push.di
import
chat.rocket.android.dagger.module.AppModule
import
chat.rocket.android.push.DeleteReceiver
import
dagger.Module
import
dagger.android.ContributesAndroidInjector
@Module
abstract
class
DeleteReceiverProvider
{
@ContributesAndroidInjector
(
modules
=
[
AppModule
::
class
])
abstract
fun
provideDeleteReceiver
():
DeleteReceiver
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/push/di/GcmListenerServiceProvider.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.push.di
import
chat.rocket.android.dagger.module.AppModule
import
chat.rocket.android.push.GcmListenerService
import
dagger.Module
import
dagger.android.ContributesAndroidInjector
@Module
abstract
class
GcmListenerServiceProvider
{
@ContributesAndroidInjector
(
modules
=
[
AppModule
::
class
])
abstract
fun
provideGcmListenerService
():
GcmListenerService
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/di/ChangeServerModule.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.server.di
import
android.arch.lifecycle.LifecycleOwner
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.dagger.scope.PerActivity
import
chat.rocket.android.server.presentation.ChangeServerNavigator
import
chat.rocket.android.server.presentation.ChangeServerView
import
chat.rocket.android.server.ui.ChangeServerActivity
import
dagger.Module
import
dagger.Provides
import
kotlinx.coroutines.experimental.Job
@Module
class
ChangeServerModule
{
@Provides
@PerActivity
fun
provideChangeServerNavigator
(
activity
:
ChangeServerActivity
)
=
ChangeServerNavigator
(
activity
)
@Provides
@PerActivity
fun
ChangeServerView
(
activity
:
ChangeServerActivity
):
ChangeServerView
{
return
activity
}
@Provides
fun
provideLifecycleOwner
(
activity
:
ChangeServerActivity
):
LifecycleOwner
=
activity
@Provides
fun
provideCancelStrategy
(
owner
:
LifecycleOwner
,
jobs
:
Job
):
CancelStrategy
=
CancelStrategy
(
owner
,
jobs
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/AccountsRepository.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.server.domain
import
chat.rocket.android.server.domain.model.Account
interface
AccountsRepository
{
suspend
fun
save
(
account
:
Account
)
suspend
fun
load
():
List
<
Account
>
suspend
fun
remove
(
serverUrl
:
String
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/GetAccountInteractor.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.server.domain
import
javax.inject.Inject
class
GetAccountInteractor
@Inject
constructor
(
val
repository
:
AccountsRepository
)
{
suspend
fun
get
(
url
:
String
)
=
repository
.
load
().
firstOrNull
{
account
->
url
==
account
.
serverUrl
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/GetAccountsInteractor.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.server.domain
import
javax.inject.Inject
class
GetAccountsInteractor
@Inject
constructor
(
val
repository
:
AccountsRepository
)
{
suspend
fun
get
()
=
repository
.
load
()
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/GetServersInteractor.java
deleted
100644 → 0
View file @
3d2ec050
package
chat
.
rocket
.
android
.
server
.
domain
;
import
java.util.List
;
import
io.reactivex.Scheduler
;
import
io.reactivex.Single
;
public
class
GetServersInteractor
{
private
final
ServersRepository
repository
;
private
final
Scheduler
executionScheduler
;
public
GetServersInteractor
(
ServersRepository
repository
,
Scheduler
executionScheduler
)
{
this
.
repository
=
repository
;
this
.
executionScheduler
=
executionScheduler
;
}
}
app/src/main/java/chat/rocket/android/server/domain/RefreshSettingsInteractor.kt
View file @
f136cf38
...
...
@@ -17,11 +17,12 @@ class RefreshSettingsInteractor @Inject constructor(private val factory: RocketC
ACCOUNT_GOOGLE
,
ACCOUNT_FACEBOOK
,
ACCOUNT_GITHUB
,
ACCOUNT_LINKEDIN
,
ACCOUNT_METEOR
,
ACCOUNT_TWITTER
,
ACCOUNT_WORDPRESS
,
ACCOUNT_GITLAB
,
SITE_URL
,
SITE_NAME
,
FAVICON_512
,
USE_REALNAME
,
ALLOW_ROOM_NAME_SPECIAL_CHARS
,
SITE_URL
,
SITE_NAME
,
FAVICON_512
,
FAVICON_196
,
USE_REALNAME
,
ALLOW_ROOM_NAME_SPECIAL_CHARS
,
FAVORITE_ROOMS
,
UPLOAD_STORAGE_TYPE
,
UPLOAD_MAX_FILE_SIZE
,
UPLOAD_WHITELIST_MIMETYPES
,
HIDE_USER_JOIN
,
HIDE_USER_LEAVE
,
HIDE_TYPE_AU
,
HIDE_MUTE_UNMUTE
,
HIDE_TYPE_RU
,
ALLOW_MESSAGE_DELETING
,
ALLOW_MESSAGE_EDITING
,
ALLOW_MESSAGE_PINNING
,
SHOW_DELETED_STATUS
,
SHOW_EDITED_STATUS
)
ALLOW_MESSAGE_EDITING
,
ALLOW_MESSAGE_PINNING
,
SHOW_DELETED_STATUS
,
SHOW_EDITED_STATUS
,
WIDE_TILE_310
)
suspend
fun
refresh
(
server
:
String
)
{
withContext
(
CommonPool
)
{
...
...
app/src/main/java/chat/rocket/android/server/domain/RemoveAccountInterector.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.server.domain
import
javax.inject.Inject
class
RemoveAccountInterector
@Inject
constructor
(
val
repository
:
AccountsRepository
)
{
suspend
fun
remove
(
serverUrl
:
String
)
{
repository
.
remove
(
serverUrl
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/SaveAccountInteractor.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.server.domain
import
chat.rocket.android.server.domain.model.Account
import
javax.inject.Inject
class
SaveAccountInteractor
@Inject
constructor
(
val
repository
:
AccountsRepository
)
{
suspend
fun
save
(
account
:
Account
)
=
repository
.
save
(
account
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/SaveServerInteractor.java
deleted
100644 → 0
View file @
3d2ec050
package
chat
.
rocket
.
android
.
server
.
domain
;
public
class
SaveServerInteractor
{
}
app/src/main/java/chat/rocket/android/server/domain/ServersRepository.kt
deleted
100644 → 0
View file @
3d2ec050
package
chat.rocket.android.server.domain
import
chat.rocket.android.server.domain.model.Server
import
chat.rocket.android.server.infraestructure.ServerEntity
import
io.reactivex.Completable
import
io.reactivex.Single
interface
ServersRepository
{
val
servers
:
Single
<
List
<
Server
>>
fun
saveServer
(
server
:
Server
):
Completable
fun
updateServer
(
server
:
Server
):
Completable
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/SettingsRepository.kt
View file @
f136cf38
...
...
@@ -29,7 +29,9 @@ const val ACCOUNT_GITLAB = "Accounts_OAuth_Gitlab"
const
val
SITE_URL
=
"Site_Url"
const
val
SITE_NAME
=
"Site_Name"
const
val
FAVICON_196
=
"Assets_favicon_192"
const
val
FAVICON_512
=
"Assets_favicon_512"
const
val
WIDE_TILE_310
=
"Assets_tile_310_wide"
const
val
USE_REALNAME
=
"UI_Use_Real_Name"
const
val
ALLOW_ROOM_NAME_SPECIAL_CHARS
=
"UI_Allow_room_names_with_special_chars"
const
val
FAVORITE_ROOMS
=
"Favorite_Rooms"
...
...
@@ -69,6 +71,9 @@ fun PublicSettings.isGitlabAuthenticationEnabled(): Boolean = this[ACCOUNT_GITLA
fun
PublicSettings
.
isWordpressAuthenticationEnabled
():
Boolean
=
this
[
ACCOUNT_WORDPRESS
]
?.
value
==
true
fun
PublicSettings
.
useRealName
():
Boolean
=
this
[
USE_REALNAME
]
?.
value
==
true
fun
PublicSettings
.
faviconLarge
():
String
?
=
this
[
FAVICON_512
]
?.
value
as
String
?
fun
PublicSettings
.
favicon
():
String
?
=
this
[
FAVICON_196
]
?.
value
as
String
?
fun
PublicSettings
.
wideTile
():
String
?
=
this
[
WIDE_TILE_310
]
?.
value
as
String
?
// Message settings
fun
PublicSettings
.
showDeletedStatus
():
Boolean
=
this
[
SHOW_DELETED_STATUS
]
?.
value
==
true
...
...
@@ -91,3 +96,4 @@ fun PublicSettings.uploadMaxFileSize(): Int {
}
fun
PublicSettings
.
baseUrl
():
String
?
=
this
[
SITE_URL
]
?.
value
as
String
fun
PublicSettings
.
siteName
():
String
?
=
this
[
SITE_NAME
]
?.
value
as
String
?
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/TokenRepository.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.server.domain
interface
TokenRepository
:
chat
.
rocket
.
core
.
TokenRepository
{
fun
remove
(
url
:
String
)
fun
clear
()
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/model/Account.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.server.domain.model
import
se.ansman.kotshi.JsonSerializable
@JsonSerializable
data class
Account
(
val
serverUrl
:
String
,
val
serverLogo
:
String
?,
val
serverBg
:
String
?,
val
userName
:
String
,
val
avatar
:
String
?
)
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/infraestructure/ConnectionManagerFactory.kt
View file @
f136cf38
...
...
@@ -19,4 +19,6 @@ class ConnectionManagerFactory @Inject constructor(private val factory: RocketCh
cache
[
url
]
=
manager
return
manager
}
fun
get
(
url
:
String
)
=
cache
[
url
]
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/infraestructure/RocketChatClientFactory.kt
View file @
f136cf38
...
...
@@ -2,16 +2,16 @@ package chat.rocket.android.server.infraestructure
import
chat.rocket.common.util.PlatformLogger
import
chat.rocket.core.RocketChatClient
import
chat.rocket.
core
.TokenRepository
import
chat.rocket.
android.server.domain
.TokenRepository
import
okhttp3.OkHttpClient
import
timber.log.Timber
import
javax.inject.Inject
import
javax.inject.Singleton
@Singleton
class
RocketChatClientFactory
@Inject
constructor
(
val
okHttpClient
:
OkHttpClient
,
val
repository
:
TokenRepository
,
val
logger
:
PlatformLogger
)
{
class
RocketChatClientFactory
@Inject
constructor
(
private
val
okHttpClient
:
OkHttpClient
,
private
val
repository
:
TokenRepository
,
private
val
logger
:
PlatformLogger
)
{
private
val
cache
=
HashMap
<
String
,
RocketChatClient
>()
fun
create
(
url
:
String
):
RocketChatClient
{
...
...
app/src/main/java/chat/rocket/android/server/infraestructure/RoomServersRepository.kt
deleted
100644 → 0
View file @
3d2ec050
package
chat.rocket.android.server.infraestructure
import
chat.rocket.android.server.domain.ServersRepository
import
chat.rocket.android.server.domain.model.Server
import
io.reactivex.Completable
import
io.reactivex.Single
class
RoomServersRepository
:
ServersRepository
{
override
val
servers
:
Single
<
List
<
Server
>>
get
()
=
TODO
(
"not implemented"
)
override
fun
saveServer
(
server
:
Server
):
Completable
{
TODO
(
"not implemented"
)
}
override
fun
updateServer
(
server
:
Server
):
Completable
{
TODO
(
"not implemented"
)
}
}
app/src/main/java/chat/rocket/android/server/infraestructure/SharedPreferencesAccountsRepository.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.server.infraestructure
import
android.content.SharedPreferences
import
androidx.content.edit
import
chat.rocket.android.server.domain.AccountsRepository
import
chat.rocket.android.server.domain.model.Account
import
com.squareup.moshi.Moshi
import
com.squareup.moshi.Types
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.withContext
class
SharedPreferencesAccountsRepository
(
private
val
preferences
:
SharedPreferences
,
private
val
moshi
:
Moshi
)
:
AccountsRepository
{
override
suspend
fun
save
(
newAccount
:
Account
)
{
withContext
(
CommonPool
)
{
val
accounts
=
load
()
val
newList
=
accounts
.
filter
{
account
->
newAccount
.
serverUrl
!=
account
.
serverUrl
}
.
toMutableList
()
newList
.
add
(
0
,
newAccount
)
save
(
newList
)
}
}
override
suspend
fun
load
():
List
<
Account
>
=
withContext
(
CommonPool
)
{
val
json
=
preferences
.
getString
(
ACCOUNTS_KEY
,
"[]"
)
val
type
=
Types
.
newParameterizedType
(
List
::
class
.
java
,
Account
::
class
.
java
)
val
adapter
=
moshi
.
adapter
<
List
<
Account
>>(
type
)
adapter
.
fromJson
(
json
)
?:
emptyList
()
}
override
suspend
fun
remove
(
serverUrl
:
String
)
{
withContext
(
CommonPool
)
{
val
accounts
=
load
()
val
newList
=
accounts
.
filter
{
account
->
serverUrl
!=
account
.
serverUrl
}
.
toMutableList
()
save
(
newList
)
}
}
private
fun
save
(
accounts
:
List
<
Account
>)
{
val
type
=
Types
.
newParameterizedType
(
List
::
class
.
java
,
Account
::
class
.
java
)
val
adapter
=
moshi
.
adapter
<
List
<
Account
>>(
type
)
preferences
.
edit
{
putString
(
ACCOUNTS_KEY
,
adapter
.
toJson
(
accounts
))
}
}
}
private
const
val
ACCOUNTS_KEY
=
"ACCOUNTS_KEY"
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/infraestructure/SharedPreferencesSettingsRepository.kt
View file @
f136cf38
...
...
@@ -15,9 +15,7 @@ class SharedPreferencesSettingsRepository(private val localRepository: LocalRepo
}
override
fun
get
(
url
:
String
):
PublicSettings
{
val
settings
=
localRepository
.
get
(
"$SETTINGS_KEY$url"
)
!!
settings
.
let
{
return
adapter
.
fromJson
(
it
)
!!
}
val
settings
=
localRepository
.
get
(
"$SETTINGS_KEY$url"
)
return
if
(
settings
==
null
)
hashMapOf
()
else
adapter
.
fromJson
(
settings
)
?:
hashMapOf
()
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/presentation/ChangeServerNavigator.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.server.presentation
import
android.content.Intent
import
chat.rocket.android.authentication.ui.newServerIntent
import
chat.rocket.android.main.ui.MainActivity
import
chat.rocket.android.server.ui.ChangeServerActivity
class
ChangeServerNavigator
(
internal
val
activity
:
ChangeServerActivity
)
{
fun
toServerScreen
()
{
activity
.
startActivity
(
activity
.
newServerIntent
())
activity
.
finish
()
}
fun
toChatRooms
()
{
activity
.
startActivity
(
Intent
(
activity
,
MainActivity
::
class
.
java
))
activity
.
finish
()
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/presentation/ChangeServerPresenter.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.server.presentation
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.*
import
chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.common.util.ifNull
import
javax.inject.Inject
class
ChangeServerPresenter
@Inject
constructor
(
private
val
view
:
ChangeServerView
,
private
val
navigator
:
ChangeServerNavigator
,
private
val
strategy
:
CancelStrategy
,
private
val
saveCurrentServerInteractor
:
SaveCurrentServerInteractor
,
private
val
getCurrentServerInteractor
:
GetCurrentServerInteractor
,
private
val
getAccountInteractor
:
GetAccountInteractor
,
private
val
getAccountsInteractor
:
GetAccountsInteractor
,
private
val
settingsRepository
:
SettingsRepository
,
private
val
tokenRepository
:
TokenRepository
,
private
val
localRepository
:
LocalRepository
,
private
val
connectionManager
:
ConnectionManagerFactory
)
{
fun
loadServer
(
newUrl
:
String
?)
{
launchUI
(
strategy
)
{
view
.
showProgress
()
var
url
=
newUrl
if
(
url
==
null
)
{
// Try to load next server on the list...
val
accounts
=
getAccountsInteractor
.
get
()
url
=
accounts
.
firstOrNull
()
?.
serverUrl
}
url
?.
let
{
serverUrl
->
val
token
=
tokenRepository
.
get
(
serverUrl
)
if
(
token
==
null
)
{
view
.
showInvalidCredentials
()
view
.
hideProgress
()
navigator
.
toServerScreen
()
return
@launchUI
}
val
settings
=
settingsRepository
.
get
(
serverUrl
)
if
(
settings
==
null
)
{
// TODO - reload settings...
}
// Call disconnect on the old url if any...
getCurrentServerInteractor
.
get
()
?.
let
{
url
->
connectionManager
.
get
(
url
)
?.
disconnect
()
}
// Save the current username.
getAccountInteractor
.
get
(
serverUrl
)
?.
let
{
account
->
localRepository
.
save
(
LocalRepository
.
CURRENT_USERNAME_KEY
,
account
.
userName
)
}
saveCurrentServerInteractor
.
save
(
serverUrl
)
view
.
hideProgress
()
navigator
.
toChatRooms
()
}.
ifNull
{
view
.
hideProgress
()
navigator
.
toServerScreen
()
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/presentation/ChangeServerView.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.server.presentation
interface
ChangeServerView
{
fun
showInvalidCredentials
()
fun
showProgress
()
fun
hideProgress
()
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/ui/ChangeServerActivity.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.server.ui
import
android.app.ProgressDialog
import
android.content.Context
import
android.content.Intent
import
android.os.Bundle
import
android.support.v7.app.AppCompatActivity
import
chat.rocket.android.server.presentation.ChangeServerPresenter
import
chat.rocket.android.server.presentation.ChangeServerView
import
chat.rocket.android.util.extensions.showToast
import
dagger.android.AndroidInjection
import
javax.inject.Inject
class
ChangeServerActivity
:
AppCompatActivity
(),
ChangeServerView
{
@Inject
lateinit
var
presenter
:
ChangeServerPresenter
var
progress
:
ProgressDialog
?
=
null
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
AndroidInjection
.
inject
(
this
)
super
.
onCreate
(
savedInstanceState
)
val
serverUrl
:
String
?
=
intent
.
getStringExtra
(
INTENT_SERVER_URL
)
presenter
.
loadServer
(
serverUrl
)
}
override
fun
showInvalidCredentials
()
{
showToast
(
"Missing credentials for this server"
)
}
override
fun
showProgress
()
{
progress
=
ProgressDialog
.
show
(
this
,
"Rocket.Chat"
,
"Changing Server"
)
}
override
fun
hideProgress
()
{
progress
?.
dismiss
()
}
}
private
const
val
INTENT_SERVER_URL
=
"INTENT_SERVER_URL"
private
const
val
INTENT_CHAT_ROOM_NAME
=
"INTENT_CHAT_ROOM_NAME"
private
const
val
INTENT_CHAT_ROOM_TYPE
=
"INTENT_CHAT_ROOM_TYPE"
fun
Context
.
changeServerIntent
(
serverUrl
:
String
?):
Intent
{
return
Intent
(
this
,
ChangeServerActivity
::
class
.
java
).
apply
{
serverUrl
?.
let
{
url
->
putExtra
(
INTENT_SERVER_URL
,
url
)
}
flags
=
Intent
.
FLAG_ACTIVITY_CLEAR_TOP
or
Intent
.
FLAG_ACTIVITY_CLEAR_TASK
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/util/extensions/Animation.kt
View file @
f136cf38
...
...
@@ -29,12 +29,12 @@ fun View.fadeIn(startValue: Float = 0f, finishValue: Float = 1f, duration: Long
animate
()
.
alpha
(
startValue
)
.
setDuration
(
duration
)
.
setDuration
(
duration
/
2
)
.
setInterpolator
(
DecelerateInterpolator
())
.
withEndAction
({
animate
()
.
alpha
(
finishValue
)
.
setDuration
(
duration
)
.
setDuration
(
duration
/
2
)
.
setInterpolator
(
AccelerateInterpolator
()).
start
()
}).
start
()
...
...
app/src/main/java/chat/rocket/android/util/extensions/RocketChatClient.kt
0 → 100644
View file @
f136cf38
package
chat.rocket.android.util.extensions
import
chat.rocket.android.server.domain.model.Account
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.rest.registerPushToken
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.launch
import
timber.log.Timber
suspend
fun
RocketChatClient
.
registerPushToken
(
token
:
String
,
accounts
:
List
<
Account
>,
factory
:
RocketChatClientFactory
)
{
launch
(
CommonPool
)
{
accounts
.
forEach
{
account
->
try
{
factory
.
create
(
account
.
serverUrl
).
registerPushToken
(
token
)
}
catch
(
ex
:
Exception
)
{
Timber
.
d
(
ex
,
"Error registering Push token for ${account.serverUrl}"
)
ex
.
printStackTrace
()
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/util/extensions/Ui.kt
View file @
f136cf38
...
...
@@ -27,7 +27,8 @@ fun View.isVisible(): Boolean {
return
visibility
==
View
.
VISIBLE
}
fun
ViewGroup
.
inflate
(
@LayoutRes
resource
:
Int
):
View
=
LayoutInflater
.
from
(
context
).
inflate
(
resource
,
this
,
false
)
fun
ViewGroup
.
inflate
(
@LayoutRes
resource
:
Int
,
attachToRoot
:
Boolean
=
false
):
View
=
LayoutInflater
.
from
(
context
).
inflate
(
resource
,
this
,
attachToRoot
)
fun
AppCompatActivity
.
addFragment
(
tag
:
String
,
layoutId
:
Int
,
newInstance
:
()
->
Fragment
)
{
val
fragment
=
supportFragmentManager
.
findFragmentByTag
(
tag
)
?:
newInstance
()
...
...
@@ -36,10 +37,12 @@ fun AppCompatActivity.addFragment(tag: String, layoutId: Int, newInstance: () ->
.
commit
()
}
fun
AppCompatActivity
.
addFragmentBackStack
(
tag
:
String
,
layoutId
:
Int
,
newInstance
:
()
->
Fragment
)
{
fun
AppCompatActivity
.
addFragmentBackStack
(
tag
:
String
,
layoutId
:
Int
,
newInstance
:
()
->
Fragment
)
{
val
fragment
=
supportFragmentManager
.
findFragmentByTag
(
tag
)
?:
newInstance
()
supportFragmentManager
.
beginTransaction
()
.
setCustomAnimations
(
R
.
anim
.
enter_from_right
,
R
.
anim
.
exit_to_left
,
R
.
anim
.
enter_from_left
,
R
.
anim
.
exit_to_right
)
.
setCustomAnimations
(
R
.
anim
.
enter_from_right
,
R
.
anim
.
exit_to_left
,
R
.
anim
.
enter_from_left
,
R
.
anim
.
exit_to_right
)
.
replace
(
layoutId
,
fragment
,
tag
)
.
addToBackStack
(
tag
)
.
commit
()
...
...
@@ -52,13 +55,17 @@ fun Activity.hideKeyboard() {
}
}
fun
Activity
.
showToast
(
@StringRes
resource
:
Int
,
duration
:
Int
=
Toast
.
LENGTH_SHORT
)
=
showToast
(
getString
(
resource
),
duration
)
fun
Activity
.
showToast
(
@StringRes
resource
:
Int
,
duration
:
Int
=
Toast
.
LENGTH_SHORT
)
=
showToast
(
getString
(
resource
),
duration
)
fun
Activity
.
showToast
(
message
:
String
,
duration
:
Int
=
Toast
.
LENGTH_SHORT
)
=
Toast
.
makeText
(
this
,
message
,
duration
).
show
()
fun
Activity
.
showToast
(
message
:
String
,
duration
:
Int
=
Toast
.
LENGTH_SHORT
)
=
Toast
.
makeText
(
this
,
message
,
duration
).
show
()
fun
Fragment
.
showToast
(
@StringRes
resource
:
Int
,
duration
:
Int
=
Toast
.
LENGTH_SHORT
)
=
showToast
(
getString
(
resource
),
duration
)
fun
Fragment
.
showToast
(
@StringRes
resource
:
Int
,
duration
:
Int
=
Toast
.
LENGTH_SHORT
)
=
showToast
(
getString
(
resource
),
duration
)
fun
Fragment
.
showToast
(
message
:
String
,
duration
:
Int
=
Toast
.
LENGTH_SHORT
)
=
activity
!!
.
showToast
(
message
,
duration
)
fun
Fragment
.
showToast
(
message
:
String
,
duration
:
Int
=
Toast
.
LENGTH_SHORT
)
=
activity
?.
showToast
(
message
,
duration
)
fun
RecyclerView
.
isAtBottom
():
Boolean
{
val
manager
:
RecyclerView
.
LayoutManager
?
=
layoutManager
...
...
app/src/main/res/drawable/black_gradient.xml
0 → 100644
View file @
f136cf38
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:shape=
"rectangle"
>
<gradient
android:angle=
"90"
android:endColor=
"#00000000"
android:centerColor=
"#30000000"
android:startColor=
"#C0000000"
android:type=
"linear"
/>
</shape>
\ No newline at end of file
app/src/main/res/drawable/ic_add_24dp.xml
View file @
f136cf38
...
...
@@ -3,9 +3,7 @@
android:height=
"24dp"
android:viewportWidth=
"24.0"
android:viewportHeight=
"24.0"
>
<path
android:fillColor=
"#FF
2F343D
"
android:fillColor=
"#FF
000000
"
android:pathData=
"M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"
/>
</vector>
app/src/main/res/drawable/ic_expand_more_24dp.xml
0 → 100644
View file @
f136cf38
<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=
"#FF000000"
android:pathData=
"M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z"
/>
</vector>
app/src/main/res/layout/activity_main.xml
View file @
f136cf38
...
...
@@ -23,11 +23,26 @@
android:layout_height=
"match_parent"
/>
</LinearLayout>
<FrameLayout
android:id=
"@+id/navigation_container"
android:layout_width=
"wrap_content"
android:layout_height=
"match_parent"
android:layout_gravity=
"start"
>
<android.support.design.widget.NavigationView
android:id=
"@+id/view_navigation"
android:layout_width=
"wrap_content"
android:layout_height=
"match_parent"
android:layout_gravity=
"start"
app:menu=
"@menu/navigation"
/>
app:menu=
"@menu/navigation"
app:headerLayout=
"@layout/nav_header"
/>
<android.support.v7.widget.RecyclerView
android:id=
"@+id/accounts_list"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:layout_marginTop=
"@dimen/nav_header_height"
android:elevation=
"20dp"
android:background=
"@color/white"
android:alpha=
"0"
android:visibility=
"gone"
/>
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
\ No newline at end of file
app/src/main/res/layout/fragment_authentication_server.xml
View file @
f136cf38
...
...
@@ -27,7 +27,7 @@
android:digits=
"0123456789abcdefghijklmnopqrstuvwxyz.-/:"
android:inputType=
"textUri"
android:paddingEnd=
"0dp"
android:paddingStart=
"
2
dp"
/>
android:paddingStart=
"
4
dp"
/>
<TextView
android:id=
"@+id/text_server_protocol"
...
...
app/src/main/res/layout/item_account.xml
0 → 100644
View file @
f136cf38
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:background=
"?selectableItemBackground"
>
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/server_logo"
android:layout_width=
"40dp"
android:layout_height=
"40dp"
android:layout_marginTop=
"8dp"
android:layout_marginStart=
"16dp"
android:layout_marginBottom=
"8dp"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintBottom_toBottomOf=
"parent"
app:actualImageScaleType=
"centerInside"
/>
<TextView
android:id=
"@+id/text_server_url"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"8dp"
android:layout_marginEnd=
"16dp"
android:textStyle=
"bold"
app:layout_constraintTop_toTopOf=
"@id/server_logo"
app:layout_constraintStart_toEndOf=
"@id/server_logo"
app:layout_constraintEnd_toEndOf=
"parent"
tools:text=
"https://open.rocket.chat"
/>
<TextView
android:id=
"@+id/text_username"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"8dp"
android:layout_marginEnd=
"16dp"
app:layout_constraintBottom_toBottomOf=
"@id/server_logo"
app:layout_constraintStart_toEndOf=
"@id/server_logo"
app:layout_constraintEnd_toEndOf=
"parent"
tools:text=
"Lucio Maciel"
/>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
app/src/main/res/layout/item_add_account.xml
0 → 100644
View file @
f136cf38
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:background=
"?selectableItemBackground"
>
<ImageView
android:id=
"@+id/server_logo"
android:layout_width=
"40dp"
android:layout_height=
"40dp"
android:layout_marginTop=
"8dp"
android:layout_marginStart=
"16dp"
android:layout_marginBottom=
"8dp"
android:src=
"@drawable/ic_add_24dp"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintBottom_toBottomOf=
"parent"
/>
<TextView
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginStart=
"8dp"
android:layout_marginEnd=
"16dp"
android:textAppearance=
"@style/TextAppearance.AppCompat.Medium"
android:text=
"@string/action_add_account"
app:layout_constraintTop_toTopOf=
"parent"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintStart_toEndOf=
"@id/server_logo"
app:layout_constraintEnd_toEndOf=
"parent"
/>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
app/src/main/res/layout/nav_header.xml
0 → 100644
View file @
f136cf38
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"@dimen/nav_header_height"
>
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/server_logo"
android:layout_width=
"0dp"
android:layout_height=
"0dp"
android:foreground=
"@drawable/black_gradient"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:actualImageScaleType=
"centerCrop"
tools:src=
"@tools:sample/backgrounds/scenic"
/>
<com.facebook.drawee.view.SimpleDraweeView
android:id=
"@+id/image_avatar"
android:layout_width=
"60dp"
android:layout_height=
"60dp"
android:layout_marginStart=
"16dp"
android:layout_marginTop=
"16dp"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
app:roundedCornerRadius=
"3dp"
tools:src=
"@tools:sample/avatars"
/>
<android.support.constraint.ConstraintLayout
android:id=
"@+id/account_container"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginBottom=
"8dp"
android:layout_marginStart=
"12dp"
android:layout_marginEnd=
"12dp"
android:layout_marginTop=
"16dp"
android:padding=
"4dp"
android:elevation=
"2dp"
android:background=
"?selectableItemBackground"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintStart_toStartOf=
"@+id/image_avatar"
app:layout_constraintTop_toBottomOf=
"@+id/image_avatar"
>
<TextView
android:id=
"@+id/text_name"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginEnd=
"8dp"
android:textAppearance=
"@style/TextAppearance.AppCompat.Medium"
android:textColor=
"@color/white"
app:layout_constraintEnd_toStartOf=
"@+id/account_expand"
app:layout_constraintStart_toStartOf=
"parent"
tools:text=
"Lucio Maciel"
/>
<TextView
android:id=
"@+id/text_server"
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_marginEnd=
"8dp"
android:textAppearance=
"@style/TextAppearance.AppCompat.Small"
android:textColor=
"@color/white"
app:layout_constraintEnd_toStartOf=
"@+id/account_expand"
app:layout_constraintStart_toStartOf=
"parent"
app:layout_constraintTop_toBottomOf=
"@+id/text_name"
tools:text=
"https://open.rocket.chat"
/>
<ImageView
android:id=
"@+id/account_expand"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginEnd=
"8dp"
android:src=
"@drawable/ic_expand_more_24dp"
android:tint=
"@color/whitesmoke"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toEndOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
app/src/main/res/values-pt-rBR/strings.xml
View file @
f136cf38
...
...
@@ -25,6 +25,7 @@
<string
name=
"action_files"
>
Arquivos
</string>
<string
name=
"action_confirm_password"
>
Confirme a nova senha
</string>
<string
name=
"action_join_chat"
>
Entrar no Chat
</string>
<string
name=
"action_add_account"
>
Adicionar Conta
</string>
<!-- Settings List -->
...
...
app/src/main/res/values/colors.xml
View file @
f136cf38
...
...
@@ -34,6 +34,8 @@
<color
name=
"actionMenuColor"
>
#FF727272
</color>
<color
name=
"whitesmoke"
>
#FFf1f1f1
</color>
<color
name=
"translucent_white"
>
#70F1F1F1
</color>
<color
name=
"colorEmojiIcon"
>
#FF767676
</color>
<!-- Suggestions -->
...
...
app/src/main/res/values/dimens.xml
View file @
f136cf38
...
...
@@ -35,5 +35,6 @@
<!-- Autocomplete Popup -->
<dimen
name=
"popup_max_height"
>
150dp
</dimen>
<dimen
name=
"suggestions_box_max_height"
>
250dp
</dimen>
<dimen
name=
"nav_header_height"
>
160dp
</dimen>
</resources>
\ No newline at end of file
app/src/main/res/values/strings.xml
View file @
f136cf38
...
...
@@ -26,6 +26,7 @@
<string
name=
"action_files"
>
Files
</string>
<string
name=
"action_confirm_password"
>
Confirm Password Change
</string>
<string
name=
"action_join_chat"
>
Join Chat
</string>
<string
name=
"action_add_account"
>
Add Account
</string>
<!-- Settings List -->
<string-array
name=
"settings_actions"
>
...
...
build.gradle
View file @
f136cf38
This diff is collapsed.
Click to expand it.
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