feat(l10n): 국제화(L10n) 시스템 도입 및 하드코딩 텍스트 변환
- flutter_localizations 및 intl 패키지 추가 - l10n.yaml 설정 파일 및 app_ko.arb 메시지 파일 생성 - 모든 화면(app, front, game_play, new_character, save_picker)의 하드코딩 텍스트를 L10n 키로 변환 - 테스트 파일에 localizationsDelegates 추가하여 L10n 지원
This commit is contained in:
@@ -2,6 +2,7 @@ import 'dart:math' as math;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:askiineverdie/l10n/app_localizations.dart';
|
||||
import 'package:askiineverdie/src/core/model/game_state.dart';
|
||||
import 'package:askiineverdie/src/core/model/pq_config.dart';
|
||||
import 'package:askiineverdie/src/core/util/deterministic_random.dart';
|
||||
@@ -241,6 +242,7 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
}
|
||||
|
||||
Widget _buildNameSection() {
|
||||
final l10n = L10n.of(context);
|
||||
return Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
@@ -249,9 +251,9 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _nameController,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Name',
|
||||
border: OutlineInputBorder(),
|
||||
decoration: InputDecoration(
|
||||
labelText: l10n.name,
|
||||
border: const OutlineInputBorder(),
|
||||
),
|
||||
maxLength: 30,
|
||||
),
|
||||
@@ -260,7 +262,7 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
IconButton.filled(
|
||||
onPressed: _onGenerateName,
|
||||
icon: const Icon(Icons.casino),
|
||||
tooltip: 'Generate Name',
|
||||
tooltip: l10n.generateName,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -269,29 +271,30 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
}
|
||||
|
||||
Widget _buildStatsSection() {
|
||||
final l10n = L10n.of(context);
|
||||
return Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Stats', style: Theme.of(context).textTheme.titleMedium),
|
||||
Text(l10n.stats, style: Theme.of(context).textTheme.titleMedium),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// 스탯 그리드
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: _buildStatTile('STR', _str)),
|
||||
Expanded(child: _buildStatTile('CON', _con)),
|
||||
Expanded(child: _buildStatTile('DEX', _dex)),
|
||||
Expanded(child: _buildStatTile(l10n.statStr, _str)),
|
||||
Expanded(child: _buildStatTile(l10n.statCon, _con)),
|
||||
Expanded(child: _buildStatTile(l10n.statDex, _dex)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: _buildStatTile('INT', _int)),
|
||||
Expanded(child: _buildStatTile('WIS', _wis)),
|
||||
Expanded(child: _buildStatTile('CHA', _cha)),
|
||||
Expanded(child: _buildStatTile(l10n.statInt, _int)),
|
||||
Expanded(child: _buildStatTile(l10n.statWis, _wis)),
|
||||
Expanded(child: _buildStatTile(l10n.statCha, _cha)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
@@ -307,9 +310,9 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text(
|
||||
'Total',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
Text(
|
||||
l10n.total,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
'$_total',
|
||||
@@ -333,7 +336,7 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
OutlinedButton.icon(
|
||||
onPressed: _onUnroll,
|
||||
icon: const Icon(Icons.undo),
|
||||
label: const Text('Unroll'),
|
||||
label: Text(l10n.unroll),
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: _rollHistory.isEmpty ? Colors.grey : null,
|
||||
),
|
||||
@@ -342,7 +345,7 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
FilledButton.icon(
|
||||
onPressed: _onReroll,
|
||||
icon: const Icon(Icons.casino),
|
||||
label: const Text('Roll'),
|
||||
label: Text(l10n.roll),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -389,7 +392,7 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Race', style: Theme.of(context).textTheme.titleMedium),
|
||||
Text(L10n.of(context).race, style: Theme.of(context).textTheme.titleMedium),
|
||||
const SizedBox(height: 8),
|
||||
SizedBox(
|
||||
height: 300,
|
||||
@@ -434,7 +437,7 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Class', style: Theme.of(context).textTheme.titleMedium),
|
||||
Text(L10n.of(context).classTitle, style: Theme.of(context).textTheme.titleMedium),
|
||||
const SizedBox(height: 8),
|
||||
SizedBox(
|
||||
height: 300,
|
||||
|
||||
Reference in New Issue
Block a user