This commit is contained in:
Oystein Kristoffer Tveit 2024-11-13 22:43:44 +01:00
parent 5ba64bbb46
commit 4fe36c4b0c
Signed by: oysteikt
GPG Key ID: 9F2F7D8250F35146
16 changed files with 618 additions and 460 deletions

View File

@ -26,6 +26,7 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
namespace = "app.jishostudytool.jisho_study_tool"
compileSdkVersion flutter.compileSdkVersion
compileOptions {
@ -45,7 +46,7 @@ android {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "app.jishostudytool.jisho_study_tool"
// minSdkVersion flutter.minSdkVersion
minSdkVersion 19
minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName

View File

@ -1,20 +0,0 @@
// Generated file.
// If you wish to remove Flutter's multidex support, delete this entire file.
package io.flutter.app;
import android.content.Context;
import androidx.annotation.CallSuper;
import androidx.multidex.MultiDex;
/**
* Extension of {@link io.flutter.app.FlutterApplication}, adding multidex support.
*/
public class FlutterMultiDexApplication extends FlutterApplication {
@Override
@CallSuper
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}

View File

@ -1,12 +1,12 @@
buildscript {
ext.kotlin_version = '1.6.10'
ext.kotlin_version = '1.9.22'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.android.tools.build:gradle:8.7.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
@ -26,6 +26,6 @@ subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
tasks.register("clean", Delete) {
delete rootProject.buildDir
}

View File

@ -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-8.9-all.zip

View File

@ -5,10 +5,10 @@ import '../../routing/routes.dart';
import '../../settings.dart';
import 'language_selector.dart';
class SearchBar extends StatelessWidget {
class GlobalSearchBar extends StatelessWidget {
final TextEditingController controller = TextEditingController();
SearchBar({Key? key}) : super(key: key);
GlobalSearchBar({Key? key}) : super(key: key);
void _search(BuildContext context, String text) => Navigator.pushNamed(
context,

View File

@ -1,10 +1,10 @@
import 'package:flutter/material.dart';
class Badge extends StatelessWidget {
class CircleBadge extends StatelessWidget {
final Widget? child;
final Color color;
const Badge({
const CircleBadge({
Key? key,
this.child,
required this.color,

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import './badge.dart';
import 'circle_badge.dart';
class CommonBadge extends StatelessWidget {
final bool isCommon;
@ -11,7 +11,7 @@ class CommonBadge extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Badge(
return CircleBadge(
color: isCommon ? Colors.green : Colors.transparent,
child: Text(
'C',

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import './badge.dart';
import 'circle_badge.dart';
class JLPTBadge extends StatelessWidget {
final String? jlptLevel;
@ -14,7 +14,7 @@ class JLPTBadge extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Badge(
return CircleBadge(
color: jlptLevel != null ? Colors.blue : Colors.transparent,
child: Text(
formattedJlptLevel,

View File

@ -24,7 +24,11 @@ Widget _wiki({
margin: EdgeInsets.fromLTRB(0, 0, 10, isJapanese ? 12 : 10),
child: IconButton(
onPressed: () => open_webpage(link),
icon: SvgPicture.asset('assets/images/links/wikipedia.svg'),
icon: SvgPicture.asset(
'assets/images/links/wikipedia.svg',
height: 50,
width: 50,
),
),
),
Container(
@ -52,6 +56,8 @@ Widget _dbpedia(String link) => Container(
onPressed: () => open_webpage(link),
icon: Image.asset(
'assets/images/links/dbpedia.png',
height: 50,
width: 50,
),
),
);

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import './badge.dart';
import 'circle_badge.dart';
class WKBadge extends StatelessWidget {
final String level;
@ -15,7 +15,7 @@ class WKBadge extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Badge(
return CircleBadge(
color: level.isNotEmpty ? Colors.red : Colors.transparent,
child: Text(
_extractWkLevel(level),

View File

@ -30,9 +30,8 @@ class Search {
Map<String, Object?> toJson() => {
'timestamps': [for (final ts in timestamps) ts.millisecondsSinceEpoch],
'lastTimestamp': timestamps.last.millisecondsSinceEpoch,
'wordQuery': wordQuery?.toJson(),
'kanjiQuery': kanjiQuery?.toJson(),
'word': wordQuery?.toJson(),
'kanji': kanjiQuery?.toJson(),
};
factory Search.fromJson(Map<String, dynamic> json) {
@ -41,13 +40,13 @@ class Search {
DateTime.fromMillisecondsSinceEpoch(ts as int)
];
return json['wordQuery'] != null
return json['word'] != null
? Search.fromWordQuery(
wordQuery: WordQuery.fromJson(json['wordQuery']),
wordQuery: WordQuery.fromJson(json['word']),
timestamps: timestamps,
)
: Search.fromKanjiQuery(
kanjiQuery: KanjiQuery.fromJson(json['kanjiQuery']),
kanjiQuery: KanjiQuery.fromJson(json['kanji']),
timestamps: timestamps,
);
}

View File

@ -15,7 +15,7 @@ class AboutView extends StatelessWidget {
const SizedBox(height: _verticalSeparation),
Text(
'Jisho Study Tool',
style: Theme.of(context).textTheme.headline5,
style: Theme.of(context).textTheme.headlineSmall,
),
const SizedBox(height: _verticalSeparation),
Row(
@ -32,7 +32,7 @@ class AboutView extends StatelessWidget {
const SizedBox(height: _verticalSeparation),
Text(
'Version: $appVersion',
style: Theme.of(context).textTheme.bodyText2,
style: Theme.of(context).textTheme.headlineLarge,
),
const SizedBox(height: _verticalSeparation),
],
@ -56,13 +56,13 @@ class AboutView extends StatelessWidget {
'Jisho Study Tool is a frontend for Jisho.org, a a powerful Japanese-English dictionary. '
"It's made to aid you in your journey towards Japanese proficiency. "
'More features to come!',
style: Theme.of(context).textTheme.bodyText2,
style: Theme.of(context).textTheme.bodyMedium,
),
),
const SizedBox(height: 2 * _verticalSeparation),
Text('Contact:', style: Theme.of(context).textTheme.headline6),
Text('Contact:', style: Theme.of(context).textTheme.headlineSmall),
const SizedBox(height: _verticalSeparation),
IntrinsicHeight(
child: Row(
@ -105,7 +105,7 @@ class AboutView extends StatelessWidget {
const SizedBox(height: _verticalSeparation),
Text(
'File a bug report:',
style: Theme.of(context).textTheme.headline6,
style: Theme.of(context).textTheme.headlineSmall,
),
InkWell(
onTap: () => open_webpage(
@ -126,7 +126,7 @@ class AboutView extends StatelessWidget {
'I would really appreciate it if you send in some bug reports! '
'If you find something weird, '
'please send me a mail, or open an issue on GitHub.',
style: Theme.of(context).textTheme.bodyText2,
style: Theme.of(context).textTheme.bodyMedium,
),
const SizedBox(height: _verticalSeparation),
Center(
@ -134,7 +134,7 @@ class AboutView extends StatelessWidget {
'頑張れ!',
style: Theme.of(context)
.textTheme
.headline5
.headlineSmall
?.merge(japaneseFont.textStyle),
),
),

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import '../../components/search/search_bar.dart';
import '../../components/search/global_search_bar.dart';
class SearchView extends StatelessWidget {
const SearchView({Key? key}) : super(key: key);
@ -8,7 +8,7 @@ class SearchView extends StatelessWidget {
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[SearchBar()],
children: <Widget>[GlobalSearchBar()],
);
}
}

View File

@ -92,11 +92,12 @@ class _SettingsViewState extends State<SettingsView> {
.toList();
late final List<Search> importedSearches;
try {
importedSearches = ((((jsonDecode(await file.readAsString())
as Map<String, Object?>)['stores']! as List)
.map((e) => e as Map)
.where((e) => e['name'] == 'search')
.first)['values'] as List)
importedSearches = (jsonDecode(await file.readAsString()) as List<dynamic>)
// importedSearches = (((jsonDecode(await file.readAsString())
// as Map<String, Object?>)['stores']! as List<Object?>)
// .map((e) => e! as Map<String, Object?>)
// .where((e) => e['name'] == 'search')
// .first['values'] as List<dynamic>)
.map((item) => Search.fromJson(item))
.toList();
} catch (e) {
@ -166,81 +167,81 @@ class _SettingsViewState extends State<SettingsView> {
@override
Widget build(BuildContext context) => BlocBuilder<ThemeBloc, ThemeState>(
builder: (context, state) {
final TextStyle _titleTextStyle = TextStyle(
color:
state is DarkThemeState ? AppTheme.jishoGreen.background : null,
);
// final TextStyle _titleTextStyle = TextStyle(
// color:
// state is DarkThemeState ? AppTheme.jishoGreen.background : null,
// );
const SettingsTileTheme theme = SettingsTileTheme(
horizontalTitleGap: 0,
);
// const SettingsTileTheme theme = SettingsTileTheme(
// horizontalTitleGap: 0,
// );
return SettingsList(
backgroundColor: Colors.transparent,
// backgroundColor: Colors.transparent,
contentPadding: const EdgeInsets.symmetric(vertical: 10),
sections: <SettingsSection>[
SettingsSection(
title: 'Dictionary',
titleTextStyle: _titleTextStyle,
title: const Text('Dictionary'),
// titleTextStyle: _titleTextStyle,
tiles: <SettingsTile>[
SettingsTile.switchTile(
title: 'Use romaji',
title: const Text('Use romaji'),
leading: const Icon(Mdi.alphabetical),
onToggle: (b) => setState(() => romajiEnabled = b),
switchValue: romajiEnabled,
theme: theme,
switchActiveColor: AppTheme.jishoGreen.background,
initialValue: romajiEnabled,
// theme: theme,
activeSwitchColor: AppTheme.jishoGreen.background,
),
SettingsTile.switchTile(
title: 'Extensive search',
title: const Text('Extensive search'),
leading: const Icon(Icons.downloading),
onToggle: (b) => setState(() => extensiveSearchEnabled = b),
switchValue: extensiveSearchEnabled,
theme: theme,
switchActiveColor: AppTheme.jishoGreen.background,
initialValue: extensiveSearchEnabled,
// theme: theme,
activeSwitchColor: AppTheme.jishoGreen.background,
// subtitle:
// 'Gathers extra data when searching for words, at the expense of having to wait for extra word details.',
// subtitleWidget:
trailing: const Icon(Icons.info),
subtitleMaxLines: 3,
// subtitleMaxLines: 3,
),
SettingsTile(
title: 'Japanese font',
title: const Text('Japanese font'),
leading: const Icon(Icons.format_size),
onPressed: changeFont,
theme: theme,
// theme: theme,
trailing: Text(japaneseFont.name),
// subtitle:
// 'Which font to use for japanese text. This might be useful if your phone shows kanji with a Chinese font.',
subtitleMaxLines: 3,
// subtitleMaxLines: 3,
),
],
),
SettingsSection(
title: 'Theme',
titleTextStyle: _titleTextStyle,
title: const Text('Theme'),
// titleTextStyle: _titleTextStyle,
tiles: <SettingsTile>[
SettingsTile.switchTile(
title: 'Automatic theme',
title: const Text('Automatic theme'),
leading: const Icon(Icons.brightness_auto),
onToggle: toggleAutoTheme,
switchValue: autoThemeEnabled,
theme: theme,
switchActiveColor: AppTheme.jishoGreen.background,
initialValue: autoThemeEnabled,
// theme: theme,
activeSwitchColor: AppTheme.jishoGreen.background,
),
SettingsTile.switchTile(
title: 'Dark Theme',
title: const Text('Dark Theme'),
leading: const Icon(Icons.dark_mode),
onToggle: (b) {
BlocProvider.of<ThemeBloc>(context)
.add(SetTheme(themeIsDark: b));
setState(() => darkThemeEnabled = b);
},
switchValue: darkThemeEnabled,
initialValue: darkThemeEnabled,
enabled: !autoThemeEnabled,
theme: theme,
switchActiveColor: AppTheme.jishoGreen.background,
// theme: theme,
activeSwitchColor: AppTheme.jishoGreen.background,
),
],
),
@ -282,53 +283,53 @@ class _SettingsViewState extends State<SettingsView> {
// ),
SettingsSection(
title: 'Data',
titleTextStyle: _titleTextStyle,
title: const Text('Data'),
// titleTextStyle: _titleTextStyle,
tiles: <SettingsTile>[
SettingsTile(
leading: const Icon(Icons.file_upload),
title: 'Import Data',
title: const Text('Import Data'),
onPressed: importData,
enabled: Platform.isAndroid,
subtitle:
Platform.isAndroid ? null : 'Not available on iOS yet',
subtitleWidget: dataImportIsLoading
? const LinearProgressIndicator()
: null,
// subtitle:
// Platform.isAndroid ? null : 'Not available on iOS yet',
// subtitleWidget: dataImportIsLoading
// ? const LinearProgressIndicator()
// : null,
),
SettingsTile(
leading: const Icon(Icons.file_download),
title: 'Export Data',
title: const Text('Export Data'),
enabled: Platform.isAndroid,
subtitle:
Platform.isAndroid ? null : 'Not available on iOS yet',
subtitleWidget: dataExportIsLoading
? const LinearProgressIndicator()
: null,
// subtitle:
// Platform.isAndroid ? null : 'Not available on iOS yet',
// subtitleWidget: dataExportIsLoading
// ? const LinearProgressIndicator()
// : null,
),
SettingsTile(
leading: const Icon(Icons.delete),
title: 'Clear History',
title: const Text('Clear History'),
onPressed: clearHistory,
titleTextStyle: const TextStyle(color: Colors.red),
// titleTextStyle: const TextStyle(color: Colors.red),
),
SettingsTile(
leading: const Icon(Icons.delete),
title: 'Clear Favourites',
title: const Text('Clear Favourites'),
onPressed: (c) {},
titleTextStyle: const TextStyle(color: Colors.red),
// titleTextStyle: const TextStyle(color: Colors.red),
enabled: false,
)
),
],
),
SettingsSection(
title: 'Info',
titleTextStyle: _titleTextStyle,
title: const Text('Info'),
// titleTextStyle: _titleTextStyle,
tiles: <SettingsTile>[
SettingsTile(
leading: const Icon(Icons.info),
title: 'About',
title: const Text('About'),
onPressed: (c) =>
Navigator.pushNamed(context, Routes.about),
),
@ -337,17 +338,17 @@ class _SettingsViewState extends State<SettingsView> {
'assets/images/logo/logo_icon_transparent_green.png',
width: 30,
),
title: 'Jisho',
title: const Text('Jisho'),
onPressed: (c) => open_webpage('https://jisho.org/about'),
),
SettingsTile(
leading: const Icon(Icons.copyright),
title: 'Licenses',
title: const Text('Licenses'),
onPressed: (c) =>
Navigator.pushNamed(context, Routes.aboutLicenses),
),
],
)
),
],
);
},

File diff suppressed because it is too large Load Diff

View File

@ -3,40 +3,40 @@ description: A dictionary app for studying japanese
version: 1.0.0+1
environment:
sdk: ">=2.12.0 <3.0.0"
sdk: ">=3.2.0<4.0.0"
dependencies:
animated_size_and_fade: ^3.0.0
animated_size_and_fade: ^5.0.0
collection: ^1.15.0
confirm_dialog: ^1.0.0
division: ^0.9.0
file_picker: ^4.5.1
file_picker: ^8.1.4
flutter:
sdk: flutter
flutter_bloc: ^8.0.0
flutter_settings_ui: ^2.0.1
flutter_slidable: ^1.1.0
flutter_svg: ^1.0.2
get_it: ^7.2.0
http: ^0.13.4
flutter_bloc: ^8.1.3
flutter_settings_ui: ^3.0.0
flutter_slidable: ^3.0.1
flutter_svg: ^2.0.9
get_it: ^8.0.2
http: ^0.13.0
just_audio: ^0.9.18
mdi: ^5.0.0-nullsafety.0
path: ^1.8.0
path_provider: ^2.0.2
sembast: ^3.1.1
share_plus: ^4.0.4
test: ^1.19.5
shared_preferences: ^2.0.6
sembast: ^3.5.0
share_plus: ^10.1.2
test: ^1.24.9
shared_preferences: ^2.2.2
signature: ^5.0.0
unofficial_jisho_api: ^3.0.0
url_launcher: ^6.0.9
url_launcher: ^6.2.4
dev_dependencies:
build_runner: ^2.0.6
flutter_test:
sdk: flutter
flutter_native_splash: ^2.1.6
flutter_launcher_icons: "^0.9.2"
flutter_launcher_icons: ^0.14.1
flutter_icons:
android: "launcher_icon"