Add themes and drawing field for kanji

This commit is contained in:
Oystein Kristoffer Tveit 2022-02-04 04:22:35 +01:00
parent 4a98522973
commit fef9733ad7
10 changed files with 365 additions and 40 deletions

View File

@ -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

View File

@ -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(

View File

@ -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,
),
),
);
}

View File

@ -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)),
],
),
);

View File

@ -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;

View File

@ -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();
}),

View File

@ -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,

View 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);
});
}
}

View File

@ -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"

View File

@ -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: