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
2b3858b1
Commit
2b3858b1
authored
Feb 24, 2018
by
Leonardo Aramaki
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move emoji keyboard from fragment approach to popup approach.
parent
bc77daa5
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
359 additions
and
127 deletions
+359
-127
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+4
-1
ChatRoomPresenter.kt
...rocket/android/chatroom/presentation/ChatRoomPresenter.kt
+0
-4
ChatRoomView.kt
...chat/rocket/android/chatroom/presentation/ChatRoomView.kt
+0
-5
ChatRoomActivity.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt
+1
-10
ChatRoomAdapter.kt
...n/java/chat/rocket/android/chatroom/ui/ChatRoomAdapter.kt
+0
-1
ChatRoomFragment.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
+30
-66
KeyboardHelper.kt
...rc/main/java/chat/rocket/android/helper/KeyboardHelper.kt
+4
-12
CategoryPagerAdapter.kt
.../chat/rocket/android/widget/emoji/CategoryPagerAdapter.kt
+1
-3
EmojiKeyboardPopup.kt
...va/chat/rocket/android/widget/emoji/EmojiKeyboardPopup.kt
+153
-0
EmojiRepository.kt
.../java/chat/rocket/android/widget/emoji/EmojiRepository.kt
+3
-22
OverKeyboardPopupWindow.kt
...at/rocket/android/widget/emoji/OverKeyboardPopupWindow.kt
+159
-0
emoji_popup_layout.xml
app/src/main/res/layout/emoji_popup_layout.xml
+2
-3
dimens.xml
app/src/main/res/values/dimens.xml
+2
-0
No files found.
app/src/main/AndroidManifest.xml
View file @
2b3858b1
...
...
@@ -37,19 +37,22 @@
<activity
android:name=
".main.ui.MainActivity"
android:windowSoftInputMode=
"adjustResize|stateAlwaysHidden"
android:theme=
"@style/AppTheme"
/>
<activity
android:name=
".webview.WebViewActivity"
android:windowSoftInputMode=
"adjustResize|stateAlwaysHidden"
android:theme=
"@style/AppTheme"
/>
<activity
android:name=
".chatroom.ui.ChatRoomActivity"
android:windowSoftInputMode=
"adjust
Pa
n"
android:windowSoftInputMode=
"adjust
Resize|stateAlwaysHidde
n"
android:theme=
"@style/AppTheme"
/>
<activity
android:name=
".chatroom.ui.PinnedMessagesActivity"
android:windowSoftInputMode=
"adjustResize|stateAlwaysHidden"
android:theme=
"@style/AppTheme"
/>
<receiver
...
...
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt
View file @
2b3858b1
...
...
@@ -302,10 +302,6 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
}
}
fun
dispatchRestoreUIState
()
{
view
.
restoreUIState
()
}
private
suspend
fun
listenMessages
(
roomId
:
String
)
{
launch
(
CommonPool
+
strategy
.
jobs
)
{
for
(
message
in
client
.
messagesChannel
)
{
...
...
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomView.kt
View file @
2b3858b1
...
...
@@ -97,9 +97,4 @@ interface ChatRoomView : LoadingView, MessageView {
fun
clearMessageComposition
()
fun
showInvalidFileSize
(
fileSize
:
Int
,
maxFileSize
:
Int
)
/**
* Restore UI state.
*/
fun
restoreUIState
()
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomActivity.kt
View file @
2b3858b1
...
...
@@ -5,10 +5,8 @@ import android.content.Intent
import
android.os.Bundle
import
android.support.v4.app.Fragment
import
chat.rocket.android.R
import
chat.rocket.android.helper.KeyboardHelper
import
chat.rocket.android.util.extensions.addFragment
import
chat.rocket.android.util.extensions.textContent
import
chat.rocket.android.widget.emoji.EmojiFragment
import
dagger.android.AndroidInjection
import
dagger.android.AndroidInjector
import
dagger.android.DispatchingAndroidInjector
...
...
@@ -67,14 +65,7 @@ class ChatRoomActivity : SwipeBackActivity(), HasSupportFragmentInjector {
}
override
fun
onBackPressed
()
{
val
frag
=
supportFragmentManager
.
findFragmentByTag
(
EmojiFragment
.
TAG
)
as
EmojiFragment
?
if
(
frag
!=
null
&&
frag
.
isExpanded
())
{
frag
.
collapse
()
}
else
{
KeyboardHelper
.
hideSoftKeyboard
(
this
)
finishActivity
()
super
.
onBackPressed
()
}
}
override
fun
supportFragmentInjector
():
AndroidInjector
<
Fragment
>
{
...
...
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomAdapter.kt
View file @
2b3858b1
...
...
@@ -96,7 +96,6 @@ class ChatRoomAdapter(private val roomType: String,
setChecked
(
isPinned
)
}
val
adapter
=
ActionListAdapter
(
menuItems
,
this
@ViewHolder
)
presenter
.
dispatchRestoreUIState
()
BottomSheetMenu
(
adapter
).
show
(
it
.
context
)
}
}
...
...
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
View file @
2b3858b1
...
...
@@ -24,7 +24,7 @@ import chat.rocket.android.helper.MessageParser
import
chat.rocket.android.util.extensions.*
import
chat.rocket.android.widget.emoji.ComposerEditText
import
chat.rocket.android.widget.emoji.Emoji
import
chat.rocket.android.widget.emoji.Emoji
Fragment
import
chat.rocket.android.widget.emoji.Emoji
KeyboardPopup
import
chat.rocket.android.widget.emoji.EmojiParser
import
dagger.android.support.AndroidSupportInjection
import
io.reactivex.disposables.CompositeDisposable
...
...
@@ -52,7 +52,7 @@ private const val BUNDLE_CHAT_ROOM_TYPE = "chat_room_type"
private
const
val
BUNDLE_IS_CHAT_ROOM_READ_ONLY
=
"is_chat_room_read_only"
private
const
val
REQUEST_CODE_FOR_PERFORM_SAF
=
42
class
ChatRoomFragment
:
Fragment
(),
ChatRoomView
,
Emoji
Fragment
.
Listener
{
class
ChatRoomFragment
:
Fragment
(),
ChatRoomView
,
Emoji
KeyboardPopup
.
Listener
{
@Inject
lateinit
var
presenter
:
ChatRoomPresenter
@Inject
lateinit
var
parser
:
MessageParser
private
lateinit
var
adapter
:
ChatRoomAdapter
...
...
@@ -60,6 +60,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiFragment.Listener {
private
lateinit
var
chatRoomId
:
String
private
lateinit
var
chatRoomName
:
String
private
lateinit
var
chatRoomType
:
String
private
lateinit
var
emojiKeyboardPopup
:
EmojiKeyboardPopup
private
var
isChatRoomReadOnly
:
Boolean
=
false
private
lateinit
var
actionSnackbar
:
ActionSnackbar
...
...
@@ -106,8 +107,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiFragment.Listener {
override
fun
onActivityCreated
(
savedInstanceState
:
Bundle
?)
{
super
.
onActivityCreated
(
savedInstanceState
)
attachOrGetEmojiFragment
()
text_message
.
addTextChangedListener
(
EmojiFragment
.
EmojiTextWatcher
(
text_message
))
text_message
.
addTextChangedListener
(
EmojiKeyboardPopup
.
EmojiTextWatcher
(
text_message
))
}
override
fun
onDestroyView
()
{
...
...
@@ -212,10 +212,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiFragment.Listener {
adapter
.
removeItem
(
msgId
)
}
override
fun
restoreUIState
()
{
hideAllKeyboards
()
}
override
fun
showReplyingAction
(
username
:
String
,
replyMarkdown
:
String
,
quotedMessage
:
String
)
{
activity
?.
apply
{
citation
=
replyMarkdown
...
...
@@ -269,27 +265,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiFragment.Listener {
}
}
override
fun
onEmojiPanelCollapsed
()
{
setReactionButtonIcon
(
R
.
drawable
.
ic_reaction_24dp
)
}
override
fun
onEmojiPanelExpanded
()
{
}
private
fun
setReactionButtonIcon
(
@DrawableRes
drawableId
:
Int
)
{
button_add_reaction
.
setImageResource
(
drawableId
)
button_add_reaction
.
setTag
(
drawableId
)
}
private
fun
hideAllKeyboards
()
{
activity
?.
let
{
KeyboardHelper
.
hideSoftKeyboard
(
it
)
attachOrGetEmojiFragment
()
?.
collapse
()
setReactionButtonIcon
(
R
.
drawable
.
ic_reaction_24dp
)
}
}
override
fun
showFileSelection
(
filter
:
Array
<
String
>)
{
val
intent
=
Intent
(
Intent
.
ACTION_GET_CONTENT
)
intent
.
type
=
"*/*"
...
...
@@ -329,28 +309,21 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiFragment.Listener {
input_container
.
setVisible
(
false
)
}
else
{
subscribeTextMessage
()
emojiKeyboardPopup
=
EmojiKeyboardPopup
(
activity
!!
,
activity
!!
.
findViewById
(
R
.
id
.
fragment_container
))
emojiKeyboardPopup
.
listener
=
this
text_message
.
listener
=
object
:
ComposerEditText
.
ComposerEditTextListener
{
override
fun
onKeyboardOpened
()
{
activity
?.
let
{
val
fragment
=
EmojiFragment
.
getOrAttach
(
it
,
R
.
id
.
emoji_fragment_placeholder
,
composer
)
if
(
fragment
.
isCollapsed
())
{
fragment
.
expandHidden
()
}
setReactionButtonIcon
(
R
.
drawable
.
ic_reaction_24dp
)
}
}
override
fun
onKeyboardClosed
()
{
activity
?.
let
{
setReactionButtonIcon
(
R
.
drawable
.
ic_reaction_24dp
)
val
fragment
=
EmojiFragment
.
getOrAttach
(
it
,
R
.
id
.
emoji_fragment_placeholder
,
composer
)
if
(
fragment
.
isCollapsed
())
{
if
(!
emojiKeyboardPopup
.
isKeyboardOpen
)
{
it
.
onBackPressed
()
}
else
{
hideAllKeyboards
()
}
KeyboardHelper
.
hideSoftKeyboard
(
it
)
emojiKeyboardPopup
.
dismiss
()
}
setReactionButtonIcon
(
R
.
drawable
.
ic_reaction_24dp
)
}
}
...
...
@@ -358,11 +331,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiFragment.Listener {
var
textMessage
=
citation
?:
""
textMessage
+=
text_message
.
textContent
sendMessage
(
textMessage
)
attachOrGetEmojiFragment
()
?.
let
{
if
(
it
.
softKeyboardVisible
)
{
it
.
collapse
()
}
}
clearMessageComposition
()
}
...
...
@@ -370,7 +339,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiFragment.Listener {
if
(
layout_message_attachment_options
.
isShown
)
{
hideAttachmentOptions
()
}
else
{
hideAllKeyboards
()
showAttachmentOptions
()
}
}
...
...
@@ -390,33 +358,29 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiFragment.Listener {
}
button_add_reaction
.
setOnClickListener
{
view
->
activity
?.
let
{
val
editor
=
text_message
val
emojiFragment
=
attachOrGetEmojiFragment
()
!!
val
tag
=
if
(
view
.
tag
==
null
)
R
.
drawable
.
ic_reaction_24dp
else
view
.
tag
as
Int
when
(
tag
)
{
R
.
drawable
.
ic_reaction_24dp
->
{
KeyboardHelper
.
hideSoftKeyboard
(
it
)
if
(!
emojiFragment
.
isExpanded
())
{
emojiFragment
.
show
()
}
setReactionButtonIcon
(
R
.
drawable
.
ic_keyboard_black_24dp
)
}
R
.
drawable
.
ic_keyboard_black_24dp
->
{
KeyboardHelper
.
showSoftKeyboard
(
editor
)
setReactionButtonIcon
(
R
.
drawable
.
ic_reaction_24dp
)
}
}
}
openEmojiKeyboardPopup
()
}
}
}
private
fun
attachOrGetEmojiFragment
():
EmojiFragment
?
{
return
activity
?.
let
{
val
frag
=
EmojiFragment
.
getOrAttach
(
it
,
R
.
id
.
emoji_fragment_placeholder
,
composer
)
frag
.
listener
=
this
frag
private
fun
openEmojiKeyboardPopup
()
{
if
(!
emojiKeyboardPopup
.
isShowing
())
{
// If keyboard is visible, simply show the popup
if
(
emojiKeyboardPopup
.
isKeyboardOpen
)
{
emojiKeyboardPopup
.
showAtBottom
()
}
else
{
// Open the text keyboard first and immediately after that show the emoji popup
text_message
.
setFocusableInTouchMode
(
true
)
text_message
.
requestFocus
()
emojiKeyboardPopup
.
showAtBottomPending
()
KeyboardHelper
.
showSoftKeyboard
(
text_message
)
}
setReactionButtonIcon
(
R
.
drawable
.
ic_keyboard_black_24dp
)
}
else
{
// If popup is showing, simply dismiss it to show the undelying text keyboard
emojiKeyboardPopup
.
dismiss
()
setReactionButtonIcon
(
R
.
drawable
.
ic_reaction_24dp
)
}
}
...
...
app/src/main/java/chat/rocket/android/helper/KeyboardHelper.kt
View file @
2b3858b1
package
chat.rocket.android.helper
import
android.graphics.Rect
import
android.view.View
import
android.content.Context.INPUT_METHOD_SERVICE
import
android.app.Activity
import
android.content.Context
import
android.graphics.Rect
import
android.view.View
import
android.view.inputmethod.InputMethodManager
...
...
@@ -36,7 +35,7 @@ object KeyboardHelper {
val
currentFocus
=
activity
.
currentFocus
if
(
currentFocus
!=
null
)
{
val
inputMethodManager
=
activity
.
getSystemService
(
Context
.
INPUT_METHOD_SERVICE
)
as
InputMethodManager
inputMethodManager
.
hideSoftInputFromWindow
(
currentFocus
.
windowToken
,
0
)
inputMethodManager
.
hideSoftInputFromWindow
(
currentFocus
.
windowToken
,
InputMethodManager
.
HIDE_NOT_ALWAYS
)
}
}
...
...
@@ -48,14 +47,7 @@ object KeyboardHelper {
fun
showSoftKeyboard
(
view
:
View
)
{
if
(
view
.
requestFocus
())
{
val
inputMethodManager
=
view
.
context
.
getSystemService
(
Context
.
INPUT_METHOD_SERVICE
)
as
InputMethodManager
inputMethodManager
.
toggleSoftInput
(
InputMethodManager
.
SHOW_FORCED
,
0
)
}
}
fun
restart
(
view
:
View
)
{
if
(
view
.
requestFocus
())
{
val
inputMethodManager
=
view
.
context
.
getSystemService
(
Context
.
INPUT_METHOD_SERVICE
)
as
InputMethodManager
inputMethodManager
.
restartInput
(
view
)
inputMethodManager
.
toggleSoftInput
(
InputMethodManager
.
SHOW_IMPLICIT
,
InputMethodManager
.
SHOW_IMPLICIT
)
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/widget/emoji/CategoryPagerAdapter.kt
View file @
2b3858b1
...
...
@@ -9,9 +9,7 @@ import android.view.View
import
android.view.ViewGroup
import
android.widget.TextView
import
chat.rocket.android.R
import
chat.rocket.android.widget.emoji.EmojiFragment.Listener
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.async
import
chat.rocket.android.widget.emoji.EmojiKeyboardPopup.Listener
import
java.util.*
class
CategoryPagerAdapter
(
val
listener
:
Listener
)
:
PagerAdapter
()
{
...
...
app/src/main/java/chat/rocket/android/widget/emoji/Emoji
Fragment
.kt
→
app/src/main/java/chat/rocket/android/widget/emoji/Emoji
KeyboardPopup
.kt
View file @
2b3858b1
package
chat.rocket.android.widget.emoji
import
android.graphics.Rect
import
android.os.Bundle
import
android.support.annotation.IdRes
import
android.content.Context
import
android.support.design.widget.TabLayout
import
android.support.v4.app.Fragment
import
android.support.v4.app.FragmentActivity
import
android.support.v4.view.ViewPager
import
android.support.v7.app.AppCompatActivity
import
android.text.Editable
import
android.text.TextWatcher
import
android.view.*
import
android.view.KeyEvent
import
android.view.LayoutInflater
import
android.view.View
import
android.view.ViewGroup
import
android.widget.EditText
import
android.widget.ImageView
import
chat.rocket.android.R
class
Emoji
Fragment
:
Fragment
(
)
{
class
Emoji
KeyboardPopup
(
context
:
Context
,
view
:
View
)
:
OverKeyboardPopupWindow
(
context
,
view
)
{
private
lateinit
var
viewPager
:
ViewPager
private
lateinit
var
tabLayout
:
TabLayout
private
lateinit
var
searchView
:
View
private
lateinit
var
backspaceView
:
View
private
lateinit
var
parentContainer
:
ViewGroup
private
var
editor
:
View
?
=
null
private
var
decorLayoutListener
:
ViewTreeObserver
.
OnGlobalLayoutListener
?
=
null
var
softKeyboardVisible
=
false
var
listener
:
Listener
?
=
null
companion
object
{
const
val
PREF_EMOJI_RECENTS
=
"PREF_EMOJI_RECENTS"
const
val
PREF_KEYBOARD_HEIGHT
=
"PREF_KEYBOARD_HEIGHT"
const
val
MIN_KEYBOARD_HEIGHT_PX
=
150
val
TAG
:
String
=
EmojiFragment
::
class
.
java
.
simpleName
fun
newInstance
(
editor
:
View
)
=
EmojiFragment
().
apply
{
this
.
editor
=
editor
}
fun
getOrAttach
(
activity
:
FragmentActivity
,
@IdRes
containerId
:
Int
,
editor
:
View
):
EmojiFragment
{
val
fragmentManager
=
activity
.
supportFragmentManager
var
fragment
:
Fragment
?
=
fragmentManager
.
findFragmentByTag
(
TAG
)
return
if
(
fragment
==
null
)
{
fragment
=
newInstance
(
editor
)
fragment
.
parentContainer
=
activity
.
findViewById
(
containerId
)
fragmentManager
.
beginTransaction
()
.
replace
(
containerId
,
fragment
,
TAG
)
.
commit
()
fragment
}
else
{
fragment
as
EmojiFragment
}
}
}
override
fun
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
?,
savedInstanceState
:
Bundle
?
):
View
{
val
view
=
inflater
.
inflate
(
R
.
layout
.
emoji_popup_layout
,
container
,
false
)
override
fun
onCreateView
(
inflater
:
LayoutInflater
):
View
{
val
view
=
inflater
.
inflate
(
R
.
layout
.
emoji_popup_layout
,
null
,
false
)
parentContainer
=
view
.
findViewById
(
R
.
id
.
emoji_keyboard_container
)
viewPager
=
view
.
findViewById
(
R
.
id
.
pager_categories
)
searchView
=
view
.
findViewById
(
R
.
id
.
emoji_search
)
...
...
@@ -60,67 +38,13 @@ class EmojiFragment : Fragment() {
return
view
}
override
fun
onDetach
()
{
super
.
onDetach
()
activity
?.
getWindow
()
?.
decorView
?.
viewTreeObserver
?.
removeOnGlobalLayoutListener
(
decorLayoutListener
)
listener
=
null
editor
=
null
}
override
fun
onViewCreated
(
view
:
View
,
savedInstanceState
:
Bundle
?)
{
setupLayout
()
override
fun
onViewCreated
(
view
:
View
)
{
setupViewPager
()
setupBottomBar
()
}
private
fun
setupLayout
()
{
activity
?.
let
{
val
decorView
=
it
.
getWindow
().
decorView
decorLayoutListener
=
object
:
ViewTreeObserver
.
OnGlobalLayoutListener
{
private
val
windowVisibleDisplayFrame
=
Rect
()
private
var
lastVisibleDecorViewHeight
:
Int
=
0
override
fun
onGlobalLayout
()
{
if
(
editor
==
null
)
{
return
}
// Retrieve visible rectangle inside window.
decorView
.
getWindowVisibleDisplayFrame
(
windowVisibleDisplayFrame
)
val
visibleDecorViewHeight
=
windowVisibleDisplayFrame
.
height
()
// Decide whether keyboard is visible from changing decor view height.
if
(
lastVisibleDecorViewHeight
!=
0
)
{
if
(
lastVisibleDecorViewHeight
>
visibleDecorViewHeight
+
MIN_KEYBOARD_HEIGHT_PX
)
{
// Calculate current keyboard height (this includes also navigation bar height when in fullscreen mode).
val
currentKeyboardHeight
=
decorView
.
height
-
windowVisibleDisplayFrame
.
bottom
-
editor
!!
.
measuredHeight
// Notify listener about keyboard being shown.
EmojiRepository
.
saveKeyboardHeight
(
currentKeyboardHeight
)
setKeyboardHeight
(
currentKeyboardHeight
)
softKeyboardVisible
=
true
parentContainer
.
postDelayed
({
expandHidden
()
},
100
)
}
else
if
(
lastVisibleDecorViewHeight
+
MIN_KEYBOARD_HEIGHT_PX
<
visibleDecorViewHeight
)
{
// Notify listener about keyboard being hidden.
softKeyboardVisible
=
false
}
}
// Save current decor view height for the next call.
lastVisibleDecorViewHeight
=
visibleDecorViewHeight
}
}
decorView
.
viewTreeObserver
.
addOnGlobalLayoutListener
(
decorLayoutListener
)
}
val
storedHeight
=
EmojiRepository
.
getKeyboardHeight
()
if
(
storedHeight
>
0
)
{
setKeyboardHeight
(
storedHeight
)
}
}
private
fun
setupBottomBar
()
{
searchView
.
setOnClickListener
{
}
backspaceView
.
setOnClickListener
{
...
...
@@ -129,11 +53,11 @@ class EmojiFragment : Fragment() {
}
private
fun
setupViewPager
()
{
activity
?
.
let
{
context
.
let
{
val
callback
=
when
(
it
)
{
is
Listener
->
it
as
Listener
is
Listener
->
it
else
->
{
val
fragments
=
it
.
supportFragmentManager
.
fragments
val
fragments
=
(
it
as
AppCompatActivity
)
.
supportFragmentManager
.
fragments
if
(
fragments
==
null
||
fragments
.
size
==
0
||
!(
fragments
[
0
]
is
Listener
))
{
throw
IllegalStateException
(
"activity/fragment should implement Listener interface"
)
}
...
...
@@ -141,14 +65,6 @@ class EmojiFragment : Fragment() {
}
}
viewPager
.
adapter
=
CategoryPagerAdapter
(
object
:
Listener
{
override
fun
onEmojiPanelExpanded
()
{
// do nothing
}
override
fun
onEmojiPanelCollapsed
()
{
// do nothing
}
override
fun
onNonEmojiKeyPressed
(
keyCode
:
Int
)
{
// do nothing
}
...
...
@@ -161,7 +77,7 @@ class EmojiFragment : Fragment() {
for
(
category
in
EmojiCategory
.
values
())
{
val
tab
=
tabLayout
.
getTabAt
(
category
.
ordinal
)
val
tabView
=
layoutInflater
.
inflate
(
R
.
layout
.
emoji_picker_tab
,
null
)
val
tabView
=
LayoutInflater
.
from
(
context
)
.
inflate
(
R
.
layout
.
emoji_picker_tab
,
null
)
tab
?.
setCustomView
(
tabView
)
val
textView
=
tabView
.
findViewById
(
R
.
id
.
image_category
)
as
ImageView
textView
.
setImageResource
(
category
.
resourceIcon
())
...
...
@@ -173,14 +89,6 @@ class EmojiFragment : Fragment() {
}
}
private
fun
setKeyboardHeight
(
height
:
Int
)
{
val
oldHeight
=
parentContainer
.
layoutParams
.
height
if
(
oldHeight
!=
height
)
{
parentContainer
.
layoutParams
.
height
=
height
parentContainer
.
requestLayout
()
}
}
class
EmojiTextWatcher
(
val
editor
:
EditText
)
:
TextWatcher
{
@Volatile
private
var
emojiToRemove
=
mutableListOf
<
EmojiTypefaceSpan
>()
...
...
@@ -225,51 +133,6 @@ class EmojiFragment : Fragment() {
}
}
private
fun
setKeyboardVisibility
(
visibility
:
Int
)
{
if
(
visibility
!=
parentContainer
.
visibility
)
{
parentContainer
.
visibility
=
visibility
}
}
/**
* Show the emoji keyboard.
*/
fun
show
()
{
setKeyboardVisibility
(
View
.
VISIBLE
)
}
/**
* Expand the emoji keyboard with invisible contents.
*/
fun
expandHidden
()
{
setKeyboardVisibility
(
View
.
INVISIBLE
)
}
/**
* Hide the emoji keyboard.
*/
fun
collapse
()
{
// Since the emoji keyboard is always behind the soft keyboard assume it's also dismissed
// when the emoji one is about to get close. Hence we should invoke our listener to update
// the UI as if the soft keyboard is hidden.
listener
?.
onEmojiPanelCollapsed
()
setKeyboardVisibility
(
View
.
GONE
)
}
/**
* Whether the emoji keyboard is visible.
*
* @return <code>true</code> if opened.
*/
fun
isExpanded
()
=
parentContainer
.
visibility
==
View
.
VISIBLE
/**
* Whether the emoji keyboard is collapsed.
*
* @return false if the emoji keyboard is visible and not obscured
*/
fun
isCollapsed
()
=
parentContainer
.
visibility
==
View
.
GONE
interface
Listener
{
/**
* When an emoji is selected on the picker.
...
...
@@ -286,9 +149,5 @@ class EmojiFragment : Fragment() {
* @see android.view.KeyEvent
*/
fun
onNonEmojiKeyPressed
(
keyCode
:
Int
)
fun
onEmojiPanelCollapsed
()
fun
onEmojiPanelExpanded
()
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/widget/emoji/EmojiRepository.kt
View file @
2b3858b1
...
...
@@ -79,14 +79,14 @@ object EmojiRepository {
*/
fun
addToRecents
(
emoji
:
Emoji
)
{
val
emojiShortname
=
emoji
.
shortname
val
recentsJson
=
JSONObject
(
preferences
.
getString
(
Emoji
Fragment
.
PREF_EMOJI_RECENTS
,
"{}"
))
val
recentsJson
=
JSONObject
(
preferences
.
getString
(
Emoji
KeyboardPopup
.
PREF_EMOJI_RECENTS
,
"{}"
))
if
(
recentsJson
.
has
(
emojiShortname
))
{
val
useCount
=
recentsJson
.
getInt
(
emojiShortname
)
recentsJson
.
put
(
emojiShortname
,
useCount
+
1
)
}
else
{
recentsJson
.
put
(
emojiShortname
,
1
)
}
preferences
.
edit
().
putString
(
Emoji
Fragment
.
PREF_EMOJI_RECENTS
,
recentsJson
.
toString
()).
apply
()
preferences
.
edit
().
putString
(
Emoji
KeyboardPopup
.
PREF_EMOJI_RECENTS
,
recentsJson
.
toString
()).
apply
()
}
/**
...
...
@@ -96,7 +96,7 @@ object EmojiRepository {
*/
fun
getRecents
():
List
<
Emoji
>
{
val
list
=
mutableListOf
<
Emoji
>()
val
recentsJson
=
JSONObject
(
preferences
.
getString
(
Emoji
Fragment
.
PREF_EMOJI_RECENTS
,
"{}"
))
val
recentsJson
=
JSONObject
(
preferences
.
getString
(
Emoji
KeyboardPopup
.
PREF_EMOJI_RECENTS
,
"{}"
))
for
(
shortname
in
recentsJson
.
keys
())
{
val
emoji
=
getEmojiByShortname
(
shortname
)
emoji
?.
let
{
...
...
@@ -110,25 +110,6 @@ object EmojiRepository {
return
list
}
/**
* Store current soft keyboard height for later reference.
*/
fun
saveKeyboardHeight
(
height
:
Int
)
{
if
(
height
<=
0
)
{
return
}
preferences
.
edit
()
.
putInt
(
EmojiFragment
.
PREF_KEYBOARD_HEIGHT
,
height
)
.
apply
()
}
/**
* Get stored keyboard height.
*
* @return Height of the current soft keyboard.
*/
fun
getKeyboardHeight
()
=
preferences
.
getInt
(
EmojiFragment
.
PREF_KEYBOARD_HEIGHT
,
0
)
/**
* Replace shortnames to unicode characters.
*/
...
...
app/src/main/java/chat/rocket/android/widget/emoji/OverKeyboardPopupWindow.kt
0 → 100644
View file @
2b3858b1
/**
* Copyright 2015 YA LLC
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
chat.rocket.android.widget.emoji
import
android.content.Context
import
android.graphics.Point
import
android.graphics.Rect
import
android.os.Build
import
android.view.*
import
android.widget.PopupWindow
import
chat.rocket.android.BuildConfig
import
chat.rocket.android.R
/**
* Base class to create popup window that appears over software keyboard.
*/
abstract
class
OverKeyboardPopupWindow
(
val
context
:
Context
,
private
val
rootView
:
View
)
:
PopupWindow
(
context
),
ViewTreeObserver
.
OnGlobalLayoutListener
{
/**
* @return keyboard height in pixels
*/
var
keyboardHeight
=
0
private
set
private
var
pendingOpen
=
false
/**
* @return Returns true if the soft keyboard is open, false otherwise.
*/
var
isKeyboardOpen
=
false
private
set
private
var
keyboardHideListener
:
OnKeyboardHideListener
?
=
null
interface
OnKeyboardHideListener
{
fun
onKeyboardHide
()
}
init
{
setBackgroundDrawable
(
null
)
if
(
BuildConfig
.
VERSION_CODE
>=
Build
.
VERSION_CODES
.
LOLLIPOP
)
{
elevation
=
0f
}
val
view
=
onCreateView
(
LayoutInflater
.
from
(
context
))
onViewCreated
(
view
)
contentView
=
view
softInputMode
=
WindowManager
.
LayoutParams
.
SOFT_INPUT_STATE_ALWAYS_VISIBLE
// Default size
setSize
(
this
.
context
.
resources
.
getDimensionPixelSize
(
R
.
dimen
.
supposed_keyboard_height
),
WindowManager
.
LayoutParams
.
MATCH_PARENT
)
setSizeForSoftKeyboard
()
}
fun
setKeyboardHideListener
(
keyboardHideListener
:
OnKeyboardHideListener
)
{
this
.
keyboardHideListener
=
keyboardHideListener
}
/**
* Manually set the popup window size
*
* @param width Width of the popup
* @param height Height of the popup
*/
fun
setSize
(
width
:
Int
,
height
:
Int
)
{
setWidth
(
width
)
setHeight
(
height
)
}
/**
* Call this function to resize the emoji popup according to your soft keyboard size
*/
fun
setSizeForSoftKeyboard
()
{
val
viewTreeObserver
=
rootView
.
viewTreeObserver
viewTreeObserver
.
addOnGlobalLayoutListener
(
this
)
}
override
fun
onGlobalLayout
()
{
val
r
=
Rect
()
rootView
.
getWindowVisibleDisplayFrame
(
r
)
val
screenHeight
=
calculateScreenHeight
()
var
heightDifference
=
screenHeight
-
(
r
.
bottom
-
r
.
top
)
val
resources
=
context
.
resources
val
resourceId
=
resources
.
getIdentifier
(
"status_bar_height"
,
"dimen"
,
"android"
)
if
(
resourceId
>
0
)
{
heightDifference
-=
resources
.
getDimensionPixelSize
(
resourceId
)
}
if
(
heightDifference
>
100
)
{
keyboardHeight
=
heightDifference
setSize
(
WindowManager
.
LayoutParams
.
MATCH_PARENT
,
keyboardHeight
)
isKeyboardOpen
=
true
if
(
pendingOpen
)
{
showAtBottom
()
pendingOpen
=
false
}
}
else
{
if
(
isKeyboardOpen
&&
keyboardHideListener
!=
null
)
{
keyboardHideListener
!!
.
onKeyboardHide
()
}
isKeyboardOpen
=
false
}
}
private
fun
calculateScreenHeight
():
Int
{
val
wm
=
context
.
getSystemService
(
Context
.
WINDOW_SERVICE
)
as
WindowManager
val
display
=
wm
.
getDefaultDisplay
()
val
size
=
Point
()
display
.
getSize
(
size
)
return
size
.
y
}
/**
* Use this function to show the popup.
* NOTE: Since, the soft keyboard sizes are variable on different android devices, the
* library needs you to open the soft keyboard at least once before calling this function.
* If that is not possible see showAtBottomPending() function.
*/
fun
showAtBottom
()
{
showAtLocation
(
rootView
,
Gravity
.
BOTTOM
,
0
,
0
)
}
/**
* Use this function when the soft keyboard has not been opened yet. This
* will show the popup after the keyboard is up next time.
* Generally, you will be calling InputMethodManager.showSoftInput function after
* calling this function.
*/
fun
showAtBottomPending
()
{
if
(
isKeyboardOpen
)
{
showAtBottom
()
}
else
{
pendingOpen
=
true
}
}
abstract
fun
onCreateView
(
inflater
:
LayoutInflater
):
View
abstract
fun
onViewCreated
(
view
:
View
)
}
\ No newline at end of file
app/src/main/res/layout/emoji_popup_layout.xml
View file @
2b3858b1
...
...
@@ -3,9 +3,8 @@
xmlns:app=
"http://schemas.android.com/apk/res-auto"
android:id=
"@+id/emoji_keyboard_container"
android:layout_width=
"match_parent"
android:layout_height=
"200dp"
android:background=
"@color/white"
android:visibility=
"gone"
>
android:layout_height=
"0dp"
android:background=
"@color/white"
>
<View
android:id=
"@+id/divider"
...
...
app/src/main/res/values/dimens.xml
View file @
2b3858b1
...
...
@@ -17,4 +17,6 @@
<!-- Emoji -->
<dimen
name=
"picker_padding_bottom"
>
16dp
</dimen>
<dimen
name=
"supposed_keyboard_height"
>
252dp
</dimen>
</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