Add themes and drawing field for kanji
This commit is contained in:
parent
4a98522973
commit
fef9733ad7
@ -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
|
||||
|
@ -4,12 +4,14 @@ 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
|
||||
@ -29,12 +31,18 @@ class NavigationButtons extends StatelessWidget {
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
middleText,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.headline6!
|
||||
.merge(const TextStyle(color: Colors.white)),
|
||||
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(
|
@ -1,21 +1,41 @@
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:tangocard_reader/router.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
void main() => runApp(const MyApp());
|
||||
import 'service/theme_bloc.dart';
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
runApp(MyApp(prefs: prefs));
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({Key? key}) : super(key: key);
|
||||
final SharedPreferences prefs;
|
||||
|
||||
const MyApp({
|
||||
Key? key,
|
||||
required this.prefs,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'Tangocard Reader',
|
||||
theme: ThemeData(
|
||||
fontFamily: 'Noto Sans CJK',
|
||||
primarySwatch: Colors.blue,
|
||||
),
|
||||
initialRoute: '/',
|
||||
onGenerateRoute: PageRouter.generateRoute,
|
||||
);
|
||||
}
|
||||
Widget build(BuildContext context) => BlocProvider(
|
||||
create: (context) => ThemeBloc(
|
||||
prefs: prefs,
|
||||
init: (prefs.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,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tangocard_reader/service/tangocard_files.dart';
|
||||
import 'package:tangocard_reader/service/theme_bloc.dart';
|
||||
|
||||
import 'pages/tango_set_list.dart';
|
||||
|
||||
@ -14,14 +15,31 @@ class _HomeState extends State<Home> {
|
||||
int page = 0;
|
||||
|
||||
final _pages = [
|
||||
TangoSetList(files: tangocardFilePaths, route: '/list/tango',),
|
||||
TangoSetList(files: kanjicardFilePaths, route: '/list/kanji',),
|
||||
TangoSetList(
|
||||
files: tangocardFilePaths,
|
||||
route: '/list/tango',
|
||||
),
|
||||
TangoSetList(
|
||||
files: kanjicardFilePaths,
|
||||
route: '/list/kanji',
|
||||
),
|
||||
];
|
||||
|
||||
@override
|
||||
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],
|
||||
@ -29,8 +47,8 @@ class _HomeState extends State<Home> {
|
||||
onTap: (int index) => setState(() => page = index),
|
||||
currentIndex: page,
|
||||
items: const [
|
||||
BottomNavigationBarItem(label: 'Tango', icon: Icon(Icons.style)),
|
||||
BottomNavigationBarItem(label: 'Kanji', icon: Text('漢字')),
|
||||
BottomNavigationBarItem(label: '単語', icon: Icon(Icons.style)),
|
||||
BottomNavigationBarItem(label: '漢字', icon: Icon(Icons.translate)),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'package:tangocard_reader/components/flashcard.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tangocard_reader/models/data_entry.dart';
|
||||
import 'package:tangocard_reader/screens/practise/navigation_buttons.dart';
|
||||
import 'package:tangocard_reader/components/navigation_buttons.dart';
|
||||
|
||||
class FlashcardPage extends StatefulWidget {
|
||||
final YokutangoEntry card;
|
||||
|
@ -1,7 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:signature/signature.dart';
|
||||
|
||||
import '../../models/data_entry.dart';
|
||||
import 'navigation_buttons.dart';
|
||||
import '../../components/navigation_buttons.dart';
|
||||
|
||||
class KanjiPage extends StatefulWidget {
|
||||
final KanjiEntry entry;
|
||||
@ -27,19 +28,33 @@ class KanjiPage extends StatefulWidget {
|
||||
|
||||
class _KanjiPageState extends State<KanjiPage> {
|
||||
bool isPressed = false;
|
||||
late final controller = SignatureController(
|
||||
penColor: Theme.of(context).textTheme.bodyText1?.color ?? Colors.black,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
if (isPressed) widget.onNextCard();
|
||||
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: [
|
||||
@ -49,13 +64,18 @@ class _KanjiPageState extends State<KanjiPage> {
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
const Divider(thickness: 5),
|
||||
if (isPressed) ...[
|
||||
const SizedBox(width: 20),
|
||||
Text(
|
||||
widget.entry.kanji,
|
||||
style: Theme.of(context).textTheme.headline1,
|
||||
),
|
||||
],
|
||||
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),
|
||||
],
|
||||
),
|
||||
Positioned(
|
||||
@ -63,11 +83,20 @@ class _KanjiPageState extends State<KanjiPage> {
|
||||
child: NavigationButtons(
|
||||
middleText:
|
||||
widget.index == null ? 'N' : (widget.index! + 1).toString(),
|
||||
onMiddlePressed: () {
|
||||
if (isPressed) {
|
||||
controller.clear();
|
||||
widget.onNextCard();
|
||||
}
|
||||
setState(() => isPressed = !isPressed);
|
||||
},
|
||||
onNextCard: () => setState(() {
|
||||
controller.clear();
|
||||
isPressed = false;
|
||||
widget.onNextCard();
|
||||
}),
|
||||
onPreviousCard: () => setState(() {
|
||||
controller.clear();
|
||||
isPressed = false;
|
||||
widget.onPreviousCard();
|
||||
}),
|
||||
|
@ -121,9 +121,9 @@ class _PractiseViewState extends State<PractiseView> {
|
||||
Icon(Icons.edit),
|
||||
Icon(Icons.animation),
|
||||
],
|
||||
isSelected: _flashcardToggles,
|
||||
isSelected: _kanjiToggles,
|
||||
onPressed: (int index) =>
|
||||
setState(() => _flashcardToggles[index] = !_flashcardToggles[index])),
|
||||
setState(() => _kanjiToggles[index] = !_kanjiToggles[index])),
|
||||
],
|
||||
),
|
||||
centerTitle: true,
|
||||
|
26
lib/service/theme_bloc.dart
Normal file
26
lib/service/theme_bloc.dart
Normal file
@ -0,0 +1,26 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter/services.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> {
|
||||
final SharedPreferences prefs;
|
||||
|
||||
ThemeBloc({
|
||||
required this.prefs,
|
||||
required Brightness init,
|
||||
}) : super(init) {
|
||||
on<SetTheme>((event, emit) {
|
||||
prefs.setBool('darkTheme', event.isDark);
|
||||
emit(event.isDark ? Brightness.dark : Brightness.light);
|
||||
});
|
||||
}
|
||||
}
|
211
pubspec.lock
211
pubspec.lock
@ -1,6 +1,13 @@
|
||||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: archive
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.11"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -8,6 +15,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.8.2"
|
||||
bloc:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: bloc
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "8.0.2"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -43,6 +57,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.15.0"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -50,11 +71,32 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.2"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_bloc:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_bloc
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "8.0.1"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@ -67,6 +109,25 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_web_plugins:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
image:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.3"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -88,6 +149,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.7.0"
|
||||
nested:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: nested
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -95,6 +163,125 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.3"
|
||||
path_provider_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.5"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: petitparser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.4.0"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: plugin_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: process
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.2.4"
|
||||
provider:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.0.2"
|
||||
shared_preferences:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: shared_preferences
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.12"
|
||||
shared_preferences_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_android
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.10"
|
||||
shared_preferences_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_ios
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.9"
|
||||
shared_preferences_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.4"
|
||||
shared_preferences_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
shared_preferences_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
shared_preferences_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.3"
|
||||
shared_preferences_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.4"
|
||||
signature:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: signature
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.0.0"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@ -156,5 +343,27 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.3.10"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xdg_directories
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0+1"
|
||||
xml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.3.1"
|
||||
sdks:
|
||||
dart: ">=2.14.0 <3.0.0"
|
||||
dart: ">=2.15.0 <3.0.0"
|
||||
flutter: ">=2.5.0"
|
||||
|
@ -29,6 +29,9 @@ environment:
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
flutter_bloc: ^8.0.1
|
||||
shared_preferences: ^2.0.12
|
||||
signature: ^5.0.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
Loading…
Reference in New Issue
Block a user