1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2025-09-05 08:09:21 +00:00

preview version of inputs for tasks

This commit is contained in:
2025-07-07 14:38:39 +06:00
parent 0a01d2567e
commit e2ce9cfebf
6 changed files with 280 additions and 94 deletions

View File

@@ -27,3 +27,12 @@ interface TextedOutput : ParsableOutput, EntitiesOutput
interface TextedInput : TextedWithTextSources { interface TextedInput : TextedWithTextSources {
override val textSources: List<TextSource> override val textSources: List<TextSource>
} }
interface TitledInput : TextedInput {
val title: String
val titleTextSources: List<TextSource>
override val text: String
get() = title
override val textSources: List<TextSource>
get() = titleTextSources
}

View File

@@ -311,6 +311,7 @@ const val emojiListField = "emoji_list"
const val completedByUserField = "completed_by_user" const val completedByUserField = "completed_by_user"
const val completionDateField = "completion_date" const val completionDateField = "completion_date"
const val titleEntitiesField = "title_entities" const val titleEntitiesField = "title_entities"
const val tasksField = "tasks"
const val othersCanAddTasksField = "others_can_add_tasks" const val othersCanAddTasksField = "others_can_add_tasks"
const val othersCanMarkTasksAsDoneField = "others_can_mark_tasks_as_done" const val othersCanMarkTasksAsDoneField = "others_can_mark_tasks_as_done"

View File

@@ -1,33 +1,49 @@
package dev.inmo.tgbotapi.types.checklists package dev.inmo.tgbotapi.types.checklists
import dev.inmo.micro_utils.common.Warning
import dev.inmo.tgbotapi.abstracts.TitledInput
import dev.inmo.tgbotapi.types.message.ParseMode
import dev.inmo.tgbotapi.types.message.RawMessageEntity import dev.inmo.tgbotapi.types.message.RawMessageEntity
import dev.inmo.tgbotapi.types.message.asTextSources import dev.inmo.tgbotapi.types.message.asTextSources
import dev.inmo.tgbotapi.types.message.parseModeField
import dev.inmo.tgbotapi.types.message.textsources.TextSource import dev.inmo.tgbotapi.types.message.textsources.TextSource
import dev.inmo.tgbotapi.types.message.toRawMessageEntities import dev.inmo.tgbotapi.types.message.toRawMessageEntities
import dev.inmo.tgbotapi.types.tasksField
import dev.inmo.tgbotapi.types.titleEntitiesField
import dev.inmo.tgbotapi.types.titleField
import dev.inmo.tgbotapi.utils.extensions.makeSourceString import dev.inmo.tgbotapi.utils.extensions.makeSourceString
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.encoding.Encoder
@Serializable(Checklist.Companion::class) @Serializable
data class Checklist( sealed interface Checklist : TitledInput {
val titleTextSources: List<TextSource>, val tasks: List<ChecklistTask>
val tasks: List<ChecklistTask>, val othersCanAddTasks: Boolean
val othersCanAddTasks: Boolean = false, val othersCanCompleteTasks: Boolean
val othersCanCompleteTasks: Boolean = false, @Serializable
) { data class Input @Warning("It is low level API. Do not use it without need") constructor(
val title: String by lazy { @SerialName(titleField)
titleTextSources.makeSourceString() override val title: String,
} @SerialName(tasksField)
override val tasks: List<ChecklistTask.Input>,
companion object : KSerializer<Checklist> { @SerialName(parseModeField)
val parseMode: ParseMode? = null,
@SerialName(titleEntitiesField)
override val titleTextSources: List<TextSource> = emptyList(),
override val othersCanAddTasks: Boolean = false,
override val othersCanCompleteTasks: Boolean = false,
) : Checklist {
companion object : KSerializer<Input> {
@Serializable @Serializable
private class RawChecklist( private class RawChecklist(
val title: String, val title: String,
val parseMode: ParseMode? = null,
val title_entities: List<RawMessageEntity> = emptyList(), val title_entities: List<RawMessageEntity> = emptyList(),
val tasks: List<ChecklistTask>, val tasks: List<ChecklistTask.Input>,
val others_can_add_tasks: Boolean = false, val others_can_add_tasks: Boolean = false,
val others_can_mark_tasks_as_done: Boolean = false, val others_can_mark_tasks_as_done: Boolean = false,
) )
@@ -35,7 +51,60 @@ data class Checklist(
override fun serialize( override fun serialize(
encoder: Encoder, encoder: Encoder,
value: Checklist value: Input
) {
RawChecklist.serializer().serialize(
encoder,
RawChecklist(
title = value.title,
title_entities = value.titleTextSources.toRawMessageEntities(),
tasks = value.tasks,
parseMode = value.parseMode,
others_can_add_tasks = value.othersCanAddTasks,
others_can_mark_tasks_as_done = value.othersCanCompleteTasks,
)
)
}
override fun deserialize(decoder: Decoder): Input {
val raw = RawChecklist.serializer().deserialize(decoder)
return Input(
title = raw.title,
titleTextSources = raw.title_entities.asTextSources(raw.title),
tasks = raw.tasks,
parseMode = raw.parseMode,
othersCanAddTasks = raw.others_can_add_tasks,
othersCanCompleteTasks = raw.others_can_mark_tasks_as_done
)
}
}
}
@Serializable(Created.Companion::class)
data class Created(
override val titleTextSources: List<TextSource>,
override val tasks: List<ChecklistTask.Created>,
override val othersCanAddTasks: Boolean = false,
override val othersCanCompleteTasks: Boolean = false,
): Checklist {
override val title: String by lazy {
titleTextSources.makeSourceString()
}
companion object : KSerializer<Created> {
@Serializable
private class RawChecklist(
val title: String,
val title_entities: List<RawMessageEntity> = emptyList(),
val tasks: List<ChecklistTask.Created>,
val others_can_add_tasks: Boolean = false,
val others_can_mark_tasks_as_done: Boolean = false,
)
override val descriptor: SerialDescriptor = RawChecklist.serializer().descriptor
override fun serialize(
encoder: Encoder,
value: Created
) { ) {
RawChecklist.serializer().serialize( RawChecklist.serializer().serialize(
encoder, encoder,
@@ -49,9 +118,9 @@ data class Checklist(
) )
} }
override fun deserialize(decoder: Decoder): Checklist { override fun deserialize(decoder: Decoder): Created {
val raw = RawChecklist.serializer().deserialize(decoder) val raw = RawChecklist.serializer().deserialize(decoder)
return Checklist( return Created(
titleTextSources = raw.title_entities.asTextSources(raw.title), titleTextSources = raw.title_entities.asTextSources(raw.title),
tasks = raw.tasks, tasks = raw.tasks,
othersCanAddTasks = raw.others_can_add_tasks, othersCanAddTasks = raw.others_can_add_tasks,
@@ -59,4 +128,5 @@ data class Checklist(
) )
} }
} }
}
} }

View File

@@ -1,19 +1,28 @@
package dev.inmo.tgbotapi.types.checklists package dev.inmo.tgbotapi.types.checklists
import dev.inmo.micro_utils.common.Warning
import dev.inmo.tgbotapi.abstracts.TextedInput import dev.inmo.tgbotapi.abstracts.TextedInput
import dev.inmo.tgbotapi.abstracts.TitledInput
import dev.inmo.tgbotapi.types.TelegramDate import dev.inmo.tgbotapi.types.TelegramDate
import dev.inmo.tgbotapi.types.chat.PreviewUser import dev.inmo.tgbotapi.types.chat.PreviewUser
import dev.inmo.tgbotapi.types.completedByUserField import dev.inmo.tgbotapi.types.completedByUserField
import dev.inmo.tgbotapi.types.completionDateField import dev.inmo.tgbotapi.types.completionDateField
import dev.inmo.tgbotapi.types.idField import dev.inmo.tgbotapi.types.idField
import dev.inmo.tgbotapi.types.message.ParseMode
import dev.inmo.tgbotapi.types.message.RawMessageEntity import dev.inmo.tgbotapi.types.message.RawMessageEntity
import dev.inmo.tgbotapi.types.message.asTextSources import dev.inmo.tgbotapi.types.message.asTextSources
import dev.inmo.tgbotapi.types.message.parseModeField
import dev.inmo.tgbotapi.types.message.textsources.RegularTextSource import dev.inmo.tgbotapi.types.message.textsources.RegularTextSource
import dev.inmo.tgbotapi.types.message.textsources.TextSource import dev.inmo.tgbotapi.types.message.textsources.TextSource
import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList
import dev.inmo.tgbotapi.types.message.toRawMessageEntities import dev.inmo.tgbotapi.types.message.toRawMessageEntities
import dev.inmo.tgbotapi.types.tasksField
import dev.inmo.tgbotapi.types.textEntitiesField import dev.inmo.tgbotapi.types.textEntitiesField
import dev.inmo.tgbotapi.types.textField import dev.inmo.tgbotapi.types.textField
import dev.inmo.tgbotapi.types.textParseModeField
import dev.inmo.tgbotapi.types.titleEntitiesField
import dev.inmo.tgbotapi.types.titleField
import dev.inmo.tgbotapi.utils.EntitiesBuilder
import dev.inmo.tgbotapi.utils.EntitiesBuilderBody
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.extensions.makeSourceString import dev.inmo.tgbotapi.utils.extensions.makeSourceString
import kotlinx.serialization.EncodeDefault import kotlinx.serialization.EncodeDefault
@@ -29,18 +38,93 @@ import kotlinx.serialization.encoding.Encoder
sealed interface ChecklistTask : TextedInput { sealed interface ChecklistTask : TextedInput {
val id: ChecklistTaskId val id: ChecklistTaskId
override val text: String override val text: String
val completedByUser: PreviewUser?
get() = null
val completionDate: TelegramDate?
get() = null
@Serializable @Serializable
data class InputChecklist @Warning("It is low level API. Do not use it without need") constructor(
@SerialName(titleField)
override val title: String,
@SerialName(tasksField)
val tasks: List<InputChecklistTask>,
@SerialName(parseModeField)
val parseMode: ParseMode? = null,
@SerialName(titleEntitiesField)
override val titleTextSources: List<TextSource> = emptyList(),
) : TitledInput
@Serializable(Input.Companion::class)
data class Input @Warning("It is low level API. Do not use it without need") constructor(
@SerialName(idField)
override val id: ChecklistTaskId,
@SerialName(textField)
override val text: String,
@SerialName(textParseModeField)
val parseMode: ParseMode? = null,
@SerialName(textEntitiesField)
override val textSources: List<TextSource> = emptyList(),
) : ChecklistTask {
constructor(id: ChecklistTaskId, text: String, parseMode: ParseMode? = null) : this(
id = id,
text = text,
parseMode = parseMode,
textSources = emptyList()
)
constructor(id: ChecklistTaskId, textSources: List<TextSource>) : this(
id = id,
text = textSources.makeSourceString(),
parseMode = null,
textSources = textSources
)
constructor(id: ChecklistTaskId, builderBody: EntitiesBuilderBody) : this(
id = id,
textSources = EntitiesBuilder().apply(builderBody).build()
)
companion object : KSerializer<Input> {
@Serializable
private data class RawInput(
@SerialName(idField)
val id: ChecklistTaskId,
@SerialName(textField)
val text: String,
@SerialName(textParseModeField)
val parseMode: ParseMode? = null,
@SerialName(textEntitiesField)
val textSources: List<RawMessageEntity> = emptyList(),
)
override val descriptor: SerialDescriptor
get() = RawInput.serializer().descriptor
override fun deserialize(decoder: Decoder): Input {
val raw = RawInput.serializer().deserialize(decoder)
return Input(
raw.id,
raw.text,
raw.parseMode,
raw.textSources.asTextSources(raw.text)
)
}
override fun serialize(encoder: Encoder, value: Input) {
RawInput.serializer().serialize(
encoder,
RawInput(
value.id,
value.text,
value.parseMode,
value.textSources.toRawMessageEntities()
)
)
}
}
}
@Serializable(Created.Serializer::class)
data class Undone( data class Undone(
@SerialName(idField) @SerialName(idField)
override val id: ChecklistTaskId, override val id: ChecklistTaskId,
@SerialName(textEntitiesField) @SerialName(textEntitiesField)
override val textSources: List<TextSource> = emptyList(), override val textSources: List<TextSource> = emptyList(),
) : ChecklistTask { ) : ChecklistTask.Created {
@OptIn(ExperimentalSerializationApi::class) @OptIn(ExperimentalSerializationApi::class)
@EncodeDefault @EncodeDefault
@Serializable @Serializable
@@ -55,7 +139,7 @@ sealed interface ChecklistTask : TextedInput {
) )
} }
@Serializable @Serializable(Created.Serializer::class)
data class Done( data class Done(
@SerialName(idField) @SerialName(idField)
override val id: ChecklistTaskId, override val id: ChecklistTaskId,
@@ -65,7 +149,7 @@ sealed interface ChecklistTask : TextedInput {
override val completionDate: TelegramDate, override val completionDate: TelegramDate,
@SerialName(textEntitiesField) @SerialName(textEntitiesField)
override val textSources: List<TextSource> = emptyList() override val textSources: List<TextSource> = emptyList()
) : ChecklistTask { ) : ChecklistTask.Created {
@OptIn(ExperimentalSerializationApi::class) @OptIn(ExperimentalSerializationApi::class)
@EncodeDefault @EncodeDefault
@Serializable @Serializable
@@ -87,11 +171,17 @@ sealed interface ChecklistTask : TextedInput {
) )
} }
@Serializable(Created.Serializer::class)
sealed interface Created : ChecklistTask {
val completedByUser: PreviewUser?
get() = null
val completionDate: TelegramDate?
get() = null
@RiskFeature @RiskFeature
object Serializer : KSerializer<ChecklistTask> { object Serializer : KSerializer<Created> {
@Serializable @Serializable
private data class RawChecklistTask( private data class RawCreatedChecklistTask(
@SerialName(idField) @SerialName(idField)
val id: ChecklistTaskId, val id: ChecklistTaskId,
@SerialName(textField) @SerialName(textField)
@@ -103,10 +193,10 @@ sealed interface ChecklistTask : TextedInput {
@SerialName(completionDateField) @SerialName(completionDateField)
val completionDate: TelegramDate = TelegramDate(0), // TelegramDate(0) is the default according to https://core.telegram.org/bots/api#checklisttask val completionDate: TelegramDate = TelegramDate(0), // TelegramDate(0) is the default according to https://core.telegram.org/bots/api#checklisttask
) )
override val descriptor: SerialDescriptor = RawChecklistTask.serializer().descriptor override val descriptor: SerialDescriptor = RawCreatedChecklistTask.serializer().descriptor
override fun deserialize(decoder: Decoder): ChecklistTask { override fun deserialize(decoder: Decoder): Created {
val raw = RawChecklistTask.serializer().deserialize( val raw = RawCreatedChecklistTask.serializer().deserialize(
decoder decoder
) )
@@ -124,10 +214,10 @@ sealed interface ChecklistTask : TextedInput {
} }
} }
override fun serialize(encoder: Encoder, value: ChecklistTask) { override fun serialize(encoder: Encoder, value: Created) {
RawChecklistTask.serializer().serialize( RawCreatedChecklistTask.serializer().serialize(
encoder, encoder,
RawChecklistTask( RawCreatedChecklistTask(
id = value.id, id = value.id,
text = value.text, text = value.text,
completedByUser = value.completedByUser, completedByUser = value.completedByUser,
@@ -137,4 +227,5 @@ sealed interface ChecklistTask : TextedInput {
) )
} }
} }
}
} }

View File

@@ -6,5 +6,5 @@ import kotlin.jvm.JvmInline
@Serializable @Serializable
@JvmInline @JvmInline
value class ChecklistTaskId( value class ChecklistTaskId(
val int: Int val int: UInt
) )

View File

@@ -0,0 +1,15 @@
package dev.inmo.tgbotapi.types.checklists
import dev.inmo.micro_utils.common.Warning
import dev.inmo.tgbotapi.abstracts.TextedInput
import dev.inmo.tgbotapi.abstracts.TitledInput
import dev.inmo.tgbotapi.types.message.ParseMode
import dev.inmo.tgbotapi.types.message.parseModeField
import dev.inmo.tgbotapi.types.message.textsources.TextSource
import dev.inmo.tgbotapi.types.tasksField
import dev.inmo.tgbotapi.types.titleEntitiesField
import dev.inmo.tgbotapi.types.titleField
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable