1
+ import 'dart:ui' ;
2
+
1
3
import 'package:drift/drift.dart' ;
2
4
import 'package:drift/internal/versioned_schema.dart' ;
3
5
import 'package:drift/remote.dart' ;
@@ -24,13 +26,66 @@ class GlobalSettings extends Table {
24
26
Column <String > get browserPreference => textEnum <BrowserPreference >()
25
27
.nullable ()();
26
28
29
+ Column <String > get language => text ().map (const LocaleConverter ()).nullable ()();
30
+
27
31
// If adding a new column to this table, consider whether [BoolGlobalSettings]
28
32
// can do the job instead (by adding a value to the [BoolGlobalSetting] enum).
29
33
// That way is more convenient, when it works, because
30
34
// it avoids a migration and therefore several added copies of our schema
31
35
// in the Drift generated files.
32
36
}
33
37
38
+ class LocaleConverter extends TypeConverter <Locale , String > {
39
+ const LocaleConverter ();
40
+
41
+ /// Parse a Unicode BCP 47 Language Identifier into [Locale] .
42
+ ///
43
+ /// This supports parsing a subset of syntactically valid Unicode Language
44
+ /// Identifiers, including values [Locale.toLanguageTag] might return.
45
+ ///
46
+ /// Like [Locale] , neither
47
+ /// [variant subtags] (https://www.unicode.org/reports/tr35/#unicode_variant_subtag).
48
+ /// nor [extensions] (https://www.unicode.org/reports/tr35/#extensions)
49
+ /// are supported. It throws when it fails to convert [languageTag] into a
50
+ /// [Locale] .
51
+ ///
52
+ /// See also:
53
+ /// * https://www.unicode.org/reports/tr35/#Unicode_language_identifier;
54
+ /// the method implements a subset of this EBNF grammar.
55
+ // TODO(upstream): support Locale.fromLanguageTag:
56
+ // https://github.com/flutter/flutter/issues/143491
57
+ Locale _fromLanguageTag (String languageTag) {
58
+ final subtags = languageTag.replaceAll ('_' , '-' ).split ('-' );
59
+
60
+ return switch (subtags) {
61
+ [final language, final script, final region] =>
62
+ Locale .fromSubtags (
63
+ languageCode: language, scriptCode: script, countryCode: region),
64
+
65
+ [final language, final script] when script.length == 4 =>
66
+ Locale .fromSubtags (languageCode: language, scriptCode: script),
67
+
68
+ [final language, final region] =>
69
+ Locale (language, region),
70
+
71
+ [final language] =>
72
+ Locale (language),
73
+
74
+ _ => throw ArgumentError .value (languageTag, 'languageTag' ),
75
+ };
76
+ }
77
+
78
+ @override
79
+ Locale fromSql (String fromDb) {
80
+ return _fromLanguageTag (fromDb);
81
+ }
82
+
83
+ @override
84
+ String toSql (Locale value) {
85
+ return value.toLanguageTag ();
86
+ }
87
+ }
88
+
34
89
/// The table of the user's bool-valued, account-independent settings.
35
90
///
36
91
/// These apply across all the user's accounts on this client
@@ -119,7 +174,7 @@ class AppDatabase extends _$AppDatabase {
119
174
// information on using the build_runner.
120
175
// * Write a migration in `_migrationSteps` below.
121
176
// * Write tests.
122
- static const int latestSchemaVersion = 6 ; // See note.
177
+ static const int latestSchemaVersion = 7 ; // See note.
123
178
124
179
@override
125
180
int get schemaVersion => latestSchemaVersion;
@@ -174,6 +229,9 @@ class AppDatabase extends _$AppDatabase {
174
229
from5To6: (m, schema) async {
175
230
await m.createTable (schema.boolGlobalSettings);
176
231
},
232
+ from6To7: (m, schema) async {
233
+ await m.addColumn (schema.globalSettings, schema.globalSettings.language);
234
+ }
177
235
);
178
236
179
237
Future <void > _createLatestSchema (Migrator m) async {
0 commit comments