Skip to content

Commit

Permalink
fix chat download out of memory error
Browse files Browse the repository at this point in the history
(cherry picked from commit ea00431)
  • Loading branch information
crackededed committed May 29, 2024
1 parent de642c3 commit 6d27ec9
Show file tree
Hide file tree
Showing 10 changed files with 612 additions and 438 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ android {
applicationId = "com.github.andreyasadchy.xtra"
minSdk = 21
targetSdk = 34
versionCode = 239
versionName = "2.32.0"
versionCode = 240
versionName = "2.32.1"
}

buildTypes {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.github.andreyasadchy.xtra.model.chat

class CheerEmote(
val name: String,
val localData: ByteArray? = null,
val localData: Pair<Long, Int>? = null,
val url1x: String? = null,
val url2x: String? = null,
val url3x: String? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.github.andreyasadchy.xtra.model.chat

class Emote(
val name: String? = null,
val localData: ByteArray? = null,
val localData: Pair<Long, Int>? = null,
val url1x: String? = null,
val url2x: String? = null,
val url3x: String? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.github.andreyasadchy.xtra.model.chat
class TwitchBadge(
val setId: String,
val version: String,
val localData: ByteArray? = null,
val localData: Pair<Long, Int>? = null,
val url1x: String? = null,
val url2x: String? = null,
val url3x: String? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.github.andreyasadchy.xtra.model.chat
class TwitchEmote(
val id: String? = null,
val name: String? = null,
val localData: ByteArray? = null,
val localData: Pair<Long, Int>? = null,
val url1x: String? = "https://static-cdn.jtvnw.net/emoticons/v2/$id/default/dark/1.0",
val url2x: String? = "https://static-cdn.jtvnw.net/emoticons/v2/$id/default/dark/2.0",
val url3x: String? = "https://static-cdn.jtvnw.net/emoticons/v2/$id/default/dark/2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class ChatFragment : BaseNetworkFragment(), LifecycleListener, MessageClickedDia
true
}
chatUrl != null || (args.getString(KEY_VIDEO_ID) != null && !args.getBoolean(KEY_START_TIME_EMPTY)) -> {
chatView.init(this@ChatFragment, channelId)
chatView.init(this@ChatFragment, channelId, viewModel::getEmoteBytes, chatUrl)
true
}
else -> {
Expand Down
572 changes: 354 additions & 218 deletions app/src/main/java/com/github/andreyasadchy/xtra/ui/chat/ChatViewModel.kt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import kotlin.collections.set
import kotlin.math.floor
import kotlin.math.pow


private const val RED_HUE_DEGREES = 0f
private const val GREEN_HUE_DEGREES = 120f
private const val BLUE_HUE_DEGREES = 240f
Expand All @@ -67,7 +68,9 @@ class ChatAdapter(
private val redeemedChatMsg: String,
private val redeemedNoMsg: String,
private val imageLibrary: String?,
private val channelId: String?) : RecyclerView.Adapter<ChatAdapter.ViewHolder>() {
private val channelId: String?,
private val getEmoteBytes: ((String, Pair<Long, Int>) -> ByteArray?)?,
private val chatUrl: String?) : RecyclerView.Adapter<ChatAdapter.ViewHolder>() {

var messages: MutableList<ChatMessage>? = null
set(value) {
Expand All @@ -82,6 +85,10 @@ class ChatAdapter(
private val random = Random()
private val userColors = HashMap<String, Int>()
private val savedColors = HashMap<String, Int>()
private val savedLocalTwitchEmotes = mutableMapOf<String, ByteArray>()
private val savedLocalBadges = mutableMapOf<String, ByteArray>()
private val savedLocalCheerEmotes = mutableMapOf<String, ByteArray>()
private val savedLocalEmotes = mutableMapOf<String, ByteArray>()
private var localTwitchEmotes: List<TwitchEmote>? = null
private var globalStvEmotes: List<Emote>? = null
private var channelStvEmotes: List<Emote>? = null
Expand Down Expand Up @@ -191,7 +198,7 @@ class ChatAdapter(
if (badge != null) {
builder.append(" ")
images.add(Image(
localData = badge.localData,
localData = badge.localData?.let { getLocalBadgeData(badge.setId + badge.version, it) },
url1x = badge.url1x,
url2x = badge.url2x,
url3x = badge.url3x,
Expand Down Expand Up @@ -265,18 +272,20 @@ class ChatAdapter(
}
e.end -= length
}
copy.forEach { images.add(Image(
localData = it.localData,
url1x = it.url1x,
url2x = it.url2x,
url3x = it.url3x,
url4x = it.url4x,
format = it.format,
isAnimated = it.isAnimated,
isEmote = true,
start = builderIndex + it.begin,
end = builderIndex + it.end + 1
)) }
copy.forEach { emote ->
images.add(Image(
localData = emote.localData?.let { getLocalTwitchEmoteData(emote.id!!, it) },
url1x = emote.url1x,
url2x = emote.url2x,
url3x = emote.url3x,
url4x = emote.url4x,
format = emote.format,
isAnimated = emote.isAnimated,
isEmote = true,
start = builderIndex + emote.begin,
end = builderIndex + emote.end + 1
))
}
}
val split = builder.substring(builderIndex).split(" ")
var emotesFound = 0
Expand All @@ -299,7 +308,7 @@ class ChatAdapter(
builder.replace(builderIndex, builderIndex + bitsName.length, ".")
builder.setSpan(ForegroundColorSpan(Color.TRANSPARENT), builderIndex, builderIndex + 1, SPAN_EXCLUSIVE_EXCLUSIVE)
images.add(Image(
localData = emote.localData,
localData = emote.localData?.let { getLocalCheerEmoteData(emote.name + emote.minBits, it) },
url1x = emote.url1x,
url2x = emote.url2x,
url3x = emote.url3x,
Expand Down Expand Up @@ -340,7 +349,7 @@ class ChatAdapter(
builder.replace(builderIndex, builderIndex + value.length, ".")
builder.setSpan(ForegroundColorSpan(Color.TRANSPARENT), builderIndex, builderIndex + 1, SPAN_EXCLUSIVE_EXCLUSIVE)
images.add(Image(
localData = emote.localData,
localData = emote.localData?.let { getLocalEmoteData(emote.name!!, it) },
url1x = emote.url1x,
url2x = emote.url2x,
url3x = emote.url3x,
Expand Down Expand Up @@ -503,6 +512,58 @@ class ChatAdapter(
})
}

private fun getLocalTwitchEmoteData(name: String, data: Pair<Long, Int>): ByteArray? {
return savedLocalTwitchEmotes[name] ?: chatUrl?.let{ url ->
getEmoteBytes?.let { get ->
get(url, data)?.also {
if (savedLocalTwitchEmotes.size >= 100) {
savedLocalTwitchEmotes.remove(savedLocalTwitchEmotes.keys.first())
}
savedLocalTwitchEmotes[name] = it
}
}
}
}

private fun getLocalBadgeData(name: String, data: Pair<Long, Int>): ByteArray? {
return savedLocalBadges[name] ?: chatUrl?.let{ url ->
getEmoteBytes?.let { get ->
get(url, data)?.also {
if (savedLocalBadges.size >= 100) {
savedLocalBadges.remove(savedLocalBadges.keys.first())
}
savedLocalBadges[name] = it
}
}
}
}

private fun getLocalCheerEmoteData(name: String, data: Pair<Long, Int>): ByteArray? {
return savedLocalCheerEmotes[name] ?: chatUrl?.let{ url ->
getEmoteBytes?.let { get ->
get(url, data)?.also {
if (savedLocalCheerEmotes.size >= 100) {
savedLocalCheerEmotes.remove(savedLocalCheerEmotes.keys.first())
}
savedLocalCheerEmotes[name] = it
}
}
}
}

private fun getLocalEmoteData(name: String, data: Pair<Long, Int>): ByteArray? {
return savedLocalEmotes[name] ?: chatUrl?.let{ url ->
getEmoteBytes?.let { get ->
get(url, data)?.also {
if (savedLocalEmotes.size >= 100) {
savedLocalEmotes.remove(savedLocalEmotes.keys.first())
}
savedLocalEmotes[name] = it
}
}
}
}

fun addLocalTwitchEmotes(list: List<TwitchEmote>?) {
localTwitchEmotes = list
}
Expand Down
Loading

0 comments on commit 6d27ec9

Please sign in to comment.