Skip to content

Commit

Permalink
helix user emotes
Browse files Browse the repository at this point in the history
  • Loading branch information
crackededed committed Mar 17, 2024
1 parent a12eb3a commit 4d38676
Show file tree
Hide file tree
Showing 9 changed files with 240 additions and 33 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ android {
minSdk = 21
targetSdk = 34
versionCode = 121
versionName = "2.30.3"
versionName = "2.30.4"
resourceConfigurations += listOf("ar", "de", "en", "es", "fr", "in", "it", "ja", "pt-rBR", "ru", "tr", "zh-rTW", "zh-rCN")
}

Expand Down
24 changes: 22 additions & 2 deletions app/src/main/java/com/github/andreyasadchy/xtra/api/HelixApi.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package com.github.andreyasadchy.xtra.api

import com.github.andreyasadchy.xtra.model.helix.channel.ChannelSearchResponse
import com.github.andreyasadchy.xtra.model.helix.chat.*
import com.github.andreyasadchy.xtra.model.helix.chat.ChatBadgesResponse
import com.github.andreyasadchy.xtra.model.helix.chat.CheerEmotesResponse
import com.github.andreyasadchy.xtra.model.helix.chat.EmoteSetResponse
import com.github.andreyasadchy.xtra.model.helix.chat.ModeratorsResponse
import com.github.andreyasadchy.xtra.model.helix.chat.UserEmotesResponse
import com.github.andreyasadchy.xtra.model.helix.clip.ClipsResponse
import com.github.andreyasadchy.xtra.model.helix.follows.FollowResponse
import com.github.andreyasadchy.xtra.model.helix.game.GamesResponse
Expand All @@ -14,7 +18,14 @@ import com.github.andreyasadchy.xtra.model.ui.VideoSortEnum
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import retrofit2.Response
import retrofit2.http.*
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.PATCH
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Query

interface HelixApi {

Expand Down Expand Up @@ -130,6 +141,15 @@ interface HelixApi {
@Query("after") offset: String? = null
): FollowResponse

@GET("chat/emotes/user")
suspend fun getUserEmotes(
@Header("Client-ID") clientId: String?,
@Header("Authorization") token: String?,
@Query("user_id") userId: String?,
@Query("broadcaster_id") channelId: String? = null,
@Query("after") offset: String? = null
): UserEmotesResponse

@GET("chat/emotes/set")
suspend fun getEmotesFromSet(
@Header("Client-ID") clientId: String?,
Expand Down
105 changes: 94 additions & 11 deletions app/src/main/java/com/github/andreyasadchy/xtra/di/XtraModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,107 @@ import android.app.Application
import com.apollographql.apollo3.ApolloClient
import com.apollographql.apollo3.network.okHttpClient
import com.github.andreyasadchy.xtra.BuildConfig
import com.github.andreyasadchy.xtra.api.*
import com.github.andreyasadchy.xtra.model.chat.*
import com.github.andreyasadchy.xtra.model.gql.channel.*
import com.github.andreyasadchy.xtra.model.gql.chat.*
import com.github.andreyasadchy.xtra.model.gql.clip.*
import com.github.andreyasadchy.xtra.model.gql.followed.*
import com.github.andreyasadchy.xtra.model.gql.game.*
import com.github.andreyasadchy.xtra.api.GraphQLApi
import com.github.andreyasadchy.xtra.api.HelixApi
import com.github.andreyasadchy.xtra.api.IdApi
import com.github.andreyasadchy.xtra.api.MiscApi
import com.github.andreyasadchy.xtra.api.UsherApi
import com.github.andreyasadchy.xtra.model.chat.BttvChannelDeserializer
import com.github.andreyasadchy.xtra.model.chat.BttvChannelResponse
import com.github.andreyasadchy.xtra.model.chat.BttvGlobalDeserializer
import com.github.andreyasadchy.xtra.model.chat.BttvGlobalResponse
import com.github.andreyasadchy.xtra.model.chat.FfzChannelDeserializer
import com.github.andreyasadchy.xtra.model.chat.FfzChannelResponse
import com.github.andreyasadchy.xtra.model.chat.FfzGlobalDeserializer
import com.github.andreyasadchy.xtra.model.chat.FfzGlobalResponse
import com.github.andreyasadchy.xtra.model.chat.RecentMessagesDeserializer
import com.github.andreyasadchy.xtra.model.chat.RecentMessagesResponse
import com.github.andreyasadchy.xtra.model.chat.StvChannelDeserializer
import com.github.andreyasadchy.xtra.model.chat.StvChannelResponse
import com.github.andreyasadchy.xtra.model.chat.StvGlobalDeserializer
import com.github.andreyasadchy.xtra.model.chat.StvGlobalResponse
import com.github.andreyasadchy.xtra.model.gql.channel.ChannelClipsDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.channel.ChannelClipsDataResponse
import com.github.andreyasadchy.xtra.model.gql.channel.ChannelVideosDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.channel.ChannelVideosDataResponse
import com.github.andreyasadchy.xtra.model.gql.channel.ChannelViewerListDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.channel.ChannelViewerListDataResponse
import com.github.andreyasadchy.xtra.model.gql.chat.ChannelCheerEmotesDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.chat.ChannelCheerEmotesDataResponse
import com.github.andreyasadchy.xtra.model.gql.chat.ChannelPointsContextDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.chat.ChannelPointsContextDataResponse
import com.github.andreyasadchy.xtra.model.gql.chat.ChatBadgesDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.chat.ChatBadgesDataResponse
import com.github.andreyasadchy.xtra.model.gql.chat.EmoteCardDeserializer
import com.github.andreyasadchy.xtra.model.gql.chat.EmoteCardResponse
import com.github.andreyasadchy.xtra.model.gql.chat.GlobalCheerEmotesDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.chat.GlobalCheerEmotesDataResponse
import com.github.andreyasadchy.xtra.model.gql.chat.ModeratorsDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.chat.ModeratorsDataResponse
import com.github.andreyasadchy.xtra.model.gql.chat.UserEmotesDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.chat.UserEmotesDataResponse
import com.github.andreyasadchy.xtra.model.gql.chat.VipsDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.chat.VipsDataResponse
import com.github.andreyasadchy.xtra.model.gql.clip.ClipDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.clip.ClipDataResponse
import com.github.andreyasadchy.xtra.model.gql.clip.ClipUrlsDeserializer
import com.github.andreyasadchy.xtra.model.gql.clip.ClipUrlsResponse
import com.github.andreyasadchy.xtra.model.gql.clip.ClipVideoDeserializer
import com.github.andreyasadchy.xtra.model.gql.clip.ClipVideoResponse
import com.github.andreyasadchy.xtra.model.gql.followed.FollowDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.followed.FollowDataResponse
import com.github.andreyasadchy.xtra.model.gql.followed.FollowedChannelsDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.followed.FollowedChannelsDataResponse
import com.github.andreyasadchy.xtra.model.gql.followed.FollowedGamesDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.followed.FollowedGamesDataResponse
import com.github.andreyasadchy.xtra.model.gql.followed.FollowedStreamsDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.followed.FollowedStreamsDataResponse
import com.github.andreyasadchy.xtra.model.gql.followed.FollowedVideosDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.followed.FollowedVideosDataResponse
import com.github.andreyasadchy.xtra.model.gql.followed.FollowingGameDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.followed.FollowingGameDataResponse
import com.github.andreyasadchy.xtra.model.gql.followed.FollowingUserDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.followed.FollowingUserDataResponse
import com.github.andreyasadchy.xtra.model.gql.game.GameClipsDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.game.GameClipsDataResponse
import com.github.andreyasadchy.xtra.model.gql.game.GameDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.game.GameDataResponse
import com.github.andreyasadchy.xtra.model.gql.game.GameStreamsDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.game.GameStreamsDataResponse
import com.github.andreyasadchy.xtra.model.gql.game.GameVideosDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.game.GameVideosDataResponse
import com.github.andreyasadchy.xtra.model.gql.playlist.PlaybackAccessTokenDeserializer
import com.github.andreyasadchy.xtra.model.gql.playlist.PlaybackAccessTokenResponse
import com.github.andreyasadchy.xtra.model.gql.search.*
import com.github.andreyasadchy.xtra.model.gql.search.SearchChannelDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.search.SearchChannelDataResponse
import com.github.andreyasadchy.xtra.model.gql.search.SearchGameDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.search.SearchGameDataResponse
import com.github.andreyasadchy.xtra.model.gql.search.SearchVideosDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.search.SearchVideosDataResponse
import com.github.andreyasadchy.xtra.model.gql.stream.StreamsDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.stream.StreamsDataResponse
import com.github.andreyasadchy.xtra.model.gql.stream.ViewersDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.stream.ViewersDataResponse
import com.github.andreyasadchy.xtra.model.gql.tag.*
import com.github.andreyasadchy.xtra.model.gql.video.*
import com.github.andreyasadchy.xtra.model.gql.tag.FreeformTagDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.tag.FreeformTagDataResponse
import com.github.andreyasadchy.xtra.model.gql.tag.TagGameDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.tag.TagGameDataResponse
import com.github.andreyasadchy.xtra.model.gql.video.VideoGamesDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.video.VideoGamesDataResponse
import com.github.andreyasadchy.xtra.model.gql.video.VideoMessagesDataDeserializer
import com.github.andreyasadchy.xtra.model.gql.video.VideoMessagesDataResponse
import com.github.andreyasadchy.xtra.model.helix.channel.ChannelSearchDeserializer
import com.github.andreyasadchy.xtra.model.helix.channel.ChannelSearchResponse
import com.github.andreyasadchy.xtra.model.helix.chat.*
import com.github.andreyasadchy.xtra.model.helix.chat.ChatBadgesDeserializer
import com.github.andreyasadchy.xtra.model.helix.chat.ChatBadgesResponse
import com.github.andreyasadchy.xtra.model.helix.chat.CheerEmotesDeserializer
import com.github.andreyasadchy.xtra.model.helix.chat.CheerEmotesResponse
import com.github.andreyasadchy.xtra.model.helix.chat.EmoteSetDeserializer
import com.github.andreyasadchy.xtra.model.helix.chat.EmoteSetResponse
import com.github.andreyasadchy.xtra.model.helix.chat.ModeratorsDeserializer
import com.github.andreyasadchy.xtra.model.helix.chat.ModeratorsResponse
import com.github.andreyasadchy.xtra.model.helix.chat.UserEmotesDeserializer
import com.github.andreyasadchy.xtra.model.helix.chat.UserEmotesResponse
import com.github.andreyasadchy.xtra.model.helix.clip.ClipsDeserializer
import com.github.andreyasadchy.xtra.model.helix.clip.ClipsResponse
import com.github.andreyasadchy.xtra.model.helix.follows.FollowDeserializer
Expand Down Expand Up @@ -130,6 +212,7 @@ class XtraModule {
.registerTypeAdapter(ChatBadgesResponse::class.java, ChatBadgesDeserializer())
.registerTypeAdapter(CheerEmotesResponse::class.java, CheerEmotesDeserializer())
.registerTypeAdapter(FollowResponse::class.java, FollowDeserializer())
.registerTypeAdapter(UserEmotesResponse::class.java, UserEmotesDeserializer())
.registerTypeAdapter(EmoteSetResponse::class.java, EmoteSetDeserializer())
.registerTypeAdapter(ModeratorsResponse::class.java, ModeratorsDeserializer())

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.github.andreyasadchy.xtra.model.helix.chat

import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import com.google.gson.JsonParseException
import java.lang.reflect.Type

class UserEmotesDeserializer : JsonDeserializer<UserEmotesResponse> {

@Throws(JsonParseException::class)
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): UserEmotesResponse {
val data = mutableListOf<EmoteSetResponse.EmoteTemplate>()
val cursor = json.takeIf { it.isJsonObject }?.asJsonObject?.get("pagination")?.takeIf { it.isJsonObject }?.asJsonObject?.get("cursor")?.takeIf { it.isJsonPrimitive }?.asJsonPrimitive?.takeIf { it.isString }?.asString
json.takeIf { it.isJsonObject }?.asJsonObject?.get("template")?.takeIf { it.isJsonPrimitive }?.asJsonPrimitive?.takeIf { it.isString }?.asString?.let { template ->
json.takeIf { it.isJsonObject }?.asJsonObject?.get("data")?.takeIf { it.isJsonArray }?.asJsonArray?.forEach { item ->
item.takeIf { it.isJsonObject }?.asJsonObject?.let { obj ->
obj.get("name")?.takeIf { it.isJsonPrimitive }?.asJsonPrimitive?.takeIf { it.isString }?.asString?.let { name ->
obj.get("id")?.takeIf { it.isJsonPrimitive }?.asJsonPrimitive?.takeIf { it.isString }?.asString?.let { id ->
val formats = mutableListOf<String>()
obj.get("format")?.takeIf { it.isJsonArray }?.asJsonArray?.forEach { element ->
element.takeIf { it.isJsonPrimitive }?.asJsonPrimitive?.takeIf { it.isString }?.asString?.let { formats.add(it) }
}
val themes = mutableListOf<String>()
obj.get("theme_mode")?.takeIf { it.isJsonArray }?.asJsonArray?.forEach { element ->
element.takeIf { it.isJsonPrimitive }?.asJsonPrimitive?.takeIf { it.isString }?.asString?.let { themes.add(it) }
}
val scales = mutableListOf<String>()
obj.get("scale")?.takeIf { it.isJsonArray }?.asJsonArray?.forEach { element ->
element.takeIf { it.isJsonPrimitive }?.asJsonPrimitive?.takeIf { it.isString }?.asString?.let { scales.add(it) }
}
data.add(EmoteSetResponse.EmoteTemplate(
template = template,
id = id,
formats = formats,
themes = themes,
scales = scales,
name = name.removePrefix("\\").replace("?\\", ""),
setId = obj.get("emote_set_id")?.takeIf { it.isJsonPrimitive }?.asJsonPrimitive?.takeIf { it.isString }?.asString,
ownerId = obj.get("owner_id")?.takeIf { it.isJsonPrimitive }?.asJsonPrimitive?.takeIf { it.isString }?.asString
))
}
}
}
}
}
return UserEmotesResponse(data, cursor)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.github.andreyasadchy.xtra.model.helix.chat

class UserEmotesResponse(val data: List<EmoteSetResponse.EmoteTemplate>, val cursor: String?)
Loading

0 comments on commit 4d38676

Please sign in to comment.