diff --git a/core/api/core.api b/core/api/core.api index 0c369518656..61fa8784427 100644 --- a/core/api/core.api +++ b/core/api/core.api @@ -641,6 +641,37 @@ public final class dev/kord/core/behavior/MessageCommandBehavior$DefaultImpls { public static fun compareTo (Ldev/kord/core/behavior/MessageCommandBehavior;Ldev/kord/core/entity/Entity;)I } +public abstract interface class dev/kord/core/behavior/PollBehavior : dev/kord/core/behavior/MessageBehavior { + public abstract fun end (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public abstract fun getAnswerVoters (ILkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + +public final class dev/kord/core/behavior/PollBehavior$DefaultImpls { + public static fun addReaction (Ldev/kord/core/behavior/PollBehavior;Ldev/kord/core/entity/GuildEmoji;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun addReaction (Ldev/kord/core/behavior/PollBehavior;Ldev/kord/core/entity/ReactionEmoji;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun asMessage (Ldev/kord/core/behavior/PollBehavior;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun asMessageOrNull (Ldev/kord/core/behavior/PollBehavior;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun compareTo (Ldev/kord/core/behavior/PollBehavior;Ldev/kord/core/entity/Entity;)I + public static fun delete (Ldev/kord/core/behavior/PollBehavior;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;Ldev/kord/common/entity/Snowflake;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun delete (Ldev/kord/core/behavior/PollBehavior;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun deleteAllReactions (Ldev/kord/core/behavior/PollBehavior;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun deleteOwnReaction (Ldev/kord/core/behavior/PollBehavior;Ldev/kord/core/entity/ReactionEmoji;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun deleteReaction (Ldev/kord/core/behavior/PollBehavior;Ldev/kord/common/entity/Snowflake;Ldev/kord/core/entity/ReactionEmoji;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun deleteReaction (Ldev/kord/core/behavior/PollBehavior;Ldev/kord/core/entity/ReactionEmoji;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun end (Ldev/kord/core/behavior/PollBehavior;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun fetchMessage (Ldev/kord/core/behavior/PollBehavior;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun fetchMessageOrNull (Ldev/kord/core/behavior/PollBehavior;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun getAnswerVoters (Ldev/kord/core/behavior/PollBehavior;ILkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun getChannel (Ldev/kord/core/behavior/PollBehavior;)Ldev/kord/core/behavior/channel/MessageChannelBehavior; + public static fun getChannel (Ldev/kord/core/behavior/PollBehavior;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun getChannelOrNull (Ldev/kord/core/behavior/PollBehavior;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun getReactors (Ldev/kord/core/behavior/PollBehavior;Ldev/kord/core/entity/ReactionEmoji;)Lkotlinx/coroutines/flow/Flow; + public static fun pin (Ldev/kord/core/behavior/PollBehavior;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun publish (Ldev/kord/core/behavior/PollBehavior;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun unpin (Ldev/kord/core/behavior/PollBehavior;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static fun withStrategy (Ldev/kord/core/behavior/PollBehavior;Ldev/kord/core/supplier/EntitySupplyStrategy;)Ldev/kord/core/behavior/MessageBehavior; +} + public abstract interface class dev/kord/core/behavior/RoleBehavior : dev/kord/core/entity/KordEntity, dev/kord/core/entity/Strategizable { public abstract fun asRole (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun asRoleOrNull (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -6922,7 +6953,7 @@ public final class dev/kord/core/entity/PermissionOverwriteEntity : dev/kord/cor public synthetic fun withStrategy (Ldev/kord/core/supplier/EntitySupplyStrategy;)Ldev/kord/core/entity/Strategizable; } -public final class dev/kord/core/entity/Poll : dev/kord/core/entity/Message { +public final class dev/kord/core/entity/Poll : dev/kord/core/behavior/PollBehavior, dev/kord/core/entity/Message { public fun (Ldev/kord/core/cache/data/MessageData;Ldev/kord/core/Kord;Ldev/kord/core/supplier/EntitySupplier;)V public synthetic fun (Ldev/kord/core/cache/data/MessageData;Ldev/kord/core/Kord;Ldev/kord/core/supplier/EntitySupplier;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun addReaction (Ldev/kord/core/entity/GuildEmoji;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -6937,10 +6968,12 @@ public final class dev/kord/core/entity/Poll : dev/kord/core/entity/Message { public fun deleteOwnReaction (Ldev/kord/core/entity/ReactionEmoji;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun deleteReaction (Ldev/kord/common/entity/Snowflake;Ldev/kord/core/entity/ReactionEmoji;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun deleteReaction (Ldev/kord/core/entity/ReactionEmoji;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun end (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun equals (Ljava/lang/Object;)Z public fun fetchMessage (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun fetchMessageOrNull (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getActionRows ()Ljava/util/List; + public fun getAnswerVoters (ILkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getApplicationId ()Ldev/kord/common/entity/Snowflake; public fun getAttachments ()Ljava/util/Set; public fun getAuthor ()Ldev/kord/core/entity/User; diff --git a/core/api/core.klib.api b/core/api/core.klib.api index 77150c7d21c..078c2ac70c7 100644 --- a/core/api/core.klib.api +++ b/core/api/core.klib.api @@ -625,6 +625,11 @@ abstract interface dev.kord.core.behavior/MessageCommandBehavior : dev.kord.core abstract suspend fun edit(kotlin.coroutines/SuspendFunction1): dev.kord.core.entity.application/MessageCommand // dev.kord.core.behavior/MessageCommandBehavior.edit|edit(kotlin.coroutines.SuspendFunction1){}[0] } +abstract interface dev.kord.core.behavior/PollBehavior : dev.kord.core.behavior/MessageBehavior { // dev.kord.core.behavior/PollBehavior|null[0] + open suspend fun end(): dev.kord.core.entity/Poll // dev.kord.core.behavior/PollBehavior.end|end(){}[0] + open suspend fun getAnswerVoters(kotlin/Int): kotlin.collections/List // dev.kord.core.behavior/PollBehavior.getAnswerVoters|getAnswerVoters(kotlin.Int){}[0] +} + abstract interface dev.kord.core.behavior/RoleBehavior : dev.kord.core.entity/KordEntity, dev.kord.core.entity/Strategizable { // dev.kord.core.behavior/RoleBehavior|null[0] abstract val guildId // dev.kord.core.behavior/RoleBehavior.guildId|{}guildId[0] abstract fun (): dev.kord.common.entity/Snowflake // dev.kord.core.behavior/RoleBehavior.guildId.|(){}[0] @@ -8081,7 +8086,7 @@ final class dev.kord.core.entity/PermissionOverwriteEntity : dev.kord.core.entit final suspend fun getGuildOrNull(): dev.kord.core.entity/Guild? // dev.kord.core.entity/PermissionOverwriteEntity.getGuildOrNull|getGuildOrNull(){}[0] } -final class dev.kord.core.entity/Poll : dev.kord.core.entity/Message { // dev.kord.core.entity/Poll|null[0] +final class dev.kord.core.entity/Poll : dev.kord.core.behavior/PollBehavior, dev.kord.core.entity/Message { // dev.kord.core.entity/Poll|null[0] constructor (dev.kord.core.cache.data/MessageData, dev.kord.core/Kord, dev.kord.core.supplier/EntitySupplier = ...) // dev.kord.core.entity/Poll.|(dev.kord.core.cache.data.MessageData;dev.kord.core.Kord;dev.kord.core.supplier.EntitySupplier){}[0] final val data // dev.kord.core.entity/Poll.data|{}data[0] diff --git a/core/src/commonMain/kotlin/behavior/MessageBehavior.kt b/core/src/commonMain/kotlin/behavior/MessageBehavior.kt index fbf1b2e01ce..04db07f517b 100644 --- a/core/src/commonMain/kotlin/behavior/MessageBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/MessageBehavior.kt @@ -1,15 +1,16 @@ package dev.kord.core.behavior -import dev.kord.common.entity.Permission import dev.kord.common.entity.Snowflake import dev.kord.common.exception.RequestException import dev.kord.core.Kord import dev.kord.core.behavior.channel.MessageChannelBehavior import dev.kord.core.behavior.channel.createMessage import dev.kord.core.cache.data.MessageData +import dev.kord.core.cache.data.UserData import dev.kord.core.entity.* import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.exception.EntityNotFoundException +import dev.kord.core.hash import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy import dev.kord.core.supplier.getChannelOf @@ -20,7 +21,6 @@ import dev.kord.rest.builder.message.modify.WebhookMessageModifyBuilder import dev.kord.rest.request.RestRequestException import dev.kord.rest.service.RestClient import kotlinx.coroutines.flow.Flow -import dev.kord.core.hash import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -215,7 +215,32 @@ public interface MessageBehavior : KordEntity, Strategizable { override fun withStrategy( strategy: EntitySupplyStrategy<*>, ): MessageBehavior = MessageBehavior(channelId, id, kord, strategy) +} + +/** + * Behavior of a Poll message. + */ +public interface PollBehavior : MessageBehavior { + + /** + * Retrieves the voters who voted for the specified [answer][answerId]. + */ + public suspend fun getAnswerVoters(answerId: Int): List = + kord.rest.channel.getPollUsersByAnswer(channelId, id, answerId).map { + val data = UserData.from(it) + User(data, kord, supplier) + } + + /** + * Ends this poll. + */ + public suspend fun end(): Poll { + val message = kord.rest.channel.expirePoll(channelId, id) + val data = MessageData.from(message) + + return Message(data, kord, supplier) as Poll + } } public fun MessageBehavior( diff --git a/core/src/commonMain/kotlin/entity/Message.kt b/core/src/commonMain/kotlin/entity/Message.kt index 6811afedd1d..78795b96c6b 100644 --- a/core/src/commonMain/kotlin/entity/Message.kt +++ b/core/src/commonMain/kotlin/entity/Message.kt @@ -6,6 +6,7 @@ import dev.kord.common.entity.optional.* import dev.kord.common.exception.RequestException import dev.kord.core.Kord import dev.kord.core.behavior.MessageBehavior +import dev.kord.core.behavior.PollBehavior import dev.kord.core.behavior.UserBehavior import dev.kord.core.behavior.channel.ChannelBehavior import dev.kord.core.behavior.interaction.response.InteractionResponseBehavior @@ -369,7 +370,7 @@ public class Poll( override val data: MessageData, override val kord: Kord, override val supplier: EntitySupplier = kord.defaultSupplier, -) : Message { +) : Message, PollBehavior { /** * The [poll][DiscordPoll]. */ diff --git a/core/src/jvmTest/kotlin/rest/RestTest.kt b/core/src/jvmTest/kotlin/rest/RestTest.kt index dac8135d779..afe37f0b6fa 100644 --- a/core/src/jvmTest/kotlin/rest/RestTest.kt +++ b/core/src/jvmTest/kotlin/rest/RestTest.kt @@ -1,6 +1,7 @@ package dev.kord.core.rest import dev.kord.common.Color +import dev.kord.common.annotation.KordUnsafe import dev.kord.common.entity.* import dev.kord.core.Kord import dev.kord.core.behavior.* @@ -21,6 +22,7 @@ import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.toList import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.* import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable import kotlin.io.path.toPath @@ -535,6 +537,20 @@ class RestServiceTest { } + @OptIn(KordUnsafe::class) + @Test + @Order(29) + fun `poll in channel`() = runTest { + val poll = channel.createPoll { + question("Is Kord great?") + answer("Yes") + answer("no") + } + + assertEquals(emptyList(), poll.getAnswerVoters(1)) + poll.end() + } + @Test @Order(Int.MAX_VALUE - 2) fun `delete channel`(): Unit = runBlocking {