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
2cd3446d
Commit
2cd3446d
authored
Feb 08, 2018
by
Leonardo Aramaki
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix url markdown parsing and change style for usernames
parent
37795ffb
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
62 additions
and
18 deletions
+62
-18
LoginPresenter.kt
...droid/authentication/login/presentation/LoginPresenter.kt
+3
-0
SignupPresenter.kt
...oid/authentication/signup/presentation/SignupPresenter.kt
+3
-0
MessageViewModel.kt
...hat/rocket/android/chatroom/viewmodel/MessageViewModel.kt
+7
-3
MessageViewModelMapper.kt
...cket/android/chatroom/viewmodel/MessageViewModelMapper.kt
+12
-3
MessageParser.kt
...src/main/java/chat/rocket/android/helper/MessageParser.kt
+32
-12
LocalRepository.kt
...ava/chat/rocket/android/infrastructure/LocalRepository.kt
+1
-0
SharedPrefsLocalRepository.kt
...cket/android/infrastructure/SharedPrefsLocalRepository.kt
+1
-0
colors.xml
app/src/main/res/values/colors.xml
+3
-0
No files found.
app/src/main/java/chat/rocket/android/authentication/login/presentation/LoginPresenter.kt
View file @
2cd3446d
...
...
@@ -13,6 +13,7 @@ import chat.rocket.common.RocketChatTwoFactorException
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.rest.login
import
chat.rocket.core.internal.rest.me
import
chat.rocket.core.internal.rest.registerPushToken
import
javax.inject.Inject
...
...
@@ -93,7 +94,9 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
try
{
val
token
=
client
.
login
(
usernameOrEmail
,
password
)
val
me
=
client
.
me
()
multiServerRepository
.
save
(
server
,
TokenModel
(
token
.
userId
,
token
.
authToken
))
localRepository
.
save
(
LocalRepository
.
USERNAME_KEY
,
me
.
username
)
registerPushToken
()
navigator
.
toChatList
()
}
catch
(
exception
:
RocketChatException
)
{
...
...
app/src/main/java/chat/rocket/android/authentication/signup/presentation/SignupPresenter.kt
View file @
2cd3446d
...
...
@@ -12,6 +12,7 @@ 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.me
import
chat.rocket.core.internal.rest.registerPushToken
import
chat.rocket.core.internal.rest.signup
import
javax.inject.Inject
...
...
@@ -51,6 +52,8 @@ class SignupPresenter @Inject constructor(private val view: SignupView,
try
{
client
.
signup
(
email
,
name
,
username
,
password
)
// TODO This function returns a user so should we save it?
client
.
login
(
username
,
password
)
// TODO This function returns a user token so should we save it?
val
me
=
client
.
me
()
localRepository
.
save
(
LocalRepository
.
USERNAME_KEY
,
me
.
username
)
registerPushToken
()
navigator
.
toChatList
()
}
catch
(
exception
:
RocketChatException
)
{
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/MessageViewModel.kt
View file @
2cd3446d
...
...
@@ -12,6 +12,7 @@ import android.text.style.StyleSpan
import
chat.rocket.android.R
import
chat.rocket.android.helper.MessageParser
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.MessagesRepository
import
chat.rocket.android.server.domain.SITE_URL
import
chat.rocket.android.server.domain.useRealName
...
...
@@ -29,7 +30,8 @@ data class MessageViewModel(val context: Context,
private
val
message
:
Message
,
private
val
settings
:
Map
<
String
,
Value
<
Any
>>,
private
val
parser
:
MessageParser
,
private
val
messagesRepository
:
MessagesRepository
)
{
private
val
messagesRepository
:
MessagesRepository
,
private
val
localRepository
:
LocalRepository
)
{
val
id
:
String
=
message
.
id
val
roomId
:
String
=
message
.
roomId
val
time
:
CharSequence
...
...
@@ -46,8 +48,10 @@ data class MessageViewModel(val context: Context,
var
attachmentTimestamp
:
Long
?
=
null
var
isSystemMessage
:
Boolean
=
false
var
isPinned
:
Boolean
=
false
var
currentUsername
:
String
?
=
null
init
{
currentUsername
=
localRepository
.
get
(
LocalRepository
.
USERNAME_KEY
)
sender
=
getSenderName
()
time
=
getTime
(
message
.
timestamp
)
isPinned
=
message
.
pinned
...
...
@@ -153,9 +157,9 @@ data class MessageViewModel(val context: Context,
var
quoteViewModel
:
MessageViewModel
?
=
null
if
(
quote
!=
null
)
{
val
quoteMessage
:
Message
=
quote
!!
quoteViewModel
=
MessageViewModel
(
context
,
token
,
quoteMessage
,
settings
,
parser
,
messagesRepository
)
quoteViewModel
=
MessageViewModel
(
context
,
token
,
quoteMessage
,
settings
,
parser
,
messagesRepository
,
localRepository
)
}
return
parser
.
renderMarkdown
(
message
.
message
,
quoteViewModel
,
urlsWithMeta
)
return
parser
.
renderMarkdown
(
message
.
message
,
quoteViewModel
,
currentUsername
)
}
private
fun
getSystemMessage
(
content
:
String
):
CharSequence
{
...
...
app/src/main/java/chat/rocket/android/chatroom/viewmodel/MessageViewModelMapper.kt
View file @
2cd3446d
...
...
@@ -2,6 +2,7 @@ package chat.rocket.android.chatroom.viewmodel
import
android.content.Context
import
chat.rocket.android.helper.MessageParser
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.MessagesRepository
import
chat.rocket.core.TokenRepository
import
chat.rocket.core.model.Message
...
...
@@ -13,7 +14,8 @@ import javax.inject.Inject
class
MessageViewModelMapper
@Inject
constructor
(
private
val
context
:
Context
,
private
val
tokenRepository
:
TokenRepository
,
private
val
messageParser
:
MessageParser
,
private
val
messagesRepository
:
MessagesRepository
)
{
private
val
messagesRepository
:
MessagesRepository
,
private
val
localRepository
:
LocalRepository
)
{
suspend
fun
mapToViewModel
(
message
:
Message
,
settings
:
Map
<
String
,
Value
<
Any
>>):
MessageViewModel
=
withContext
(
CommonPool
)
{
MessageViewModel
(
...
...
@@ -22,11 +24,18 @@ class MessageViewModelMapper @Inject constructor(private val context: Context,
message
,
settings
,
messageParser
,
messagesRepository
messagesRepository
,
localRepository
)
}
suspend
fun
mapToViewModelList
(
messageList
:
List
<
Message
>,
settings
:
Map
<
String
,
Value
<
Any
>>):
List
<
MessageViewModel
>
{
return
messageList
.
map
{
MessageViewModel
(
context
,
tokenRepository
.
get
(),
it
,
settings
,
messageParser
,
messagesRepository
)
}
return
messageList
.
map
{
MessageViewModel
(
context
,
tokenRepository
.
get
(),
it
,
settings
,
messageParser
,
messagesRepository
,
localRepository
)
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/helper/MessageParser.kt
View file @
2cd3446d
...
...
@@ -15,7 +15,6 @@ import android.text.style.*
import
android.view.View
import
chat.rocket.android.R
import
chat.rocket.android.chatroom.viewmodel.MessageViewModel
import
chat.rocket.core.model.url.Url
import
org.commonmark.node.BlockQuote
import
ru.noties.markwon.Markwon
import
ru.noties.markwon.SpannableBuilder
...
...
@@ -28,7 +27,9 @@ import javax.inject.Inject
class
MessageParser
@Inject
constructor
(
val
context
:
Application
,
private
val
configuration
:
SpannableConfiguration
)
{
private
val
parser
=
Markwon
.
createParser
()
private
val
usernameRegex
=
Pattern
.
compile
(
"([^\\S]|^)+(@[\\w.]+)"
,
private
val
regexUsername
=
Pattern
.
compile
(
"([^\\S]|^)+(@[\\w.]+)"
,
Pattern
.
MULTILINE
or
Pattern
.
CASE_INSENSITIVE
)
private
val
regexLink
=
Pattern
.
compile
(
"(https?:\\/\\/)?(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&/=]*)"
,
Pattern
.
MULTILINE
or
Pattern
.
CASE_INSENSITIVE
)
/**
...
...
@@ -40,14 +41,19 @@ class MessageParser @Inject constructor(val context: Application, private val co
*
* @return A Spannable with the parsed markdown.
*/
fun
renderMarkdown
(
text
:
String
,
quote
:
MessageViewModel
?
=
null
,
urls
:
List
<
Url
>
?
=
null
):
CharSequence
{
fun
renderMarkdown
(
text
:
String
,
quote
:
MessageViewModel
?
=
null
,
selfUsername
:
String
?
=
null
):
CharSequence
{
val
builder
=
SpannableBuilder
()
var
content
:
String
=
text
// Replace all url links to markdown url syntax.
if
(
urls
!=
null
)
{
for
(
url
in
urls
)
{
content
=
content
.
replace
(
url
.
url
,
"[${url.url}](${url.url})"
)
val
matcher
=
regexLink
.
matcher
(
content
)
val
consumed
=
mutableListOf
<
String
>()
while
(
matcher
.
find
())
{
val
link
=
matcher
.
group
(
0
)
// skip usernames
if
(!
link
.
startsWith
(
"@"
)
&&
!
consumed
.
contains
(
link
))
{
content
=
content
.
replace
(
link
,
"[$link]($link)"
)
consumed
.
add
(
link
)
}
}
...
...
@@ -62,18 +68,22 @@ class MessageParser @Inject constructor(val context: Application, private val co
}
val
result
=
builder
.
text
()
applySpans
(
result
)
applySpans
(
result
,
selfUsername
)
return
result
}
private
fun
applySpans
(
text
:
CharSequence
)
{
val
matcher
=
usernameRegex
.
matcher
(
text
)
private
fun
applySpans
(
text
:
CharSequence
,
currentUser
:
String
?
)
{
val
matcher
=
regexUsername
.
matcher
(
text
)
val
result
=
text
as
Spannable
while
(
matcher
.
find
())
{
val
user
=
matcher
.
group
(
2
)
val
start
=
matcher
.
start
(
2
)
//TODO: should check if username actually exists prior to applying.
result
.
setSpan
(
UsernameClickableSpan
(),
start
,
start
+
user
.
length
,
0
)
val
linkColor
=
context
.
resources
.
getColor
(
R
.
color
.
linkTextColor
)
val
linkBackgroundColor
=
context
.
resources
.
getColor
(
R
.
color
.
linkBackgroundColor
)
val
referSelf
=
currentUser
!=
null
&&
"@$currentUser"
==
user
val
usernameSpan
=
UsernameClickableSpan
(
linkBackgroundColor
,
linkColor
,
referSelf
)
result
.
setSpan
(
usernameSpan
,
start
,
start
+
user
.
length
,
0
)
}
}
...
...
@@ -164,13 +174,23 @@ class MessageParser @Inject constructor(val context: Application, private val co
}
}
class
UsernameClickableSpan
:
ClickableSpan
()
{
class
UsernameClickableSpan
(
private
val
linkBackgroundColor
:
Int
,
private
val
linkTextColor
:
Int
,
private
val
referSelf
:
Boolean
)
:
ClickableSpan
()
{
override
fun
onClick
(
widget
:
View
)
{
//TODO: Implement action when clicking on username, like showing user profile.
}
override
fun
updateDrawState
(
ds
:
TextPaint
)
{
ds
.
color
=
ds
.
linkColor
if
(
referSelf
)
{
ds
.
color
=
Color
.
WHITE
ds
.
typeface
=
Typeface
.
DEFAULT_BOLD
ds
.
bgColor
=
linkTextColor
}
else
{
ds
.
color
=
linkTextColor
ds
.
bgColor
=
linkBackgroundColor
}
ds
.
isUnderlineText
=
false
}
...
...
app/src/main/java/chat/rocket/android/infrastructure/LocalRepository.kt
View file @
2cd3446d
...
...
@@ -6,6 +6,7 @@ interface LocalRepository {
const
val
KEY_PUSH_TOKEN
=
"KEY_PUSH_TOKEN"
const
val
TOKEN_KEY
=
"token_"
const
val
SETTINGS_KEY
=
"settings_"
const
val
USERNAME_KEY
=
"my_username"
}
fun
save
(
key
:
String
,
value
:
String
?)
...
...
app/src/main/java/chat/rocket/android/infrastructure/SharedPrefsLocalRepository.kt
View file @
2cd3446d
...
...
@@ -20,5 +20,6 @@ class SharedPrefsLocalRepository(private val preferences: SharedPreferences) : L
clear
(
LocalRepository
.
KEY_PUSH_TOKEN
)
clear
(
LocalRepository
.
TOKEN_KEY
+
server
)
clear
(
LocalRepository
.
SETTINGS_KEY
+
server
)
clear
(
LocalRepository
.
USERNAME_KEY
+
server
)
}
}
\ No newline at end of file
app/src/main/res/values/colors.xml
View file @
2cd3446d
...
...
@@ -21,4 +21,7 @@
<color
name=
"darkGray"
>
#a0a0a0
</color>
<color
name=
"actionMenuColor"
>
#727272
</color>
<color
name=
"linkTextColor"
>
#FF074481
</color>
<color
name=
"linkBackgroundColor"
>
#30074481
</color>
</resources>
\ No newline at end of file
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