Compare commits
2 Commits
29909a07a7
...
a572a6e6fc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a572a6e6fc | ||
|
|
6dabb9c977 |
BIN
assets/sfx/confirm.mp3
Normal file
BIN
assets/sfx/confirm.mp3
Normal file
Binary file not shown.
@@ -96,19 +96,27 @@ class VocabSrsItem {
|
||||
}) : lastAsked = lastAsked ?? DateTime.now();
|
||||
}
|
||||
|
||||
class PronunciationAudio {
|
||||
final String url;
|
||||
final String gender;
|
||||
|
||||
PronunciationAudio({required this.url, required this.gender});
|
||||
}
|
||||
|
||||
class VocabularyItem {
|
||||
final int id;
|
||||
final String characters;
|
||||
final List<String> meanings;
|
||||
final List<String> readings;
|
||||
final List<PronunciationAudio> pronunciationAudios;
|
||||
final Map<String, VocabSrsItem> srsItems = {};
|
||||
|
||||
VocabularyItem({
|
||||
required this.id,
|
||||
VocabularyItem(
|
||||
{required this.id,
|
||||
required this.characters,
|
||||
required this.meanings,
|
||||
required this.readings,
|
||||
});
|
||||
required this.pronunciationAudios});
|
||||
|
||||
factory VocabularyItem.fromSubject(Map<String, dynamic> subj) {
|
||||
final int id = subj['id'] as int;
|
||||
@@ -116,6 +124,7 @@ class VocabularyItem {
|
||||
final String characters = (data['characters'] ?? '') as String;
|
||||
final List<String> meanings = <String>[];
|
||||
final List<String> readings = <String>[];
|
||||
final List<PronunciationAudio> pronunciationAudios = <PronunciationAudio>[];
|
||||
|
||||
if (data['meanings'] != null) {
|
||||
for (final m in data['meanings'] as List) {
|
||||
@@ -129,11 +138,26 @@ class VocabularyItem {
|
||||
}
|
||||
}
|
||||
|
||||
if (data['pronunciation_audios'] != null) {
|
||||
for (final audio in data['pronunciation_audios'] as List) {
|
||||
final url = audio['url'] as String?;
|
||||
final metadata = audio['metadata'] as Map<String, dynamic>?;
|
||||
final gender = metadata?['gender'] as String?;
|
||||
|
||||
if (url != null && gender != null) {
|
||||
pronunciationAudios.add(PronunciationAudio(
|
||||
url: url,
|
||||
gender: gender,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return VocabularyItem(
|
||||
id: id,
|
||||
characters: characters,
|
||||
meanings: meanings,
|
||||
readings: readings,
|
||||
);
|
||||
pronunciationAudios: pronunciationAudios);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import '../services/deck_repository.dart';
|
||||
import '../services/distractor_generator.dart';
|
||||
import '../widgets/kanji_card.dart';
|
||||
import '../widgets/options_grid.dart';
|
||||
import 'package:audioplayers/audioplayers.dart';
|
||||
|
||||
import 'settings_screen.dart';
|
||||
|
||||
class _ReadingInfo {
|
||||
@@ -28,6 +30,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
String _status = 'Loading deck...';
|
||||
final DistractorGenerator _dg = DistractorGenerator();
|
||||
final Random _random = Random();
|
||||
final _audioPlayer = AudioPlayer();
|
||||
|
||||
QuizMode _mode = QuizMode.kanjiToEnglish;
|
||||
KanjiItem? _current;
|
||||
@@ -109,14 +112,20 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
|
||||
void _nextQuestion() {
|
||||
_deck.sort((a, b) {
|
||||
final aSrsItem = a.srsItems[_mode.toString()] ?? SrsItem(kanjiId: a.id, quizMode: _mode);
|
||||
final bSrsItem = b.srsItems[_mode.toString()] ?? SrsItem(kanjiId: b.id, quizMode: _mode);
|
||||
final aSrsItem = a.srsItems[_mode.toString()];
|
||||
final bSrsItem = b.srsItems[_mode.toString()];
|
||||
|
||||
final stageComparison = aSrsItem.srsStage.compareTo(bSrsItem.srsStage);
|
||||
if (stageComparison != 0) {
|
||||
return stageComparison;
|
||||
final aStage = aSrsItem?.srsStage ?? 0;
|
||||
final bStage = bSrsItem?.srsStage ?? 0;
|
||||
|
||||
if (aStage != bStage) {
|
||||
return aStage.compareTo(bStage);
|
||||
}
|
||||
return aSrsItem.lastAsked.compareTo(bSrsItem.lastAsked);
|
||||
|
||||
final aLastAsked = aSrsItem?.lastAsked ?? DateTime.fromMillisecondsSinceEpoch(0);
|
||||
final bLastAsked = bSrsItem?.lastAsked ?? DateTime.fromMillisecondsSinceEpoch(0);
|
||||
|
||||
return aLastAsked.compareTo(bLastAsked);
|
||||
});
|
||||
|
||||
_current = _deck.first;
|
||||
@@ -128,16 +137,19 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
switch (_mode) {
|
||||
case QuizMode.kanjiToEnglish:
|
||||
_correctAnswers = [_current!.meanings.first];
|
||||
_options = [_correctAnswers.first, ..._dg.generateMeanings(_current!, _deck, 3)]
|
||||
.map(_toTitleCase)
|
||||
.toList()
|
||||
_options = [
|
||||
_correctAnswers.first,
|
||||
..._dg.generateMeanings(_current!, _deck, 3)
|
||||
].map(_toTitleCase).toList()
|
||||
..shuffle();
|
||||
break;
|
||||
|
||||
case QuizMode.englishToKanji:
|
||||
_correctAnswers = [_current!.characters];
|
||||
_options = [_correctAnswers.first, ..._dg.generateKanji(_current!, _deck, 3)]
|
||||
..shuffle();
|
||||
_options = [
|
||||
_correctAnswers.first,
|
||||
..._dg.generateKanji(_current!, _deck, 3)
|
||||
]..shuffle();
|
||||
break;
|
||||
|
||||
case QuizMode.reading:
|
||||
@@ -149,10 +161,15 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
? _deck.expand((k) => k.onyomi)
|
||||
: _deck.expand((k) => k.kunyomi);
|
||||
|
||||
final distractors =
|
||||
readingsSource.where((r) => !_correctAnswers.contains(r)).toSet().toList()
|
||||
final distractors = readingsSource
|
||||
.where((r) => !_correctAnswers.contains(r))
|
||||
.toSet()
|
||||
.toList()
|
||||
..shuffle();
|
||||
_options = ([_correctAnswers[_random.nextInt(_correctAnswers.length)], ...distractors.take(3)])
|
||||
_options = ([
|
||||
_correctAnswers[_random.nextInt(_correctAnswers.length)],
|
||||
...distractors.take(3)
|
||||
])
|
||||
..shuffle();
|
||||
break;
|
||||
}
|
||||
@@ -176,29 +193,31 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
|
||||
var srsItem = current.srsItems[srsKey];
|
||||
final isNew = srsItem == null;
|
||||
srsItem ??= SrsItem(kanjiId: current.id, quizMode: _mode, readingType: readingType);
|
||||
|
||||
final srsItemForUpdate = srsItem ??=
|
||||
SrsItem(kanjiId: current.id, quizMode: _mode, readingType: readingType);
|
||||
setState(() {
|
||||
_asked += 1;
|
||||
if (isCorrect) {
|
||||
_score += 1;
|
||||
srsItem!.srsStage += 1;
|
||||
_audioPlayer.play(AssetSource('sfx/confirm.mp3'));
|
||||
} else {
|
||||
srsItem!.srsStage = max(0, srsItem.srsStage - 1);
|
||||
srsItemForUpdate.srsStage = max(0, srsItemForUpdate.srsStage - 1);
|
||||
}
|
||||
srsItem.lastAsked = DateTime.now();
|
||||
current.srsItems[srsKey] = srsItem;
|
||||
srsItemForUpdate.lastAsked = DateTime.now();
|
||||
current.srsItems[srsKey] = srsItemForUpdate;
|
||||
});
|
||||
|
||||
if (isNew) {
|
||||
await repo.insertSrsItem(srsItem);
|
||||
await repo.insertSrsItem(srsItemForUpdate);
|
||||
} else {
|
||||
await repo.updateSrsItem(srsItem);
|
||||
await repo.updateSrsItem(srsItemForUpdate);
|
||||
}
|
||||
|
||||
final correctDisplay = (_mode == QuizMode.kanjiToEnglish)
|
||||
? _toTitleCase(_correctAnswers.first)
|
||||
: (_mode == QuizMode.reading ? _correctAnswers.join(', ') : _correctAnswers.first);
|
||||
: (_mode == QuizMode.reading
|
||||
? _correctAnswers.join(', ')
|
||||
: _correctAnswers.first);
|
||||
|
||||
final snack = SnackBar(
|
||||
content: Text(
|
||||
@@ -271,7 +290,6 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
Wrap(
|
||||
spacing: 6,
|
||||
runSpacing: 4,
|
||||
@@ -282,9 +300,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
_buildChoiceChip('Reading', QuizMode.reading),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 18),
|
||||
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Center(
|
||||
@@ -303,9 +319,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 12),
|
||||
|
||||
SafeArea(
|
||||
top: false,
|
||||
child: Column(
|
||||
|
||||
@@ -6,11 +6,13 @@ import '../services/deck_repository.dart';
|
||||
import '../services/distractor_generator.dart';
|
||||
import '../widgets/kanji_card.dart';
|
||||
import '../widgets/options_grid.dart';
|
||||
import 'package:audioplayers/audioplayers.dart';
|
||||
import 'settings_screen.dart';
|
||||
|
||||
class VocabScreen extends StatefulWidget {
|
||||
const VocabScreen({super.key});
|
||||
|
||||
@override
|
||||
State<VocabScreen> createState() => _VocabScreenState();
|
||||
}
|
||||
|
||||
@@ -19,7 +21,7 @@ class _VocabScreenState extends State<VocabScreen> {
|
||||
bool _loading = false;
|
||||
String _status = 'Loading deck...';
|
||||
final DistractorGenerator _dg = DistractorGenerator();
|
||||
final Random _random = Random();
|
||||
final _audioPlayer = AudioPlayer();
|
||||
|
||||
VocabQuizMode _mode = VocabQuizMode.vocabToEnglish;
|
||||
VocabularyItem? _current;
|
||||
@@ -55,7 +57,8 @@ class _VocabScreenState extends State<VocabScreen> {
|
||||
}
|
||||
|
||||
var items = await repo.loadVocabulary();
|
||||
if (items.isEmpty) {
|
||||
if (items.isEmpty ||
|
||||
items.every((item) => item.pronunciationAudios.isEmpty)) {
|
||||
setState(() {
|
||||
_status = 'Fetching deck...';
|
||||
});
|
||||
@@ -138,17 +141,18 @@ class _VocabScreenState extends State<VocabScreen> {
|
||||
|
||||
final srsKey = _mode.toString();
|
||||
|
||||
var srsItem = current.srsItems[srsKey];
|
||||
final isNew = srsItem == null;
|
||||
srsItem ??= VocabSrsItem(vocabId: current.id, quizMode: _mode);
|
||||
var srsItemNullable = current.srsItems[srsKey];
|
||||
final isNew = srsItemNullable == null;
|
||||
final srsItem =
|
||||
srsItemNullable ?? VocabSrsItem(vocabId: current.id, quizMode: _mode);
|
||||
|
||||
setState(() {
|
||||
_asked += 1;
|
||||
if (isCorrect) {
|
||||
_score += 1;
|
||||
srsItem!.srsStage += 1;
|
||||
srsItem.srsStage += 1;
|
||||
} else {
|
||||
srsItem!.srsStage = max(0, srsItem.srsStage - 1);
|
||||
srsItem.srsStage = max(0, srsItem.srsStage - 1);
|
||||
}
|
||||
srsItem.lastAsked = DateTime.now();
|
||||
current.srsItems[srsKey] = srsItem;
|
||||
@@ -179,7 +183,23 @@ class _VocabScreenState extends State<VocabScreen> {
|
||||
ScaffoldMessenger.of(context).showSnackBar(snack);
|
||||
}
|
||||
|
||||
Future.delayed(const Duration(milliseconds: 900), _nextQuestion);
|
||||
if (isCorrect) {
|
||||
await _audioPlayer.play(AssetSource('sfx/confirm.mp3'));
|
||||
final maleAudios =
|
||||
current.pronunciationAudios.where((a) => a.gender == 'male');
|
||||
if (maleAudios.isNotEmpty) {
|
||||
try {
|
||||
await _audioPlayer.play(UrlSource(maleAudios.first.url));
|
||||
} catch (e) {
|
||||
// Ignore player errors
|
||||
}
|
||||
}
|
||||
await Future.delayed(const Duration(milliseconds: 400));
|
||||
} else {
|
||||
await Future.delayed(const Duration(milliseconds: 900));
|
||||
}
|
||||
|
||||
_nextQuestion();
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'package:path/path.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
@@ -23,7 +24,7 @@ class DeckRepository {
|
||||
|
||||
_db = await openDatabase(
|
||||
path,
|
||||
version: 5,
|
||||
version: 6,
|
||||
onCreate: (db, version) async {
|
||||
await db.execute(
|
||||
'''CREATE TABLE kanji (id INTEGER PRIMARY KEY, characters TEXT, meanings TEXT, onyomi TEXT, kunyomi TEXT)''');
|
||||
@@ -32,7 +33,7 @@ class DeckRepository {
|
||||
await db.execute(
|
||||
'''CREATE TABLE srs_items (kanjiId INTEGER, quizMode TEXT, readingType TEXT, srsStage INTEGER, lastAsked TEXT, PRIMARY KEY (kanjiId, quizMode, readingType))''');
|
||||
await db.execute(
|
||||
'''CREATE TABLE vocabulary (id INTEGER PRIMARY KEY, characters TEXT, meanings TEXT, readings TEXT)''');
|
||||
'''CREATE TABLE vocabulary (id INTEGER PRIMARY KEY, characters TEXT, meanings TEXT, readings TEXT, pronunciation_audios TEXT)''');
|
||||
await db.execute(
|
||||
'''CREATE TABLE srs_vocab_items (vocabId INTEGER, quizMode TEXT, srsStage INTEGER, lastAsked TEXT, PRIMARY KEY (vocabId, quizMode))''');
|
||||
},
|
||||
@@ -56,6 +57,13 @@ class DeckRepository {
|
||||
await db.execute(
|
||||
'''CREATE TABLE srs_vocab_items (vocabId INTEGER, quizMode TEXT, srsStage INTEGER, lastAsked TEXT, PRIMARY KEY (vocabId, quizMode))''');
|
||||
}
|
||||
if (oldVersion < 6) {
|
||||
try {
|
||||
await db.execute('ALTER TABLE vocabulary ADD COLUMN pronunciation_audios TEXT');
|
||||
} catch (_) {
|
||||
// Ignore error, column might already exist
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
@@ -257,6 +265,9 @@ class DeckRepository {
|
||||
final db = await _openDb();
|
||||
final batch = db.batch();
|
||||
for (final it in items) {
|
||||
final audios = it.pronunciationAudios
|
||||
.map((a) => {'url': a.url, 'gender': a.gender})
|
||||
.toList();
|
||||
batch.insert(
|
||||
'vocabulary',
|
||||
{
|
||||
@@ -264,6 +275,7 @@ class DeckRepository {
|
||||
'characters': it.characters,
|
||||
'meanings': it.meanings.join('|'),
|
||||
'readings': it.readings.join('|'),
|
||||
'pronunciation_audios': jsonEncode(audios),
|
||||
},
|
||||
conflictAlgorithm: ConflictAlgorithm.replace,
|
||||
);
|
||||
@@ -275,7 +287,23 @@ class DeckRepository {
|
||||
final db = await _openDb();
|
||||
final rows = await db.query('vocabulary');
|
||||
final vocabItems = rows
|
||||
.map((r) => VocabularyItem(
|
||||
.map((r) {
|
||||
final audiosRaw = r['pronunciation_audios'] as String?;
|
||||
final List<PronunciationAudio> audios = [];
|
||||
if (audiosRaw != null && audiosRaw.isNotEmpty) {
|
||||
try {
|
||||
final decoded = jsonDecode(audiosRaw) as List;
|
||||
for (final audioData in decoded) {
|
||||
audios.add(PronunciationAudio(
|
||||
url: audioData['url'] as String,
|
||||
gender: audioData['gender'] as String,
|
||||
));
|
||||
}
|
||||
} catch (e) {
|
||||
// Error decoding, so we'll just have no audio for this item
|
||||
}
|
||||
}
|
||||
return VocabularyItem(
|
||||
id: r['id'] as int,
|
||||
characters: r['characters'] as String,
|
||||
meanings: (r['meanings'] as String)
|
||||
@@ -286,7 +314,9 @@ class DeckRepository {
|
||||
.split('|')
|
||||
.where((s) => s.isNotEmpty)
|
||||
.toList(),
|
||||
))
|
||||
pronunciationAudios: audios,
|
||||
);
|
||||
})
|
||||
.toList();
|
||||
|
||||
for (final item in vocabItems) {
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <audioplayers_linux/audioplayers_linux_plugin.h>
|
||||
|
||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||
g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "AudioplayersLinuxPlugin");
|
||||
audioplayers_linux_plugin_register_with_registrar(audioplayers_linux_registrar);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
audioplayers_linux
|
||||
)
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
|
||||
@@ -5,11 +5,13 @@
|
||||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import audioplayers_darwin
|
||||
import path_provider_foundation
|
||||
import shared_preferences_foundation
|
||||
import sqflite_darwin
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||
|
||||
72
pubspec.lock
72
pubspec.lock
@@ -41,6 +41,62 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.13.0"
|
||||
audioplayers:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: audioplayers
|
||||
sha256: "5441fa0ceb8807a5ad701199806510e56afde2b4913d9d17c2f19f2902cf0ae4"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.5.1"
|
||||
audioplayers_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: audioplayers_android
|
||||
sha256: "60a6728277228413a85755bd3ffd6fab98f6555608923813ce383b190a360605"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.2.1"
|
||||
audioplayers_darwin:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: audioplayers_darwin
|
||||
sha256: "0811d6924904ca13f9ef90d19081e4a87f7297ddc19fc3d31f60af1aaafee333"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.3.0"
|
||||
audioplayers_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: audioplayers_linux
|
||||
sha256: f75bce1ce864170ef5e6a2c6a61cd3339e1a17ce11e99a25bae4474ea491d001
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.2.1"
|
||||
audioplayers_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: audioplayers_platform_interface
|
||||
sha256: "0e2f6a919ab56d0fec272e801abc07b26ae7f31980f912f24af4748763e5a656"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.1.1"
|
||||
audioplayers_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: audioplayers_web
|
||||
sha256: "1c0f17cec68455556775f1e50ca85c40c05c714a99c5eb1d2d57cc17ba5522d7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.1.1"
|
||||
audioplayers_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: audioplayers_windows
|
||||
sha256: "4048797865105b26d47628e6abb49231ea5de84884160229251f37dfcbe52fd7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.2.1"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -693,6 +749,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.1"
|
||||
sprintf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sprintf
|
||||
sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.0"
|
||||
sqflite:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -821,6 +885,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: uuid
|
||||
sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.5.1"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -13,6 +13,7 @@ dependencies:
|
||||
path: ^1.9.1
|
||||
provider: ^6.1.5+1
|
||||
http: ^1.5.0
|
||||
audioplayers: ^6.0.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
@@ -28,3 +29,5 @@ flutter_icons:
|
||||
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
assets:
|
||||
- assets/sfx/confirm.mp3
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <audioplayers_windows/audioplayers_windows_plugin.h>
|
||||
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
AudioplayersWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin"));
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
audioplayers_windows
|
||||
)
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
|
||||
Reference in New Issue
Block a user