Skip to content

Commit

Permalink
Initial locale selector
Browse files Browse the repository at this point in the history
  • Loading branch information
jmshrv committed Apr 23, 2023
1 parent 797535d commit 26754a7
Show file tree
Hide file tree
Showing 10 changed files with 323 additions and 131 deletions.
82 changes: 82 additions & 0 deletions lib/components/LanguageSelectionScreen/language_list.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import 'dart:collection';

import 'package:flutter/material.dart';

import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:locale_names/locale_names.dart';

import '../../services/finamp_settings_helper.dart';
import '../../services/locale_helper.dart';

class LanguageList extends StatefulWidget {
const LanguageList({super.key});

@override
State<LanguageList> createState() => _LanguageListState();
}

class _LanguageListState extends State<LanguageList> {
// yeah I'm a computer science student how could you tell
// (sorts locales without having to copy them into a list first)
final locales = SplayTreeMap<String, Locale>.fromIterable(
AppLocalizations.supportedLocales,
key: (element) => (element as Locale).defaultDisplayLanguage,
value: (element) => element,
);

@override
Widget build(BuildContext context) {
return Scrollbar(
// We have a ValueListenableBuilder here to rebuild all the ListTiles when
// the language changes
child: ValueListenableBuilder(
valueListenable: LocaleHelper.localeListener,
builder: (_, __, ___) {
return CustomScrollView(
slivers: [
const SliverList(
delegate: SliverChildListDelegate.fixed([
LanguageListTile(),
Divider(),
]),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
final locale = locales.values.elementAt(index);

return LanguageListTile(locale: locale);
},
childCount: locales.length,
),
)
],
);
},
),
);
}
}

class LanguageListTile extends StatelessWidget {
const LanguageListTile({
super.key,
this.locale,
});

final Locale? locale;

@override
Widget build(BuildContext context) {
return RadioListTile<Locale?>(
title: Text(locale?.nativeDisplayLanguage ??
AppLocalizations.of(context)!.system),
subtitle: locale == null ? null : Text(locale!.defaultDisplayLanguage),
value: locale,
groupValue: LocaleHelper.locale,
onChanged: (_) {
LocaleHelper.setLocale(locale);
},
);
}
}
5 changes: 3 additions & 2 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -479,5 +479,6 @@
"bufferDuration": "Buffer Duration",
"@bufferDuration": {},
"bufferDurationSubtitle": "How much the player should buffer, in seconds. Requires a restart.",
"@bufferDurationSubtitle": {}
}
"@bufferDurationSubtitle": {},
"language": "Language"
}
267 changes: 142 additions & 125 deletions lib/main.dart

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions lib/models/locale_adapter.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';

class LocaleAdapter extends TypeAdapter<Locale> {
@override
int get typeId => 42;

@override
Locale read(BinaryReader reader) {
final localeList = reader.readStringList();

final languageCode = localeList[0];

// scriptCode and countryCode are empty strings when null (see write)
final scriptCode = localeList[1] == "" ? null : localeList[1];
final countryCode = localeList[2] == "" ? null : localeList[2];

return Locale.fromSubtags(
languageCode: languageCode,
scriptCode: scriptCode,
countryCode: countryCode,
);
}

@override
void write(BinaryWriter writer, Locale obj) {
writer.writeStringList([
obj.languageCode,
obj.scriptCode ?? "",
obj.countryCode ?? "",
]);
}
}
21 changes: 21 additions & 0 deletions lib/screens/language_selection_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import 'package:flutter/material.dart';

import 'package:flutter_gen/gen_l10n/app_localizations.dart';

import '../components/LanguageSelectionScreen/language_list.dart';

class LanguageSelectionScreen extends StatelessWidget {
const LanguageSelectionScreen({super.key});

static const routeName = "/settings/language";

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context)!.language),
),
body: const LanguageList(),
);
}
}
11 changes: 11 additions & 0 deletions lib/screens/settings_screen.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:locale_names/locale_names.dart';
import 'package:package_info_plus/package_info_plus.dart';

import '../services/finamp_settings_helper.dart';
import '../services/locale_helper.dart';
import 'transcoding_settings_screen.dart';
import 'downloads_settings_screen.dart';
import 'audio_service_settings_screen.dart';
import 'layout_settings_screen.dart';
import '../components/SettingsScreen/logout_list_tile.dart';
import 'view_selector.dart';
import 'language_selection_screen.dart';

class SettingsScreen extends StatelessWidget {
const SettingsScreen({Key? key}) : super(key: key);
Expand Down Expand Up @@ -76,6 +79,14 @@ class SettingsScreen extends StatelessWidget {
onTap: () =>
Navigator.of(context).pushNamed(ViewSelector.routeName),
),
ListTile(
leading: const Icon(Icons.language),
title: Text(AppLocalizations.of(context)!.language),
subtitle: Text(LocaleHelper.locale?.nativeDisplayLanguage ??
AppLocalizations.of(context)!.system),
onTap: () => Navigator.of(context)
.pushNamed(LanguageSelectionScreen.routeName),
),
const LogoutListTile(),
],
),
Expand Down
6 changes: 2 additions & 4 deletions lib/services/finamp_settings_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,9 @@ class FinampSettingsHelper {
.put("FinampSettings", finampSettingsTemp);
}

static void setDisableGesture(
bool disableGesture) {
static void setDisableGesture(bool disableGesture) {
FinampSettings finampSettingsTemp = finampSettings;
finampSettingsTemp.disableGesture =
disableGesture;
finampSettingsTemp.disableGesture = disableGesture;
Hive.box<FinampSettings>("FinampSettings")
.put("FinampSettings", finampSettingsTemp);
}
Expand Down
16 changes: 16 additions & 0 deletions lib/services/locale_helper.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';

class LocaleHelper {
static const boxName = "Locale";

static ValueListenable<Box<Locale?>> get localeListener =>
Hive.box<Locale?>(boxName).listenable();

static Locale? get locale => Hive.box<Locale?>(boxName).get(boxName);

static void setLocale(Locale? locale) {
Hive.box<Locale?>(boxName).put(boxName, locale);
}
}
9 changes: 9 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,15 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.1"
locale_names:
dependency: "direct main"
description:
path: "."
ref: "74e55fd"
resolved-ref: "74e55fd2997cc5a0d5283604a09c307036cac020"
url: "https://github.com/Mantano/locale_names.git"
source: git
version: "0.0.1"
logging:
dependency: "direct main"
description:
Expand Down
4 changes: 4 additions & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ dependencies:
intl: ^0.17.0
auto_size_text: ^3.0.0
flutter_riverpod: ^2.3.4
locale_names:
git:
url: https://github.com/Mantano/locale_names.git
ref: 74e55fd

dev_dependencies:
flutter_test:
Expand Down

0 comments on commit 26754a7

Please sign in to comment.