Skip to content

Commit a753570

Browse files
committed
Add language selection screen
1 parent 69a2f86 commit a753570

20 files changed

Lines changed: 220 additions & 38 deletions

dist/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ <h2>JavaScript Disabled or not Supported.</h2>
100100

101101
<div id="monogatari">
102102
<visual-novel>
103+
<language-selection-screen></language-selection-screen>
103104
<loading-screen></loading-screen>
104105
<main-screen>
105106
<main-menu></main-menu>

dist/js/options.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ monogatari.settings({
3131
// Change to true for a MultiLanguage GameScreen.
3232
'MultiLanguage': false,
3333

34+
// If the 'Multilanguage' setting is set to `true`. This will enable a
35+
// language selection screen that will be shown before the asset loading
36+
// screen. If set to false, the loading screen will appear first instead and
37+
// players will have to change the language from the settings screen.
38+
'LanguageSelectionScreen': true,
39+
3440
// Music for the Main Menu.
3541
'MainScreenMusic': '',
3642

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
language-selection-screen {
2+
& [data-content="wrapper"] {
3+
flex-direction: column;
4+
padding: 2rem;
5+
6+
height: 100%;
7+
justify-content: center;
8+
}
9+
10+
& [data-content="buttons"] {
11+
display: flex;
12+
flex-wrap: wrap;
13+
justify-content: center;
14+
}
15+
16+
& button {
17+
background: transparent;
18+
border: 4px solid var(--main-color);
19+
border-radius: 10px;
20+
padding: 1rem;
21+
color: var(--text-color);
22+
23+
display: flex;
24+
flex-direction: column;
25+
height: auto;
26+
padding: 1rem;
27+
28+
& [data-content="icon"] {
29+
font-size: 6rem;
30+
line-height: 1;
31+
}
32+
33+
& [data-content="language"] {
34+
font-weight: bold;
35+
}
36+
37+
&:hover,
38+
&:focus {
39+
background: transparent;
40+
41+
& [data-content="language"] {
42+
text-decoration: underline;
43+
}
44+
}
45+
}
46+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { $_ } from '@aegis-framework/artemis';
2+
3+
import { ScreenComponent } from './../../lib/ScreenComponent';
4+
5+
class LanguageSelectionScreen extends ScreenComponent {
6+
7+
constructor (...args) {
8+
super (...args);
9+
10+
this.props = {
11+
languages: Object.keys (this.engine._script),
12+
timeout: 2000,
13+
};
14+
15+
this.setState ({
16+
index: 0,
17+
});
18+
19+
this.timer = null;
20+
}
21+
22+
onStateUpdate (property, oldValue, newValue) {
23+
super.onStateUpdate (property, oldValue, newValue);
24+
25+
if (property === 'index') {
26+
const { languages } = this.props;
27+
this.content ('title').text (this.engine.translation (languages[newValue]).SelectYourLanguage);
28+
}
29+
return Promise.resolve ();
30+
}
31+
32+
onPropsUpdate (property, oldValue, newValue) {
33+
super.onPropsUpdate (property, oldValue, newValue);
34+
}
35+
36+
didMount () {
37+
const { languages, timeout } = this.props;
38+
this.timer = setTimeout (() => {
39+
if (this.element ().isVisible ()) {
40+
const { index } = this.state;
41+
if (index >= (languages.length - 1)) {
42+
this.setState ({ index: 0});
43+
} else {
44+
this.setState ({ index: index + 1});
45+
}
46+
this.timer = setTimeout (() => this.didMount (), parseInt(timeout));
47+
} else {
48+
clearTimeout (this.timer);
49+
}
50+
}, parseInt(timeout));
51+
52+
this.element ().on ('click', '[data-language]', (event) => {
53+
const language = $_(event.target).closest('[data-language]').data ('language');
54+
this.engine.preference ('Language', language);
55+
this.engine.localize ();
56+
});
57+
return Promise.resolve ();
58+
}
59+
60+
render () {
61+
const { languages } = this.props;
62+
const buttons = languages.map ((language) =>{
63+
const { code, icon } = this.engine._languageMetadata[language];
64+
65+
return `
66+
<button data-language="${language}" title="${language}">
67+
<span data-content="icon">${icon}</span>
68+
<span data-content="language">${language}</span>
69+
</button>`;
70+
}).join ('');
71+
72+
return `
73+
<div data-content="wrapper">
74+
<h1 data-content="title" data-string="SelectYourLanguage">${this.engine.string ('SelectYourLanguage')}</h1>
75+
<div data-content="buttons">
76+
${buttons}
77+
</div>
78+
</div>
79+
`;
80+
}
81+
}
82+
83+
LanguageSelectionScreen.tag = 'language-selection-screen';
84+
85+
86+
export default LanguageSelectionScreen;

src/index.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
@import './components/game-screen/index.css';
3434
@import './components/help-screen/index.css';
3535
@import './components/gallery-screen/index.css';
36+
@import './components/language-selection-screen/index.css';
3637
@import './components/load-screen/index.css';
3738
@import './components/loading-screen/index.css';
3839
@import './components/main-menu/index.css';

src/index.js

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -76,20 +76,20 @@ Monogatari._translations = {
7676
'toki pona': tokipona,
7777
};
7878

79-
Monogatari._languageCodes = {
80-
'Беларуская': 'be',
81-
'Deutsch': 'de',
82-
'English': 'en',
83-
'Español': 'es',
84-
'Français': 'fr',
85-
'Nederlands': 'nl',
86-
'Português': 'pt',
87-
'Русский': 'ru',
88-
'اللغه العربية': 'ar',
89-
'한국어': 'ko',
90-
'日本語': 'ja',
91-
'简体中文': 'zh',
92-
'toki pona': 'en',
79+
Monogatari._languageMetadata = {
80+
'Беларуская': { code: 'be', icon: '🇧🇾' },
81+
'Deutsch': { code: 'de', icon: '🇩🇪' },
82+
'English': { code: 'en', icon: '🇺🇸' },
83+
'Español': { code: 'es', icon: '🇲🇽' },
84+
'Français': { code: 'fr', icon: '🇫🇷' },
85+
'Nederlands': { code: 'nl', icon: '🇳🇱' },
86+
'Português': { code: 'pt', icon: '🇧🇷' },
87+
'Русский': { code: 'ru', icon: '🇷🇺' },
88+
'اللغه العربية': { code: 'ar', icon: '🇦🇪' },
89+
'한국어': { code: 'ko', icon: '🇰🇷' },
90+
'日本語': { code: 'ja', icon: '🇯🇵' },
91+
'简体中文': { code: 'zh', icon: '🇨🇳' },
92+
'toki pona': { code: 'en', icon: '🕮' },
9393
};
9494

9595
/**
@@ -109,6 +109,7 @@ import DialogLog from './components/dialog-log';
109109
import GalleryScreen from './components/gallery-screen';
110110
import GameScreen from './components/game-screen';
111111
import HelpScreen from './components/help-screen';
112+
import LanguageSelectionScreen from './components/language-selection-screen';
112113
import LoadScreen from './components/load-screen';
113114
import LoadingScreen from './components/loading-screen';
114115
import MainMenu from './components/main-menu';
@@ -133,6 +134,7 @@ Monogatari._components = [
133134
GalleryScreen,
134135
GameScreen,
135136
HelpScreen,
137+
LanguageSelectionScreen,
136138
LoadScreen,
137139
LoadingScreen,
138140
MainMenu,

src/monogatari.js

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -869,7 +869,7 @@ class Monogatari {
869869
this.trigger ('willLocalize');
870870

871871
// Setup the correct locale for the momentjs dates
872-
moment.locale (this._languageCodes[this.preference ('Language')]);
872+
moment.locale (this._languageMetadata[this.preference ('Language').code]);
873873

874874
this.element ().find ('[data-string]').each ((element) => {
875875
const string_translation = this.string ($_(element).data ('string'));
@@ -2439,10 +2439,14 @@ class Monogatari {
24392439
// Set the initial settings if they don't exist or load them from the
24402440
// Storage if they do.
24412441
this.Storage.get ('Settings').then ((local_settings) => {
2442+
this.global ('_first_run', false);
24422443
this._preferences = merge (this._preferences, local_settings);
24432444
}).catch ((e) => {
2445+
this.global ('_first_run', true);
2446+
if (this.setting ('MultiLanguage') !== true || this.setting ('LanguageSelectionScreen') !== true) {
2447+
this.Storage.set ('Settings', this._preferences);
2448+
}
24442449
console.warn ('There was no settings saved. This may be the first time this game was opened, we\'ll create them now.', e);
2445-
this.Storage.set ('Settings', this._preferences);
24462450
});
24472451

24482452
// Define all the components that were registered to this point
@@ -2909,6 +2913,31 @@ class Monogatari {
29092913
}
29102914
}
29112915

2916+
static displayInitialScreen () {
2917+
// Preload all the game assets
2918+
this.preload ().then (() => {
2919+
2920+
}).catch ((e) => {
2921+
console.error (e);
2922+
}).finally (() => {
2923+
if (this.label ()) {
2924+
this.showSplashScreen ();
2925+
} else {
2926+
FancyError.show (
2927+
`"${this.setting ('Label')}" Label was not found`,
2928+
'Monogatari tried to get your start label but it couldn\'t find it in your script.',
2929+
{
2930+
'Start Label on your Settings': this.setting ('Label'),
2931+
'Labels Available': Object.keys (this.script ()),
2932+
'Help': {
2933+
'_': 'Please check that the label exists in your script.'
2934+
}
2935+
}
2936+
);
2937+
}
2938+
});
2939+
}
2940+
29122941
static init (selector = '#monogatari') {
29132942
this._selector = selector;
29142943

@@ -2990,28 +3019,20 @@ class Monogatari {
29903019
this.global ('_didInit', true);
29913020
this.trigger ('didInit');
29923021

2993-
// Preload all the game assets
2994-
this.preload ().then (() => {
3022+
if (this.setting ('MultiLanguage') === true && this.setting ('LanguageSelectionScreen') === true && this.global ('_first_run') === true) {
3023+
this.showScreen ('language-selection');
29953024

2996-
}).catch ((e) => {
2997-
console.error (e);
2998-
}).finally (() => {
2999-
if (this.label ()) {
3000-
this.showSplashScreen ();
3001-
} else {
3002-
FancyError.show (
3003-
`"${this.setting ('Label')}" Label was not found`,
3004-
'Monogatari tried to get your start label but it couldn\'t find it in your script.',
3005-
{
3006-
'Start Label on your Settings': this.setting ('Label'),
3007-
'Labels Available': Object.keys (this.script ()),
3008-
'Help': {
3009-
'_': 'Please check that the label exists in your script.'
3010-
}
3011-
}
3012-
);
3013-
}
3014-
});
3025+
this.on ('didLocalize', () => {
3026+
this.Storage.set ('Settings', this._preferences);
3027+
const languageSelectionScreen = this.element ().find ('[data-screen="language-selection"]');
3028+
if (languageSelectionScreen.isVisible ()) {
3029+
this.displayInitialScreen ();
3030+
3031+
}
3032+
});
3033+
} else {
3034+
this.displayInitialScreen ();
3035+
}
30153036
});
30163037
});
30173038
});
@@ -3111,6 +3132,12 @@ Monogatari._settings = {
31113132
// Change to true for a MultiLanguage GameScreen.
31123133
'MultiLanguage': false,
31133134

3135+
// If the 'Multilanguage' setting is set to `true`. This will enable a
3136+
// language selection screen that will be shown before the asset loading
3137+
// screen. If set to false, the loading screen will appear first instead and
3138+
// players will have to change the language from the settings screen.
3139+
'LanguageSelectionScreen': true,
3140+
31143141
// Music for the Main Menu.
31153142
'MainScreenMusic': '',
31163143

src/translations/Deutsch.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ export default {
7171
'Save': 'Speichern',
7272
'SaveButton': 'Öffne den Speicherbildschirm',
7373
'SaveInSlot': 'In Slot speichern',
74+
'SelectYourLanguage': 'Select your language',
7475
'Settings': 'Optionen',
7576
'SettingsButton': 'Öffne die Optionen',
7677
'Show': 'Einblenden',

src/translations/English.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export default {
7272
'Save': 'Save',
7373
'SaveButton': 'Open the Save Screen',
7474
'SaveInSlot': 'Save in slot',
75+
'SelectYourLanguage': 'Select your language',
7576
'Settings': 'Settings',
7677
'SettingsButton': 'Open the Settings Screen',
7778
'Show': 'Show',

src/translations/Español.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export default {
7070
'Save': 'Guardar',
7171
'SaveButton': 'Abrir la Pantalla de Guardar',
7272
'SaveInSlot': 'Guardar en ranura',
73+
'SelectYourLanguage': 'Selecciona tu idioma',
7374
'Settings': 'Configuración',
7475
'SettingsButton': 'Abrir la Pantalla de Configuración',
7576
'Show': 'Mostrar',

0 commit comments

Comments
 (0)