11package xyz .xenondevs .invui .i18n ;
22
33import com .google .gson .stream .JsonReader ;
4+ import net .kyori .adventure .key .Key ;
45import net .kyori .adventure .text .Component ;
6+ import net .kyori .adventure .text .TranslatableComponent ;
7+ import net .kyori .adventure .text .TranslationArgument ;
58import net .kyori .adventure .text .minimessage .tag .resolver .TagResolver ;
9+ import net .kyori .adventure .text .minimessage .translation .Argument ;
10+ import net .kyori .adventure .text .minimessage .translation .MiniMessageTranslator ;
11+ import net .kyori .adventure .text .renderer .ComponentRenderer ;
12+ import net .kyori .adventure .text .renderer .TranslatableComponentRenderer ;
13+ import net .kyori .adventure .translation .Translator ;
14+ import net .kyori .adventure .util .TriState ;
615import org .bukkit .entity .Player ;
716import org .jspecify .annotations .Nullable ;
8- import xyz .xenondevs .invui .internal . util . ComponentLocalizer ;
17+ import xyz .xenondevs .invui .InvUI ;
918
1019import java .io .File ;
1120import java .io .FileReader ;
1221import java .io .IOException ;
1322import java .io .Reader ;
1423import java .nio .charset .Charset ;
15- import java .util .HashMap ;
16- import java .util .Locale ;
17- import java .util .Map ;
18- import java .util .function .BiFunction ;
24+ import java .text .MessageFormat ;
25+ import java .util .*;
1926import java .util .function .Function ;
2027
2128/**
@@ -25,14 +32,34 @@ public class Languages {
2532
2633 private static final Languages INSTANCE = new Languages ();
2734 private final Map <Locale , Map <String , String >> translations = new HashMap <>();
28- private Function <Player , Locale > localeProvider = Player ::locale ;
35+ private Function <? super Player , Locale > localeProvider = Player ::locale ;
2936 private boolean serverSideTranslations = true ;
3037
38+ private final Translator translator = new MiniMessageTranslator () {
39+
40+ @ Override
41+ public Key name () {
42+ return Key .key (InvUI .getInstance ().getPlugin (), "invui_translator" );
43+ }
44+
45+ @ Override
46+ public boolean canTranslate (String key , Locale locale ) {
47+ return getFormatString (locale , key ) != null ;
48+ }
49+
50+ @ Override
51+ protected String getMiniMessageString (String key , Locale locale ) {
52+ return Objects .requireNonNull (getFormatString (locale , key ));
53+ }
54+
55+ };
56+
3157 private Languages () {
3258 }
3359
3460 /**
3561 * Gets the singleton instance of Languages.
62+ *
3663 * @return The singleton instance of Languages.
3764 */
3865 public static Languages getInstance () {
@@ -111,7 +138,7 @@ public void loadLanguage(Locale locale, File file, Charset charset) throws IOExc
111138 *
112139 * @param localeProvider The language provider.
113140 */
114- public void setLocaleProvider (Function <Player , Locale > localeProvider ) {
141+ public void setLocaleProvider (Function <? super Player , Locale > localeProvider ) {
115142 this .localeProvider = localeProvider ;
116143 }
117144
@@ -148,8 +175,7 @@ public boolean doesServerSideTranslations() {
148175 *
149176 * @param player The player to translate the component for.
150177 * @param component The component to translate.
151- * @param resolvers Additional mini message tag resolvers that may or may not be used, depending on the
152- * configured {@link #setComponentCreator(BiFunction) component creator}
178+ * @param resolvers Additional mini message tag resolvers
153179 * @return The translated component or the original component if server-side translations are disabled.
154180 */
155181 public Component localized (Player player , Component component , TagResolver ... resolvers ) {
@@ -161,25 +187,50 @@ public Component localized(Player player, Component component, TagResolver... re
161187 *
162188 * @param locale The language to translate the component to.
163189 * @param component The component to translate.
164- * @param resolvers Additional mini message tag resolvers that may or may not be used, depending on the
165- * configured {@link #setComponentCreator(BiFunction) component creator}
190+ * @param resolvers Additional mini message tag resolvers
166191 * @return The translated component or the original component if server-side translations are disabled.
167192 */
168193 public Component localized (Locale locale , Component component , TagResolver ... resolvers ) {
169194 if (serverSideTranslations ) {
170- return ComponentLocalizer . getInstance (). localize ( locale , component , resolvers );
195+ return getRenderer ( resolvers ). render ( component , locale );
171196 }
172197
173198 return component ;
174199 }
175200
176- /**
177- * Configures how components are created from translation strings.
178- *
179- * @param componentCreator The function that creates components from translation strings.
180- */
181- public void setComponentCreator (BiFunction <String , TagResolver [], Component > componentCreator ) {
182- ComponentLocalizer .getInstance ().setComponentCreator (componentCreator );
201+ private ComponentRenderer <Locale > getRenderer (TagResolver [] resolvers ) {
202+ if (resolvers .length == 0 )
203+ return TranslatableComponentRenderer .usingTranslationSource (translator );
204+
205+ // specialized TranslatableComponentRenderer that injects resolvers to each TranslatableComponent's arguments
206+ return new TranslatableComponentRenderer <>() {
207+
208+ @ Override
209+ protected @ Nullable MessageFormat translate (String key , Locale context ) {
210+ return translator .translate (key , context );
211+ }
212+
213+ @ Override
214+ protected Component renderTranslatableInner (TranslatableComponent component , Locale context ) {
215+ TriState anyTranslations = translator .hasAnyTranslations ();
216+ if (anyTranslations == TriState .FALSE )
217+ return component ;
218+
219+ Component translated ;
220+ if (translator .canTranslate (component .key (), context )) {
221+ var args = new ArrayList <>(component .arguments ());
222+ args .add (TranslationArgument .component (Argument .tagResolver (resolvers )));
223+ translated = translator .translate (component .arguments (args ), context );
224+ } else {
225+ translated = null ;
226+ }
227+
228+ return translated != null
229+ ? this .render (translated , context )
230+ : super .renderTranslatableInner (component , context );
231+ }
232+
233+ };
183234 }
184235
185236}
0 commit comments