Merge branch 'content-html' into 'master'

refactor: Improve handling of API content in material feature

See merge request profile-image/kedaireka/polinema-adapative-learning/mobile-adaptive-learning!2
This commit is contained in:
Naresh Pratista 2024-11-05 06:51:06 +00:00
commit 6e91ce7898
14 changed files with 442 additions and 61 deletions

View File

@ -1,2 +1 @@
const String baseUrl = const String baseUrl = 'https://c62a-139-255-101-170.ngrok-free.app/';
'https://3be6-2001-448a-50a0-58e3-1c9f-405a-b360-22ed.ngrok-free.app/';

View File

@ -1,5 +1,4 @@
import 'package:english_learning/core/services/dio_client.dart'; import 'package:english_learning/core/services/dio_client.dart';
import 'package:english_learning/core/services/constants.dart';
import 'package:english_learning/core/services/repositories/student_learning_repository.dart'; import 'package:english_learning/core/services/repositories/student_learning_repository.dart';
import 'package:english_learning/core/widgets/global_button.dart'; import 'package:english_learning/core/widgets/global_button.dart';
import 'package:english_learning/features/auth/provider/user_provider.dart'; import 'package:english_learning/features/auth/provider/user_provider.dart';
@ -10,6 +9,7 @@ import 'package:english_learning/features/learning/modules/material/widgets/imag
import 'package:english_learning/features/learning/modules/material/widgets/video_player_widget.dart'; import 'package:english_learning/features/learning/modules/material/widgets/video_player_widget.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:english_learning/core/utils/styles/theme.dart'; import 'package:english_learning/core/utils/styles/theme.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class MaterialScreen extends StatefulWidget { class MaterialScreen extends StatefulWidget {
@ -80,13 +80,8 @@ class _MaterialScreenState extends State<MaterialScreen>
final result = final result =
await _repository.createStudentLearning(widget.levelId, token); await _repository.createStudentLearning(widget.levelId, token);
print('Student Learning created: ${result['message']}');
// Navigate to ExerciseScreen
_navigateToExercise(result['payload']['ID_STUDENT_LEARNING']); _navigateToExercise(result['payload']['ID_STUDENT_LEARNING']);
} catch (e) { } catch (e) {
// Show error message
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error: $e')), SnackBar(content: Text('Error: $e')),
); );
@ -152,31 +147,33 @@ class _MaterialScreenState extends State<MaterialScreen>
child: Column( child: Column(
children: [ children: [
const SizedBox(height: 22), const SizedBox(height: 22),
Text( Html(
level.content, data: level.content,
style: AppTextStyles.blackTextStyle.copyWith( style: {
fontSize: 14, 'body': Style(
fontSize: FontSize(14),
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
},
extensions: [
ImageExtension(
builder: (context) => ImageWidget(
imageFileName: context.attributes['src'] ?? '',
), ),
const SizedBox(height: 24),
if (level.image != null)
ImageWidget(
imageFileName: level.image!,
baseUrl: '${baseUrl}uploads/level/image/',
), ),
const SizedBox(height: 24), AudioExtension(
if (level.audio != null) builder: (context) => AudioPlayerWidget(
AudioPlayerWidget(
key: _audioPlayerKey, key: _audioPlayerKey,
audioFileName: level.audio!, audioFileName: context.attributes['src'] ?? '',
baseUrl: '${baseUrl}uploads/level/audio/',
), ),
const SizedBox(height: 24), ),
if (level.video != null) VideoExtension(
VideoPlayerWidget( builder: (context) => VideoPlayerWidget(
key: _videoPlayerKey, key: _videoPlayerKey,
videoUrl: level.video!, videoUrl: context.attributes['src'] ?? '',
),
),
],
), ),
const SizedBox(height: 32), const SizedBox(height: 32),
if (!widget.isReview) if (!widget.isReview)
@ -209,3 +206,49 @@ class _MaterialScreenState extends State<MaterialScreen>
}); });
} }
} }
class ImageExtension extends HtmlExtension {
final Widget Function(ExtensionContext) builder;
ImageExtension({required this.builder});
@override
Set<String> get supportedTags => {'img'};
@override
InlineSpan build(ExtensionContext context) {
context.attributes.remove('width');
context.attributes.remove('height');
return WidgetSpan(child: builder(context));
}
}
class AudioExtension extends HtmlExtension {
final Widget Function(ExtensionContext) builder;
AudioExtension({required this.builder});
@override
Set<String> get supportedTags => {'audio'};
@override
InlineSpan build(ExtensionContext context) =>
WidgetSpan(child: builder(context));
}
class VideoExtension extends HtmlExtension {
final Widget Function(ExtensionContext) builder;
VideoExtension({required this.builder});
@override
Set<String> get supportedTags => {'iframe'};
@override
InlineSpan build(ExtensionContext context) {
context.attributes.remove('width');
context.attributes.remove('height');
return WidgetSpan(child: builder(context));
}
}

View File

@ -2,13 +2,13 @@ import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class AudioPlayerWidget extends StatefulWidget { class AudioPlayerWidget extends StatefulWidget {
final String? audioFileName; final String audioFileName;
final String baseUrl; final String? baseUrl;
const AudioPlayerWidget({ const AudioPlayerWidget({
super.key, super.key,
required this.audioFileName, required this.audioFileName,
required this.baseUrl, this.baseUrl,
}); });
@override @override
@ -34,8 +34,10 @@ class AudioPlayerWidgetState extends State<AudioPlayerWidget> {
} }
void _setupAudioPlayer() { void _setupAudioPlayer() {
if (widget.audioFileName != null && widget.audioFileName!.isNotEmpty) { if (widget.audioFileName.isNotEmpty) {
String fullAudioUrl = '${widget.baseUrl}${widget.audioFileName}'; String fullAudioUrl = widget.audioFileName.startsWith('http')
? widget.audioFileName
: '${widget.baseUrl ?? ''}${widget.audioFileName}';
_audioPlayer.setSource(UrlSource(fullAudioUrl)).then((_) { _audioPlayer.setSource(UrlSource(fullAudioUrl)).then((_) {
setState(() { setState(() {

View File

@ -3,17 +3,19 @@ import 'package:flutter/material.dart';
class ImageWidget extends StatelessWidget { class ImageWidget extends StatelessWidget {
final String imageFileName; final String imageFileName;
final String baseUrl; final String? baseUrl;
const ImageWidget({ const ImageWidget({
super.key, super.key,
required this.imageFileName, required this.imageFileName,
required this.baseUrl, this.baseUrl,
}); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
String fullImageUrl = '$baseUrl$imageFileName'; String fullImageUrl = imageFileName.startsWith('http')
? imageFileName
: '${baseUrl ?? ''}$imageFileName';
return Container( return Container(
width: double.infinity, width: double.infinity,

View File

@ -132,18 +132,11 @@ class _EditProfileScreenState extends State<EditProfileScreen> {
baseUrl: '$baseUrl/uploads/avatar/', baseUrl: '$baseUrl/uploads/avatar/',
onImageSelected: _pickImage, onImageSelected: _pickImage,
selectedImage: userProvider.selectedImage, selectedImage: userProvider.selectedImage,
showCameraIcon: true,
), ),
), ),
], ],
), ),
const SizedBox(height: 8),
Text(
'Change Avatar',
style: AppTextStyles.blueTextStyle.copyWith(
fontSize: 18,
fontWeight: FontWeight.w900,
),
),
const SizedBox(height: 39), const SizedBox(height: 39),
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0), padding: const EdgeInsets.symmetric(horizontal: 16.0),

View File

@ -1,5 +1,4 @@
import 'dart:io'; import 'dart:io';
import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:english_learning/core/utils/styles/theme.dart'; import 'package:english_learning/core/utils/styles/theme.dart';
@ -10,6 +9,7 @@ class UserAvatar extends StatelessWidget {
final String baseUrl; final String baseUrl;
final Function()? onImageSelected; final Function()? onImageSelected;
final File? selectedImage; final File? selectedImage;
final bool showCameraIcon;
const UserAvatar({ const UserAvatar({
super.key, super.key,
@ -18,17 +18,87 @@ class UserAvatar extends StatelessWidget {
required this.baseUrl, required this.baseUrl,
this.onImageSelected, this.onImageSelected,
this.selectedImage, this.selectedImage,
this.showCameraIcon = false,
}); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GestureDetector( return Stack(
onTap: onImageSelected, children: [
// Avatar with detail view
GestureDetector(
onTap: () {
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
child: Container(
width: double.infinity,
height: 400,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: ClipRRect(
borderRadius: const BorderRadius.vertical(
top: Radius.circular(12),
),
child: _getDetailAvatarContent(),
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: TextButton(
style: TextButton.styleFrom(
foregroundColor: AppColors.primaryColor,
),
onPressed: () => Navigator.pop(context),
child: const Text('Close'),
),
),
],
),
),
);
},
);
},
child: CircleAvatar( child: CircleAvatar(
radius: radius, radius: radius,
backgroundColor: AppColors.primaryColor, backgroundColor: AppColors.primaryColor,
child: _getAvatarContent(), child: _getAvatarContent(),
), ),
),
// Camera icon
if (showCameraIcon)
Positioned(
right: 0,
bottom: 0,
child: GestureDetector(
onTap: onImageSelected,
child: Container(
padding: const EdgeInsets.all(6),
decoration: BoxDecoration(
color: AppColors.primaryColor,
shape: BoxShape.circle,
border: Border.all(
color: Colors.white,
width: 2,
),
),
child: Icon(
BootstrapIcons.camera,
color: AppColors.whiteColor,
size: radius * 0.3,
),
),
),
),
],
); );
} }
@ -60,6 +130,37 @@ class UserAvatar extends StatelessWidget {
} }
} }
Widget _getDetailAvatarContent() {
if (selectedImage != null) {
return Image.file(
selectedImage!,
fit: BoxFit.cover,
);
} else if (pictureUrl != null && pictureUrl!.isNotEmpty) {
return Image.network(
'$baseUrl$pictureUrl',
fit: BoxFit.cover,
errorBuilder: (context, error, stackTrace) {
return Center(
child: Icon(
BootstrapIcons.person,
color: AppColors.primaryColor,
size: 120,
),
);
},
);
} else {
return Center(
child: Icon(
BootstrapIcons.person,
color: AppColors.primaryColor,
size: 120,
),
);
}
}
Widget _buildDefaultIcon() { Widget _buildDefaultIcon() {
return Icon( return Icon(
BootstrapIcons.person, BootstrapIcons.person,

View File

@ -9,6 +9,7 @@
#include <audioplayers_linux/audioplayers_linux_plugin.h> #include <audioplayers_linux/audioplayers_linux_plugin.h>
#include <file_selector_linux/file_selector_plugin.h> #include <file_selector_linux/file_selector_plugin.h>
#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h> #include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar = g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar =
@ -20,4 +21,7 @@ void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar = g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin");
flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar); flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
} }

View File

@ -6,6 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
audioplayers_linux audioplayers_linux
file_selector_linux file_selector_linux
flutter_secure_storage_linux flutter_secure_storage_linux
url_launcher_linux
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST

View File

@ -5,26 +5,32 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import audio_session
import audioplayers_darwin import audioplayers_darwin
import file_selector_macos import file_selector_macos
import flutter_inappwebview_macos import flutter_inappwebview_macos
import flutter_secure_storage_macos import flutter_secure_storage_macos
import just_audio
import package_info_plus import package_info_plus
import path_provider_foundation import path_provider_foundation
import shared_preferences_foundation import shared_preferences_foundation
import sqflite import sqflite
import url_launcher_macos
import video_player_avfoundation import video_player_avfoundation
import wakelock_plus import wakelock_plus
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin")) AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin"))
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin")) InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin"))
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin")) FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
} }

View File

@ -17,6 +17,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.11.0" version: "2.11.0"
audio_session:
dependency: transitive
description:
name: audio_session
sha256: "343e83bc7809fbda2591a49e525d6b63213ade10c76f15813be9aed6657b3261"
url: "https://pub.dev"
source: hosted
version: "0.1.21"
audioplayers: audioplayers:
dependency: "direct main" dependency: "direct main"
description: description:
@ -137,6 +145,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.1" version: "1.3.1"
chewie:
dependency: transitive
description:
name: chewie
sha256: "335df378c025588aef400c704bd71f0daea479d4cd57c471c88c056c1144e7cd"
url: "https://pub.dev"
source: hosted
version: "1.8.5"
clock: clock:
dependency: transitive dependency: transitive
description: description:
@ -173,10 +189,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: csslib name: csslib
sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" sha256: "831883fb353c8bdc1d71979e5b342c7d88acfbc643113c14ae51e2442ea0f20f"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.0" version: "0.17.3"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
@ -294,8 +310,16 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.4.1" version: "3.4.1"
flutter_html:
dependency: "direct main"
description:
name: flutter_html
sha256: "02ad69e813ecfc0728a455e4bf892b9379983e050722b1dce00192ee2e41d1ee"
url: "https://pub.dev"
source: hosted
version: "3.0.0-beta.2"
flutter_inappwebview: flutter_inappwebview:
dependency: transitive dependency: "direct main"
description: description:
name: flutter_inappwebview name: flutter_inappwebview
sha256: "3e9a443a18ecef966fb930c3a76ca5ab6a7aafc0c7b5e14a4a850cf107b09959" sha256: "3e9a443a18ecef966fb930c3a76ca5ab6a7aafc0c7b5e14a4a850cf107b09959"
@ -432,6 +456,70 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_widget_from_html:
dependency: "direct main"
description:
name: flutter_widget_from_html
sha256: "9e2a6201c4d2eb910b6b3ebb2a9f5c490fc61c9a1aa35eafdde38f0fc659cf4c"
url: "https://pub.dev"
source: hosted
version: "0.15.2"
flutter_widget_from_html_core:
dependency: transitive
description:
name: flutter_widget_from_html_core
sha256: b1048fd119a14762e2361bd057da608148a895477846d6149109b2151d2f7abf
url: "https://pub.dev"
source: hosted
version: "0.15.2"
fwfh_cached_network_image:
dependency: transitive
description:
name: fwfh_cached_network_image
sha256: "8e44226801bfba27930673953afce8af44da7e92573be93f60385d9865a089dd"
url: "https://pub.dev"
source: hosted
version: "0.14.3"
fwfh_chewie:
dependency: transitive
description:
name: fwfh_chewie
sha256: "37bde9cedfb6dc5546176f7f0c56af1e814966cb33ec58f16c9565ed93ccb704"
url: "https://pub.dev"
source: hosted
version: "0.14.8"
fwfh_just_audio:
dependency: transitive
description:
name: fwfh_just_audio
sha256: "38dc2c55803bd3cef33042c473e0c40b891ad4548078424641a32032f6a1245f"
url: "https://pub.dev"
source: hosted
version: "0.15.2"
fwfh_svg:
dependency: transitive
description:
name: fwfh_svg
sha256: "550b1014d12b5528d8bdb6e3b44b58721f3fb1f65d7a852d1623a817008bdfc4"
url: "https://pub.dev"
source: hosted
version: "0.8.3"
fwfh_url_launcher:
dependency: transitive
description:
name: fwfh_url_launcher
sha256: b9f5d55a5ae2c2c07243ba33f7ba49ac9544bdb2f4c16d8139df9ccbebe3449c
url: "https://pub.dev"
source: hosted
version: "0.9.1"
fwfh_webview:
dependency: transitive
description:
name: fwfh_webview
sha256: f67890bc0d6278da98bd197469ae9511c859f7db327e92299fe0ea0cf46c4057
url: "https://pub.dev"
source: hosted
version: "0.15.2"
google_fonts: google_fonts:
dependency: "direct main" dependency: "direct main"
description: description:
@ -552,6 +640,30 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.6.7" version: "0.6.7"
just_audio:
dependency: transitive
description:
name: just_audio
sha256: a49e7120b95600bd357f37a2bb04cd1e88252f7cdea8f3368803779b925b1049
url: "https://pub.dev"
source: hosted
version: "0.9.42"
just_audio_platform_interface:
dependency: transitive
description:
name: just_audio_platform_interface
sha256: "0243828cce503c8366cc2090cefb2b3c871aa8ed2f520670d76fd47aa1ab2790"
url: "https://pub.dev"
source: hosted
version: "4.3.0"
just_audio_web:
dependency: transitive
description:
name: just_audio_web
sha256: "9a98035b8b24b40749507687520ec5ab404e291d2b0937823ff45d92cb18d448"
url: "https://pub.dev"
source: hosted
version: "0.4.13"
jwt_decoder: jwt_decoder:
dependency: "direct main" dependency: "direct main"
description: description:
@ -592,6 +704,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.0" version: "4.0.0"
list_counter:
dependency: transitive
description:
name: list_counter
sha256: c447ae3dfcd1c55f0152867090e67e219d42fe6d4f2807db4bbe8b8d69912237
url: "https://pub.dev"
source: hosted
version: "1.0.2"
logging:
dependency: transitive
description:
name: logging
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
url: "https://pub.dev"
source: hosted
version: "1.3.0"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
@ -933,6 +1061,70 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.2" version: "2.2.2"
url_launcher:
dependency: transitive
description:
name: url_launcher
sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603"
url: "https://pub.dev"
source: hosted
version: "6.3.1"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: f0c73347dfcfa5b3db8bc06e1502668265d39c08f310c29bff4e28eea9699f79
url: "https://pub.dev"
source: hosted
version: "6.3.9"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e
url: "https://pub.dev"
source: hosted
version: "6.3.1"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af
url: "https://pub.dev"
source: hosted
version: "3.2.0"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
sha256: "769549c999acdb42b8bcfa7c43d72bf79a382ca7441ab18a808e101149daf672"
url: "https://pub.dev"
source: hosted
version: "3.2.1"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e"
url: "https://pub.dev"
source: hosted
version: "2.3.3"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: "44cf3aabcedde30f2dba119a9dea3b0f2672fbe6fa96e85536251d678216b3c4"
url: "https://pub.dev"
source: hosted
version: "3.1.3"
uuid: uuid:
dependency: transitive dependency: transitive
description: description:
@ -1045,6 +1237,38 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.0" version: "1.0.0"
webview_flutter:
dependency: transitive
description:
name: webview_flutter
sha256: "6869c8786d179f929144b4a1f86e09ac0eddfe475984951ea6c634774c16b522"
url: "https://pub.dev"
source: hosted
version: "4.8.0"
webview_flutter_android:
dependency: transitive
description:
name: webview_flutter_android
sha256: ed021f27ae621bc97a6019fb601ab16331a3db4bf8afa305e9f6689bdb3edced
url: "https://pub.dev"
source: hosted
version: "3.16.8"
webview_flutter_platform_interface:
dependency: transitive
description:
name: webview_flutter_platform_interface
sha256: d937581d6e558908d7ae3dc1989c4f87b786891ab47bb9df7de548a151779d8d
url: "https://pub.dev"
source: hosted
version: "2.10.0"
webview_flutter_wkwebview:
dependency: transitive
description:
name: webview_flutter_wkwebview
sha256: "9c62cc46fa4f2d41e10ab81014c1de470a6c6f26051a2de32111b2ee55287feb"
url: "https://pub.dev"
source: hosted
version: "3.14.0"
win32: win32:
dependency: transitive dependency: transitive
description: description:

View File

@ -37,8 +37,11 @@ dependencies:
flick_video_player: ^0.9.0 flick_video_player: ^0.9.0
flutter: flutter:
sdk: flutter sdk: flutter
flutter_html: ^3.0.0-beta.2
flutter_inappwebview: ^6.0.0
flutter_secure_storage: ^9.2.2 flutter_secure_storage: ^9.2.2
flutter_svg: ^2.0.10+1 flutter_svg: ^2.0.10+1
flutter_widget_from_html: ^0.15.2
google_fonts: ^6.2.1 google_fonts: ^6.2.1
google_nav_bar: ^5.0.6 google_nav_bar: ^5.0.6
image_picker: ^1.1.2 image_picker: ^1.1.2

View File

@ -9,6 +9,7 @@
#include <audioplayers_windows/audioplayers_windows_plugin.h> #include <audioplayers_windows/audioplayers_windows_plugin.h>
#include <file_selector_windows/file_selector_windows.h> #include <file_selector_windows/file_selector_windows.h>
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h> #include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
AudioplayersWindowsPluginRegisterWithRegistrar( AudioplayersWindowsPluginRegisterWithRegistrar(
@ -17,4 +18,6 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("FileSelectorWindows")); registry->GetRegistrarForPlugin("FileSelectorWindows"));
FlutterSecureStorageWindowsPluginRegisterWithRegistrar( FlutterSecureStorageWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin")); registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin"));
UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
} }

View File

@ -6,6 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
audioplayers_windows audioplayers_windows
file_selector_windows file_selector_windows
flutter_secure_storage_windows flutter_secure_storage_windows
url_launcher_windows
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST