Compare commits
10 Commits
a8b0f3b737
...
1aaa2a5858
Author | SHA1 | Date |
---|---|---|
Oystein Kristoffer Tveit | 1aaa2a5858 | |
Oystein Kristoffer Tveit | b26636d400 | |
Oystein Kristoffer Tveit | d6fb9caa63 | |
Oystein Kristoffer Tveit | fef9733ad7 | |
Oystein Kristoffer Tveit | 4a98522973 | |
Oystein Kristoffer Tveit | 9e7632a8d5 | |
Oystein Kristoffer Tveit | 79923a8131 | |
Oystein Kristoffer Tveit | 4b812a25ca | |
Oystein Kristoffer Tveit | 5d3f3e2c87 | |
Oystein Kristoffer Tveit | c1ccbc00b3 |
|
@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
|
|||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
android {
|
||||
compileSdkVersion 30
|
||||
compileSdkVersion 33
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
|
@ -43,8 +43,8 @@ android {
|
|||
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId "com.example.tangocard_reader"
|
||||
minSdkVersion 16
|
||||
applicationId "xyz.h7x4.tangocard_reader"
|
||||
minSdkVersion 26
|
||||
targetSdkVersion 30
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example.tangocard_reader">
|
||||
<application
|
||||
android:label="tangocard_reader"
|
||||
android:label="Tangocard Reader"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
|
|
|
@ -24,6 +24,6 @@ subprojects {
|
|||
project.evaluationDependsOn(':app')
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
tasks.register("clean", Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
|||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
|
||||
|
|
Binary file not shown.
|
@ -1 +1 @@
|
|||
Subproject commit d8964efd9524859f97b416c97f9d7f1c6d809ae4
|
||||
Subproject commit 00f37fddf6656c4cca07e1afd26d6ad431e8db94
|
|
@ -1,7 +1,7 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:tangocard_reader/models/yokutango_entry.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tangocard_reader/models/data_entry.dart';
|
||||
|
||||
class Flashcard extends StatelessWidget {
|
||||
final YokutangoEntry? card;
|
||||
|
@ -104,7 +104,10 @@ class _FlashCardPaper extends StatelessWidget {
|
|||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text((cardIndex != null) ? (cardIndex! + 1).toString() : "?")
|
||||
Text(
|
||||
(cardIndex != null) ? (cardIndex! + 1).toString() : "?",
|
||||
style: const TextStyle(color: Colors.black),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -140,13 +143,19 @@ class _NorwegianContent extends StatelessWidget {
|
|||
child: FittedBox(
|
||||
fit: BoxFit.fitHeight,
|
||||
child: DefaultTextStyle.merge(
|
||||
style: const TextStyle(fontFamily: 'Heart Warming'),
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Heart Warming',
|
||||
color: Colors.black,
|
||||
),
|
||||
child: Column(
|
||||
children: card.norwegian.map((n) {
|
||||
final text = (n.hints == null)
|
||||
? n.word
|
||||
: "${n.word} (${n.hints?.join(', ')})";
|
||||
return Text(text);
|
||||
return Text(
|
||||
text,
|
||||
style: const TextStyle(color: Colors.black),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
|
@ -170,7 +179,10 @@ class _JapaneseContent extends StatelessWidget {
|
|||
child: FittedBox(
|
||||
fit: BoxFit.fitHeight,
|
||||
child: DefaultTextStyle.merge(
|
||||
style: const TextStyle(fontFamily: 'K Gothic'),
|
||||
style: const TextStyle(
|
||||
fontFamily: 'K Gothic',
|
||||
color: Colors.black,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: card.japanese
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class NavigationButtons extends StatelessWidget {
|
||||
final String middleText;
|
||||
final void Function() onNextCard;
|
||||
final void Function() onPreviousCard;
|
||||
final void Function()? onMiddlePressed;
|
||||
|
||||
const NavigationButtons({
|
||||
Key? key,
|
||||
required this.middleText,
|
||||
required this.onNextCard,
|
||||
required this.onPreviousCard,
|
||||
this.onMiddlePressed,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) =>
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.blue,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: ButtonBar(
|
||||
alignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
IconButton(
|
||||
padding: const EdgeInsets.all(20),
|
||||
color: Colors.white,
|
||||
onPressed: onPreviousCard,
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
InkWell(
|
||||
onTap: onMiddlePressed,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Text(
|
||||
middleText,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.headline6!
|
||||
.merge(const TextStyle(color: Colors.white)),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
IconButton(
|
||||
padding: const EdgeInsets.all(20),
|
||||
color: Colors.white,
|
||||
onPressed: onNextCard,
|
||||
icon: const Icon(Icons.arrow_forward),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
|
@ -1,22 +1,41 @@
|
|||
import 'package:get_it/get_it.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:tangocard_reader/router.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
void main() {
|
||||
import 'service/theme_bloc.dart';
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
GetIt.instance.registerSingleton<SharedPreferences>(
|
||||
await SharedPreferences.getInstance());
|
||||
runApp(const MyApp());
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({Key? key}) : super(key: key);
|
||||
const MyApp({
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'Tangocard Reader',
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.blue,
|
||||
),
|
||||
initialRoute: '/',
|
||||
onGenerateRoute: PageRouter.generateRoute,
|
||||
);
|
||||
}
|
||||
Widget build(BuildContext context) => BlocProvider(
|
||||
create: (context) => ThemeBloc(
|
||||
init:
|
||||
(GetIt.instance.get<SharedPreferences>().getBool('darkTheme') ??
|
||||
false)
|
||||
? Brightness.dark
|
||||
: Brightness.light),
|
||||
child: BlocBuilder<ThemeBloc, Brightness>(
|
||||
builder: (context, state) => MaterialApp(
|
||||
title: 'Tangocard Reader',
|
||||
theme: ThemeData(
|
||||
fontFamily: 'Noto Sans CJK',
|
||||
primarySwatch: Colors.blue,
|
||||
brightness: state,
|
||||
),
|
||||
initialRoute: '/',
|
||||
onGenerateRoute: PageRouter.generateRoute,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
part 'yokutango_entry.dart';
|
||||
part 'kanji_entry.dart';
|
||||
|
||||
abstract class DataEntry {
|
||||
const DataEntry();
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
part of 'data_entry.dart';
|
||||
|
||||
class KanjiEntry extends DataEntry {
|
||||
final String kanji;
|
||||
final List<WordConstruct> kana;
|
||||
|
||||
KanjiEntry.fromJson(Map<String, dynamic> json)
|
||||
: kanji = json['kanji'] as String,
|
||||
kana = [
|
||||
for (final j in json['kana'] as List) WordConstruct.fromJson(j)
|
||||
];
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return '$kanji - ${kana.join('、')}';
|
||||
}
|
||||
}
|
||||
|
||||
class WordConstruct {
|
||||
final List<WordPiece> pieces;
|
||||
|
||||
WordConstruct({required this.pieces});
|
||||
|
||||
WordConstruct.fromJson(dynamic json)
|
||||
: pieces = (json is String)
|
||||
? [WordPiece(word: json, isActive: true)]
|
||||
: [for (final j in json as List) WordPiece.fromJson(j)];
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return pieces.map((p) => p.isActive ? p.word : '(${p.word})').join('');
|
||||
}
|
||||
}
|
||||
|
||||
class WordPiece {
|
||||
final String? kana;
|
||||
final String? romaji;
|
||||
final String word;
|
||||
final bool isActive;
|
||||
|
||||
const WordPiece({
|
||||
required this.word,
|
||||
this.kana,
|
||||
this.romaji,
|
||||
this.isActive = false,
|
||||
});
|
||||
|
||||
WordPiece.fromJson(Map<String, dynamic> json)
|
||||
: kana = json['kana'] as String?,
|
||||
romaji = json['romaji'] as String?,
|
||||
word = json['text'] as String,
|
||||
isActive = json['active'] as bool? ?? false;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:tangocard_reader/models/yokutango_entry.dart';
|
||||
import 'data_entry.dart';
|
||||
|
||||
class BenkyouArgs {
|
||||
final List<YokutangoEntry> cards;
|
||||
final List<DataEntry> cards;
|
||||
final int? index;
|
||||
|
||||
const BenkyouArgs({required this.cards, this.index});
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
class YokutangoEntry {
|
||||
part of 'data_entry.dart';
|
||||
|
||||
class YokutangoEntry extends DataEntry {
|
||||
final List<JapaneseWord> japanese;
|
||||
final List<NorwegianWord> norwegian;
|
||||
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:tangocard_reader/models/data_entry.dart';
|
||||
import 'package:tangocard_reader/models/router_args.dart';
|
||||
import 'package:tangocard_reader/screens/flashcard.dart';
|
||||
import 'package:tangocard_reader/screens/home.dart';
|
||||
import 'package:tangocard_reader/screens/tango_list.dart';
|
||||
import 'package:tangocard_reader/screens/pages/tango_list.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tangocard_reader/screens/practise/practise.dart';
|
||||
|
||||
import 'screens/pages/kanji_list.dart';
|
||||
|
||||
class PageRouter {
|
||||
static Route<dynamic> generateRoute(RouteSettings settings) {
|
||||
|
@ -14,22 +17,41 @@ class PageRouter {
|
|||
case '/':
|
||||
return MaterialPageRoute(builder: (_) => const Home());
|
||||
|
||||
case '/tangolist':
|
||||
case '/list/tango':
|
||||
final file = args as File;
|
||||
return MaterialPageRoute(builder: (_) => TangoList(file: file));
|
||||
|
||||
case '/benkyou':
|
||||
case '/list/kanji':
|
||||
final file = args as File;
|
||||
return MaterialPageRoute(builder: (_) => KanjiList(file: file));
|
||||
|
||||
case '/benkyou/tango':
|
||||
final benkyouArgs = args as BenkyouArgs;
|
||||
return MaterialPageRoute(
|
||||
builder: (_) => FlashcardView(
|
||||
cards: benkyouArgs.cards,
|
||||
index: benkyouArgs.index,
|
||||
builder: (_) => PractiseView(
|
||||
entries: benkyouArgs.cards as List<YokutangoEntry>,
|
||||
index: benkyouArgs.index ?? 0,
|
||||
isKanji: false,
|
||||
),
|
||||
);
|
||||
|
||||
case '/benkyou/kanji':
|
||||
final benkyouArgs = args as BenkyouArgs;
|
||||
return MaterialPageRoute(
|
||||
builder: (_) => PractiseView(
|
||||
entries: benkyouArgs.cards as List<KanjiEntry>,
|
||||
index: benkyouArgs.index ?? 0,
|
||||
isKanji: true,
|
||||
),
|
||||
);
|
||||
|
||||
default:
|
||||
return MaterialPageRoute(
|
||||
builder: (_) => const Text("ERROR: this route does not exist"));
|
||||
builder: (_) => Scaffold(
|
||||
appBar: AppBar(title: const Text('Error')),
|
||||
body: Center(child: ErrorWidget('No such route...')),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,168 +0,0 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:tangocard_reader/components/flashcard.dart';
|
||||
import 'package:tangocard_reader/models/yokutango_entry.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class FlashcardView extends StatefulWidget {
|
||||
final List<YokutangoEntry> cards;
|
||||
final int? index;
|
||||
|
||||
const FlashcardView({
|
||||
required this.cards,
|
||||
this.index,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_FlashcardViewState createState() => _FlashcardViewState();
|
||||
}
|
||||
|
||||
const encouragingWords = [
|
||||
'頑張れ〜!',
|
||||
'できるぞ!',
|
||||
'ヨッシャー!',
|
||||
'いけいけいけー!',
|
||||
];
|
||||
|
||||
class _FlashcardViewState extends State<FlashcardView> {
|
||||
String title = '';
|
||||
int currentCard = 0;
|
||||
final List<bool> _isSelected = [false, false];
|
||||
|
||||
get isShuffleMode => _isSelected[0];
|
||||
get isLanguageSwitchedMode => _isSelected[1];
|
||||
get randomCard => Random().nextInt(widget.cards.length);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
title = encouragingWords[Random().nextInt(encouragingWords.length)];
|
||||
currentCard = widget.index ?? 0;
|
||||
|
||||
final isPhone = MediaQueryData.fromWindow(WidgetsBinding.instance!.window)
|
||||
.size
|
||||
.shortestSide <
|
||||
600;
|
||||
if (isPhone) {
|
||||
SystemChrome.setPreferredOrientations([
|
||||
DeviceOrientation.landscapeLeft,
|
||||
DeviceOrientation.landscapeRight,
|
||||
]);
|
||||
}
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
SystemChrome.setPreferredOrientations([
|
||||
DeviceOrientation.portraitDown,
|
||||
DeviceOrientation.portraitUp,
|
||||
DeviceOrientation.landscapeLeft,
|
||||
DeviceOrientation.landscapeRight,
|
||||
]);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Row(
|
||||
children: [
|
||||
Expanded(child: Container()),
|
||||
Text(title),
|
||||
Expanded(child: Container()),
|
||||
IconButton(
|
||||
onPressed: () => setState(() {
|
||||
currentCard = 0;
|
||||
}),
|
||||
icon: const Icon(Icons.repeat),
|
||||
),
|
||||
ToggleButtons(
|
||||
children: const [
|
||||
Icon(Icons.shuffle),
|
||||
Icon(Icons.translate),
|
||||
],
|
||||
isSelected: _isSelected,
|
||||
onPressed: (int index) {
|
||||
setState(() {
|
||||
_isSelected[index] = !_isSelected[index];
|
||||
});
|
||||
})
|
||||
],
|
||||
),
|
||||
centerTitle: true,
|
||||
),
|
||||
body: _FlashcardPage(
|
||||
card: widget.cards[currentCard],
|
||||
index: currentCard,
|
||||
languageFlipped: isLanguageSwitchedMode,
|
||||
onNextCard: () {
|
||||
setState(() {
|
||||
currentCard = isShuffleMode ? randomCard : currentCard + 1;
|
||||
if (currentCard == widget.cards.length) currentCard = 0;
|
||||
title = encouragingWords[Random().nextInt(encouragingWords.length)];
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _FlashcardPage extends StatefulWidget {
|
||||
final YokutangoEntry card;
|
||||
final Function() onNextCard;
|
||||
final bool languageFlipped;
|
||||
final int? index;
|
||||
|
||||
const _FlashcardPage({
|
||||
required this.card,
|
||||
required this.onNextCard,
|
||||
this.languageFlipped = false,
|
||||
this.index,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_FlashcardPageState createState() => _FlashcardPageState();
|
||||
}
|
||||
|
||||
class _FlashcardPageState extends State<_FlashcardPage> {
|
||||
bool isPressed = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
if (isPressed) {
|
||||
widget.onNextCard();
|
||||
}
|
||||
|
||||
setState(() {
|
||||
isPressed = !isPressed;
|
||||
});
|
||||
},
|
||||
child: Center(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Flashcard(
|
||||
card: widget.card,
|
||||
cardIndex: widget.index,
|
||||
isLeftSide: true,
|
||||
languageFlipped: widget.languageFlipped,
|
||||
),
|
||||
const SizedBox(width: 40),
|
||||
Flashcard(
|
||||
card: isPressed ? widget.card : null,
|
||||
cardIndex: widget.index,
|
||||
languageFlipped: widget.languageFlipped,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,81 +1,55 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:tangocard_reader/models/yokutango_entry.dart';
|
||||
import 'package:tangocard_reader/screens/error.dart';
|
||||
import 'package:tangocard_reader/screens/loading.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:tangocard_reader/service/tangocard_files.dart';
|
||||
import 'package:tangocard_reader/service/theme_bloc.dart';
|
||||
|
||||
class Home extends StatelessWidget {
|
||||
import 'pages/tango_set_list.dart';
|
||||
|
||||
class Home extends StatefulWidget {
|
||||
const Home({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text("よく単語"),
|
||||
centerTitle: true,
|
||||
),
|
||||
body: const TangocardList());
|
||||
}
|
||||
State<Home> createState() => _HomeState();
|
||||
}
|
||||
|
||||
class TangocardList extends StatelessWidget {
|
||||
const TangocardList({Key? key}) : super(key: key);
|
||||
class _HomeState extends State<Home> {
|
||||
int page = 0;
|
||||
|
||||
Future<Map<File, List<YokutangoEntry>>> get tangocardFilePaths => rootBundle
|
||||
.loadString('AssetManifest.json')
|
||||
.then(
|
||||
(json) => jsonDecode(json)
|
||||
.keys
|
||||
.where((String key) =>
|
||||
key.contains('yokutango/json/') && key.contains('.json'))
|
||||
.toList(),
|
||||
)
|
||||
.then(
|
||||
(l) async => Map.fromIterables(
|
||||
l.map<File>((f) => File(f)),
|
||||
await Future.wait<List<YokutangoEntry>>(
|
||||
l
|
||||
.map<Future<List<YokutangoEntry>>>(
|
||||
(String t) => rootBundle
|
||||
.loadString(t)
|
||||
.then<List<YokutangoEntry>>((s) => jsonDecode(s)
|
||||
.map<YokutangoEntry>(
|
||||
(e) => YokutangoEntry.fromJson(e))
|
||||
.toList()),
|
||||
)
|
||||
),
|
||||
),
|
||||
);
|
||||
final _pages = [
|
||||
TangoSetList(
|
||||
files: tangocardFilePaths,
|
||||
route: '/list/tango',
|
||||
),
|
||||
TangoSetList(
|
||||
files: kanjicardFilePaths,
|
||||
route: '/list/kanji',
|
||||
),
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FutureBuilder(
|
||||
future: tangocardFilePaths,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasError) {
|
||||
debugPrint(snapshot.error.toString());
|
||||
return const ErrorScreen();
|
||||
} else if (!snapshot.hasData) {
|
||||
return const LoadingScreen();
|
||||
}
|
||||
|
||||
return ListView(
|
||||
children: (snapshot.data as Map<File, List<YokutangoEntry>>)
|
||||
.entries
|
||||
.map(
|
||||
(e) => ListTile(
|
||||
title: Text(
|
||||
"${e.key.uri.pathSegments.last} - ${e.value.length} cards"),
|
||||
onTap: () => Navigator.pushNamed(context, '/tangolist',
|
||||
arguments: e.key),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
Widget build(BuildContext context) => Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text("よく単語"),
|
||||
actions: [
|
||||
BlocBuilder<ThemeBloc, Brightness>(
|
||||
builder: (context, state) {
|
||||
return Switch(
|
||||
value: state == Brightness.dark,
|
||||
onChanged: (b) => BlocProvider.of<ThemeBloc>(context)
|
||||
.add(SetTheme(state != Brightness.dark)),
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
centerTitle: true,
|
||||
),
|
||||
body: _pages[page],
|
||||
bottomNavigationBar: BottomNavigationBar(
|
||||
onTap: (int index) => setState(() => page = index),
|
||||
currentIndex: page,
|
||||
items: const [
|
||||
BottomNavigationBarItem(label: '単語', icon: Icon(Icons.style)),
|
||||
BottomNavigationBarItem(label: '漢字', icon: Icon(Icons.translate)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:tangocard_reader/models/router_args.dart';
|
||||
import 'package:tangocard_reader/models/yokutango_entry.dart';
|
||||
import 'package:tangocard_reader/screens/error.dart';
|
||||
import 'package:tangocard_reader/screens/loading.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:tangocard_reader/models/data_entry.dart';
|
||||
import 'package:tangocard_reader/models/router_args.dart';
|
||||
import 'package:tangocard_reader/screens/misc/error.dart';
|
||||
import 'package:tangocard_reader/screens/misc/loading.dart';
|
||||
|
||||
class TangoList extends StatelessWidget {
|
||||
class KanjiList extends StatelessWidget {
|
||||
final File file;
|
||||
|
||||
const TangoList({
|
||||
required this.file,
|
||||
const KanjiList({
|
||||
Key? key,
|
||||
required this.file,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
Widget build(BuildContext context) => Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(file.uri.pathSegments.last),
|
||||
),
|
||||
|
@ -33,7 +32,7 @@ class TangoList extends StatelessWidget {
|
|||
}
|
||||
|
||||
final entries = (jsonSnapshot.data as List)
|
||||
.map((e) => YokutangoEntry.fromJson(e))
|
||||
.map((e) => KanjiEntry.fromJson(e))
|
||||
.toList();
|
||||
|
||||
return ListView(
|
||||
|
@ -44,7 +43,7 @@ class TangoList extends StatelessWidget {
|
|||
i,
|
||||
ListTile(
|
||||
title: Text(e.toString()),
|
||||
onTap: () => Navigator.pushNamed(context, '/benkyou',
|
||||
onTap: () => Navigator.pushNamed(context, '/benkyou/kanji',
|
||||
arguments: BenkyouArgs(cards: entries, index: i)),
|
||||
),
|
||||
),
|
||||
|
@ -53,7 +52,7 @@ class TangoList extends StatelessWidget {
|
|||
.toList(),
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:tangocard_reader/models/data_entry.dart';
|
||||
import 'package:tangocard_reader/models/router_args.dart';
|
||||
import 'package:tangocard_reader/screens/misc/error.dart';
|
||||
import 'package:tangocard_reader/screens/misc/loading.dart';
|
||||
|
||||
class TangoList extends StatelessWidget {
|
||||
final File file;
|
||||
|
||||
const TangoList({
|
||||
required this.file,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(file.uri.pathSegments.last),
|
||||
),
|
||||
body: FutureBuilder(
|
||||
future:
|
||||
rootBundle.loadString(file.path).then((data) => jsonDecode(data)),
|
||||
builder: (context, jsonSnapshot) {
|
||||
if (jsonSnapshot.hasError) {
|
||||
return const ErrorScreen();
|
||||
} else if (!jsonSnapshot.hasData) {
|
||||
return const LoadingScreen();
|
||||
}
|
||||
|
||||
final entries = (jsonSnapshot.data as List)
|
||||
.map((e) => YokutangoEntry.fromJson(e))
|
||||
.toList();
|
||||
|
||||
return ListView(
|
||||
children: entries
|
||||
.asMap()
|
||||
.map(
|
||||
(i, e) => MapEntry(
|
||||
i,
|
||||
ListTile(
|
||||
title: Text(e.toString()),
|
||||
onTap: () => Navigator.pushNamed(
|
||||
context,
|
||||
'/benkyou/tango',
|
||||
arguments: BenkyouArgs(cards: entries, index: i),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
.values
|
||||
.toList(),
|
||||
);
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tangocard_reader/screens/misc/error.dart';
|
||||
import 'package:tangocard_reader/screens/misc/loading.dart';
|
||||
|
||||
class TangoSetList extends StatelessWidget {
|
||||
final String route;
|
||||
final Future<Map<File, List>> files;
|
||||
|
||||
const TangoSetList({
|
||||
Key? key,
|
||||
required this.route,
|
||||
required this.files,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => FutureBuilder(
|
||||
future: files,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasError) {
|
||||
debugPrint(snapshot.error.toString());
|
||||
return const ErrorScreen();
|
||||
} else if (!snapshot.hasData) {
|
||||
return const LoadingScreen();
|
||||
}
|
||||
|
||||
return ListView(
|
||||
children: (snapshot.data as Map<File, List>)
|
||||
.entries
|
||||
.map(
|
||||
(e) => ListTile(
|
||||
title: Text(
|
||||
"${e.key.uri.pathSegments.last} - ${e.value.length} cards"),
|
||||
onTap: () => Navigator.pushNamed(
|
||||
context,
|
||||
route,
|
||||
arguments: e.key,
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
import 'package:tangocard_reader/components/flashcard.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tangocard_reader/models/data_entry.dart';
|
||||
import 'package:tangocard_reader/components/navigation_buttons.dart';
|
||||
|
||||
class FlashcardPage extends StatefulWidget {
|
||||
final YokutangoEntry card;
|
||||
final void Function() onNextCard;
|
||||
final void Function() onPreviousCard;
|
||||
final bool languageFlipped;
|
||||
final int? index;
|
||||
|
||||
const FlashcardPage({
|
||||
required this.card,
|
||||
required this.onNextCard,
|
||||
required this.onPreviousCard,
|
||||
this.languageFlipped = false,
|
||||
this.index,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_FlashcardPageState createState() => _FlashcardPageState();
|
||||
}
|
||||
|
||||
class _FlashcardPageState extends State<FlashcardPage> {
|
||||
bool isPressed = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
if (isPressed) {
|
||||
widget.onNextCard();
|
||||
}
|
||||
|
||||
setState(() {
|
||||
isPressed = !isPressed;
|
||||
});
|
||||
},
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Flashcard(
|
||||
card: widget.card,
|
||||
cardIndex: widget.index,
|
||||
isLeftSide: true,
|
||||
languageFlipped: widget.languageFlipped,
|
||||
),
|
||||
const SizedBox(width: 40),
|
||||
Flashcard(
|
||||
card: isPressed ? widget.card : null,
|
||||
cardIndex: widget.index,
|
||||
languageFlipped: widget.languageFlipped,
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
const Expanded(child: SizedBox()),
|
||||
NavigationButtons(
|
||||
middleText:
|
||||
widget.index == null ? 'N' : (widget.index! + 1).toString(),
|
||||
onNextCard: () => setState(() {
|
||||
isPressed = false;
|
||||
widget.onNextCard();
|
||||
}),
|
||||
onPreviousCard: () => setState(() {
|
||||
isPressed = false;
|
||||
widget.onPreviousCard();
|
||||
}),
|
||||
),
|
||||
const Expanded(child: SizedBox()),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:signature/signature.dart';
|
||||
|
||||
import '../../models/data_entry.dart';
|
||||
import '../../components/navigation_buttons.dart';
|
||||
|
||||
class KanjiPage extends StatefulWidget {
|
||||
final KanjiEntry entry;
|
||||
final Function() onNextCard;
|
||||
final Function() onPreviousCard;
|
||||
final bool showDrawingPanel;
|
||||
final bool showStrokeOrder;
|
||||
final int? index;
|
||||
|
||||
const KanjiPage({
|
||||
required this.entry,
|
||||
required this.onNextCard,
|
||||
required this.onPreviousCard,
|
||||
this.showDrawingPanel = false,
|
||||
this.showStrokeOrder = false,
|
||||
this.index,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_KanjiPageState createState() => _KanjiPageState();
|
||||
}
|
||||
|
||||
class _KanjiPageState extends State<KanjiPage> {
|
||||
final focusNode = FocusNode();
|
||||
bool isPressed = false;
|
||||
late final controller = SignatureController(
|
||||
penColor: Theme.of(context).textTheme.bodyText1?.color ?? Colors.black,
|
||||
);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
focusNode.requestFocus();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
focusNode.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RawKeyboardListener(
|
||||
focusNode: focusNode,
|
||||
onKey: (event) {
|
||||
if (event.isKeyPressed(LogicalKeyboardKey.enter) || event.isKeyPressed(LogicalKeyboardKey.space)) {
|
||||
if (widget.showDrawingPanel) return;
|
||||
if (isPressed) {
|
||||
controller.clear();
|
||||
widget.onNextCard();
|
||||
}
|
||||
setState(() => isPressed = !isPressed);
|
||||
}
|
||||
},
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
if (widget.showDrawingPanel) return;
|
||||
if (isPressed) {
|
||||
controller.clear();
|
||||
widget.onNextCard();
|
||||
}
|
||||
setState(() => isPressed = !isPressed);
|
||||
},
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
if (widget.showDrawingPanel) ...[
|
||||
const SizedBox(width: 20),
|
||||
Signature(
|
||||
controller: controller,
|
||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
)
|
||||
],
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
widget.entry.kana.join('\n'),
|
||||
style: Theme.of(context).textTheme.headline3,
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
const Divider(thickness: 5),
|
||||
const SizedBox(width: 20),
|
||||
Text(
|
||||
widget.entry.kanji,
|
||||
style: isPressed
|
||||
? Theme.of(context).textTheme.headline1
|
||||
: Theme.of(context)
|
||||
.textTheme
|
||||
.headline1
|
||||
?.merge(const TextStyle(color: Colors.transparent)),
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
const Divider(thickness: 5),
|
||||
if (widget.showDrawingPanel) ...[
|
||||
const SizedBox(width: 20),
|
||||
Row(
|
||||
children: [
|
||||
const Expanded(child: SizedBox()),
|
||||
IconButton(
|
||||
iconSize: 40,
|
||||
onPressed: controller.clear,
|
||||
icon: const Icon(Icons.delete),
|
||||
)
|
||||
],
|
||||
)
|
||||
]
|
||||
],
|
||||
),
|
||||
Positioned(
|
||||
bottom: 40,
|
||||
child: NavigationButtons(
|
||||
middleText:
|
||||
widget.index == null ? 'N' : (widget.index! + 1).toString(),
|
||||
onMiddlePressed: () {
|
||||
if (isPressed) {
|
||||
controller.clear();
|
||||
widget.onNextCard();
|
||||
}
|
||||
setState(() => isPressed = !isPressed);
|
||||
},
|
||||
onNextCard: () => setState(() {
|
||||
if (isPressed) {
|
||||
controller.clear();
|
||||
widget.onNextCard();
|
||||
}
|
||||
setState(() => isPressed = !isPressed);
|
||||
}),
|
||||
onPreviousCard: () => setState(() {
|
||||
controller.clear();
|
||||
isPressed = false;
|
||||
widget.onPreviousCard();
|
||||
}),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:tangocard_reader/models/data_entry.dart';
|
||||
import 'package:tangocard_reader/screens/practise/kanji.dart';
|
||||
|
||||
import 'flashcard.dart';
|
||||
|
||||
class PractiseView extends StatefulWidget {
|
||||
final List<DataEntry> entries;
|
||||
final bool isKanji;
|
||||
final int index;
|
||||
|
||||
const PractiseView({
|
||||
Key? key,
|
||||
required this.entries,
|
||||
required this.isKanji,
|
||||
this.index = 0,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<PractiseView> createState() => _PractiseViewState();
|
||||
}
|
||||
|
||||
const encouragingWords = [
|
||||
'頑張れ〜!',
|
||||
'できるぞ!',
|
||||
'ヨッシャー!',
|
||||
'いけいけー!',
|
||||
];
|
||||
|
||||
class _PractiseViewState extends State<PractiseView> {
|
||||
late int currentCard;
|
||||
|
||||
SharedPreferences get prefs => GetIt.instance.get<SharedPreferences>();
|
||||
|
||||
set isShuffleMode(b) => prefs.setBool('shuffleMode', b);
|
||||
set isLanguageSwitchedMode(b) => prefs.setBool('languageSwitchedMode', b);
|
||||
set isKanjiDrawingMode(b) => prefs.setBool('kanjiDrawingMode', b);
|
||||
set isKanjiAnimationMode(b) => prefs.setBool('kanjiAnimationMode', b);
|
||||
|
||||
bool get isShuffleMode => prefs.getBool('shuffleMode') ?? false;
|
||||
bool get isLanguageSwitchedMode =>
|
||||
prefs.getBool('languageSwitchedMode') ?? false;
|
||||
bool get isKanjiDrawingMode => prefs.getBool('kanjiDrawingMode') ?? false;
|
||||
bool get isKanjiAnimationMode => prefs.getBool('kanjiAnimationMode') ?? false;
|
||||
|
||||
List<bool> get _flashcardToggles => [isShuffleMode, isLanguageSwitchedMode];
|
||||
List<bool> get _kanjiToggles => [isKanjiDrawingMode, isKanjiAnimationMode];
|
||||
|
||||
int get randomCard => Random().nextInt(widget.entries.length);
|
||||
String get randomEncouragingWord =>
|
||||
encouragingWords[Random().nextInt(encouragingWords.length)];
|
||||
bool get isPhone =>
|
||||
MediaQueryData.fromWindow(WidgetsBinding.instance!.window)
|
||||
.size
|
||||
.shortestSide <
|
||||
600;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
currentCard = widget.index;
|
||||
|
||||
if (isPhone) {
|
||||
if (widget.isKanji) {
|
||||
SystemChrome.setPreferredOrientations([
|
||||
DeviceOrientation.portraitUp,
|
||||
DeviceOrientation.portraitDown,
|
||||
]);
|
||||
} else {
|
||||
SystemChrome.setPreferredOrientations([
|
||||
DeviceOrientation.landscapeLeft,
|
||||
DeviceOrientation.landscapeRight,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
SystemChrome.setPreferredOrientations([
|
||||
DeviceOrientation.landscapeRight,
|
||||
DeviceOrientation.landscapeLeft,
|
||||
DeviceOrientation.portraitUp,
|
||||
DeviceOrientation.portraitDown,
|
||||
]);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
AppBar get flashcardAppBar => AppBar(
|
||||
title: Row(
|
||||
children: [
|
||||
Expanded(child: Container()),
|
||||
Text(randomEncouragingWord),
|
||||
Expanded(child: Container()),
|
||||
IconButton(
|
||||
onPressed: () => setState(() => currentCard = 0),
|
||||
icon: const Icon(Icons.repeat),
|
||||
),
|
||||
ToggleButtons(
|
||||
selectedColor: Colors.white,
|
||||
children: const [
|
||||
Icon(Icons.shuffle),
|
||||
Icon(Icons.translate),
|
||||
],
|
||||
isSelected: _flashcardToggles,
|
||||
onPressed: (int index) => setState(
|
||||
() {
|
||||
if (index == 0) {
|
||||
isShuffleMode = !_flashcardToggles[index];
|
||||
} else if (index == 1) {
|
||||
isLanguageSwitchedMode = !_flashcardToggles[index];
|
||||
}
|
||||
},
|
||||
)),
|
||||
],
|
||||
),
|
||||
centerTitle: true,
|
||||
);
|
||||
|
||||
AppBar get kanjiAppBar => AppBar(
|
||||
title: Row(
|
||||
children: [
|
||||
Expanded(child: Container()),
|
||||
Text(randomEncouragingWord),
|
||||
Expanded(child: Container()),
|
||||
IconButton(
|
||||
onPressed: () => setState(() => currentCard = 0),
|
||||
icon: const Icon(Icons.repeat),
|
||||
),
|
||||
ToggleButtons(
|
||||
selectedColor: Colors.white,
|
||||
children: const [
|
||||
Icon(Icons.edit),
|
||||
Icon(Icons.animation),
|
||||
],
|
||||
isSelected: _kanjiToggles,
|
||||
onPressed: (int index) => setState(
|
||||
() {
|
||||
if (index == 0) {
|
||||
isKanjiDrawingMode = !_kanjiToggles[index];
|
||||
} else if (index == 1) {
|
||||
isKanjiAnimationMode = !_kanjiToggles[index];
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
centerTitle: true,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Scaffold(
|
||||
appBar: widget.isKanji ? kanjiAppBar : flashcardAppBar,
|
||||
body: widget.isKanji
|
||||
? KanjiPage(
|
||||
entry: widget.entries[currentCard] as KanjiEntry,
|
||||
index: currentCard,
|
||||
showDrawingPanel: isKanjiDrawingMode,
|
||||
showStrokeOrder: isKanjiAnimationMode,
|
||||
onNextCard: () => setState(() {
|
||||
currentCard = isShuffleMode ? randomCard : currentCard + 1;
|
||||
if (currentCard == widget.entries.length) currentCard = 0;
|
||||
}),
|
||||
onPreviousCard: () => setState(() {
|
||||
currentCard = isShuffleMode ? randomCard : currentCard - 1;
|
||||
if (currentCard == -1) {
|
||||
currentCard = widget.entries.length - 1;
|
||||
}
|
||||
}),
|
||||
)
|
||||
: FlashcardPage(
|
||||
card: widget.entries[currentCard] as YokutangoEntry,
|
||||
index: currentCard,
|
||||
languageFlipped: isLanguageSwitchedMode,
|
||||
onNextCard: () => setState(() {
|
||||
currentCard = isShuffleMode ? randomCard : currentCard + 1;
|
||||
if (currentCard == widget.entries.length) currentCard = 0;
|
||||
}),
|
||||
onPreviousCard: () => setState(() {
|
||||
currentCard = isShuffleMode ? randomCard : currentCard - 1;
|
||||
if (currentCard == -1) {
|
||||
currentCard = widget.entries.length - 1;
|
||||
}
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:tangocard_reader/models/data_entry.dart';
|
||||
|
||||
// TODO: merge
|
||||
|
||||
Future<Map<File, List<YokutangoEntry>>> get tangocardFilePaths => rootBundle
|
||||
.loadString('AssetManifest.json')
|
||||
.then(
|
||||
(json) => jsonDecode(json)
|
||||
.keys
|
||||
.where((String key) =>
|
||||
key.contains('yokutango/json/') && key.contains('.json'))
|
||||
.toList(),
|
||||
)
|
||||
.then(
|
||||
(l) async => Map.fromIterables(
|
||||
l.map<File>((f) => File(f)),
|
||||
await Future.wait<List<YokutangoEntry>>(
|
||||
l.map<Future<List<YokutangoEntry>>>(
|
||||
(String t) => rootBundle.loadString(t).then<List<YokutangoEntry>>(
|
||||
(s) => jsonDecode(s)
|
||||
.map<YokutangoEntry>((e) => YokutangoEntry.fromJson(e))
|
||||
.toList()),
|
||||
)),
|
||||
),
|
||||
);
|
||||
|
||||
Future<Map<File, List<KanjiEntry>>> get kanjicardFilePaths => rootBundle
|
||||
.loadString('AssetManifest.json')
|
||||
.then(
|
||||
(json) => jsonDecode(json)
|
||||
.keys
|
||||
.where((String key) =>
|
||||
key.contains(RegExp(r'yokutango/kanji/kanji_\d+.json')))
|
||||
.toList(),
|
||||
)
|
||||
.then(
|
||||
(l) async => Map.fromIterables(
|
||||
l.map<File>((f) => File(f)),
|
||||
await Future.wait<List<KanjiEntry>>(l.map<Future<List<KanjiEntry>>>(
|
||||
(String t) => rootBundle.loadString(t).then<List<KanjiEntry>>((s) =>
|
||||
jsonDecode(s)
|
||||
.map<KanjiEntry>((e) => KanjiEntry.fromJson(e))
|
||||
.toList()),
|
||||
)),
|
||||
),
|
||||
);
|
|
@ -0,0 +1,26 @@
|
|||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
export 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
@immutable
|
||||
class SetTheme {
|
||||
final bool isDark;
|
||||
const SetTheme(this.isDark);
|
||||
}
|
||||
|
||||
class ThemeBloc extends Bloc<SetTheme, Brightness> {
|
||||
ThemeBloc({
|
||||
required Brightness init,
|
||||
}) : super(init) {
|
||||
on<SetTheme>((event, emit) {
|
||||
GetIt.instance
|
||||
.get<SharedPreferences>()
|
||||
.setBool('darkTheme', event.isDark);
|
||||
emit(event.isDark ? Brightness.dark : Brightness.light);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -5,6 +5,9 @@
|
|||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
)
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
)
|
||||
|
||||
set(PLUGIN_BUNDLED_LIBRARIES)
|
||||
|
||||
foreach(plugin ${FLUTTER_PLUGIN_LIST})
|
||||
|
@ -13,3 +16,8 @@ foreach(plugin ${FLUTTER_PLUGIN_LIST})
|
|||
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
|
||||
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
|
||||
endforeach(plugin)
|
||||
|
||||
foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
|
||||
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
|
||||
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
|
||||
endforeach(ffi_plugin)
|
||||
|
|
408
pubspec.lock
408
pubspec.lock
|
@ -1,121 +1,357 @@
|
|||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: archive
|
||||
sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.4.10"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.8.2"
|
||||
version: "2.11.0"
|
||||
bloc:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: bloc
|
||||
sha256: "3820f15f502372d979121de1f6b97bfcf1630ebff8fe1d52fb2b0bfa49be5b49"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.1.2"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.1"
|
||||
version: "1.3.0"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.15.0"
|
||||
cupertino_icons:
|
||||
dependency: "direct main"
|
||||
version: "1.18.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cupertino_icons
|
||||
url: "https://pub.dartlang.org"
|
||||
name: convert
|
||||
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
version: "3.1.1"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.1"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.0"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_bloc:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_bloc
|
||||
sha256: e74efb89ee6945bcbce74a5b3a5a3376b088e5f21f55c263fc38cbdc6237faae
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.1.3"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_lints
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: b543301ad291598523947dc534aaddc5aaad597b709d2426d3a0e0d44c5cb493
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
flutter_svg:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_svg
|
||||
sha256: d39e7f95621fc84376bc0f7d504f05c3a41488c562f4a8ad410569127507402c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.9"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_web_plugins:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
get_it:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: get_it
|
||||
sha256: e6017ce7fdeaf218dc51a100344d8cb70134b80e28b760f8bb23c242437bafd7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.6.7"
|
||||
image:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image
|
||||
sha256: "004a2e90ce080f8627b5a04aecb4cdfac87d2c3f3b520aa291260be5a32c033d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.4"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
sha256: "4186c61b32f99e60f011f7160e32c89a758ae9b1d0c6d28e2c02ef0382300e2b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.0"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: lints
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: a2c3d198cb5ea2e179926622d433331d8b58374ab8f29cdda6e863bd62fd369c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.11"
|
||||
version: "0.12.16"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.7.0"
|
||||
version: "1.10.0"
|
||||
nested:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: nested
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
version: "1.8.3"
|
||||
path_parsing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_parsing
|
||||
sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_linux
|
||||
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_platform_interface
|
||||
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
path_provider_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_windows
|
||||
sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: petitparser
|
||||
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.2"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.4"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: plugin_platform_interface
|
||||
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.8"
|
||||
pointycastle:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pointycastle
|
||||
sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.7.4"
|
||||
provider:
|
||||
dependency: "direct main"
|
||||
dependency: transitive
|
||||
description:
|
||||
name: provider
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.0"
|
||||
version: "6.1.1"
|
||||
shared_preferences:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: shared_preferences
|
||||
sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.2"
|
||||
shared_preferences_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_android
|
||||
sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
shared_preferences_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_foundation
|
||||
sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.5"
|
||||
shared_preferences_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_linux
|
||||
sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
shared_preferences_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_platform_interface
|
||||
sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
shared_preferences_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_web
|
||||
sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.2"
|
||||
shared_preferences_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_windows
|
||||
sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
signature:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: signature
|
||||
sha256: d072a766e9a40496296b7593c0d9dee2abded0bdcfb306d9962d0320a9763395
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.4.1"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
|
@ -125,58 +361,122 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.8.1"
|
||||
version: "1.10.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
version: "1.11.1"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.2"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.2.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.2.1"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.4.3"
|
||||
version: "0.6.1"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.3.2"
|
||||
vector_graphics:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_graphics
|
||||
sha256: "18f6690295af52d081f6808f2f7c69f0eed6d7e23a71539d75f4aeb8f0062172"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.9+2"
|
||||
vector_graphics_codec:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_graphics_codec
|
||||
sha256: "531d20465c10dfac7f5cd90b60bbe4dd9921f1ec4ca54c83ebb176dbacb7bb2d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.9+2"
|
||||
vector_graphics_compiler:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_graphics_compiler
|
||||
sha256: "03012b0a33775c5530576b70240308080e1d5050f0faf000118c20e6463bc0ad"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.9+2"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.4"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.0"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.2.0"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xdg_directories
|
||||
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
xml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xml
|
||||
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.5.0"
|
||||
sdks:
|
||||
dart: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=1.16.0"
|
||||
dart: ">=3.2.0 <4.0.0"
|
||||
flutter: ">=3.16.0"
|
||||
|
|
16
pubspec.yaml
16
pubspec.yaml
|
@ -29,12 +29,10 @@ environment:
|
|||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
cupertino_icons: ^1.0.2
|
||||
provider: ^6.0.0
|
||||
flutter_bloc: ^8.0.1
|
||||
get_it: ^7.2.0
|
||||
shared_preferences: ^2.0.12
|
||||
signature: ^5.0.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
@ -69,10 +67,16 @@ flutter:
|
|||
- family: K Gothic
|
||||
fonts:
|
||||
- asset: assets/fonts/K Gothic.ttf
|
||||
|
||||
- family: Heart Warming
|
||||
fonts:
|
||||
- asset: assets/fonts/Heart Warming.otf
|
||||
|
||||
- family: Noto Sans CJK
|
||||
fonts:
|
||||
- asset: assets/fonts/NotoSansCJK-Regular.ttc
|
||||
|
||||
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.dev/assets-and-images/#resolution-aware.
|
||||
|
||||
|
|
Loading…
Reference in New Issue