diff --git a/buildSrc/src/main/kotlin/Translations.kt b/buildSrc/src/main/kotlin/Translations.kt index 6fadbf17f0..90e3d05f94 100644 --- a/buildSrc/src/main/kotlin/Translations.kt +++ b/buildSrc/src/main/kotlin/Translations.kt @@ -4,6 +4,7 @@ import org.gradle.api.tasks.Sync import org.gradle.configurationcache.extensions.capitalized import org.gradle.kotlin.dsl.* import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension +import java.nio.file.Files import java.util.Properties import kotlin.collections.filterNotNull @@ -45,7 +46,12 @@ fun Project.getTranslations(classesPackage: String, bundle: String = project.nam getTranslations(project.name, classesPackage, bundle) } -fun Project.getTranslations(name: String, classesPackage: String, bundle: String = name) { +fun Project.getTranslations( + name: String, + classesPackage: String, + bundle: String = name, + translationsClass: String = "Translations", +) { val outputDir = project.layout.buildDirectory.dir("translations") val gitDir = project.layout.buildDirectory.dir("translationsGit") @@ -98,17 +104,27 @@ fun Project.getTranslations(name: String, classesPackage: String, bundle: String doLast { val props = Properties() + val bundleName = if (bundle == name || "." in bundle) { + bundle + } else { + "$name.$bundle" + } + props.load( - gitDir.get() - .file("$name/$bundle.properties") - .asFile - .inputStream() + Files.newBufferedReader( + gitDir.get() + .file("$name/${bundleName.split(".").last()}.properties") + .asFile.toPath(), + + Charsets.UTF_8 + ) ) val keys = props.toList() .map { (left, _) -> left.toString() } - createTranslationsClass("$classesPackage.generated", keys).writeTo(classOutputDir.get().asFile) + createTranslationsClass("$classesPackage.generated", keys, props, bundleName, translationsClass) + .writeTo(classOutputDir.get().asFile) } } diff --git a/buildSrc/src/main/kotlin/TranslationsClassBuilder.kt b/buildSrc/src/main/kotlin/TranslationsClassBuilder.kt index 2e00ee09cd..a47c4b1976 100644 --- a/buildSrc/src/main/kotlin/TranslationsClassBuilder.kt +++ b/buildSrc/src/main/kotlin/TranslationsClassBuilder.kt @@ -1,10 +1,10 @@ import com.hanggrian.kotlinpoet.TypeSpecBuilder import com.hanggrian.kotlinpoet.addObject import com.hanggrian.kotlinpoet.buildFileSpec -import com.hanggrian.kotlinpoet.buildObjectTypeSpec import com.hanggrian.kotlinpoet.buildPropertySpec import com.squareup.kotlinpoet.ClassName import org.gradle.configurationcache.extensions.capitalized +import java.util.Properties /* * Copyrighted (Kord Extensions, 2024). Licensed under the EUPL-1.2 @@ -14,19 +14,46 @@ import org.gradle.configurationcache.extensions.capitalized * Any redistribution must include the specific provision above. */ -fun key(name: String, value: String) = buildPropertySpec(name, ClassName("dev.kordex.core.i18n.types", "Key")) { - setInitializer("Key(%S)", value) -} +fun bundle(bundleName: String) = + buildPropertySpec("bundle", ClassName("dev.kordex.core.i18n.types", "Bundle")) { + setInitializer("Bundle(%S)", bundleName) + } +fun key(name: String, value: String, property: String, translationsClassName: String) = + buildPropertySpec(name.replace("-", "_"), ClassName("dev.kordex.core.i18n.types", "Key")) { + setInitializer("Key(%S)\n.withBundle(%L.bundle)", value, translationsClassName) -fun createTranslationsClass(classPackage: String, keys: List) = - buildFileSpec(classPackage, "Translations") { - types.addObject("Translations") { - addKeys(keys) + property.lines().forEach { + kdoc.addStatement( + "%L", + it.trim().replace("*/", "") + ) } } -fun TypeSpecBuilder.addKeys(keys: List, parent: String? = null) { + +fun createTranslationsClass( + classPackage: String, + keys: List, + props: Properties, + bundleName: String, + translationsClassName: String, +) = buildFileSpec(classPackage, translationsClassName) { + types.addObject(translationsClassName) { + properties.add( + bundle(bundleName) + ) + + addKeys(keys, props, translationsClassName) + } +} + +fun TypeSpecBuilder.addKeys( + keys: List, + props: Properties, + translationsClassName: String, + parent: String? = null, +) { val paritioned = keys.partition() paritioned.forEach { (k, v) -> @@ -36,12 +63,22 @@ fun TypeSpecBuilder.addKeys(keys: List, parent: String? = null) { k } - if (v.isEmpty()) { - properties.add(key(k.toVarName(), keyName)) - } else { + if (v.isEmpty() || props[keyName] != null) { + properties.add( + key(k.toVarName(), keyName, props.getProperty(keyName), translationsClassName) + ) + } + + if (v.isNotEmpty()) { // Object - types.addObject(k.capitalized()) { - addKeys(v, keyName) + val objName = k + .replace("-", " ") + .split(" ") + .map { it.capitalized() } + .joinToString("") + + types.addObject(objName) { + addKeys(v, props, translationsClassName, keyName) } } } diff --git a/kord-extensions/build.gradle.kts b/kord-extensions/build.gradle.kts index f141bc2f61..3e88467377 100644 --- a/kord-extensions/build.gradle.kts +++ b/kord-extensions/build.gradle.kts @@ -14,7 +14,7 @@ plugins { `ksp-module` } -getTranslations("core", "dev.kordex.core.i18n", "strings") +getTranslations("core", "dev.kordex.core.i18n", "kordex.strings", "CoreTranslations") metadata { name = "KordEx Core" diff --git a/kord-extensions/src/main/kotlin/dev/kordex/core/builders/about/CopyrightType.kt b/kord-extensions/src/main/kotlin/dev/kordex/core/builders/about/CopyrightType.kt index 6073d5270d..48e32c9f35 100644 --- a/kord-extensions/src/main/kotlin/dev/kordex/core/builders/about/CopyrightType.kt +++ b/kord-extensions/src/main/kotlin/dev/kordex/core/builders/about/CopyrightType.kt @@ -8,9 +8,12 @@ package dev.kordex.core.builders.about -public sealed class CopyrightType(public val key: String) { - public object Framework : CopyrightType("extensions.about.copyright.type.frameworks") - public object Library : CopyrightType("extensions.about.copyright.type.libraries") - public object PluginModule : CopyrightType("extensions.about.copyright.type.plugins-modules") - public object Tool : CopyrightType("extensions.about.copyright.type.tools") +import dev.kordex.core.i18n.generated.CoreTranslations +import dev.kordex.core.i18n.types.Key + +public sealed class CopyrightType(public val key: Key) { + public object Framework : CopyrightType(CoreTranslations.Extensions.About.Copyright.Type.frameworks) + public object Library : CopyrightType(CoreTranslations.Extensions.About.Copyright.Type.libraries) + public object PluginModule : CopyrightType(CoreTranslations.Extensions.About.Copyright.Type.plugins_modules) + public object Tool : CopyrightType(CoreTranslations.Extensions.About.Copyright.Type.tools) } diff --git a/kord-extensions/src/main/kotlin/dev/kordex/core/commands/Argument.kt b/kord-extensions/src/main/kotlin/dev/kordex/core/commands/Argument.kt index 29f3eb5835..0fe8b11887 100644 --- a/kord-extensions/src/main/kotlin/dev/kordex/core/commands/Argument.kt +++ b/kord-extensions/src/main/kotlin/dev/kordex/core/commands/Argument.kt @@ -10,6 +10,7 @@ package dev.kordex.core.commands import dev.kordex.core.commands.converters.Converter import dev.kordex.core.i18n.TranslationsProvider +import dev.kordex.core.i18n.types.Key /** * Data class representing a single argument. @@ -19,8 +20,8 @@ import dev.kordex.core.i18n.TranslationsProvider * @param converter Argument converter to use for this argument. */ public data class Argument( - val displayName: String, - val description: String, + val displayName: Key, + val description: Key, val converter: Converter, ) { init { @@ -29,8 +30,5 @@ public data class Argument( } internal fun Argument<*>.getDefaultTranslatedDisplayName(provider: TranslationsProvider, command: Command): String = - provider.translate( - key = displayName, - bundleName = command.resolvedBundle ?: converter.bundle, - locale = provider.defaultLocale - ) + displayName.withBundle(command.resolvedBundle ?: converter.bundle) + .translateLocale(provider.defaultLocale) diff --git a/kord-extensions/src/main/kotlin/dev/kordex/core/commands/Command.kt b/kord-extensions/src/main/kotlin/dev/kordex/core/commands/Command.kt index 221ededbd9..fbb0dca897 100644 --- a/kord-extensions/src/main/kotlin/dev/kordex/core/commands/Command.kt +++ b/kord-extensions/src/main/kotlin/dev/kordex/core/commands/Command.kt @@ -21,6 +21,8 @@ import dev.kordex.core.builders.ExtensibleBotBuilder import dev.kordex.core.commands.events.CommandEvent import dev.kordex.core.extensions.Extension import dev.kordex.core.i18n.TranslationsProvider +import dev.kordex.core.i18n.types.Bundle +import dev.kordex.core.i18n.types.Key import dev.kordex.core.koin.KordExKoinComponent import dev.kordex.core.sentry.SentryAdapter import dev.kordex.core.types.Lockable @@ -44,19 +46,19 @@ public abstract class Command(public val extension: Extension) : Lockable, KordE /** * The name of this command, for invocation and help commands. */ - public open lateinit var name: String + public open lateinit var name: Key /** Set this to `true` to lock command execution with a Mutex. **/ public override var locking: Boolean = false /** Translation bundle to use, if not the one provided by the extension. **/ - public var bundle: String? = null + public var bundle: Bundle? = null /** * @suppress Bundle getter that exists because the extension bundle may have changed by the time the command is * registered. */ - public val resolvedBundle: String? + public val resolvedBundle: Bundle? get() = bundle ?: extension.bundle override var mutex: Mutex? = null diff --git a/kord-extensions/src/main/kotlin/dev/kordex/core/commands/chat/ChatCommand.kt b/kord-extensions/src/main/kotlin/dev/kordex/core/commands/chat/ChatCommand.kt index 54d5727296..7897fa7754 100644 --- a/kord-extensions/src/main/kotlin/dev/kordex/core/commands/chat/ChatCommand.kt +++ b/kord-extensions/src/main/kotlin/dev/kordex/core/commands/chat/ChatCommand.kt @@ -22,6 +22,8 @@ import dev.kordex.core.commands.events.* import dev.kordex.core.extensions.Extension import dev.kordex.core.extensions.impl.SENTRY_EXTENSION_NAME import dev.kordex.core.i18n.EMPTY_VALUE_STRING +import dev.kordex.core.i18n.generated.Translations +import dev.kordex.core.i18n.types.Key import dev.kordex.core.sentry.BreadcrumbType import dev.kordex.core.types.FailureReason import dev.kordex.core.utils.MutableStringKeyedMap @@ -63,7 +65,7 @@ public open class ChatCommand( * * This is intended to be made use of by help commands. */ - public open var description: String = "commands.defaultDescription" + public open var description: Key = Translations.Commands.defaultDescription /** * Whether this command is enabled and can be invoked. @@ -105,7 +107,7 @@ public open class ChatCommand( * If this is set, the [aliases] list is ignored. This is also slightly more efficient during the first * translation pass, as only one key will ever need to be translated. */ - public open var aliasKey: String? = null + public open var aliasKey: Key? = null /** * @suppress diff --git a/kord-extensions/src/main/kotlin/dev/kordex/core/commands/converters/Converter.kt b/kord-extensions/src/main/kotlin/dev/kordex/core/commands/converters/Converter.kt index 424b743cfe..1a0a4d12dc 100644 --- a/kord-extensions/src/main/kotlin/dev/kordex/core/commands/converters/Converter.kt +++ b/kord-extensions/src/main/kotlin/dev/kordex/core/commands/converters/Converter.kt @@ -16,6 +16,8 @@ import dev.kordex.core.commands.Arguments import dev.kordex.core.commands.CommandContext import dev.kordex.core.commands.converters.builders.ConverterBuilder import dev.kordex.core.commands.converters.builders.ValidationContext +import dev.kordex.core.i18n.types.Bundle +import dev.kordex.core.i18n.types.Key import dev.kordex.core.koin.KordExKoinComponent import dev.kordex.parser.StringParser import org.koin.core.component.inject @@ -70,14 +72,14 @@ public abstract class Converter = mutableListOf() /** String representing the bundle to get translations from for command names/descriptions. **/ - @Translatable(TranslatableType.BUNDLE) - public open val bundle: String? = null + public open val bundle: Bundle? = null /** Set of intents required by this extension's event handlers and commands. **/ public open val intents: MutableSet = mutableSetOf() diff --git a/kord-extensions/src/main/kotlin/dev/kordex/core/extensions/impl/AboutExtension.kt b/kord-extensions/src/main/kotlin/dev/kordex/core/extensions/impl/AboutExtension.kt index e0b6ad7526..f10be19b06 100644 --- a/kord-extensions/src/main/kotlin/dev/kordex/core/extensions/impl/AboutExtension.kt +++ b/kord-extensions/src/main/kotlin/dev/kordex/core/extensions/impl/AboutExtension.kt @@ -20,7 +20,8 @@ import dev.kordex.core.extensions.Extension import dev.kordex.core.extensions.chatGroupCommand import dev.kordex.core.extensions.ephemeralSlashCommand import dev.kordex.core.extensions.publicSlashCommand -import dev.kordex.core.i18n.TranslationsProvider +import dev.kordex.core.i18n.generated.Translations +import dev.kordex.core.i18n.key import dev.kordex.core.pagination.builders.PaginatorBuilder import org.koin.core.component.inject import java.util.Locale @@ -29,7 +30,6 @@ import java.util.Locale public class AboutExtension : Extension() { override val name: String = "kordex.about" - private val translations: TranslationsProvider by inject() private val settings: ExtensibleBotBuilder by inject() override suspend fun setup() { @@ -177,23 +177,17 @@ public class AboutExtension : Extension() { color = DISCORD_BLURPLE title = "Copyright Information" - description = buildString { - appendLine( - translations.translate( - "extensions.about.copyright.intro", - locale, - replacements = arrayOf( - "[Kord Extensions](https://kordex.dev)", - "EUPL", - "1.2" - ) - ) + description = Translations.Extensions.About.Copyright.intro + .withLocale(locale) + .translate( + "[Kord Extensions](https://kordex.dev)", + "EUPL", + "1.2" ) - } } copyright - .groupBy { translations.translate(it.type.key, locale) } + .groupBy { it.type.key.withLocale(locale).translate() } .toSortedMap { left, right -> left.compareTo(right) } .forEach { (type, items) -> items diff --git a/kord-extensions/src/main/kotlin/dev/kordex/core/extensions/impl/HelpExtension.kt b/kord-extensions/src/main/kotlin/dev/kordex/core/extensions/impl/HelpExtension.kt index 199e8b368f..175afc82db 100644 --- a/kord-extensions/src/main/kotlin/dev/kordex/core/extensions/impl/HelpExtension.kt +++ b/kord-extensions/src/main/kotlin/dev/kordex/core/extensions/impl/HelpExtension.kt @@ -18,6 +18,7 @@ import dev.kordex.core.extensions.Extension import dev.kordex.core.extensions.base.HelpProvider import dev.kordex.core.extensions.chatCommand import dev.kordex.core.i18n.TranslationsProvider +import dev.kordex.core.i18n.generated.CoreTranslations import dev.kordex.core.pagination.BasePaginator import dev.kordex.core.pagination.MessageButtonPaginator import dev.kordex.core.pagination.pages.Page @@ -46,7 +47,7 @@ private const val ARGUMENTS_GROUP = "Arguments" public class HelpExtension : HelpProvider, Extension() { override val name: String = "kordex.help" - /** Translations provider, for retrieving translations. **/ + /** Translations provider, for retrieving CoreTranslations. **/ public val translationsProvider: TranslationsProvider by inject() /** Message command registry. **/ @@ -61,9 +62,9 @@ public class HelpExtension : HelpProvider, Extension() { override suspend fun setup() { chatCommand(::HelpArguments) { - name = "extensions.help.commandName" - aliasKey = "extensions.help.commandAliases" - description = "extensions.help.commandDescription" + name = CoreTranslations.Extensions.Help.commandName + aliasKey = CoreTranslations.Extensions.Help.commandAliases + description = CoreTranslations.Extensions.Help.commandDescription localeFallback = true @@ -100,14 +101,13 @@ public class HelpExtension : HelpProvider, Extension() { Page { description = page.joinToString("\n\n") { "${it.first}\n${it.second}" } - title = translationsProvider.translate("extensions.help.paginator.title.commands", locale) + + title = CoreTranslations.Extensions.Help.Paginator.Title.commands + .translateLocale(locale) footer { - text = translationsProvider.translate( - "extensions.help.paginator.footer", - locale, - replacements = arrayOf(totalCommands) - ) + text = CoreTranslations.Extensions.Help.Paginator.footer + .translateLocale(locale, totalCommands) } color = settings.colourGetter(event) @@ -119,14 +119,12 @@ public class HelpExtension : HelpProvider, Extension() { Page { description = page.joinToString("\n\n") { "${it.first}\n${it.third}" } - title = translationsProvider.translate("extensions.help.paginator.title.arguments", locale) + title = CoreTranslations.Extensions.Help.Paginator.Title.arguments + .translateLocale(locale) footer { - text = translationsProvider.translate( - "extensions.help.paginator.footer", - locale, - replacements = arrayOf(totalCommands) - ) + text = CoreTranslations.Extensions.Help.Paginator.footer + .translateLocale(locale, totalCommands) } color = settings.colourGetter(event) @@ -140,16 +138,17 @@ public class HelpExtension : HelpProvider, Extension() { pages.addPage( COMMANDS_GROUP, Page { - description = translationsProvider.translate("extensions.help.paginator.noCommands", locale) - title = translationsProvider.translate("extensions.help.paginator.noCommands", locale) + color = settings.colourGetter(event) + description = CoreTranslations.Extensions.Help.Paginator.noCommands + .translateLocale(locale) + + title = CoreTranslations.Extensions.Help.Paginator.noCommands + .translateLocale(locale) + footer { - text = translationsProvider.translate( - "extensions.help.paginator.footer", - locale, - replacements = arrayOf(0) - ) + text = CoreTranslations.Extensions.Help.Paginator.footer + .translateLocale(locale, totalCommands) } - color = settings.colourGetter(event) } ) } @@ -201,15 +200,11 @@ public class HelpExtension : HelpProvider, Extension() { Page { color = settings.colourGetter(event) - description = translationsProvider.translate( - "extensions.help.error.missingCommandDescription", - locale - ) + description = CoreTranslations.Extensions.Help.Error.missingCommandDescription + .translateLocale(locale) - title = translationsProvider.translate( - "extensions.help.error.missingCommandTitle", - locale - ) + title = CoreTranslations.Extensions.Help.Error.missingCommandTitle + .translateLocale(locale) } ) } else { @@ -228,11 +223,8 @@ public class HelpExtension : HelpProvider, Extension() { color = settings.colourGetter(event) description = "$openingLine\n$desc\n\n$arguments" - title = translationsProvider.translate( - "extensions.help.paginator.title.command", - locale, - replacements = arrayOf(commandName) - ) + title = CoreTranslations.Extensions.Help.Paginator.Title.command + .translateLocale(locale, commandName) } ) } @@ -257,10 +249,13 @@ public class HelpExtension : HelpProvider, Extension() { } } - override suspend fun gatherCommands(event: MessageCreateEvent): List> = - messageCommandsRegistry.commands + override suspend fun gatherCommands(event: MessageCreateEvent): List> { + val locale = event.getLocale() + + return messageCommandsRegistry.commands .filter { !it.hidden && it.enabled && it.runChecks(event, false, mutableMapOf()) } - .sortedBy { it.name } + .sortedBy { it.name.translateLocale(locale).lowercase(locale) } + } override suspend fun formatCommandHelp( prefix: String, @@ -282,19 +277,15 @@ public class HelpExtension : HelpProvider, Extension() { val description = buildString { if (longDescription) { append( - translationsProvider.translate( - key = command.description, - bundleName = command.extension.bundle, - locale = locale - ) + command.description + .withBundle(command.extension.bundle) + .translateLocale(locale) ) } else { append( - translationsProvider.translate( - key = command.description, - bundleName = command.extension.bundle, - locale = locale - ) + command.description + .withBundle(command.extension.bundle) + .translateLocale(locale) .trim() .takeWhile { it != '\n' } ) @@ -317,10 +308,8 @@ public class HelpExtension : HelpProvider, Extension() { append("\n") append( - translationsProvider.translate( - "extensions.help.commandDescription.aliases", - locale - ) + CoreTranslations.Extensions.Help.CommandDescription.aliases + .translateLocale(locale) ) append(" ") @@ -338,10 +327,8 @@ public class HelpExtension : HelpProvider, Extension() { append("\n") append( - translationsProvider.translate( - "extensions.help.commandDescription.subCommands", - locale - ) + CoreTranslations.Extensions.Help.CommandDescription.subCommands + .translateLocale(locale) ) append(" ") @@ -357,10 +344,8 @@ public class HelpExtension : HelpProvider, Extension() { append("\n") append( - translationsProvider.translate( - "extensions.help.commandDescription.requiredBotPermissions", - locale - ) + CoreTranslations.Extensions.Help.CommandDescription.requiredBotPermissions + .translateLocale(locale) ) append(" ") @@ -373,10 +358,8 @@ public class HelpExtension : HelpProvider, Extension() { if (command.arguments == null) { append( - translationsProvider.translate( - "extensions.help.commandDescription.noArguments", - locale - ) + CoreTranslations.Extensions.Help.CommandDescription.noArguments + .translateLocale(locale) ) } else { @Suppress("TooGenericExceptionCaught") // Hard to say really @@ -392,11 +375,9 @@ public class HelpExtension : HelpProvider, Extension() { append(" (") append( - translationsProvider.translate( - key = it.converter.signatureTypeString, - bundleName = it.converter.bundle, - locale = locale - ) + it.converter.signatureTypeString + .withBundle(it.converter.bundle) + .translateLocale(locale) ) append(")") @@ -404,11 +385,9 @@ public class HelpExtension : HelpProvider, Extension() { append("`: ") append( - translationsProvider.translate( - key = it.description, - bundleName = command.extension.bundle, - locale = locale - ) + it.description + .withBundle(command.extension.bundle) + .translateLocale(locale) ) } } @@ -417,10 +396,8 @@ public class HelpExtension : HelpProvider, Extension() { logger.error(t) { "Failed to retrieve argument list for command: $name" } append( - translationsProvider.translate( - "extensions.help.commandDescription.error.argumentList", - locale - ) + CoreTranslations.Extensions.Help.CommandDescription.Error.argumentList + .translateLocale(locale) ) } } @@ -442,10 +419,8 @@ public class HelpExtension : HelpProvider, Extension() { args.drop(1).forEach { if (command is ChatGroupCommand) { - val gc = command as ChatGroupCommand - - command = if (gc.runChecks(event, false, mutableMapOf())) { - gc.getCommand(it, event) + command = if (command.runChecks(event, false, mutableMapOf())) { + command.getCommand(it, event) } else { null } diff --git a/kord-extensions/src/main/kotlin/dev/kordex/core/i18n/_Utils.kt b/kord-extensions/src/main/kotlin/dev/kordex/core/i18n/_Utils.kt new file mode 100644 index 0000000000..5b27834842 --- /dev/null +++ b/kord-extensions/src/main/kotlin/dev/kordex/core/i18n/_Utils.kt @@ -0,0 +1,38 @@ +/* + * Copyrighted (Kord Extensions, 2024). Licensed under the EUPL-1.2 + * with the specific provision (EUPL articles 14 & 15) that the + * applicable law is the (Republic of) Irish law and the Jurisdiction + * Dublin. + * Any redistribution must include the specific provision above. + */ + +package dev.kordex.core.i18n + +import dev.kordex.core.i18n.generated.CoreTranslations.bundle +import dev.kordex.core.i18n.types.Bundle +import dev.kordex.core.i18n.types.Key +import java.util.Locale + +private val translationKeyMap: MutableMap = mutableMapOf() + +public fun String.key(bundle: Bundle? = null, locale: Locale? = null): Key { + var key = translationKeyMap.getOrPut(this) { Key(this) } + + if (bundle != null || locale != null) { + key = key.withBoth(bundle, locale) + } + + return key +} + +public fun String.key(bundle: String, locale: Locale? = null): Key = + key(Bundle(bundle), locale) + +public fun String.key(locale: Locale): Key = + translationKeyMap.getOrPut(this) { Key(this) }.withLocale(locale) + +public fun String.key(bundle: Bundle): Key = + translationKeyMap.getOrPut(this) { Key(this) }.withBundle(bundle) + +public fun String.key(bundle: String): Key = + key(Bundle(bundle)) diff --git a/kord-extensions/src/main/kotlin/dev/kordex/core/i18n/types/Key.kt b/kord-extensions/src/main/kotlin/dev/kordex/core/i18n/types/Key.kt index eccafbac63..e67c7503a3 100644 --- a/kord-extensions/src/main/kotlin/dev/kordex/core/i18n/types/Key.kt +++ b/kord-extensions/src/main/kotlin/dev/kordex/core/i18n/types/Key.kt @@ -27,25 +27,52 @@ public data class Key( } public fun withBundle(bundle: Bundle?, overwrite: Boolean = true): Key = - if (this.bundle != null && !overwrite) { + if (bundle == this.bundle) { + this + } else if (this.bundle == null || overwrite) { copy(bundle = bundle) } else { this } public fun withLocale(locale: Locale?, overwrite: Boolean = true): Key = - if (this.locale != null && !overwrite) { + if (locale == this.locale) { + this + } else if (this.locale == null || overwrite) { copy(locale = locale) } else { this } + public fun withBoth(bundle: Bundle?, locale: Locale?, overwrite: Boolean = true): Key { + val newBundle = if (this.bundle == null || overwrite) { + bundle + } else { + this.bundle + } + + val newLocale = if (this.locale == null || overwrite) { + locale + } else { + this.locale + } + + if (newBundle == this.bundle && newLocale == this.locale) { + this + } + + return copy(bundle = newBundle, locale = newLocale) + } + public fun withoutBundle(): Key = copy(bundle = null) public fun withoutLocale(): Key = copy(locale = null) + public fun withoutBoth(): Key = + copy(bundle = null, locale = null) + public fun translate(vararg replacements: Any?): String = translations.translate(this, replacements.toList().toTypedArray()) @@ -55,6 +82,15 @@ public data class Key( public fun translateNamed(vararg replacements: Pair): String = translateNamed(replacements.toMap()) + public fun translateLocale(locale: Locale, vararg replacements: Any?): String = + withLocale(locale).translate(*replacements) + + public fun translateNamedLocale(locale: Locale, replacements: Map): String = + withLocale(locale).translateNamed(replacements) + + public fun translateNamedLocale(locale: Locale, vararg replacements: Pair): String = + translateNamedLocale(locale, replacements.toMap()) + override fun toString(): String = buildString { append("Key $key") diff --git a/modules/functionality/func-mappings/build.gradle.kts b/modules/functionality/func-mappings/build.gradle.kts index 4de861a662..0da829ff8c 100644 --- a/modules/functionality/func-mappings/build.gradle.kts +++ b/modules/functionality/func-mappings/build.gradle.kts @@ -5,7 +5,12 @@ plugins { `ksp-module` } -getTranslations("dev.kordex.modules.func.mappings") +getTranslations( + "func-mappings", + "dev.kordex.modules.func.mappings.i18n", + "kordex.func-mappings", + "MappingsTranslations" +) metadata { name = "KordEx Extra: Mappings" diff --git a/modules/integrations/pluralkit/build.gradle.kts b/modules/integrations/pluralkit/build.gradle.kts index 224e71b609..8a762d443e 100644 --- a/modules/integrations/pluralkit/build.gradle.kts +++ b/modules/integrations/pluralkit/build.gradle.kts @@ -8,7 +8,12 @@ plugins { group = "dev.kordex.modules" -getTranslations("dev.kordex.modules.pluralkit") +getTranslations( + "pluralkit", + "dev.kordex.modules.pluralkit.i18n", + "kordex.pluralkit", + "PluralKitTranslations" +) metadata { name = "KordEx Extra: PluralKit"