From 230e6ee07ae241a4b0afe113d85b8586b4bc3054 Mon Sep 17 00:00:00 2001 From: Misaka Date: Mon, 11 May 2026 20:13:03 +0800 Subject: [PATCH] feat: add sound and vibration feedback for registration actions Integrate audioplayers, vibration, and file_picker packages to provide audio/haptic feedback on registration success/failure. Add sound settings UI in SettingsPage for customizing notification sounds. Co-Authored-By: Claude Opus 4.6 --- .gitignore | 1 + lib/pages/registration_page.dart | 47 ++- lib/pages/settings_page.dart | 160 ++++++++- lib/services/sound_service.dart | 59 ++++ linux/flutter/generated_plugin_registrant.cc | 4 + linux/flutter/generated_plugins.cmake | 2 + macos/Flutter/GeneratedPluginRegistrant.swift | 6 + pubspec.lock | 316 +++++++++++++++++- pubspec.yaml | 3 + .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 2 + 11 files changed, 596 insertions(+), 7 deletions(-) create mode 100644 lib/services/sound_service.dart diff --git a/.gitignore b/.gitignore index 93364ab..0f3c4be 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ migrate_working_dir/ .pub-cache/ .pub/ /build/ +android/build/ # Symbolication related app.*.symbols diff --git a/lib/pages/registration_page.dart b/lib/pages/registration_page.dart index c952ff2..9ff642f 100644 --- a/lib/pages/registration_page.dart +++ b/lib/pages/registration_page.dart @@ -1,8 +1,11 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:vibration/vibration.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:pad_scanner/services/scanner_service.dart'; import 'package:pad_scanner/services/code_parser.dart'; import 'package:pad_scanner/services/api_service.dart'; +import 'package:pad_scanner/services/sound_service.dart'; import 'package:pad_scanner/pages/settings_page.dart'; class RegistrationPage extends StatefulWidget { @@ -15,6 +18,8 @@ class RegistrationPage extends StatefulWidget { class _RegistrationPageState extends State { final _scannerService = ScannerService(); final _apiService = ApiService(); + final _soundService = SoundService(); + final _focusNode = FocusNode(); final _zongpaiNos = []; String? _locationCode; @@ -30,6 +35,23 @@ class _RegistrationPageState extends State { void initState() { super.initState(); _scannerService.scanResults.listen(_onScan); + WidgetsBinding.instance.addPostFrameCallback((_) { + _focusNode.requestFocus(); + }); + } + + @override + void dispose() { + _focusNode.dispose(); + _soundService.dispose(); + super.dispose(); + } + + void _onKeyEvent(KeyEvent event) { + if (event is KeyDownEvent && + event.logicalKey == LogicalKeyboardKey.enter) { + _submit(); + } } void _onScan(ScanResult result) { @@ -137,6 +159,7 @@ class _RegistrationPageState extends State { setState(() => _isSubmitting = false); if (result.success) { + _vibrateSuccess(); setState(() { _zongpaiNos.remove(zongpaiNo); if (!_isLocked) { @@ -151,8 +174,10 @@ class _RegistrationPageState extends State { if (mounted) setState(() => _successMessage = null); }); } else if (result.isDuplicate) { + _vibrateError(); _showDuplicateDialog(zongpaiNo, result.duplicateInfo); } else { + _vibrateError(); _showFeedback(result.errorMessage ?? '提交失败', isError: true); } } @@ -193,12 +218,24 @@ class _RegistrationPageState extends State { }); if (failed.isEmpty) { + _vibrateSuccess(); _showFeedback('批量上架成功($successCount 条)', isError: false); } else { + _vibrateError(); _showFeedback('成功 $successCount 条,失败 ${failed.length} 条', isError: true); } } + void _vibrateSuccess() { + Vibration.vibrate(duration: 200); + _soundService.playSuccess(); + } + + void _vibrateError() { + Vibration.vibrate(duration: 1000); + _soundService.playFailure(); + } + void _showDuplicateDialog(String zongpaiNo, Map? info) { showDialog( context: context, @@ -266,8 +303,11 @@ class _RegistrationPageState extends State { Widget build(BuildContext context) { final colorScheme = Theme.of(context).colorScheme; - return Scaffold( - appBar: AppBar( + return KeyboardListener( + focusNode: _focusNode, + onKeyEvent: _onKeyEvent, + child: Scaffold( + appBar: AppBar( title: const Text('上架登记'), actions: [ Padding( @@ -551,7 +591,7 @@ class _RegistrationPageState extends State { : Text( _isLocked && _zongpaiNos.length > 1 ? '批量上架(${_zongpaiNos.length} 条)' - : '确 认 上 架', + : '确认上架(P1)', style: const TextStyle(fontSize: 18), ), ), @@ -593,6 +633,7 @@ class _RegistrationPageState extends State { ), ], ), + ), ); } } diff --git a/lib/pages/settings_page.dart b/lib/pages/settings_page.dart index bbbb8cf..d7858eb 100644 --- a/lib/pages/settings_page.dart +++ b/lib/pages/settings_page.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:file_picker/file_picker.dart'; import 'package:pad_scanner/services/api_service.dart'; +import 'package:pad_scanner/services/sound_service.dart'; class SettingsPage extends StatefulWidget { const SettingsPage({super.key}); @@ -12,13 +14,18 @@ class SettingsPage extends StatefulWidget { class _SettingsPageState extends State { final _controller = TextEditingController(); final _apiService = ApiService(); + final _soundService = SoundService(); bool _saving = false; bool _testing = false; + String? _successPath; + String? _failurePath; + @override void initState() { super.initState(); _loadUrl(); + _loadSoundPaths(); } Future _loadUrl() async { @@ -27,6 +34,17 @@ class _SettingsPageState extends State { _controller.text = url; } + Future _loadSoundPaths() async { + final s = await _soundService.getSuccessPath(); + final f = await _soundService.getFailurePath(); + if (mounted) { + setState(() { + _successPath = s; + _failurePath = f; + }); + } + } + Future _saveUrl() async { final url = _controller.text.trim(); if (url.isEmpty) { @@ -59,11 +77,57 @@ class _SettingsPageState extends State { } } + Future _pickSound(bool isSuccess) async { + final result = await FilePicker.pickFiles( + type: FileType.audio, + ); + if (result != null && result.files.single.path != null) { + final path = result.files.single.path!; + if (isSuccess) { + await _soundService.setSuccessPath(path); + } else { + await _soundService.setFailurePath(path); + } + setState(() { + if (isSuccess) { + _successPath = path; + } else { + _failurePath = path; + } + }); + } + } + + Future _clearSound(bool isSuccess) async { + if (isSuccess) { + await _soundService.setSuccessPath(null); + } else { + await _soundService.setFailurePath(null); + } + setState(() { + if (isSuccess) { + _successPath = null; + } else { + _failurePath = null; + } + }); + } + + Future _previewSound(String path) async { + await _soundService.play(path); + } + + String _fileName(String? path) { + if (path == null) return '未设置'; + return path.split('/').last; + } + void _showSnackBar(String message, {bool isError = false}) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(message), - backgroundColor: isError ? Colors.red.shade700 : Colors.green.shade700, + backgroundColor: + isError ? Colors.red.shade700 : Colors.green.shade700, duration: const Duration(seconds: 2), ), ); @@ -72,6 +136,7 @@ class _SettingsPageState extends State { @override void dispose() { _controller.dispose(); + _soundService.dispose(); super.dispose(); } @@ -79,11 +144,12 @@ class _SettingsPageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('设置')), - body: Padding( + body: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ + // ---- API 地址 ---- const Text('API 服务器地址', style: TextStyle(fontSize: 14)), const SizedBox(height: 8), TextField( @@ -118,9 +184,99 @@ class _SettingsPageState extends State { : const Icon(Icons.wifi), label: const Text('测试连接'), ), + + const SizedBox(height: 24), + + // ---- 铃声设置 ---- + const Divider(), + const SizedBox(height: 8), + const Text('铃声设置', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), + const SizedBox(height: 16), + + // 上架成功铃声 + _buildSoundRow( + label: '上架成功铃声', + path: _successPath, + onPick: () => _pickSound(true), + onPreview: _successPath != null + ? () => _previewSound(_successPath!) + : null, + onClear: _successPath != null ? () => _clearSound(true) : null, + ), + + const SizedBox(height: 12), + + // 上架失败铃声 + _buildSoundRow( + label: '上架失败铃声', + path: _failurePath, + onPick: () => _pickSound(false), + onPreview: _failurePath != null + ? () => _previewSound(_failurePath!) + : null, + onClear: + _failurePath != null ? () => _clearSound(false) : null, + ), ], ), ), ); } + + Widget _buildSoundRow({ + required String label, + required String? path, + required VoidCallback onPick, + required VoidCallback? onPreview, + required VoidCallback? onClear, + }) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(label, style: const TextStyle(fontSize: 14)), + const SizedBox(height: 6), + Row( + children: [ + Expanded( + child: Container( + padding: + const EdgeInsets.symmetric(horizontal: 12, vertical: 10), + decoration: BoxDecoration( + border: Border.all(color: Colors.grey.shade400), + borderRadius: BorderRadius.circular(8), + ), + child: Text( + _fileName(path), + style: TextStyle( + fontSize: 13, + color: path != null ? Colors.black87 : Colors.grey, + ), + overflow: TextOverflow.ellipsis, + ), + ), + ), + const SizedBox(width: 8), + IconButton( + icon: const Icon(Icons.folder_open), + tooltip: '选择文件', + onPressed: onPick, + ), + if (onPreview != null) + IconButton( + icon: const Icon(Icons.play_arrow), + tooltip: '试听', + onPressed: onPreview, + ), + if (onClear != null) + IconButton( + icon: const Icon(Icons.clear, size: 20), + tooltip: '清除', + onPressed: onClear, + ), + ], + ), + ], + ); + } } diff --git a/lib/services/sound_service.dart b/lib/services/sound_service.dart new file mode 100644 index 0000000..440622e --- /dev/null +++ b/lib/services/sound_service.dart @@ -0,0 +1,59 @@ +import 'package:audioplayers/audioplayers.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class SoundService { + static const _keySuccess = 'sound_success'; + static const _keyFailure = 'sound_failure'; + + final _player = AudioPlayer(); + + Future getSuccessPath() async { + final prefs = await SharedPreferences.getInstance(); + return prefs.getString(_keySuccess); + } + + Future getFailurePath() async { + final prefs = await SharedPreferences.getInstance(); + return prefs.getString(_keyFailure); + } + + Future setSuccessPath(String? path) async { + final prefs = await SharedPreferences.getInstance(); + if (path != null) { + await prefs.setString(_keySuccess, path); + } else { + await prefs.remove(_keySuccess); + } + } + + Future setFailurePath(String? path) async { + final prefs = await SharedPreferences.getInstance(); + if (path != null) { + await prefs.setString(_keyFailure, path); + } else { + await prefs.remove(_keyFailure); + } + } + + Future playSuccess() async { + final path = await getSuccessPath(); + if (path != null) { + await _player.play(DeviceFileSource(path)); + } + } + + Future playFailure() async { + final path = await getFailurePath(); + if (path != null) { + await _player.play(DeviceFileSource(path)); + } + } + + Future play(String path) async { + await _player.play(DeviceFileSource(path)); + } + + Future dispose() async { + await _player.dispose(); + } +} diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index e71a16d..1830e5c 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -6,6 +6,10 @@ #include "generated_plugin_registrant.h" +#include 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); } diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 2e1de87..f4bf1dc 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -3,9 +3,11 @@ # list(APPEND FLUTTER_PLUGIN_LIST + audioplayers_linux ) list(APPEND FLUTTER_FFI_PLUGIN_LIST + jni ) set(PLUGIN_BUNDLED_LIBRARIES) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 724bb2a..8b5e7e2 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,8 +5,14 @@ import FlutterMacOS import Foundation +import audioplayers_darwin +import device_info_plus +import file_picker import shared_preferences_foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin")) + DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) + FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 2d76677..7f89492 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,14 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + args: + dependency: transitive + description: + name: args + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 + url: "https://pub.dev" + source: hosted + version: "2.7.0" async: dependency: transitive description: @@ -9,6 +17,62 @@ packages: url: "https://pub.dev" source: hosted version: "2.13.0" + audioplayers: + dependency: "direct main" + description: + name: audioplayers + sha256: a72dd459d1a48f61a6fb9c0134dba26597c9236af40639ff0eb70eb4e0baab70 + url: "https://pub.dev" + source: hosted + version: "6.6.0" + 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: c994b3bb3a921e4904ac40e013fbc94488e824fd7c1de6326f549943b0b44a91 + url: "https://pub.dev" + source: hosted + version: "6.4.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: faa8fa6587f996a6f604433b53af44c57a1407d4fe8dff5766cf63d6875e8de9 + url: "https://pub.dev" + source: hosted + version: "5.2.0" + audioplayers_windows: + dependency: transitive + description: + name: audioplayers_windows + sha256: bafff2b38b6f6d331887558ba6e0a01c9c208d9dbb3ad0005234db065122a734 + url: "https://pub.dev" + source: hosted + version: "4.3.0" boolean_selector: dependency: transitive description: @@ -33,6 +97,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.2" + code_assets: + dependency: transitive + description: + name: code_assets + sha256: "83ccdaa064c980b5596c35dd64a8d3ecc68620174ab9b90b6343b753aa721687" + url: "https://pub.dev" + source: hosted + version: "1.0.0" collection: dependency: transitive description: @@ -41,6 +113,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.19.1" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "28bb3ae56f117b5aec029d702a90f57d285cd975c3c5c281eaca38dbc47c5937" + url: "https://pub.dev" + source: hosted + version: "0.3.5+2" + crypto: + dependency: transitive + description: + name: crypto + sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf + url: "https://pub.dev" + source: hosted + version: "3.0.7" cupertino_icons: dependency: "direct main" description: @@ -49,6 +137,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.8" + dbus: + dependency: transitive + description: + name: dbus + sha256: d0c98dcd4f5169878b6cf8f6e0a52403a9dff371a3e2f019697accbf6f44a270 + url: "https://pub.dev" + source: hosted + version: "0.7.12" + device_info_plus: + dependency: transitive + description: + name: device_info_plus + sha256: b4fed1b2835da9d670d7bed7db79ae2a94b0f5ad6312268158a9b5479abbacdd + url: "https://pub.dev" + source: hosted + version: "12.4.0" + device_info_plus_platform_interface: + dependency: transitive + description: + name: device_info_plus_platform_interface + sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f + url: "https://pub.dev" + source: hosted + version: "7.0.3" fake_async: dependency: transitive description: @@ -73,6 +185,22 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.1" + file_picker: + dependency: "direct main" + description: + name: file_picker + sha256: "27c58ff4ec17d8e05b8b27fa66175bf5786b9ff9bd94ca418a571c7f6771b27b" + url: "https://pub.dev" + source: hosted + version: "11.0.0" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be + url: "https://pub.dev" + source: hosted + version: "1.1.1" flutter: dependency: "direct main" description: flutter @@ -86,6 +214,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.0.0" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: "38d1c268de9097ff59cf0e844ac38759fc78f76836d37edad06fa21e182055a0" + url: "https://pub.dev" + source: hosted + version: "2.0.34" flutter_test: dependency: "direct dev" description: flutter @@ -96,6 +232,22 @@ packages: description: flutter source: sdk version: "0.0.0" + glob: + dependency: transitive + description: + name: glob + sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de + url: "https://pub.dev" + source: hosted + version: "2.1.3" + hooks: + dependency: transitive + description: + name: hooks + sha256: "025f060e86d2d4c3c47b56e33caf7f93bf9283340f26d23424ebcfccf34f621e" + url: "https://pub.dev" + source: hosted + version: "1.0.3" http: dependency: "direct main" description: @@ -112,6 +264,22 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.2" + jni: + dependency: transitive + description: + name: jni + sha256: c2230682d5bc2362c1c9e8d3c7f406d9cbba23ab3f2e203a025dd47e0fb2e68f + url: "https://pub.dev" + source: hosted + version: "1.0.0" + jni_flutter: + dependency: transitive + description: + name: jni_flutter + sha256: "8b59e590786050b1cd866677dddaf76b1ade5e7bc751abe04b86e84d379d3ba6" + url: "https://pub.dev" + source: hosted + version: "1.0.1" leak_tracker: dependency: transitive description: @@ -144,6 +312,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.1.1" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.dev" + source: hosted + version: "1.3.0" matcher: dependency: transitive description: @@ -168,6 +344,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.17.0" + native_toolchain_c: + dependency: transitive + description: + name: native_toolchain_c + sha256: "6ba77bb18063eebe9de401f5e6437e95e1438af0a87a3a39084fbd37c90df572" + url: "https://pub.dev" + source: hosted + version: "0.17.6" + objective_c: + dependency: transitive + description: + name: objective_c + sha256: "100a1c87616ab6ed41ec263b083c0ef3261ee6cd1dc3b0f35f8ddfa4f996fe52" + url: "https://pub.dev" + source: hosted + version: "9.3.0" + package_config: + dependency: transitive + description: + name: package_config + sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc + url: "https://pub.dev" + source: hosted + version: "2.2.0" path: dependency: transitive description: @@ -176,6 +376,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.1" + path_provider: + dependency: transitive + description: + name: path_provider + sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" + url: "https://pub.dev" + source: hosted + version: "2.1.5" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: "69cbd515a62b94d32a7944f086b2f82b4ac40a1d45bebfc00813a430ab2dabcd" + url: "https://pub.dev" + source: hosted + version: "2.3.1" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "2a376b7d6392d80cd3705782d2caa734ca4727776db0b6ec36ef3f1855197699" + url: "https://pub.dev" + source: hosted + version: "2.6.0" path_provider_linux: dependency: transitive description: @@ -200,6 +424,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.0" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675" + url: "https://pub.dev" + source: hosted + version: "7.0.2" platform: dependency: transitive description: @@ -216,6 +448,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + record_use: + dependency: transitive + description: + name: record_use + sha256: "2551bd8eecfe95d14ae75f6021ad0248be5c27f138c2ec12fcb52b500b3ba1ed" + url: "https://pub.dev" + source: hosted + version: "0.6.0" shared_preferences: dependency: "direct main" description: @@ -309,6 +557,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.1" + synchronized: + dependency: transitive + description: + name: synchronized + sha256: "63896c27e81b28f8cb4e69ead0d3e8f03f1d1e5fc531a3e579cabed6a2c7c9e5" + url: "https://pub.dev" + source: hosted + version: "3.4.0+1" term_glyph: dependency: transitive description: @@ -333,6 +589,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + uuid: + dependency: transitive + description: + name: uuid + sha256: "1fef9e8e11e2991bb773070d4656b7bd5d850967a2456cfc83cf47925ba79489" + url: "https://pub.dev" + source: hosted + version: "4.5.3" vector_math: dependency: transitive description: @@ -341,6 +605,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.0" + vibration: + dependency: "direct main" + description: + name: vibration + sha256: "9bb06614c69260f8bd11c80fe01ed7988905cf00e3417d656c2647e41f261d87" + url: "https://pub.dev" + source: hosted + version: "3.1.8" + vibration_platform_interface: + dependency: transitive + description: + name: vibration_platform_interface + sha256: "258c273268f8aa40c88d29741137c536874a738779b92ddb8aa32ed093721ec5" + url: "https://pub.dev" + source: hosted + version: "0.1.2" vm_service: dependency: transitive description: @@ -357,6 +637,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + win32: + dependency: transitive + description: + name: win32 + sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e + url: "https://pub.dev" + source: hosted + version: "5.15.0" + win32_registry: + dependency: transitive + description: + name: win32_registry + sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae" + url: "https://pub.dev" + source: hosted + version: "2.1.0" xdg_directories: dependency: transitive description: @@ -365,6 +661,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + xml: + dependency: transitive + description: + name: xml + sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" + url: "https://pub.dev" + source: hosted + version: "6.6.1" + yaml: + dependency: transitive + description: + name: yaml + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + url: "https://pub.dev" + source: hosted + version: "3.1.3" sdks: - dart: ">=3.9.0-0 <4.0.0" - flutter: ">=3.29.0" + dart: ">=3.11.0 <4.0.0" + flutter: ">=3.38.4" diff --git a/pubspec.yaml b/pubspec.yaml index 56399fb..c9b80f5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -36,6 +36,9 @@ dependencies: cupertino_icons: ^1.0.8 http: ^1.2.0 shared_preferences: ^2.2.0 + vibration: ^3.1.8 + file_picker: 11.0.0 + audioplayers: ^6.6.0 dev_dependencies: flutter_test: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 8b6d468..09e8e2c 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,6 +6,9 @@ #include "generated_plugin_registrant.h" +#include void RegisterPlugins(flutter::PluginRegistry* registry) { + AudioplayersWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index b93c4c3..53f4ef8 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,9 +3,11 @@ # list(APPEND FLUTTER_PLUGIN_LIST + audioplayers_windows ) list(APPEND FLUTTER_FFI_PLUGIN_LIST + jni ) set(PLUGIN_BUNDLED_LIBRARIES)