Skip to content

Commit 130df0e

Browse files
WishyutCAnton-Dodonov
authored andcommitted
Refactor localization implementation and remove unused ARB files
1 parent 06886be commit 130df0e

File tree

17 files changed

+138
-123
lines changed

17 files changed

+138
-123
lines changed

assets/lang/en.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
3+
"app_name": "VPN Client",
4+
"apps_selection": "App Selection",
5+
"search": "Search",
6+
"your_location": "Your Location",
7+
"auto_select": "Auto Select",
8+
"kazakhstan": "Kazakhstan",
9+
"turkey": "Turkey",
10+
"poland": "Poland",
11+
"fastest": "Fastest",
12+
"selected_server": "Selected server",
13+
"server_selection": "Server selection",
14+
"all_servers": "All servers",
15+
"country_name": "Country name",
16+
"all_apps": "All Applications",
17+
"done": "Done",
18+
"cancel": "Cancel",
19+
"recently_searched": "Recently searched",
20+
"nothing_found": "Nothing found",
21+
"connected": "CONNECTED",
22+
"disconnected": "DISCONNECTED",
23+
"reconnecting": "RECONNECTING",
24+
"connecting": "CONNECTING",
25+
"disconnecting": "DISCONNECTING"
26+
}

lib/l10n/app_ru.arb renamed to assets/lang/ru.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"@@locale": "ru",
2+
33
"app_name": "VPN Клиент",
44
"apps_selection": "Выбор приложений",
55
"search": "Поиск",

lib/l10n/app_th.arb renamed to assets/lang/th.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"@@locale": "th",
2+
33
"app_name": "VPN Client",
44
"apps_selection": "เลือกแอป",
55
"search": "ค้นหา",

lib/l10n/app_zh.arb renamed to assets/lang/zh.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"@@locale": "zh",
2+
33
"app_name": "VPN客户端",
44
"apps_selection": "应用选择",
55
"search": "搜索",

l10n.yaml

Lines changed: 0 additions & 4 deletions
This file was deleted.

lib/l10n/app_en.arb

Lines changed: 0 additions & 26 deletions
This file was deleted.

lib/localization_service.dart

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import 'dart:convert';
2+
import 'package:flutter/services.dart';
3+
import 'package:flutter/material.dart';
4+
5+
class LocalizationService {
6+
static Map<String, dynamic> _localizedStrings = {};
7+
static late Locale _currentLocale;
8+
9+
static Future<void> load(Locale locale) async {
10+
_currentLocale = locale;
11+
String langCode = locale.languageCode;
12+
13+
// Try loading the file, fallback to English
14+
try {
15+
final String jsonString = await rootBundle.loadString(
16+
'assets/lang/$langCode.json',
17+
);
18+
_localizedStrings = json.decode(jsonString);
19+
} catch (_) {
20+
final String fallback = await rootBundle.loadString(
21+
'assets/lang/en.json',
22+
);
23+
_localizedStrings = json.decode(fallback);
24+
}
25+
}
26+
27+
static String to(String key) {
28+
return _localizedStrings[key] ?? '[$key]';
29+
}
30+
31+
static Locale get currentLocale => _currentLocale;
32+
}

lib/main.dart

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
import 'package:flutter/material.dart';
2-
import 'package:flutter_localizations/flutter_localizations.dart';
3-
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
42
import 'package:provider/provider.dart';
5-
63
import 'package:vpn_client/pages/apps/apps_page.dart';
4+
import 'dart:ui' as ui;
75
import 'package:vpn_client/pages/main/main_page.dart';
86
import 'package:vpn_client/pages/servers/servers_page.dart';
97
import 'package:vpn_client/theme_provider.dart';
8+
import 'package:flutter_localizations/flutter_localizations.dart';
109
import 'package:vpn_client/vpn_state.dart';
10+
import 'package:vpn_client/localization_service.dart';
1111

1212
import 'design/colors.dart';
1313
import 'nav_bar.dart';
1414

15-
void main() {
15+
void main() async {
16+
WidgetsFlutterBinding.ensureInitialized();
17+
18+
Locale userLocale =
19+
ui.PlatformDispatcher.instance.locale; // <-- Get the system locale
20+
await LocalizationService.load(userLocale);
21+
1622
runApp(
1723
MultiProvider(
1824
providers: [
@@ -36,28 +42,23 @@ class App extends StatelessWidget {
3642
final Locale? manualLocale = null; // ← use system by default
3743

3844
return MaterialApp(
45+
localizationsDelegates: const [
46+
GlobalMaterialLocalizations.delegate,
47+
GlobalWidgetsLocalizations.delegate,
48+
GlobalCupertinoLocalizations.delegate,
49+
],
3950
debugShowCheckedModeBanner: false,
4051
title: 'VPN Client',
4152
theme: lightTheme,
4253
darkTheme: darkTheme,
4354
locale: manualLocale,
44-
localeResolutionCallback: (locale, supportedLocales) {
55+
localeResolutionCallback: (locale, _) {
4556
if (locale == null) return const Locale('en');
4657

4758
// Check for exact match
48-
for (var supportedLocale in supportedLocales) {
49-
if (supportedLocale.languageCode == locale.languageCode &&
50-
(supportedLocale.countryCode == null ||
51-
supportedLocale.countryCode == locale.countryCode)) {
52-
return supportedLocale;
53-
}
54-
}
55-
56-
// If Chinese variants are not supported, fallback to zh
57-
if (locale.languageCode == 'zh') {
58-
return supportedLocales.contains(const Locale('zh'))
59-
? const Locale('zh')
60-
: const Locale('en');
59+
final supported = ['en', 'ru', 'th', 'zh'];
60+
if (supported.contains(locale.languageCode)) {
61+
return Locale(locale.languageCode);
6162
}
6263

6364
// Fallback to 'en' if not found
@@ -66,19 +67,6 @@ class App extends StatelessWidget {
6667

6768
themeMode: themeProvider.themeMode,
6869
home: const MainScreen(),
69-
70-
localizationsDelegates: const [
71-
AppLocalizations.delegate,
72-
GlobalMaterialLocalizations.delegate,
73-
GlobalWidgetsLocalizations.delegate,
74-
GlobalCupertinoLocalizations.delegate,
75-
],
76-
supportedLocales: const [
77-
Locale('en'),
78-
Locale('ru'),
79-
Locale('th'),
80-
Locale('zh'),
81-
],
8270
);
8371
}
8472
}

lib/pages/apps/apps_page.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import 'package:flutter/material.dart';
22
import 'package:vpn_client/pages/apps/apps_list.dart';
33
import 'package:vpn_client/search_dialog.dart';
4-
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
4+
import 'package:vpn_client/localization_service.dart';
55

66
class AppsPage extends StatefulWidget {
77
const AppsPage({super.key});
@@ -19,7 +19,7 @@ class AppsPageState extends State<AppsPage> {
1919
context: context,
2020
builder: (BuildContext context) {
2121
return SearchDialog(
22-
placeholder: AppLocalizations.of(context)!.app_name,
22+
placeholder: LocalizationService.to('app_name'),
2323
items: _apps,
2424
type: 1,
2525
);
@@ -40,7 +40,7 @@ class AppsPageState extends State<AppsPage> {
4040
Widget build(BuildContext context) {
4141
return Scaffold(
4242
appBar: AppBar(
43-
title: Text(AppLocalizations.of(context)!.apps_selection),
43+
title: Text(LocalizationService.to('apps_selection')),
4444
centerTitle: true,
4545
titleTextStyle: TextStyle(
4646
color: Theme.of(context).colorScheme.primary,
@@ -60,7 +60,7 @@ class AppsPageState extends State<AppsPage> {
6060
color: Theme.of(context).colorScheme.primary,
6161
),
6262
onPressed: () => _showSearchDialog(context),
63-
tooltip: AppLocalizations.of(context)!.search,
63+
tooltip: LocalizationService.to('search'),
6464
),
6565
),
6666
),

lib/pages/main/location_widget.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import 'package:flutter/material.dart';
22
import 'package:flutter_svg/svg.dart';
3-
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
3+
import 'package:vpn_client/localization_service.dart';
44

55
class LocationWidget extends StatelessWidget {
66
final Map<String, dynamic>? selectedServer;
@@ -27,7 +27,7 @@ class LocationWidget extends StatelessWidget {
2727
crossAxisAlignment: CrossAxisAlignment.start,
2828
children: [
2929
Text(
30-
AppLocalizations.of(context)!.your_location,
30+
LocalizationService.to('your_location'),
3131
style: TextStyle(
3232
fontSize: 14,
3333
fontWeight: FontWeight.w400,

0 commit comments

Comments
 (0)