pluralize dm recipient options

as used in the official client
This commit is contained in:
Austin Huang 2021-06-14 21:12:52 -04:00
parent 95b90ab72f
commit e89c1ac9ef
No known key found for this signature in database
GPG Key ID: 84C23AA04587A91F
13 changed files with 69 additions and 71 deletions

View File

@ -17,8 +17,8 @@ import awais.instagrabber.models.Resource.Companion.success
import awais.instagrabber.models.enums.DirectItemType import awais.instagrabber.models.enums.DirectItemType
import awais.instagrabber.repositories.requests.UploadFinishOptions import awais.instagrabber.repositories.requests.UploadFinishOptions
import awais.instagrabber.repositories.requests.VideoOptions import awais.instagrabber.repositories.requests.VideoOptions
import awais.instagrabber.repositories.requests.directmessages.ThreadIdOrUserIds import awais.instagrabber.repositories.requests.directmessages.ThreadIdsOrUserIds
import awais.instagrabber.repositories.requests.directmessages.ThreadIdOrUserIds.Companion.of import awais.instagrabber.repositories.requests.directmessages.ThreadIdsOrUserIds.Companion.of
import awais.instagrabber.repositories.responses.User import awais.instagrabber.repositories.responses.User
import awais.instagrabber.repositories.responses.directmessages.* import awais.instagrabber.repositories.responses.directmessages.*
import awais.instagrabber.repositories.responses.giphy.GiphyGif import awais.instagrabber.repositories.responses.giphy.GiphyGif
@ -61,7 +61,7 @@ class ThreadManager(
private val _pendingRequests = MutableLiveData<DirectThreadParticipantRequestsResponse?>(null) private val _pendingRequests = MutableLiveData<DirectThreadParticipantRequestsResponse?>(null)
val pendingRequests: LiveData<DirectThreadParticipantRequestsResponse?> = _pendingRequests val pendingRequests: LiveData<DirectThreadParticipantRequestsResponse?> = _pendingRequests
private val inboxManager: InboxManager = if (pending) DirectMessagesManager.pendingInboxManager else DirectMessagesManager.inboxManager private val inboxManager: InboxManager = if (pending) DirectMessagesManager.pendingInboxManager else DirectMessagesManager.inboxManager
private val threadIdOrUserIds: ThreadIdOrUserIds = of(threadId) private val threadIdsOrUserIds: ThreadIdsOrUserIds = of(threadId)
private val friendshipRepository: FriendshipRepository by lazy { FriendshipRepository.getInstance() } private val friendshipRepository: FriendshipRepository by lazy { FriendshipRepository.getInstance() }
private val mediaRepository: MediaRepository by lazy { MediaRepository.getInstance() } private val mediaRepository: MediaRepository by lazy { MediaRepository.getInstance() }
@ -353,7 +353,7 @@ class ThreadManager(
viewerId, viewerId,
deviceUuid, deviceUuid,
clientContext, clientContext,
threadIdOrUserIds, threadIdsOrUserIds,
text, text,
repliedToItemId, repliedToItemId,
repliedToClientContext repliedToClientContext
@ -411,7 +411,7 @@ class ThreadManager(
userId, userId,
deviceUuid, deviceUuid,
clientContext, clientContext,
threadIdOrUserIds, threadIdsOrUserIds,
giphyGif giphyGif
) )
parseResponse(request, data, directItem) parseResponse(request, data, directItem)
@ -460,7 +460,7 @@ class ThreadManager(
viewerId, viewerId,
deviceUuid, deviceUuid,
clientContext, clientContext,
threadIdOrUserIds, threadIdsOrUserIds,
uploadDmVoiceOptions.uploadId, uploadDmVoiceOptions.uploadId,
waveform, waveform,
samplingFreq samplingFreq
@ -504,7 +504,7 @@ class ThreadManager(
userId, userId,
deviceUuid, deviceUuid,
clientContext, clientContext,
threadIdOrUserIds, threadIdsOrUserIds,
itemId, itemId,
emojiUnicode, emojiUnicode,
false false
@ -544,7 +544,7 @@ class ThreadManager(
viewerId, viewerId,
deviceUuid, deviceUuid,
clientContext, clientContext,
threadIdOrUserIds, threadIdsOrUserIds,
itemId1, itemId1,
null, null,
true true
@ -732,7 +732,7 @@ class ThreadManager(
if (handleInvalidResponse(data, response)) return@launch if (handleInvalidResponse(data, response)) return@launch
val response1 = response.response ?: return@launch val response1 = response.response ?: return@launch
val uploadId = response1.optString("upload_id") val uploadId = response1.optString("upload_id")
val response2 = DirectMessagesService.broadcastPhoto(csrfToken, viewerId, deviceUuid, clientContext, threadIdOrUserIds, uploadId) val response2 = DirectMessagesService.broadcastPhoto(csrfToken, viewerId, deviceUuid, clientContext, threadIdsOrUserIds, uploadId)
parseResponse(response2, data, directItem) parseResponse(response2, data, directItem)
} catch (e: Exception) { } catch (e: Exception) {
data.postValue(error(e.message, null)) data.postValue(error(e.message, null))
@ -798,7 +798,7 @@ class ThreadManager(
viewerId, viewerId,
deviceUuid, deviceUuid,
clientContext, clientContext,
threadIdOrUserIds, threadIdsOrUserIds,
uploadDmVideoOptions.uploadId, uploadDmVideoOptions.uploadId,
"", "",
true true

View File

@ -5,11 +5,11 @@ import awais.instagrabber.repositories.responses.giphy.GiphyGif
class AnimatedMediaBroadcastOptions( class AnimatedMediaBroadcastOptions(
clientContext: String, clientContext: String,
threadIdOrUserIds: ThreadIdOrUserIds, threadIdsOrUserIds: ThreadIdsOrUserIds,
val giphyGif: GiphyGif val giphyGif: GiphyGif
) : BroadcastOptions( ) : BroadcastOptions(
clientContext, clientContext,
threadIdOrUserIds, threadIdsOrUserIds,
BroadcastItemType.ANIMATED_MEDIA BroadcastItemType.ANIMATED_MEDIA
) { ) {
override val formMap: Map<String, String> override val formMap: Map<String, String>

View File

@ -4,31 +4,15 @@ import awais.instagrabber.models.enums.BroadcastItemType
sealed class BroadcastOptions( sealed class BroadcastOptions(
val clientContext: String, val clientContext: String,
private val threadIdOrUserIds: ThreadIdOrUserIds, private val threadIdsOrUserIds: ThreadIdsOrUserIds,
val itemType: BroadcastItemType val itemType: BroadcastItemType
) { ) {
var repliedToItemId: String? = null var repliedToItemId: String? = null
var repliedToClientContext: String? = null var repliedToClientContext: String? = null
val threadId: String? val threadIds: List<String>?
get() = threadIdOrUserIds.threadId get() = threadIdsOrUserIds.threadIds
val userIds: List<String>? val userIds: List<List<String>>?
get() = threadIdOrUserIds.userIds get() = threadIdsOrUserIds.userIds
abstract val formMap: Map<String, String> abstract val formMap: Map<String, String>
} }
// TODO convert to data class once usages are migrated to kotlin
class ThreadIdOrUserIds(val threadId: String? = null, val userIds: List<String>? = null) {
companion object {
@JvmStatic
fun of(threadId: String?): ThreadIdOrUserIds {
return ThreadIdOrUserIds(threadId, null)
}
@JvmStatic
fun of(userIds: List<String>?): ThreadIdOrUserIds {
return ThreadIdOrUserIds(null, userIds)
}
}
}

View File

@ -5,12 +5,12 @@ import org.json.JSONArray
class LinkBroadcastOptions( class LinkBroadcastOptions(
clientContext: String, clientContext: String,
threadIdOrUserIds: ThreadIdOrUserIds, threadIdsOrUserIds: ThreadIdsOrUserIds,
val linkText: String, val linkText: String,
val urls: List<String> val urls: List<String>
) : BroadcastOptions( ) : BroadcastOptions(
clientContext, clientContext,
threadIdOrUserIds, threadIdsOrUserIds,
BroadcastItemType.LINK BroadcastItemType.LINK
) { ) {
override val formMap: Map<String, String> override val formMap: Map<String, String>

View File

@ -4,11 +4,11 @@ import awais.instagrabber.models.enums.BroadcastItemType
class MediaShareBroadcastOptions( class MediaShareBroadcastOptions(
clientContext: String, clientContext: String,
threadIdOrUserIds: ThreadIdOrUserIds, threadIdsOrUserIds: ThreadIdsOrUserIds,
val mediaId: String val mediaId: String
) : BroadcastOptions( ) : BroadcastOptions(
clientContext, clientContext,
threadIdOrUserIds, threadIdsOrUserIds,
BroadcastItemType.MEDIA_SHARE BroadcastItemType.MEDIA_SHARE
) { ) {
override val formMap: Map<String, String> override val formMap: Map<String, String>

View File

@ -4,12 +4,12 @@ import awais.instagrabber.models.enums.BroadcastItemType
class PhotoBroadcastOptions( class PhotoBroadcastOptions(
clientContext: String, clientContext: String,
threadIdOrUserIds: ThreadIdOrUserIds, threadIdsOrUserIds: ThreadIdsOrUserIds,
val allowFullAspectRatio: Boolean, val allowFullAspectRatio: Boolean,
val uploadId: String val uploadId: String
) : BroadcastOptions( ) : BroadcastOptions(
clientContext, clientContext,
threadIdOrUserIds, threadIdsOrUserIds,
BroadcastItemType.IMAGE BroadcastItemType.IMAGE
) { ) {
override val formMap: Map<String, String> override val formMap: Map<String, String>

View File

@ -4,11 +4,11 @@ import awais.instagrabber.models.enums.BroadcastItemType
class ReactionBroadcastOptions( class ReactionBroadcastOptions(
clientContext: String, clientContext: String,
threadIdOrUserIds: ThreadIdOrUserIds, threadIdsOrUserIds: ThreadIdsOrUserIds,
val itemId: String, val itemId: String,
val emoji: String?, val emoji: String?,
val delete: Boolean val delete: Boolean
) : BroadcastOptions(clientContext, threadIdOrUserIds, BroadcastItemType.REACTION) { ) : BroadcastOptions(clientContext, threadIdsOrUserIds, BroadcastItemType.REACTION) {
override val formMap: Map<String, String> override val formMap: Map<String, String>
get() = listOfNotNull( get() = listOfNotNull(
"item_id" to itemId, "item_id" to itemId,

View File

@ -4,11 +4,11 @@ import awais.instagrabber.models.enums.BroadcastItemType
class StoryReplyBroadcastOptions( class StoryReplyBroadcastOptions(
clientContext: String, clientContext: String,
threadIdOrUserIds: ThreadIdOrUserIds, threadIdsOrUserIds: ThreadIdsOrUserIds,
val text: String, val text: String,
val mediaId: String, val mediaId: String,
val reelId: String // or user id, usually same val reelId: String // or user id, usually same
) : BroadcastOptions(clientContext, threadIdOrUserIds, BroadcastItemType.REELSHARE) { ) : BroadcastOptions(clientContext, threadIdsOrUserIds, BroadcastItemType.REELSHARE) {
override val formMap: Map<String, String> override val formMap: Map<String, String>
get() = mapOf( get() = mapOf(
"text" to text, "text" to text,

View File

@ -4,11 +4,11 @@ import awais.instagrabber.models.enums.BroadcastItemType
class TextBroadcastOptions( class TextBroadcastOptions(
clientContext: String, clientContext: String,
threadIdOrUserIds: ThreadIdOrUserIds, threadIdsOrUserIds: ThreadIdsOrUserIds,
val text: String val text: String
) : BroadcastOptions( ) : BroadcastOptions(
clientContext, clientContext,
threadIdOrUserIds, threadIdsOrUserIds,
BroadcastItemType.TEXT BroadcastItemType.TEXT
) { ) {
override val formMap: Map<String, String> override val formMap: Map<String, String>

View File

@ -0,0 +1,14 @@
package awais.instagrabber.repositories.requests.directmessages
data class ThreadIdsOrUserIds(val threadIds: List<String>? = null, val userIds: List<List<String>>? = null) {
companion object {
@JvmStatic
fun of(threadId: String): ThreadIdsOrUserIds {
return ThreadIdsOrUserIds(listOf(threadId), null)
}
fun ofOneUser(userId: String): ThreadIdsOrUserIds {
return ThreadIdsOrUserIds(null, listOf(listOf(userId)))
}
}
}

View File

@ -4,13 +4,13 @@ import awais.instagrabber.models.enums.BroadcastItemType
class VideoBroadcastOptions( class VideoBroadcastOptions(
clientContext: String, clientContext: String,
threadIdOrUserIds: ThreadIdOrUserIds, threadIdsOrUserIds: ThreadIdsOrUserIds,
val videoResult: String, val videoResult: String,
val uploadId: String, val uploadId: String,
val sampled: Boolean val sampled: Boolean
) : BroadcastOptions( ) : BroadcastOptions(
clientContext, clientContext,
threadIdOrUserIds, threadIdsOrUserIds,
BroadcastItemType.VIDEO BroadcastItemType.VIDEO
) { ) {
override val formMap: Map<String, String> override val formMap: Map<String, String>

View File

@ -5,11 +5,11 @@ import org.json.JSONArray
class VoiceBroadcastOptions( class VoiceBroadcastOptions(
clientContext: String, clientContext: String,
threadIdOrUserIds: ThreadIdOrUserIds, threadIdsOrUserIds: ThreadIdsOrUserIds,
val uploadId: String, val uploadId: String,
val waveform: List<Float>, val waveform: List<Float>,
val waveformSamplingFrequencyHz: Int val waveformSamplingFrequencyHz: Int
) : BroadcastOptions(clientContext, threadIdOrUserIds, BroadcastItemType.VOICE) { ) : BroadcastOptions(clientContext, threadIdsOrUserIds, BroadcastItemType.VOICE) {
override val formMap: Map<String, String> override val formMap: Map<String, String>
get() = mapOf( get() = mapOf(
"waveform" to JSONArray(waveform).toString(), "waveform" to JSONArray(waveform).toString(),

View File

@ -54,16 +54,16 @@ object DirectMessagesService {
userId: Long, userId: Long,
deviceUuid: String, deviceUuid: String,
clientContext: String, clientContext: String,
threadIdOrUserIds: ThreadIdOrUserIds, threadIdsOrUserIds: ThreadIdsOrUserIds,
text: String, text: String,
repliedToItemId: String?, repliedToItemId: String?,
repliedToClientContext: String?, repliedToClientContext: String?,
): DirectThreadBroadcastResponse { ): DirectThreadBroadcastResponse {
val urls = extractUrls(text) val urls = extractUrls(text)
if (urls.isNotEmpty()) { if (urls.isNotEmpty()) {
return broadcastLink(csrfToken, userId, deviceUuid, clientContext, threadIdOrUserIds, text, urls, repliedToItemId, repliedToClientContext) return broadcastLink(csrfToken, userId, deviceUuid, clientContext, threadIdsOrUserIds, text, urls, repliedToItemId, repliedToClientContext)
} }
val broadcastOptions = TextBroadcastOptions(clientContext, threadIdOrUserIds, text) val broadcastOptions = TextBroadcastOptions(clientContext, threadIdsOrUserIds, text)
if (!repliedToItemId.isNullOrBlank() && !repliedToClientContext.isNullOrBlank()) { if (!repliedToItemId.isNullOrBlank() && !repliedToClientContext.isNullOrBlank()) {
broadcastOptions.repliedToItemId = repliedToItemId broadcastOptions.repliedToItemId = repliedToItemId
broadcastOptions.repliedToClientContext = repliedToClientContext broadcastOptions.repliedToClientContext = repliedToClientContext
@ -76,13 +76,13 @@ object DirectMessagesService {
userId: Long, userId: Long,
deviceUuid: String, deviceUuid: String,
clientContext: String, clientContext: String,
threadIdOrUserIds: ThreadIdOrUserIds, threadIdsOrUserIds: ThreadIdsOrUserIds,
linkText: String, linkText: String,
urls: List<String>, urls: List<String>,
repliedToItemId: String?, repliedToItemId: String?,
repliedToClientContext: String?, repliedToClientContext: String?,
): DirectThreadBroadcastResponse { ): DirectThreadBroadcastResponse {
val broadcastOptions = LinkBroadcastOptions(clientContext, threadIdOrUserIds, linkText, urls) val broadcastOptions = LinkBroadcastOptions(clientContext, threadIdsOrUserIds, linkText, urls)
if (!repliedToItemId.isNullOrBlank() && !repliedToClientContext.isNullOrBlank()) { if (!repliedToItemId.isNullOrBlank() && !repliedToClientContext.isNullOrBlank()) {
broadcastOptions.repliedToItemId = repliedToItemId broadcastOptions.repliedToItemId = repliedToItemId
broadcastOptions.repliedToClientContext = repliedToClientContext broadcastOptions.repliedToClientContext = repliedToClientContext
@ -95,77 +95,77 @@ object DirectMessagesService {
userId: Long, userId: Long,
deviceUuid: String, deviceUuid: String,
clientContext: String, clientContext: String,
threadIdOrUserIds: ThreadIdOrUserIds, threadIdsOrUserIds: ThreadIdsOrUserIds,
uploadId: String, uploadId: String,
): DirectThreadBroadcastResponse = ): DirectThreadBroadcastResponse =
broadcast(csrfToken, userId, deviceUuid, PhotoBroadcastOptions(clientContext, threadIdOrUserIds, true, uploadId)) broadcast(csrfToken, userId, deviceUuid, PhotoBroadcastOptions(clientContext, threadIdsOrUserIds, true, uploadId))
suspend fun broadcastVideo( suspend fun broadcastVideo(
csrfToken: String, csrfToken: String,
userId: Long, userId: Long,
deviceUuid: String, deviceUuid: String,
clientContext: String, clientContext: String,
threadIdOrUserIds: ThreadIdOrUserIds, threadIdsOrUserIds: ThreadIdsOrUserIds,
uploadId: String, uploadId: String,
videoResult: String, videoResult: String,
sampled: Boolean, sampled: Boolean,
): DirectThreadBroadcastResponse = ): DirectThreadBroadcastResponse =
broadcast(csrfToken, userId, deviceUuid, VideoBroadcastOptions(clientContext, threadIdOrUserIds, videoResult, uploadId, sampled)) broadcast(csrfToken, userId, deviceUuid, VideoBroadcastOptions(clientContext, threadIdsOrUserIds, videoResult, uploadId, sampled))
suspend fun broadcastVoice( suspend fun broadcastVoice(
csrfToken: String, csrfToken: String,
userId: Long, userId: Long,
deviceUuid: String, deviceUuid: String,
clientContext: String, clientContext: String,
threadIdOrUserIds: ThreadIdOrUserIds, threadIdsOrUserIds: ThreadIdsOrUserIds,
uploadId: String, uploadId: String,
waveform: List<Float>, waveform: List<Float>,
samplingFreq: Int, samplingFreq: Int,
): DirectThreadBroadcastResponse = ): DirectThreadBroadcastResponse =
broadcast(csrfToken, userId, deviceUuid, VoiceBroadcastOptions(clientContext, threadIdOrUserIds, uploadId, waveform, samplingFreq)) broadcast(csrfToken, userId, deviceUuid, VoiceBroadcastOptions(clientContext, threadIdsOrUserIds, uploadId, waveform, samplingFreq))
suspend fun broadcastStoryReply( suspend fun broadcastStoryReply(
csrfToken: String, csrfToken: String,
userId: Long, userId: Long,
deviceUuid: String, deviceUuid: String,
threadIdOrUserIds: ThreadIdOrUserIds, threadIdsOrUserIds: ThreadIdsOrUserIds,
text: String, text: String,
mediaId: String, mediaId: String,
reelId: String, reelId: String,
): DirectThreadBroadcastResponse = ): DirectThreadBroadcastResponse =
broadcast(csrfToken, userId, deviceUuid, StoryReplyBroadcastOptions(UUID.randomUUID().toString(), threadIdOrUserIds, text, mediaId, reelId)) broadcast(csrfToken, userId, deviceUuid, StoryReplyBroadcastOptions(UUID.randomUUID().toString(), threadIdsOrUserIds, text, mediaId, reelId))
suspend fun broadcastReaction( suspend fun broadcastReaction(
csrfToken: String, csrfToken: String,
userId: Long, userId: Long,
deviceUuid: String, deviceUuid: String,
clientContext: String, clientContext: String,
threadIdOrUserIds: ThreadIdOrUserIds, threadIdsOrUserIds: ThreadIdsOrUserIds,
itemId: String, itemId: String,
emoji: String?, emoji: String?,
delete: Boolean, delete: Boolean,
): DirectThreadBroadcastResponse = ): DirectThreadBroadcastResponse =
broadcast(csrfToken, userId, deviceUuid, ReactionBroadcastOptions(clientContext, threadIdOrUserIds, itemId, emoji, delete)) broadcast(csrfToken, userId, deviceUuid, ReactionBroadcastOptions(clientContext, threadIdsOrUserIds, itemId, emoji, delete))
suspend fun broadcastAnimatedMedia( suspend fun broadcastAnimatedMedia(
csrfToken: String, csrfToken: String,
userId: Long, userId: Long,
deviceUuid: String, deviceUuid: String,
clientContext: String, clientContext: String,
threadIdOrUserIds: ThreadIdOrUserIds, threadIdsOrUserIds: ThreadIdsOrUserIds,
giphyGif: GiphyGif, giphyGif: GiphyGif,
): DirectThreadBroadcastResponse = ): DirectThreadBroadcastResponse =
broadcast(csrfToken, userId, deviceUuid, AnimatedMediaBroadcastOptions(clientContext, threadIdOrUserIds, giphyGif)) broadcast(csrfToken, userId, deviceUuid, AnimatedMediaBroadcastOptions(clientContext, threadIdsOrUserIds, giphyGif))
suspend fun broadcastMediaShare( suspend fun broadcastMediaShare(
csrfToken: String, csrfToken: String,
userId: Long, userId: Long,
deviceUuid: String, deviceUuid: String,
clientContext: String, clientContext: String,
threadIdOrUserIds: ThreadIdOrUserIds, threadIdsOrUserIds: ThreadIdsOrUserIds,
mediaId: String, mediaId: String,
): DirectThreadBroadcastResponse = ): DirectThreadBroadcastResponse =
broadcast(csrfToken, userId, deviceUuid, MediaShareBroadcastOptions(clientContext, threadIdOrUserIds, mediaId)) broadcast(csrfToken, userId, deviceUuid, MediaShareBroadcastOptions(clientContext, threadIdsOrUserIds, mediaId))
private suspend fun broadcast( private suspend fun broadcast(
csrfToken: String, csrfToken: String,
@ -181,9 +181,9 @@ object DirectMessagesService {
"client_context" to broadcastOptions.clientContext, "client_context" to broadcastOptions.clientContext,
"mutation_token" to broadcastOptions.clientContext, "mutation_token" to broadcastOptions.clientContext,
) )
val threadId = broadcastOptions.threadId val threadIds = broadcastOptions.threadIds
if (!threadId.isNullOrBlank()) { if (!threadIds.isNullOrEmpty()) {
form["thread_id"] = threadId form["thread_ids"] = JSONArray(threadIds).toString()
} else { } else {
val userIds = broadcastOptions.userIds val userIds = broadcastOptions.userIds
require(!userIds.isNullOrEmpty()) { require(!userIds.isNullOrEmpty()) {