2018-01-04 19:52:25 +01:00
|
|
|
package jp.juggler.subwaytooter.dialog
|
|
|
|
|
|
|
|
import android.annotation.SuppressLint
|
|
|
|
import android.app.Activity
|
|
|
|
import android.app.Dialog
|
2019-10-05 07:59:33 +02:00
|
|
|
import android.graphics.Typeface
|
2019-09-14 22:09:52 +02:00
|
|
|
import android.graphics.drawable.PictureDrawable
|
2018-01-04 19:52:25 +01:00
|
|
|
import android.util.SparseArray
|
2021-11-08 10:29:11 +01:00
|
|
|
import android.util.TypedValue
|
2019-10-05 07:59:33 +02:00
|
|
|
import android.view.*
|
2018-01-04 19:52:25 +01:00
|
|
|
import android.widget.*
|
2021-06-20 15:12:25 +02:00
|
|
|
import androidx.annotation.StringRes
|
2019-07-31 20:30:56 +02:00
|
|
|
import androidx.viewpager.widget.ViewPager
|
2018-01-04 19:52:25 +01:00
|
|
|
import com.astuetz.PagerSlidingTabStrip
|
2019-09-14 22:09:52 +02:00
|
|
|
import com.bumptech.glide.Glide
|
2021-02-15 08:45:22 +01:00
|
|
|
import jp.juggler.subwaytooter.*
|
2021-05-19 22:14:30 +02:00
|
|
|
import jp.juggler.subwaytooter.emoji.*
|
2021-11-06 04:00:29 +01:00
|
|
|
import jp.juggler.subwaytooter.pref.PrefB
|
|
|
|
import jp.juggler.subwaytooter.pref.PrefS
|
|
|
|
import jp.juggler.subwaytooter.pref.put
|
2020-05-16 16:59:18 +02:00
|
|
|
import jp.juggler.subwaytooter.table.SavedAccount
|
2019-09-25 10:42:25 +02:00
|
|
|
import jp.juggler.subwaytooter.view.HeaderGridView
|
2018-11-12 02:34:15 +01:00
|
|
|
import jp.juggler.subwaytooter.view.MyViewPager
|
2018-01-04 19:52:25 +01:00
|
|
|
import jp.juggler.subwaytooter.view.NetworkEmojiView
|
2019-01-19 03:36:40 +01:00
|
|
|
import jp.juggler.util.*
|
2019-09-25 10:42:25 +02:00
|
|
|
import org.jetbrains.anko.padding
|
|
|
|
import org.jetbrains.anko.textColor
|
2019-01-19 03:36:40 +01:00
|
|
|
import java.util.*
|
2018-01-04 19:52:25 +01:00
|
|
|
|
2021-02-22 22:33:54 +01:00
|
|
|
class SkinTone(codeInt: Int) {
|
|
|
|
val code = StringBuilder().apply { appendCodePoint(codeInt) }.toString()
|
|
|
|
}
|
|
|
|
|
|
|
|
data class EmojiPickerResult(
|
|
|
|
val bInstanceHasCustomEmoji: Boolean,
|
2021-06-20 15:12:25 +02:00
|
|
|
val emoji: EmojiBase,
|
2021-02-22 22:33:54 +01:00
|
|
|
)
|
|
|
|
|
2018-01-04 19:52:25 +01:00
|
|
|
@SuppressLint("InflateParams")
|
|
|
|
class EmojiPicker(
|
2021-06-20 15:12:25 +02:00
|
|
|
private val activity: Activity,
|
|
|
|
private val accessInfo: SavedAccount?,
|
|
|
|
val closeOnSelected: Boolean,
|
|
|
|
private val onEmojiPickerSelected: (EmojiPickerResult) -> Unit,
|
|
|
|
// onEmojiPickedのinstance引数は通常の絵文字ならnull、カスタム絵文字なら非null、
|
2019-07-31 20:30:56 +02:00
|
|
|
) : View.OnClickListener, ViewPager.OnPageChangeListener {
|
2021-02-22 22:33:54 +01:00
|
|
|
|
|
|
|
internal class EmojiItem(
|
|
|
|
val unicodeEmoji: UnicodeEmoji? = null,
|
|
|
|
val name: String = "",
|
2021-06-20 15:12:25 +02:00
|
|
|
val instance: String? = null,
|
|
|
|
)
|
2021-02-22 22:33:54 +01:00
|
|
|
|
|
|
|
internal class CustomCategory(
|
2021-06-20 15:12:25 +02:00
|
|
|
val rangeStart: Int,
|
|
|
|
val rangeLength: Int,
|
|
|
|
val view: View,
|
|
|
|
)
|
2021-02-22 22:33:54 +01:00
|
|
|
|
|
|
|
companion object {
|
|
|
|
|
|
|
|
internal val log = LogCategory("EmojiPicker")
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
internal val toneList = arrayOf(
|
|
|
|
SkinTone(0x1F3FB),
|
|
|
|
SkinTone(0x1F3FC),
|
|
|
|
SkinTone(0x1F3FD),
|
|
|
|
SkinTone(0x1F3FE),
|
|
|
|
SkinTone(0x1F3FF),
|
|
|
|
)
|
2021-02-22 22:33:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private val viewRoot: View
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
private val pagerAdapter: EmojiPickerPagerAdapter
|
2021-02-22 22:33:54 +01:00
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
private val pageList = ArrayList<EmojiPickerPage>()
|
2021-02-22 22:33:54 +01:00
|
|
|
|
|
|
|
private val pager: MyViewPager
|
|
|
|
|
|
|
|
private val dialog: Dialog
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
private val pagerStrip: PagerSlidingTabStrip
|
2021-02-22 22:33:54 +01:00
|
|
|
|
|
|
|
private val ibSkinTone: Array<ImageButton>
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
private var selectedTone: Int = 0
|
2021-02-22 22:33:54 +01:00
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
private val recentList = ArrayList<EmojiItem>()
|
2021-02-22 22:33:54 +01:00
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
private var customList = ArrayList<EmojiItem>()
|
|
|
|
private var customCategories = ArrayList<CustomCategory>()
|
2021-02-22 22:33:54 +01:00
|
|
|
|
|
|
|
private val customEmojiMap = HashMap<String, CustomEmoji>()
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
private val recentPageIdx: Int
|
2021-02-22 22:33:54 +01:00
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
private val customPageIdx: Int
|
2021-02-22 22:33:54 +01:00
|
|
|
|
|
|
|
init {
|
|
|
|
|
|
|
|
// recentをロードする
|
|
|
|
val pref = App1.pref
|
2021-06-22 10:31:51 +02:00
|
|
|
val sv = PrefS.spEmojiPickerRecent(pref)
|
2021-02-22 22:33:54 +01:00
|
|
|
if (sv.isNotEmpty()) {
|
|
|
|
try {
|
|
|
|
for (item in sv.decodeJsonArray().objectList()) {
|
|
|
|
val name = item.string("name")
|
|
|
|
val instance = item.string("instance")
|
|
|
|
if (name.isNullOrEmpty()) continue
|
|
|
|
if (instance == null) {
|
|
|
|
val unicodeEmoji = EmojiMap.shortNameMap[name]
|
|
|
|
if (unicodeEmoji != null) {
|
2021-06-20 15:12:25 +02:00
|
|
|
recentList.add(EmojiItem(unicodeEmoji = unicodeEmoji))
|
2021-02-22 22:33:54 +01:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
2021-06-20 15:12:25 +02:00
|
|
|
recentList.add(EmojiItem(name = name, instance = instance))
|
2021-02-22 22:33:54 +01:00
|
|
|
}
|
|
|
|
} catch (ex: Throwable) {
|
|
|
|
log.trace(ex)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// create page
|
2021-06-20 15:12:25 +02:00
|
|
|
this.recentPageIdx = pageList.size
|
|
|
|
pageList.add(EmojiPickerPage(false, EmojiCategory.Recent, R.string.emoji_category_recent))
|
|
|
|
|
|
|
|
this.customPageIdx = pageList.size
|
|
|
|
pageList.add(EmojiPickerPage(false, EmojiCategory.Custom, R.string.emoji_category_custom))
|
|
|
|
|
|
|
|
pageList.add(
|
|
|
|
EmojiPickerPage(
|
|
|
|
true,
|
|
|
|
EmojiCategory.People,
|
|
|
|
R.string.emoji_category_people
|
|
|
|
)
|
|
|
|
)
|
|
|
|
pageList.add(
|
|
|
|
EmojiPickerPage(
|
|
|
|
false,
|
|
|
|
EmojiCategory.ComplexTones,
|
|
|
|
R.string.emoji_category_composite_tones
|
|
|
|
)
|
|
|
|
)
|
|
|
|
pageList.add(
|
|
|
|
EmojiPickerPage(
|
|
|
|
true,
|
|
|
|
EmojiCategory.Nature,
|
|
|
|
R.string.emoji_category_nature
|
|
|
|
)
|
|
|
|
)
|
|
|
|
pageList.add(
|
|
|
|
EmojiPickerPage(
|
|
|
|
true,
|
|
|
|
EmojiCategory.Foods,
|
|
|
|
R.string.emoji_category_foods
|
|
|
|
)
|
|
|
|
)
|
|
|
|
pageList.add(
|
|
|
|
EmojiPickerPage(
|
|
|
|
true,
|
|
|
|
EmojiCategory.Activities,
|
|
|
|
R.string.emoji_category_activity
|
|
|
|
)
|
|
|
|
)
|
|
|
|
pageList.add(
|
|
|
|
EmojiPickerPage(
|
|
|
|
true,
|
|
|
|
EmojiCategory.Places,
|
|
|
|
R.string.emoji_category_places
|
|
|
|
)
|
|
|
|
)
|
|
|
|
pageList.add(
|
|
|
|
EmojiPickerPage(
|
|
|
|
true,
|
|
|
|
EmojiCategory.Objects,
|
|
|
|
R.string.emoji_category_objects
|
|
|
|
)
|
|
|
|
)
|
|
|
|
pageList.add(
|
|
|
|
EmojiPickerPage(
|
|
|
|
true,
|
|
|
|
EmojiCategory.Symbols,
|
|
|
|
R.string.emoji_category_symbols
|
|
|
|
)
|
|
|
|
)
|
|
|
|
pageList.add(
|
|
|
|
EmojiPickerPage(
|
|
|
|
true,
|
|
|
|
EmojiCategory.Flags,
|
|
|
|
R.string.emoji_category_flags
|
|
|
|
)
|
|
|
|
)
|
2021-06-22 10:31:51 +02:00
|
|
|
if (PrefB.bpEmojiPickerCategoryOther(activity)) {
|
2021-06-20 15:12:25 +02:00
|
|
|
pageList.add(
|
|
|
|
EmojiPickerPage(
|
|
|
|
true,
|
|
|
|
EmojiCategory.Others,
|
|
|
|
R.string.emoji_category_others
|
|
|
|
)
|
|
|
|
)
|
2021-02-22 22:33:54 +01:00
|
|
|
}
|
2021-02-15 08:45:22 +01:00
|
|
|
|
2021-02-22 22:33:54 +01:00
|
|
|
this.viewRoot = activity.layoutInflater.inflate(R.layout.dlg_picker_emoji, null, false)
|
|
|
|
this.pager = viewRoot.findViewById(R.id.pager)
|
2021-06-20 15:12:25 +02:00
|
|
|
this.pagerStrip = viewRoot.findViewById(R.id.pager_strip)
|
2021-02-22 22:33:54 +01:00
|
|
|
|
|
|
|
this.ibSkinTone = arrayOf(
|
2021-06-20 15:12:25 +02:00
|
|
|
initSkinTone(0, viewRoot.findViewById(R.id.btnSkinTone1)),
|
|
|
|
initSkinTone(1, viewRoot.findViewById(R.id.btnSkinTone2)),
|
|
|
|
initSkinTone(2, viewRoot.findViewById(R.id.btnSkinTone3)),
|
|
|
|
initSkinTone(3, viewRoot.findViewById(R.id.btnSkinTone4)),
|
|
|
|
initSkinTone(4, viewRoot.findViewById(R.id.btnSkinTone5))
|
|
|
|
)
|
2021-02-22 22:33:54 +01:00
|
|
|
showSkinTone()
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
this.pagerAdapter = EmojiPickerPagerAdapter()
|
|
|
|
pager.adapter = pagerAdapter
|
|
|
|
pagerStrip.setViewPager(pager)
|
2021-02-22 22:33:54 +01:00
|
|
|
|
|
|
|
pager.addOnPageChangeListener(this)
|
|
|
|
onPageSelected(0)
|
|
|
|
|
|
|
|
// カスタム絵文字をロードする
|
|
|
|
if (accessInfo != null) {
|
|
|
|
setCustomEmojiList(
|
2021-06-20 15:12:25 +02:00
|
|
|
App1.custom_emoji_lister.getList(accessInfo) {
|
|
|
|
setCustomEmojiList(it) // ロード完了時に呼ばれる
|
|
|
|
}
|
|
|
|
)
|
2021-02-22 22:33:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
this.dialog = Dialog(activity)
|
|
|
|
dialog.setContentView(viewRoot)
|
|
|
|
dialog.setCancelable(true)
|
|
|
|
dialog.setCanceledOnTouchOutside(true)
|
|
|
|
val w = dialog.window
|
|
|
|
|
|
|
|
// XXX Android 11 で SOFT_INPUT_ADJUST_RESIZE はdeprecatedになった
|
|
|
|
@Suppress("DEPRECATION")
|
|
|
|
w?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
|
|
|
|
}
|
|
|
|
|
|
|
|
private var bInstanceHasCustomEmoji = false
|
|
|
|
|
|
|
|
private fun setCustomEmojiList(list: ArrayList<CustomEmoji>?) {
|
|
|
|
if (list == null) return
|
|
|
|
bInstanceHasCustomEmoji = true
|
|
|
|
|
|
|
|
// make categories
|
|
|
|
val newList = TreeMap<String, ArrayList<EmojiItem>>()
|
|
|
|
for (emoji in list) {
|
2021-06-20 15:12:25 +02:00
|
|
|
if (!emoji.visibleInPicker) continue
|
2021-02-22 22:33:54 +01:00
|
|
|
val category = emoji.category ?: ""
|
|
|
|
var subList = newList[category]
|
|
|
|
if (subList == null) {
|
|
|
|
subList = ArrayList()
|
|
|
|
newList[category] = subList
|
|
|
|
}
|
|
|
|
subList.add(EmojiItem(name = emoji.shortcode, instance = accessInfo!!.apiHost.ascii))
|
|
|
|
customEmojiMap[emoji.shortcode] = emoji
|
|
|
|
}
|
|
|
|
// compose categories data list
|
|
|
|
val entries = newList.entries
|
2021-06-20 15:12:25 +02:00
|
|
|
customList.clear()
|
|
|
|
customCategories.clear()
|
|
|
|
customList.ensureCapacity(entries.sumOf { it.value.size })
|
|
|
|
customCategories.ensureCapacity(entries.size)
|
2021-02-22 22:33:54 +01:00
|
|
|
entries.forEach {
|
2021-06-20 15:12:25 +02:00
|
|
|
val rangeStart = customList.size
|
|
|
|
customList.addAll(it.value)
|
|
|
|
val rangeLength = customList.size - rangeStart
|
|
|
|
|
|
|
|
customCategories.add(CustomCategory(
|
|
|
|
rangeStart,
|
|
|
|
rangeLength,
|
|
|
|
TextView(activity).apply {
|
|
|
|
layoutParams = FrameLayout.LayoutParams(
|
|
|
|
FrameLayout.LayoutParams.MATCH_PARENT,
|
|
|
|
FrameLayout.LayoutParams.WRAP_CONTENT
|
|
|
|
)
|
|
|
|
padding = (resources.displayMetrics.density * 2f + 0.5f).toInt()
|
|
|
|
gravity = Gravity.START or Gravity.CENTER_VERTICAL
|
|
|
|
|
|
|
|
setTypeface(typeface, Typeface.BOLD)
|
|
|
|
|
|
|
|
textColor = this@EmojiPicker.activity.attrColor(R.attr.colorContentText)
|
|
|
|
textSize = 16f // SP単位
|
|
|
|
|
|
|
|
text = when (val name = it.key) {
|
|
|
|
"" -> this@EmojiPicker.activity.getString(R.string.custom_emoji)
|
|
|
|
else -> name
|
|
|
|
}
|
|
|
|
}
|
|
|
|
))
|
2021-02-22 22:33:54 +01:00
|
|
|
}
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
pagerAdapter.getPageViewHolder(customPageIdx)?.reloadCustomEmoji()
|
|
|
|
pagerAdapter.getPageViewHolder(recentPageIdx)?.notifyDataSetChanged()
|
2021-02-22 22:33:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
internal fun show() {
|
|
|
|
dialog.show()
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onPageScrollStateChanged(state: Int) {
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onPageScrolled(
|
2021-06-20 15:12:25 +02:00
|
|
|
position: Int,
|
|
|
|
positionOffset: Float,
|
|
|
|
positionOffsetPixels: Int,
|
|
|
|
) {
|
2021-02-22 22:33:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun onPageSelected(position: Int) {
|
|
|
|
try {
|
2021-06-20 15:12:25 +02:00
|
|
|
val hasSkinTone = pageList[position].hasSkinTone
|
2021-02-22 22:33:54 +01:00
|
|
|
val visibility = if (hasSkinTone) View.VISIBLE else View.INVISIBLE
|
|
|
|
ibSkinTone.forEach { it.visibility = visibility }
|
|
|
|
} catch (ex: Throwable) {
|
|
|
|
log.trace(ex)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun applySkinTone(emojiArg: UnicodeEmoji): UnicodeEmoji {
|
|
|
|
|
|
|
|
var emoji = emojiArg
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
val tone = if (selectedTone == 0) {
|
2021-02-22 22:33:54 +01:00
|
|
|
null
|
|
|
|
} else {
|
2021-06-20 15:12:25 +02:00
|
|
|
viewRoot.findViewById<View>(selectedTone).tag as SkinTone
|
2021-02-22 22:33:54 +01:00
|
|
|
} ?: return emoji
|
|
|
|
|
|
|
|
// Recentなどでは既にsuffixがついた名前が用意されている
|
|
|
|
// suffixを除去する
|
|
|
|
emoji.toneParent?.let { emoji = it }
|
|
|
|
|
|
|
|
// 指定したトーンのサフィックスを追加して、絵文字が存在すればその名前にする
|
|
|
|
emoji.toneChildren.find { it.first == tone.code }?.let { return it.second }
|
|
|
|
|
|
|
|
// なければトーンなしの絵文字
|
|
|
|
return emoji
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun initSkinTone(idx: Int, ib: ImageButton): ImageButton {
|
2021-06-20 15:12:25 +02:00
|
|
|
ib.tag = toneList[idx]
|
2021-02-22 22:33:54 +01:00
|
|
|
ib.setOnClickListener(this)
|
|
|
|
return ib
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun showSkinTone() {
|
|
|
|
for (button in ibSkinTone) {
|
2021-06-20 15:12:25 +02:00
|
|
|
if (selectedTone == button.id) {
|
2021-02-22 22:33:54 +01:00
|
|
|
button.setImageResource(R.drawable.check_mark)
|
|
|
|
} else {
|
|
|
|
button.setImageDrawable(null)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onClick(view: View) {
|
|
|
|
val id = view.id
|
2021-06-20 15:12:25 +02:00
|
|
|
selectedTone = if (selectedTone == id) 0 else id
|
2021-02-22 22:33:54 +01:00
|
|
|
showSkinTone()
|
2021-06-20 15:12:25 +02:00
|
|
|
pagerAdapter.eachViewHolder { _, vh -> vh.reloadSkinTone() }
|
2021-02-22 22:33:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
internal inner class EmojiPickerPage(
|
2021-05-19 22:14:30 +02:00
|
|
|
val hasSkinTone: Boolean,
|
|
|
|
val category: EmojiCategory,
|
2021-06-20 15:12:25 +02:00
|
|
|
@StringRes titleId: Int,
|
|
|
|
) {
|
2021-02-22 22:33:54 +01:00
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
val title: String = activity.getString(titleId)
|
2021-02-22 22:33:54 +01:00
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
val emojiList = when (category) {
|
2021-02-22 22:33:54 +01:00
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
EmojiCategory.Custom -> customList
|
2021-02-22 22:33:54 +01:00
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
EmojiCategory.Recent -> ArrayList<EmojiItem>().apply {
|
|
|
|
for (item in recentList) {
|
|
|
|
if (item.instance != null && item.instance != accessInfo?.apiHost?.ascii) continue
|
|
|
|
add(item)
|
|
|
|
}
|
|
|
|
}
|
2021-02-22 22:33:54 +01:00
|
|
|
|
|
|
|
else -> ArrayList<EmojiItem>().apply {
|
2021-06-20 15:12:25 +02:00
|
|
|
category.emojiList.forEach { emoji ->
|
2021-02-22 22:33:54 +01:00
|
|
|
add(EmojiItem(unicodeEmoji = emoji, name = emoji.unifiedName))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inner class EmojiPickerPageViewHolder(activity: Activity, root: View) : BaseAdapter(),
|
|
|
|
AdapterView.OnItemClickListener {
|
|
|
|
|
|
|
|
private val gridView: HeaderGridView = root.findViewById(R.id.gridView)
|
|
|
|
private val wh = (0.5f + 48f * activity.resources.displayMetrics.density).toInt()
|
|
|
|
|
|
|
|
private var page: EmojiPickerPage? = null
|
|
|
|
|
|
|
|
internal fun onPageCreate(page: EmojiPickerPage) {
|
|
|
|
this.page = page
|
|
|
|
if (page.category == EmojiCategory.Custom) {
|
|
|
|
reloadCustomEmoji()
|
|
|
|
} else {
|
|
|
|
gridView.adapter = this
|
|
|
|
}
|
|
|
|
gridView.onItemClickListener = this
|
|
|
|
}
|
|
|
|
|
|
|
|
internal fun onPageDestroy() {
|
|
|
|
}
|
|
|
|
|
|
|
|
internal fun reloadSkinTone() {
|
2021-06-20 15:12:25 +02:00
|
|
|
val page = this.page ?: error("page is not assigned")
|
2021-02-22 22:33:54 +01:00
|
|
|
if (page.category != EmojiCategory.Custom) {
|
|
|
|
this.notifyDataSetChanged()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun reloadCustomEmoji() {
|
|
|
|
gridView.reset()
|
2021-06-20 15:12:25 +02:00
|
|
|
if (customCategories.size >= 2) {
|
|
|
|
for (item in customCategories) {
|
2021-02-22 22:33:54 +01:00
|
|
|
gridView.addHeaderView(
|
2021-06-20 15:12:25 +02:00
|
|
|
rangeStart = item.rangeStart,
|
|
|
|
rangeLength = item.rangeLength,
|
|
|
|
itemHeight = wh,
|
|
|
|
v = item.view,
|
|
|
|
isSelectable = false
|
|
|
|
)
|
2021-02-22 22:33:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
gridView.adapter = this
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun getCount(): Int {
|
2021-06-20 15:12:25 +02:00
|
|
|
return page?.emojiList?.size ?: 0
|
2021-02-22 22:33:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun getItem(i: Int): Any? {
|
2021-06-20 15:12:25 +02:00
|
|
|
return page?.emojiList?.get(i)
|
2021-02-22 22:33:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun getItemId(i: Int): Long {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun getViewTypeCount(): Int {
|
|
|
|
return 2
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun getItemViewType(position: Int): Int {
|
2021-06-20 15:12:25 +02:00
|
|
|
return if (page?.emojiList?.get(position)?.instance != null) 1 else 0
|
2021-02-22 22:33:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun getView(position: Int, viewOld: View?, viewGroup: ViewGroup): View {
|
2021-06-20 15:12:25 +02:00
|
|
|
val page = this.page ?: error("page is not assigned")
|
2021-02-22 22:33:54 +01:00
|
|
|
val view: View
|
2021-06-20 15:12:25 +02:00
|
|
|
val item = page.emojiList[position]
|
2021-02-22 22:33:54 +01:00
|
|
|
var unicodeEmoji = item.unicodeEmoji
|
2021-11-08 10:29:11 +01:00
|
|
|
if (unicodeEmoji == null) {
|
|
|
|
view = viewOld ?: NetworkEmojiView(activity).apply {
|
|
|
|
layoutParams = AbsListView.LayoutParams(wh, wh)
|
|
|
|
}
|
|
|
|
view.setTag(R.id.btnAbout, item)
|
|
|
|
(view as? NetworkEmojiView)?.setEmoji(customEmojiMap[item.name]?.url)
|
|
|
|
} else if(PrefB.bpUseTwemoji(App1.pref)){
|
2021-02-22 22:33:54 +01:00
|
|
|
view = viewOld
|
|
|
|
?: ImageView(activity).apply {
|
|
|
|
layoutParams = AbsListView.LayoutParams(wh, wh)
|
|
|
|
}
|
|
|
|
|
|
|
|
view.setTag(R.id.btnAbout, item)
|
|
|
|
|
|
|
|
if (view is ImageView && view.activity?.isDestroyed == false) {
|
2021-06-20 15:12:25 +02:00
|
|
|
if (page.hasSkinTone) unicodeEmoji = applySkinTone(unicodeEmoji)
|
2021-02-22 22:33:54 +01:00
|
|
|
|
|
|
|
if (unicodeEmoji.isSvg) {
|
|
|
|
Glide.with(activity)
|
|
|
|
.`as`(PictureDrawable::class.java)
|
|
|
|
.load("file:///android_asset/${unicodeEmoji.assetsName}")
|
|
|
|
.into(view)
|
|
|
|
} else {
|
|
|
|
Glide.with(activity)
|
|
|
|
.load(unicodeEmoji.drawableId)
|
|
|
|
.into(view)
|
|
|
|
}
|
|
|
|
}
|
2021-11-08 10:29:11 +01:00
|
|
|
}else{
|
|
|
|
view = viewOld
|
|
|
|
?: TextView(activity).apply {
|
|
|
|
layoutParams = AbsListView.LayoutParams(wh, wh)
|
|
|
|
}
|
|
|
|
|
2021-02-22 22:33:54 +01:00
|
|
|
view.setTag(R.id.btnAbout, item)
|
2021-11-08 10:29:11 +01:00
|
|
|
|
|
|
|
if (view is TextView && view.activity?.isDestroyed == false) {
|
|
|
|
if (page.hasSkinTone) unicodeEmoji = applySkinTone(unicodeEmoji)
|
|
|
|
|
|
|
|
view.text = unicodeEmoji.unifiedCode
|
|
|
|
view.gravity = Gravity.CENTER
|
|
|
|
view.setLineSpacing(0f,0f)
|
|
|
|
view.setTextSize(TypedValue.COMPLEX_UNIT_PX, wh.toFloat()*0.7f)
|
|
|
|
}
|
2021-02-22 22:33:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return view
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onItemClick(
|
2021-06-20 15:12:25 +02:00
|
|
|
adapterView: AdapterView<*>,
|
|
|
|
view: View,
|
|
|
|
idxArg: Int,
|
|
|
|
l: Long,
|
|
|
|
) {
|
2021-02-22 22:33:54 +01:00
|
|
|
val page = this.page ?: return
|
|
|
|
|
|
|
|
val idx = gridView.findListItemIndex(idxArg)
|
2021-06-20 15:12:25 +02:00
|
|
|
val item = page.emojiList.elementAtOrNull(idx) ?: return
|
2021-02-22 22:33:54 +01:00
|
|
|
|
|
|
|
// unicode絵文字
|
|
|
|
item.unicodeEmoji?.let {
|
2021-06-20 15:12:25 +02:00
|
|
|
selected(if (page.hasSkinTone) applySkinTone(it) else it)
|
2021-02-22 22:33:54 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// カスタム絵文字
|
|
|
|
customEmojiMap[item.name]?.let {
|
2021-06-20 15:12:25 +02:00
|
|
|
selected(it)
|
2021-02-22 22:33:54 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// name はスキントーン適用済みであること
|
2021-06-20 15:12:25 +02:00
|
|
|
internal fun selected(emoji: EmojiBase) {
|
2021-02-22 22:33:54 +01:00
|
|
|
|
|
|
|
val pref = App1.pref
|
|
|
|
|
|
|
|
if (closeOnSelected) dialog.dismissSafe()
|
|
|
|
|
|
|
|
// Recentをロード(他インスタンスの絵文字を含む)
|
|
|
|
val list: MutableList<JsonObject> = try {
|
2021-06-22 10:31:51 +02:00
|
|
|
PrefS.spEmojiPickerRecent(pref).decodeJsonArray().objectList()
|
2021-02-22 22:33:54 +01:00
|
|
|
} catch (_: Throwable) {
|
|
|
|
emptyList()
|
|
|
|
}.toMutableList()
|
|
|
|
|
|
|
|
// 選択された絵文字と同じ項目を除去
|
|
|
|
// 項目が増えすぎたら減らす
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
val name: String
|
|
|
|
val instance: String?
|
2021-02-22 22:33:54 +01:00
|
|
|
when (emoji) {
|
|
|
|
is UnicodeEmoji -> {
|
|
|
|
name = emoji.unifiedName
|
|
|
|
instance = null
|
|
|
|
}
|
|
|
|
is CustomEmoji -> {
|
|
|
|
name = emoji.shortcode
|
|
|
|
instance = emoji.apDomain.ascii
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
run {
|
|
|
|
var nCount = 0
|
|
|
|
val it = list.iterator()
|
|
|
|
while (it.hasNext()) {
|
|
|
|
val item = it.next()
|
|
|
|
if (instance == item.string("instance")) {
|
|
|
|
if (name == item.string("name") || ++nCount >= 256) {
|
|
|
|
it.remove()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 先頭に項目を追加
|
|
|
|
list.add(0, JsonObject().apply {
|
2021-06-20 15:12:25 +02:00
|
|
|
put("name", name)
|
|
|
|
if (instance != null) put("instance", instance)
|
|
|
|
})
|
2021-02-22 22:33:54 +01:00
|
|
|
|
|
|
|
// 保存する
|
|
|
|
try {
|
|
|
|
val sv = list.toJsonArray().toString()
|
2021-06-22 10:31:51 +02:00
|
|
|
App1.pref.edit().put(PrefS.spEmojiPickerRecent, sv).apply()
|
2021-02-22 22:33:54 +01:00
|
|
|
} catch (ignored: Throwable) {
|
|
|
|
}
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
onEmojiPickerSelected(EmojiPickerResult(bInstanceHasCustomEmoji, emoji))
|
2021-02-22 22:33:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
internal inner class EmojiPickerPagerAdapter : androidx.viewpager.widget.PagerAdapter() {
|
|
|
|
|
|
|
|
private val inflater: LayoutInflater
|
2021-06-20 15:12:25 +02:00
|
|
|
private val holderList = SparseArray<EmojiPickerPageViewHolder>()
|
2021-02-22 22:33:54 +01:00
|
|
|
|
|
|
|
init {
|
|
|
|
this.inflater = activity.layoutInflater
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun getCount(): Int {
|
2021-06-20 15:12:25 +02:00
|
|
|
return pageList.size
|
2021-02-22 22:33:54 +01:00
|
|
|
}
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
private fun Int.validPage() = this >= 0 && this < pageList.size
|
2021-02-22 22:33:54 +01:00
|
|
|
|
|
|
|
private fun getPage(idx: Int): EmojiPickerPage? {
|
2021-06-20 15:12:25 +02:00
|
|
|
return if (idx.validPage()) pageList[idx] else null
|
2021-02-22 22:33:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fun getPageViewHolder(idx: Int): EmojiPickerPageViewHolder? {
|
2021-06-20 15:12:25 +02:00
|
|
|
return if (idx.validPage()) holderList.get(idx) else null
|
2021-02-22 22:33:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
inline fun eachViewHolder(block: (Int, EmojiPickerPageViewHolder) -> Unit) {
|
2021-06-20 15:12:25 +02:00
|
|
|
for (i in 0 until pageList.size) {
|
|
|
|
val vh = holderList.get(i) ?: continue
|
2021-02-22 22:33:54 +01:00
|
|
|
block(i, vh)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun getPageTitle(page_idx: Int): CharSequence? {
|
|
|
|
return getPage(page_idx)?.title
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun isViewFromObject(view: View, obj: Any): Boolean {
|
|
|
|
return view === obj
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun instantiateItem(container: ViewGroup, page_idx: Int): Any {
|
|
|
|
val root = inflater.inflate(R.layout.page_emoji_picker, container, false)
|
|
|
|
container.addView(root, 0)
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
val page = pageList[page_idx]
|
2021-02-22 22:33:54 +01:00
|
|
|
val holder = EmojiPickerPageViewHolder(activity, root)
|
|
|
|
//
|
2021-06-20 15:12:25 +02:00
|
|
|
holderList.put(page_idx, holder)
|
2021-02-22 22:33:54 +01:00
|
|
|
//
|
|
|
|
holder.onPageCreate(page)
|
|
|
|
|
|
|
|
return root
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun destroyItem(container: ViewGroup, page_idx: Int, obj: Any) {
|
|
|
|
if (obj is View) {
|
|
|
|
container.removeView(obj)
|
|
|
|
//
|
2021-06-20 15:12:25 +02:00
|
|
|
val holder = holderList.get(page_idx)
|
|
|
|
holderList.remove(page_idx)
|
2021-02-22 22:33:54 +01:00
|
|
|
holder?.onPageDestroy()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
}
|