@@ -58,6 +58,22 @@ export class Board {
58
58
59
59
private epoch : number | undefined ;
60
60
61
+ // The language and translations can be changed via the "config" message.
62
+ private language : string = "en" ;
63
+ private translations : Record < string , string > = {
64
+ "button-a" : "Button A" ,
65
+ "button-b" : "Button B" ,
66
+ "touch-logo" : "Touch logo" ,
67
+ "start-simulator" : "Start simulator" ,
68
+ } ;
69
+ formattedMessage = ( { id } : { id : string } ) : string => {
70
+ const result = this . translations [ id ] ;
71
+ if ( ! result ) {
72
+ console . trace ( `No string for code ${ id } ` ) ;
73
+ }
74
+ return result ?? id ;
75
+ } ;
76
+
61
77
constructor (
62
78
public operations : WebAssemblyOperations ,
63
79
private notifications : Notifications ,
@@ -72,26 +88,28 @@ export class Board {
72
88
new Button (
73
89
"buttonA" ,
74
90
this . svg . querySelector ( "#ButtonA" ) ! ,
75
- "button A" ,
91
+ ( ) => this . formattedMessage ( { id : "button-a" } ) ,
76
92
onChange
77
93
) ,
78
94
new Button (
79
95
"buttonB" ,
80
96
this . svg . querySelector ( "#ButtonB" ) ! ,
81
- "button B" ,
97
+ ( ) => this . formattedMessage ( { id : "button-b" } ) ,
82
98
onChange
83
99
) ,
84
100
] ;
85
101
this . pins = Array ( 33 ) ;
86
102
this . pins [ MICROBIT_HAL_PIN_FACE ] = new Pin (
87
103
"pinLogo" ,
88
- this . svg . querySelector ( "#Logo" ) ! ,
89
- "logo" ,
104
+ {
105
+ element : this . svg . querySelector ( "#Logo" ) ! ,
106
+ label : ( ) => this . formattedMessage ( { id : "touch-logo" } ) ,
107
+ } ,
90
108
onChange
91
109
) ;
92
- this . pins [ MICROBIT_HAL_PIN_P0 ] = new Pin ( "pin0" , null , "pin 0" , onChange ) ;
93
- this . pins [ MICROBIT_HAL_PIN_P1 ] = new Pin ( "pin1" , null , "pin 1" , onChange ) ;
94
- this . pins [ MICROBIT_HAL_PIN_P2 ] = new Pin ( "pin2" , null , "pin 2" , onChange ) ;
110
+ this . pins [ MICROBIT_HAL_PIN_P0 ] = new Pin ( "pin0" , null , onChange ) ;
111
+ this . pins [ MICROBIT_HAL_PIN_P1 ] = new Pin ( "pin1" , null , onChange ) ;
112
+ this . pins [ MICROBIT_HAL_PIN_P2 ] = new Pin ( "pin2" , null , onChange ) ;
95
113
this . audio = new Audio ( ) ;
96
114
this . temperature = new RangeSensor ( "temperature" , - 5 , 50 , 21 , "°C" ) ;
97
115
this . accelerometer = new Accelerometer ( onChange ) ;
@@ -123,6 +141,23 @@ export class Board {
123
141
this . playButton . addEventListener ( "click" , ( ) =>
124
142
this . notifications . onRequestFlash ( )
125
143
) ;
144
+
145
+ this . updateTranslationsInternal ( ) ;
146
+ }
147
+
148
+ updateTranslations ( language : string , translations : Record < string , string > ) {
149
+ this . language = language ;
150
+ this . translations = translations ;
151
+ this . updateTranslationsInternal ( ) ;
152
+ }
153
+
154
+ private updateTranslationsInternal ( ) {
155
+ document . documentElement . lang = this . language ;
156
+ this . playButton . ariaLabel = this . formattedMessage ( {
157
+ id : "start-simulator" ,
158
+ } ) ;
159
+ this . buttons . forEach ( ( b ) => b . updateTranslations ( ) ) ;
160
+ this . pins . forEach ( ( b ) => b . updateTranslations ( ) ) ;
126
161
}
127
162
128
163
getState ( ) : State {
@@ -499,6 +534,11 @@ export const createMessageListener = (board: Board) => (e: MessageEvent) => {
499
534
if ( e . source === window . parent ) {
500
535
const { data } = e ;
501
536
switch ( data . kind ) {
537
+ case "config" : {
538
+ const { language, translations } = data ;
539
+ board . updateTranslations ( language , translations ) ;
540
+ break ;
541
+ }
502
542
case "flash" : {
503
543
const { filesystem } = data ;
504
544
if ( ! isFileSystem ( filesystem ) ) {
0 commit comments