Compare commits

...

10 Commits

Author SHA1 Message Date
e6ce79528b Merge branch 'fix/level-list' into 'master'
feat: add replay functionality and improve error handling in audio player widget

See merge request profile-image/kedaireka/polinema-adapative-learning/mobile-adaptive-learning!31
2024-12-19 06:23:45 +00:00
2f1eef5f1a feat: add replay functionality and improve error handling in audio player widget 2024-12-19 13:21:55 +07:00
21e90e1b16 Merge branch 'fix/forgotPassword' into 'master'
chore: update and set minSdk to 24, and dispose emai controller in forgot password screen

See merge request profile-image/kedaireka/polinema-adapative-learning/mobile-adaptive-learning!30
2024-12-19 02:11:44 +00:00
9a357486a3 chore: update and set minSdk to 24, and dispose emai controller in forgot password screen 2024-12-19 09:10:22 +07:00
dfeb41cf79 Merge branch 'fix/responsive' into 'master'
refactor: adjust spacing and improve layout across multiple screens

See merge request profile-image/kedaireka/polinema-adapative-learning/mobile-adaptive-learning!29
2024-12-15 13:52:43 +00:00
Resh
aae59d0a86 refactor: adjust spacing and improve layout across multiple screens 2024-12-15 20:50:15 +07:00
bbd26c0cb1 Merge branch 'fix/gradle' into 'master'
chore: update Flutter and Gradle versions, and add FVM configuration

See merge request profile-image/kedaireka/polinema-adapative-learning/mobile-adaptive-learning!28
2024-12-14 11:24:56 +00:00
638c649ed9 chore: update Flutter and Gradle versions, and add FVM configuration 2024-12-14 18:23:42 +07:00
16778b14df Merge branch 'fix/section-review-logic' into 'master'
fix: section description dialog and review pretest exercise logic

See merge request profile-image/kedaireka/polinema-adapative-learning/mobile-adaptive-learning!27
2024-12-09 08:50:56 +00:00
Naresh Pratista
276d616bf0 fix: section description dialog and review pretest exercise logic 2024-12-09 15:49:09 +07:00
32 changed files with 551 additions and 381 deletions

3
.fvmrc Normal file
View File

@ -0,0 +1,3 @@
{
"flutter": "3.27.0-0.2.pre"
}

3
.gitignore vendored
View File

@ -44,3 +44,6 @@ app.*.map.json
/android/app/profile /android/app/profile
/android/app/release /android/app/release
lib/core/services/constants.dart lib/core/services/constants.dart
# FVM Version Cache
.fvm/

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"dart.flutterSdkPath": ".fvm/versions/3.27.0-0.2.pre"
}

View File

@ -14,7 +14,7 @@ android {
sourceCompatibility = JavaVersion.VERSION_1_8 sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8
} }
kotlinOptions { kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8 jvmTarget = JavaVersion.VERSION_1_8
} }
@ -24,7 +24,7 @@ android {
applicationId = "com.example.english_learning" applicationId = "com.example.english_learning"
// You can update the following values to match your application needs. // You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config. // For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion minSdk = 24
targetSdk = flutter.targetSdkVersion targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode versionCode = flutter.versionCode
versionName = flutter.versionName versionName = flutter.versionName

View File

@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip

View File

@ -18,7 +18,7 @@ pluginManagement {
plugins { plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0" id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.1.0" apply false id "com.android.application" version "8.3.2" apply false
id "org.jetbrains.kotlin.android" version "1.8.22" apply false id "org.jetbrains.kotlin.android" version "1.8.22" apply false
} }

View File

@ -1,3 +1,3 @@
const String baseUrl = 'https://580d-36-85-62-81.ngrok-free.app/'; const String baseUrl = 'http://54.173.167.62/';
const String mediaUrl = 'https://580d-36-85-62-81.ngrok-free.app/api/uploads/'; const String mediaUrl = 'http://54.173.167.62/api/uploads/';

View File

@ -21,6 +21,9 @@ class CustomButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final mediaQuery = MediaQuery.of(context);
final screenWidth = mediaQuery.size.width;
return SizedBox( return SizedBox(
width: width, width: width,
height: height, height: height,
@ -46,7 +49,7 @@ class CustomButton extends StatelessWidget {
text, text,
style: textStyle ?? style: textStyle ??
AppTextStyles.blackButtonTextStyle.copyWith( AppTextStyles.blackButtonTextStyle.copyWith(
fontSize: 14, fontSize: screenWidth * 0.036,
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
), ),
), ),

View File

@ -50,20 +50,23 @@ class CustomFieldWidget extends StatefulWidget {
class _CustomFieldWidgetState extends State<CustomFieldWidget> { class _CustomFieldWidgetState extends State<CustomFieldWidget> {
late TextEditingController _controller; late TextEditingController _controller;
late ValidatorProvider _validatorProvider;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_controller = widget.controller ?? TextEditingController(); _controller = widget.controller ?? TextEditingController();
context // Simpan referensi provider di initState
.read<ValidatorProvider>() _validatorProvider = context.read<ValidatorProvider>();
.setController(widget.fieldName, _controller); _validatorProvider.setController(widget.fieldName, _controller);
} }
@override @override
void dispose() { void dispose() {
context.read<ValidatorProvider>().removeController(widget.fieldName); // Gunakan referensi yang disimpan sebelumnya
_validatorProvider.removeController(widget.fieldName);
if (widget.controller == null) { if (widget.controller == null) {
_controller.dispose(); _controller.dispose();
} }

View File

@ -160,6 +160,7 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen> {
), ),
], ],
), ),
SizedBox(height: screenHeight * 0.1)
], ],
); );
}), }),
@ -168,4 +169,10 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen> {
), ),
); );
} }
@override
void dispose() {
_emailController.dispose();
super.dispose();
}
} }

View File

@ -19,8 +19,9 @@ class SigninScreen extends StatefulWidget {
} }
class _SigninScreenState extends State<SigninScreen> { class _SigninScreenState extends State<SigninScreen> {
final TextEditingController _loginController = TextEditingController(); late TextEditingController _loginController = TextEditingController();
final TextEditingController _passwordController = TextEditingController(); late TextEditingController _passwordController = TextEditingController();
late ValidatorProvider _validatorProvider;
final FocusNode _loginFocus = FocusNode(); final FocusNode _loginFocus = FocusNode();
final FocusNode _passwordFocus = FocusNode(); final FocusNode _passwordFocus = FocusNode();
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
@ -28,16 +29,22 @@ class _SigninScreenState extends State<SigninScreen> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
context.read<ValidatorProvider>().setController('login', _loginController); _loginController = TextEditingController();
context _passwordController = TextEditingController();
.read<ValidatorProvider>() }
.setController('password', _passwordController);
@override
void didChangeDependencies() {
super.didChangeDependencies();
_validatorProvider = context.read<ValidatorProvider>();
_validatorProvider.setController('login', _loginController);
_validatorProvider.setController('password', _passwordController);
} }
@override @override
void dispose() { void dispose() {
context.read<ValidatorProvider>().removeController('login'); _validatorProvider.removeController('login');
context.read<ValidatorProvider>().removeController('password'); _validatorProvider.removeController('password');
_loginController.dispose(); _loginController.dispose();
_passwordController.dispose(); _passwordController.dispose();
@ -346,7 +353,7 @@ class _SigninScreenState extends State<SigninScreen> {
), ),
], ],
), ),
SizedBox(height: screenHeight * 0.02), SizedBox(height: screenHeight * 0.1),
], ],
); );
}, },

View File

@ -7,10 +7,10 @@ class LoginEmailField extends StatefulWidget {
const LoginEmailField({super.key}); const LoginEmailField({super.key});
@override @override
_LoginEmailFieldState createState() => _LoginEmailFieldState(); LoginEmailFieldState createState() => LoginEmailFieldState();
} }
class _LoginEmailFieldState extends State<LoginEmailField> { class LoginEmailFieldState extends State<LoginEmailField> {
late FocusNode _focusNode; late FocusNode _focusNode;
@override @override

View File

@ -316,6 +316,7 @@ class _SignupScreenState extends State<SignupScreen> {
), ),
], ],
), ),
SizedBox(height: screenHeight * 0.1)
], ],
); );
}, },

View File

@ -67,14 +67,18 @@ class HistoryProvider with ChangeNotifier {
Future<void> fetchLearningHistory(String token) async { Future<void> fetchLearningHistory(String token) async {
if (_sectionProvider.sections.isEmpty) { if (_sectionProvider.sections.isEmpty) {
_error = 'No sections available'; _error = 'No sections available';
notifyListeners(); WidgetsBinding.instance.addPostFrameCallback((_) {
notifyListeners();
});
return; return;
} }
String sectionId = _sectionProvider.sections[_selectedPageIndex].id; String sectionId = _sectionProvider.sections[_selectedPageIndex].id;
_isLoading = true; _isLoading = true;
_error = null; _error = null;
notifyListeners(); WidgetsBinding.instance.addPostFrameCallback((_) {
notifyListeners();
});
try { try {
final history = await _repository.getLearningHistory(sectionId, token); final history = await _repository.getLearningHistory(sectionId, token);
@ -85,7 +89,9 @@ class HistoryProvider with ChangeNotifier {
_historyModel = []; _historyModel = [];
} finally { } finally {
_isLoading = false; _isLoading = false;
notifyListeners(); WidgetsBinding.instance.addPostFrameCallback((_) {
notifyListeners();
});
} }
} }

View File

@ -361,6 +361,9 @@ class _HomeContentState extends State<HomeContent> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final mediaQuery = MediaQuery.of(context);
final screenHeight = mediaQuery.size.height;
return RefreshIndicator( return RefreshIndicator(
onRefresh: _initializeData, onRefresh: _initializeData,
child: Consumer2<UserProvider, CompletedTopicsProvider>( child: Consumer2<UserProvider, CompletedTopicsProvider>(
@ -486,7 +489,7 @@ class _HomeContentState extends State<HomeContent> {
return WelcomeCard(cardModel: cardData.cardData[index]); return WelcomeCard(cardModel: cardData.cardData[index]);
}, },
options: CarouselOptions( options: CarouselOptions(
height: 168, height: screenHeight * 0.19,
viewportFraction: 0.9, viewportFraction: 0.9,
enlargeCenterPage: true, enlargeCenterPage: true,
autoPlay: true, autoPlay: true,

View File

@ -69,7 +69,7 @@ class IncompleteSubmission extends StatelessWidget {
children: [ children: [
Expanded( Expanded(
child: GlobalButton( child: GlobalButton(
text: 'Check Again', text: 'Check',
textColor: AppColors.blueColor, textColor: AppColors.blueColor,
borderColor: AppColors.blueColor, borderColor: AppColors.blueColor,
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,

View File

@ -1,6 +1,6 @@
import 'package:english_learning/core/services/repositories/level_repository.dart'; import 'package:english_learning/core/services/repositories/level_repository.dart';
import 'package:english_learning/features/learning/modules/level/models/level_model.dart'; import 'package:english_learning/features/learning/modules/level/models/level_model.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart';
class LevelProvider with ChangeNotifier { class LevelProvider with ChangeNotifier {
final LevelRepository _levelRepository = LevelRepository(); final LevelRepository _levelRepository = LevelRepository();
@ -21,8 +21,9 @@ class LevelProvider with ChangeNotifier {
Future<void> fetchLevels(String topicId, String token) async { Future<void> fetchLevels(String topicId, String token) async {
_isLoading = true; _isLoading = true;
_error = null; _error = null;
notifyListeners(); WidgetsBinding.instance.addPostFrameCallback((_) {
notifyListeners();
});
try { try {
final result = await _levelRepository.getLevels(topicId, token); final result = await _levelRepository.getLevels(topicId, token);
_levels = result['levels']; _levels = result['levels'];
@ -37,7 +38,9 @@ class LevelProvider with ChangeNotifier {
_error = 'Error fetching levels: ${e.toString()}'; _error = 'Error fetching levels: ${e.toString()}';
} finally { } finally {
_isLoading = false; _isLoading = false;
notifyListeners(); WidgetsBinding.instance.addPostFrameCallback((_) {
notifyListeners();
});
} }
} }
@ -48,7 +51,11 @@ class LevelProvider with ChangeNotifier {
bool isPretestFinished(String levelId) { bool isPretestFinished(String levelId) {
return _levels.any( return _levels.any(
(level) => level.idLevel == levelId && level.idStudentLearning != null); (level) =>
level.idLevel == levelId &&
level.idStudentLearning != null &&
level.score != null,
);
} }
int getPretestScore(String levelId) { int getPretestScore(String levelId) {

View File

@ -20,13 +20,18 @@ class LevelCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final mediaQuery = MediaQuery.of(context);
final screenHeight = mediaQuery.size.height;
return Card( return Card(
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
), ),
elevation: 0, elevation: 0,
child: Container( child: Container(
height: MediaQuery.of(context).size.height * 0.6, constraints: BoxConstraints(
maxHeight: screenHeight * 0.7,
),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
gradient: isAllowed gradient: isAllowed
@ -107,20 +112,20 @@ class LevelCard extends StatelessWidget {
), ),
), ),
const SizedBox(height: 6), const SizedBox(height: 6),
// Score Display
Text( Text(
// 'Score ${level.score}/100',
'Score $score/100', 'Score $score/100',
style: AppTextStyles.whiteTextStyle.copyWith( style: AppTextStyles.whiteTextStyle.copyWith(
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
fontSize: 12, fontSize: 12,
), ),
), ),
const Spacer(), // Learn Now Button const Spacer(),
Align( Align(
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0), padding: const EdgeInsets.symmetric(
horizontal: 8.0,
),
child: CustomButton( child: CustomButton(
text: isAllowed ? 'Learn Now' : 'Locked', text: isAllowed ? 'Learn Now' : 'Locked',
textStyle: textStyle:

View File

@ -24,12 +24,15 @@ class PretestCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final mediaQuery = MediaQuery.of(context);
final screenHeight = mediaQuery.size.height;
return Consumer<LevelProvider>(builder: (context, levelProvider, _) { return Consumer<LevelProvider>(builder: (context, levelProvider, _) {
final isFinished = levelProvider.isPretestFinished(pretest.idLevel); final isFinished = levelProvider.isPretestFinished(pretest.idLevel);
final score = levelProvider.getPretestScore(pretest.idLevel); final score = levelProvider.getPretestScore(pretest.idLevel);
// final isAllowed = levelProvider.isLevelAllowed(pretest.idLevel); // final isAllowed = levelProvider.isLevelAllowed(pretest.idLevel);
void navigateToMaterial() { void navigateToMaterial() {
if (isFinished) { if (isFinished && pretest.score != null) {
// Mode review untuk pretest yang sudah selesai // Mode review untuk pretest yang sudah selesai
Navigator.push( Navigator.push(
context, context,
@ -80,7 +83,9 @@ class PretestCard extends StatelessWidget {
children: [ children: [
Container( Container(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
vertical: 4, horizontal: 8), vertical: 4,
horizontal: 8,
),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
color: color:
@ -125,7 +130,7 @@ class PretestCard extends StatelessWidget {
Flexible( Flexible(
child: Image.asset( child: Image.asset(
'lib/features/learning/modules/level/assets/images/pretest_level_illustration.png', 'lib/features/learning/modules/level/assets/images/pretest_level_illustration.png',
height: 95, height: screenHeight * 0.13,
fit: BoxFit.cover, fit: BoxFit.cover,
), ),
), ),
@ -133,8 +138,10 @@ class PretestCard extends StatelessWidget {
), ),
const SizedBox(height: 13), const SizedBox(height: 13),
CustomButton( CustomButton(
text: isFinished ? 'Review' : 'Learn Now', text: isFinished && pretest.score != null
textStyle: isFinished ? 'Review'
: 'Learn Now',
textStyle: isFinished && pretest.score != null
? AppTextStyles.whiteTextStyle.copyWith( ? AppTextStyles.whiteTextStyle.copyWith(
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
) )
@ -143,7 +150,9 @@ class PretestCard extends StatelessWidget {
), ),
width: double.infinity, width: double.infinity,
height: 36, height: 36,
color: isFinished ? Colors.green : AppColors.yellowButtonColor, color: isFinished && pretest.score != null
? Colors.green
: AppColors.yellowButtonColor,
onPressed: navigateToMaterial, onPressed: navigateToMaterial,
), ),
], ],

View File

@ -27,7 +27,6 @@ class AudioPlayerWidgetState extends State<AudioPlayerWidget>
Duration _position = Duration.zero; Duration _position = Duration.zero;
bool _isAudioLoaded = false; bool _isAudioLoaded = false;
String? _errorMessage; String? _errorMessage;
double _volume = 1.0;
bool _isDisposed = false; bool _isDisposed = false;
@override @override
@ -88,6 +87,18 @@ class AudioPlayerWidgetState extends State<AudioPlayerWidget>
setState(() => _position = newPosition); setState(() => _position = newPosition);
} }
}); });
// Add completion listener
_audioPlayer.onPlayerComplete.listen((_) {
if (!_isDisposed) {
setState(() {
_position = Duration.zero;
_playerState = PlayerState.stopped;
});
// Reset source when playback completes
_audioPlayer.setSource(UrlSource(_getFullAudioUrl()));
}
});
} }
String _getFullAudioUrl() { String _getFullAudioUrl() {
@ -96,6 +107,20 @@ class AudioPlayerWidgetState extends State<AudioPlayerWidget>
: '${widget.baseUrl ?? ''}${widget.audioFileName}'; : '${widget.baseUrl ?? ''}${widget.audioFileName}';
} }
Future<void> _replayAudio() async {
try {
await _audioPlayer.seek(Duration.zero);
await _audioPlayer.setSource(UrlSource(_getFullAudioUrl()));
await _audioPlayer.resume();
} catch (error) {
if (!_isDisposed) {
setState(() {
_errorMessage = "Failed to replay audio: $error";
});
}
}
}
Widget _buildErrorWidget() { Widget _buildErrorWidget() {
return Container( return Container(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
@ -174,7 +199,7 @@ class AudioPlayerWidgetState extends State<AudioPlayerWidget>
), ),
), ),
const SizedBox(width: 12), const SizedBox(width: 12),
_buildVolumeButton(), _buildReplayButton(),
], ],
), ),
if (_errorMessage != null) if (_errorMessage != null)
@ -204,17 +229,36 @@ class AudioPlayerWidgetState extends State<AudioPlayerWidget>
size: 32, size: 32,
), ),
onPressed: _isAudioLoaded onPressed: _isAudioLoaded
? () { ? () async {
if (_playerState == PlayerState.playing) { try {
_audioPlayer.pause(); if (_playerState == PlayerState.playing) {
} else { await _audioPlayer.pause();
_audioPlayer.resume(); } else {
await _audioPlayer.resume();
}
} catch (error) {
if (!_isDisposed) {
setState(() {
_errorMessage = "Failed to control playback: $error";
});
}
} }
} }
: null, : null,
); );
} }
Widget _buildReplayButton() {
return IconButton(
icon: const Icon(
Icons.replay,
color: Colors.blue,
size: 24,
),
onPressed: _isAudioLoaded ? _replayAudio : null,
);
}
Widget _buildTimelineIndicator() { Widget _buildTimelineIndicator() {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -243,9 +287,17 @@ class AudioPlayerWidgetState extends State<AudioPlayerWidget>
min: 0.0, min: 0.0,
max: _duration.inSeconds.toDouble(), max: _duration.inSeconds.toDouble(),
onChanged: _isAudioLoaded onChanged: _isAudioLoaded
? (value) { ? (value) async {
final position = Duration(seconds: value.toInt()); try {
_audioPlayer.seek(position); final position = Duration(seconds: value.toInt());
await _audioPlayer.seek(position);
} catch (error) {
if (!_isDisposed) {
setState(() {
_errorMessage = "Failed to seek: $error";
});
}
}
} }
: null, : null,
activeColor: Colors.blue, activeColor: Colors.blue,
@ -254,27 +306,6 @@ class AudioPlayerWidgetState extends State<AudioPlayerWidget>
); );
} }
Widget _buildVolumeButton() {
return IconButton(
icon: Icon(
_volume == 0.0 ? Icons.volume_off : Icons.volume_up,
color: _volume == 0.0 ? Colors.grey : Colors.blue,
size: 24,
),
onPressed: _isAudioLoaded
? () {
if (_volume == 0.0) {
_audioPlayer.setVolume(1.0);
setState(() => _volume = 1.0);
} else {
_audioPlayer.setVolume(0.0);
setState(() => _volume = 0.0);
}
}
: null,
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (_errorMessage != null) { if (_errorMessage != null) {

View File

@ -1,5 +1,6 @@
import 'package:english_learning/core/services/constants.dart'; import 'package:english_learning/core/services/constants.dart';
import 'package:english_learning/core/widgets/custom_snackbar.dart'; import 'package:english_learning/core/widgets/custom_snackbar.dart';
import 'package:english_learning/core/widgets/global_button.dart';
import 'package:english_learning/core/widgets/loading/shimmer_loading_widget.dart'; import 'package:english_learning/core/widgets/loading/shimmer_loading_widget.dart';
import 'package:english_learning/features/auth/provider/user_provider.dart'; import 'package:english_learning/features/auth/provider/user_provider.dart';
import 'package:english_learning/features/learning/modules/level/screens/level_list_screen.dart'; import 'package:english_learning/features/learning/modules/level/screens/level_list_screen.dart';
@ -126,25 +127,10 @@ class _TopicsListScreenState extends State<TopicsListScreen> {
), ),
), ),
Padding( Padding(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(32.0),
child: ElevatedButton.icon( child: GlobalButton(
style: ElevatedButton.styleFrom( text: 'Close',
backgroundColor: AppColors.primaryColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
padding: const EdgeInsets.symmetric(
vertical: 12, horizontal: 20),
),
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
icon: const Icon(Icons.close, color: Colors.white),
label: const Text(
'Close',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
), ),
), ),
], ],

View File

@ -5,22 +5,42 @@ import 'package:flutter/foundation.dart';
class SectionProvider extends ChangeNotifier { class SectionProvider extends ChangeNotifier {
final SectionRepository _repository = SectionRepository(); final SectionRepository _repository = SectionRepository();
List<Section> _sections = []; List<Section> _sections = [];
final bool _isLoading = false; bool _isLoading = false;
dynamic _error; dynamic _error;
List<Section> get sections => _sections; List<Section> get sections => _sections;
bool get isLoading => _isLoading; bool get isLoading => _isLoading;
String? get error => _error; String? get error => _error;
Future<List<Section>> fetchSections(String token) async { void resetData() {
_sections = [];
_error = null;
_isLoading = true;
notifyListeners();
}
Future<void> fetchSections(String token) async {
try { try {
// Set loading state
_isLoading = true;
_error = null;
notifyListeners();
// Fetch sections
_sections = await _repository.getSections(token); _sections = await _repository.getSections(token);
// Reset loading state
_isLoading = false;
_error = null;
notifyListeners(); notifyListeners();
return _sections;
} catch (e) { } catch (e) {
_error = e.toString(); // Handle error
_isLoading = false;
_error = e;
notifyListeners(); notifyListeners();
return [];
// Rethrow the error to be handled by the caller
rethrow;
} }
} }
} }

View File

@ -24,7 +24,9 @@ class _LearningScreenState extends State<LearningScreen>
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_initializeSections(); WidgetsBinding.instance.addPostFrameCallback((_) {
_initializeSections();
});
} }
Future<void> _initializeSections() async { Future<void> _initializeSections() async {
@ -32,45 +34,91 @@ class _LearningScreenState extends State<LearningScreen>
final sectionProvider = final sectionProvider =
Provider.of<SectionProvider>(context, listen: false); Provider.of<SectionProvider>(context, listen: false);
// Cek apakah sections sudah ada try {
if (sectionProvider.sections.isEmpty) { // Reset data sebelum fetch
try { sectionProvider.resetData(); // Tambahkan method ini di SectionProvider
final token = await userProvider.getValidToken();
if (token != null) { final token = await userProvider.getValidToken();
await sectionProvider.fetchSections(token); if (token != null) {
} await sectionProvider.fetchSections(token);
} catch (e) {
rethrow;
} finally {
setState(() {
_isInitialLoading = false;
});
} }
} else { } catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Failed to load data: ${e.toString()}'),
action: SnackBarAction(
label: 'Retry',
onPressed: _initializeSections,
),
),
);
}
} finally {
setState(() { setState(() {
_isInitialLoading = false; _isInitialLoading = false;
}); });
} }
} }
Future<void> _refreshSections() async { // Future<void> _refreshSections() async {
final userProvider = Provider.of<UserProvider>(context, listen: false); // final userProvider = Provider.of<UserProvider>(context, listen: false);
final sectionProvider = // final sectionProvider =
Provider.of<SectionProvider>(context, listen: false); // Provider.of<SectionProvider>(context, listen: false);
try { // try {
final token = await userProvider.getValidToken(); // final token = await userProvider.getValidToken();
if (token != null) { // if (token != null) {
await sectionProvider.fetchSections(token); // await sectionProvider.fetchSections(token);
} // }
} catch (e) { // } catch (e) {
ScaffoldMessenger.of(context).showSnackBar( // ScaffoldMessenger.of(context).showSnackBar(
SnackBar( // SnackBar(
content: Text('Failed to refresh sections: $e'), // content: Text('Failed to refresh sections: $e'),
backgroundColor: Colors.red, // backgroundColor: Colors.red,
), // ),
); // );
} // }
// }
Widget _buildErrorWidget(String error) {
return Container(
padding: const EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.error_outline,
size: 48,
color: Colors.red[300],
),
const SizedBox(height: 16),
Text(
'Oops! Something went wrong',
style: AppTextStyles.blackTextStyle.copyWith(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Text(
error,
textAlign: TextAlign.center,
style: AppTextStyles.disableTextStyle.copyWith(fontSize: 14),
),
const SizedBox(height: 16),
ElevatedButton.icon(
onPressed: _initializeSections,
icon: const Icon(Icons.refresh),
label: const Text('Retry'),
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.primaryColor,
foregroundColor: Colors.white,
),
),
],
),
);
} }
@override @override
@ -115,35 +163,13 @@ class _LearningScreenState extends State<LearningScreen>
// Tampilkan error jika ada // Tampilkan error jika ada
if (sectionProvider.error != null) { if (sectionProvider.error != null) {
return RefreshIndicator( return _buildErrorWidget(sectionProvider.error!);
onRefresh: _refreshSections,
child: ListView(
children: [
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Error: ${sectionProvider.error}',
style: AppTextStyles.greyTextStyle,
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _refreshSections,
child: const Text('Retry'),
)
],
),
),
],
),
);
} }
// Tampilkan sections atau pesan jika kosong // Tampilkan sections atau pesan jika kosong
if (sectionProvider.sections.isEmpty) { if (sectionProvider.sections.isEmpty) {
return RefreshIndicator( return RefreshIndicator(
onRefresh: _refreshSections, onRefresh: _initializeSections,
child: ListView( child: ListView(
children: [ children: [
Center( Center(
@ -165,7 +191,7 @@ class _LearningScreenState extends State<LearningScreen>
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
ElevatedButton( ElevatedButton(
onPressed: _refreshSections, onPressed: _initializeSections,
child: const Text('Refresh'), child: const Text('Refresh'),
) )
], ],
@ -178,7 +204,7 @@ class _LearningScreenState extends State<LearningScreen>
// Tampilkan daftar sections // Tampilkan daftar sections
return RefreshIndicator( return RefreshIndicator(
onRefresh: _refreshSections, onRefresh: _initializeSections,
child: ListView.builder( child: ListView.builder(
itemCount: sectionProvider.sections.length, itemCount: sectionProvider.sections.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {

View File

@ -107,7 +107,7 @@ class _OnBoardingScreenState extends State<OnBoardingScreen> {
currentPage: _currentPage, currentPage: _currentPage,
itemCount: controller.onBoardingData.length, itemCount: controller.onBoardingData.length,
), ),
SizedBox(height: screenHeight * 0.2), SizedBox(height: screenHeight * 0.08),
if (_currentPage == controller.onBoardingData.length - 1) if (_currentPage == controller.onBoardingData.length - 1)
Column( Column(
children: [ children: [

View File

@ -51,92 +51,92 @@ class _ChangePasswordScreenState extends State<ChangePasswordScreen> {
), ),
), ),
), ),
body: SingleChildScrollView( body: SingleChildScrollView(child: Consumer<ValidatorProvider>(
physics: const NeverScrollableScrollPhysics(), builder: (
child: Consumer<ValidatorProvider>( context,
builder: (context, validatorProvider, child) { validatorProvider,
return Padding( child,
padding: const EdgeInsets.symmetric( ) {
horizontal: 16.0, return Padding(
vertical: 22.0, padding: const EdgeInsets.symmetric(
horizontal: 16.0,
vertical: 22.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
CustomFieldWidget(
isRequired: true,
labelText: 'Old Password',
hintText: 'Enter your old password',
textInputAction: TextInputAction.next,
fieldName: 'Old Password',
obscureText: true,
controller: _oldPasswordController,
), ),
child: Column( const SizedBox(height: 12),
crossAxisAlignment: CrossAxisAlignment.center, CustomFieldWidget(
children: [ isRequired: true,
CustomFieldWidget( labelText: 'New Password',
isRequired: true, hintText: 'Enter your new password',
labelText: 'Old Password', textInputAction: TextInputAction.next,
hintText: 'Enter your old password', fieldName: 'new password',
textInputAction: TextInputAction.next, obscureText: true,
fieldName: 'Old Password', controller: _newPasswordController,
obscureText: true, ),
controller: _oldPasswordController, const SizedBox(height: 12),
), CustomFieldWidget(
const SizedBox(height: 12), isRequired: true,
CustomFieldWidget( labelText: 'Confirm New Password',
isRequired: true, hintText: 'Retype your new password',
labelText: 'New Password', textInputAction: TextInputAction.next,
hintText: 'Enter your new password', fieldName: 'confirm new password',
textInputAction: TextInputAction.next, obscureText: true,
fieldName: 'new password', controller: _confirmPasswordController,
obscureText: true, ),
controller: _newPasswordController, const SizedBox(height: 24),
), GlobalButton(
const SizedBox(height: 12), text: 'Update Now',
CustomFieldWidget( onPressed: () async {
isRequired: true, final userProvider =
labelText: 'Confirm New Password', Provider.of<UserProvider>(context, listen: false);
hintText: 'Retype your new password', bool success = await userProvider.updatePassword(
textInputAction: TextInputAction.next, oldPassword: _oldPasswordController.text,
fieldName: 'confirm new password', newPassword: _newPasswordController.text,
obscureText: true, confirmPassword: _confirmPasswordController.text,
controller: _confirmPasswordController, );
),
const SizedBox(height: 24),
GlobalButton(
text: 'Update Now',
onPressed: () async {
final userProvider =
Provider.of<UserProvider>(context, listen: false);
bool success = await userProvider.updatePassword(
oldPassword: _oldPasswordController.text,
newPassword: _newPasswordController.text,
confirmPassword: _confirmPasswordController.text,
);
if (success) { if (success) {
showDialog( showDialog(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
builder: (BuildContext context) { builder: (BuildContext context) {
return ChangePasswordDialog( return ChangePasswordDialog(
onSubmit: () { onSubmit: () {
Navigator.pushAndRemoveUntil( Navigator.pushAndRemoveUntil(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => builder: (context) => const SigninScreen()),
const SigninScreen()), (route) => false,
(route) => false,
);
},
); );
}, },
); );
} else { },
CustomSnackBar.show( );
context, } else {
message: CustomSnackBar.show(
'Failed to update password. Please try again.', context,
isError: true, message: 'Failed to update password. Please try again.',
); isError: true,
} );
}, }
) },
], )
), ],
); ),
}, );
)), },
)),
); );
} }
} }

View File

@ -89,6 +89,9 @@ class _EditProfileScreenState extends State<EditProfileScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final mediaQuery = MediaQuery.of(context);
final screenHeight = mediaQuery.size.height;
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
elevation: 0, elevation: 0,
@ -196,6 +199,7 @@ class _EditProfileScreenState extends State<EditProfileScreen> {
], ],
), ),
), ),
SizedBox(height: screenHeight * 0.05),
], ],
)); ));
}), }),

View File

@ -84,7 +84,7 @@ class LogoutConfirmation extends StatelessWidget {
const SizedBox(width: 10), const SizedBox(width: 10),
Expanded( Expanded(
child: GlobalButton( child: GlobalButton(
text: 'Yes, logout!', text: 'Yes',
onPressed: onSubmit, onPressed: onSubmit,
textColor: AppColors.whiteColor, textColor: AppColors.whiteColor,
backgroundColor: AppColors.redColor, backgroundColor: AppColors.redColor,

View File

@ -25,6 +25,9 @@ class SettingsScreen extends StatefulWidget {
class _SettingsScreenState extends State<SettingsScreen> { class _SettingsScreenState extends State<SettingsScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final mediaQuery = MediaQuery.of(context);
final screenHeight = mediaQuery.size.height;
final screenWidth = mediaQuery.size.width;
return Scaffold( return Scaffold(
backgroundColor: AppColors.bgSoftColor, backgroundColor: AppColors.bgSoftColor,
body: Consumer<UserProvider>(builder: (context, userProvider, child) { body: Consumer<UserProvider>(builder: (context, userProvider, child) {
@ -35,7 +38,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
children: [ children: [
Container( Container(
width: double.infinity, width: double.infinity,
height: 210, height: screenHeight * 0.33,
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: AppColors.gradientTheme, gradient: AppColors.gradientTheme,
borderRadius: const BorderRadius.only( borderRadius: const BorderRadius.only(
@ -44,8 +47,12 @@ class _SettingsScreenState extends State<SettingsScreen> {
), ),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.only( padding: EdgeInsets.only(
top: 71.0, left: 26, right: 16.0, bottom: 19.0), top: screenHeight * 0.1,
left: screenWidth * 0.07,
right: screenWidth * 0.04,
bottom: screenHeight * 0.03,
),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
@ -54,7 +61,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
Row( Row(
children: [ children: [
UserAvatar( UserAvatar(
radius: 60, radius: screenWidth * 0.15,
pictureUrl: userProvider.userData?['PICTURE'], pictureUrl: userProvider.userData?['PICTURE'],
baseUrl: '${mediaUrl}avatar/', baseUrl: '${mediaUrl}avatar/',
onImageSelected: (File image) { onImageSelected: (File image) {
@ -63,7 +70,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
selectedImage: userProvider.selectedImage, selectedImage: userProvider.selectedImage,
isLoading: userProvider.isLoading, isLoading: userProvider.isLoading,
), ),
const SizedBox(width: 28), const SizedBox(width: 16),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -72,7 +79,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
'Loading...', 'Loading...',
style: style:
AppTextStyles.whiteTextStyle.copyWith( AppTextStyles.whiteTextStyle.copyWith(
fontSize: 18, fontSize: screenWidth * 0.05,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
@ -82,9 +89,11 @@ class _SettingsScreenState extends State<SettingsScreen> {
'Loading...', 'Loading...',
style: style:
AppTextStyles.whiteTextStyle.copyWith( AppTextStyles.whiteTextStyle.copyWith(
fontSize: 14, fontSize: screenWidth * 0.036,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
overflow: TextOverflow.ellipsis,
maxLines: 1,
), ),
], ],
), ),

View File

@ -97,7 +97,7 @@ class WelcomeScreen extends StatelessWidget {
), ),
], ],
), ),
SizedBox(height: screenHeight * 0.1), SizedBox(height: screenHeight * 0.05),
], ],
), ),
), ),

View File

@ -14,10 +14,11 @@ 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_darwin
import url_launcher_macos import url_launcher_macos
import video_player_avfoundation import video_player_avfoundation
import wakelock_plus import wakelock_plus
import webview_flutter_wkwebview
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
@ -33,4 +34,5 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) 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"))
FLTWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "FLTWebViewFlutterPlugin"))
} }

View File

@ -5,34 +5,34 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: archive name: archive
sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d sha256: "08064924cbf0ab88280a0c3f60db9dd24fec693927e725ecb176f16c629d1cb8"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.6.1" version: "4.0.1"
args: args:
dependency: transitive dependency: transitive
description: description:
name: args name: args
sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.5.0" version: "2.6.0"
async: async:
dependency: transitive dependency: transitive
description: description:
name: async name: async
sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.12.0" version: "2.11.0"
audio_session: audio_session:
dependency: transitive dependency: transitive
description: description:
name: audio_session name: audio_session
sha256: "343e83bc7809fbda2591a49e525d6b63213ade10c76f15813be9aed6657b3261" sha256: b2a26ba8b7efa1790d6460e82971fde3e398cfbe2295df9dea22f3499d2c12a7
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.1.21" version: "0.1.23"
audioplayers: audioplayers:
dependency: "direct main" dependency: "direct main"
description: description:
@ -93,10 +93,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: boolean_selector name: boolean_selector
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.2" version: "2.1.1"
bootstrap_icons: bootstrap_icons:
dependency: "direct main" dependency: "direct main"
description: description:
@ -149,10 +149,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: charcode name: charcode
sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306 sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.1" version: "1.4.0"
checked_yaml: checked_yaml:
dependency: transitive dependency: transitive
description: description:
@ -181,10 +181,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: clock name: clock
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.2" version: "1.1.1"
collection: collection:
dependency: transitive dependency: transitive
description: description:
@ -205,18 +205,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: crypto name: crypto
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.3" version: "3.0.6"
csslib: csslib:
dependency: transitive dependency: transitive
description: description:
name: csslib name: csslib
sha256: "831883fb353c8bdc1d71979e5b342c7d88acfbc643113c14ae51e2442ea0f20f" sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.17.3" version: "1.0.2"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
@ -253,42 +253,42 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: fake_async name: fake_async
sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.2" version: "1.3.1"
ffi: ffi:
dependency: transitive dependency: transitive
description: description:
name: ffi name: ffi
sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21" sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.2" version: "2.1.3"
file: file:
dependency: transitive dependency: transitive
description: description:
name: file name: file
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "7.0.0" version: "7.0.1"
file_selector_linux: file_selector_linux:
dependency: transitive dependency: transitive
description: description:
name: file_selector_linux name: file_selector_linux
sha256: "045d372bf19b02aeb69cacf8b4009555fb5f6f0b7ad8016e5f46dd1387ddd492" sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.9.2+1" version: "0.9.3+2"
file_selector_macos: file_selector_macos:
dependency: transitive dependency: transitive
description: description:
name: file_selector_macos name: file_selector_macos
sha256: f42eacb83b318e183b1ae24eead1373ab1334084404c8c16e0354f9a3e55d385 sha256: "271ab9986df0c135d45c3cdb6bd0faa5db6f4976d3e4b437cf7d0f258d941bfc"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.9.4" version: "0.9.4+2"
file_selector_platform_interface: file_selector_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -301,18 +301,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: file_selector_windows name: file_selector_windows
sha256: "2ad726953f6e8affbc4df8dc78b77c3b4a060967a291e528ef72ae846c60fb69" sha256: "8f5d2f6590d51ecd9179ba39c64f722edc15226cc93dcc8698466ad36a4a85a4"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.9.3+2" version: "0.9.3+3"
fixnum: fixnum:
dependency: transitive dependency: transitive
description: description:
name: fixnum name: fixnum
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.0" version: "1.1.1"
flick_video_player: flick_video_player:
dependency: "direct main" dependency: "direct main"
description: description:
@ -354,10 +354,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: flutter_inappwebview_internal_annotations name: flutter_inappwebview_internal_annotations
sha256: "5f80fd30e208ddded7dbbcd0d569e7995f9f63d45ea3f548d8dd4c0b473fb4c8" sha256: "787171d43f8af67864740b6f04166c13190aa74a1468a1f1f1e9ee5b90c359cd"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.1" version: "1.2.0"
flutter_inappwebview_ios: flutter_inappwebview_ios:
dependency: transitive dependency: transitive
description: description:
@ -402,10 +402,10 @@ packages:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: flutter_launcher_icons name: flutter_launcher_icons
sha256: "619817c4b65b322b5104b6bb6dfe6cda62d9729bd7ad4303ecc8b4e690a67a77" sha256: "31cd0885738e87c72d6f055564d37fabcdacee743b396b78c7636c169cac64f5"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.14.1" version: "0.14.2"
flutter_lints: flutter_lints:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -418,10 +418,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: flutter_plugin_android_lifecycle name: flutter_plugin_android_lifecycle
sha256: "9ee02950848f61c4129af3d6ec84a1cfc0e47931abc746b03e7a3bc3e8ff6eda" sha256: "9b78450b89f059e96c9ebb355fa6b3df1d6b330436e0b885fb49594c41721398"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.22" version: "2.0.23"
flutter_secure_storage: flutter_secure_storage:
dependency: "direct main" dependency: "direct main"
description: description:
@ -474,10 +474,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_svg name: flutter_svg
sha256: "7b4ca6cf3304575fe9c8ec64813c8d02ee41d2afe60bcfe0678bcb5375d596a2" sha256: "54900a1a1243f3c4a5506d853a2b5c2dbc38d5f27e52a52618a8054401431123"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.10+1" version: "2.0.16"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -492,10 +492,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_widget_from_html name: flutter_widget_from_html
sha256: "9e2a6201c4d2eb910b6b3ebb2a9f5c490fc61c9a1aa35eafdde38f0fc659cf4c" sha256: f3967a5b42896662efdd420b5adaf8a7d3692b0f44462a07c80e3b4c173b1a02
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.15.2" version: "0.15.3"
flutter_widget_from_html_core: flutter_widget_from_html_core:
dependency: transitive dependency: transitive
description: description:
@ -548,10 +548,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: fwfh_webview name: fwfh_webview
sha256: f67890bc0d6278da98bd197469ae9511c859f7db327e92299fe0ea0cf46c4057 sha256: c0a8b664b642f40f4c252a0ab4e72c22dcd97c7fb3a7e50a6b4bdb6f63afca19
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.15.2" version: "0.15.3"
google_fonts: google_fonts:
dependency: "direct main" dependency: "direct main"
description: description:
@ -564,18 +564,18 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: google_nav_bar name: google_nav_bar
sha256: "1c8e3882fa66ee7b74c24320668276ca23affbd58f0b14a24c1e5590f4d07ab0" sha256: bb12dd21514ee1b041ab3127673e2fd85e693337df308f7f2b75cd1e8e92eaf4
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.0.6" version: "5.0.7"
html: html:
dependency: "direct main" dependency: "direct main"
description: description:
name: html name: html
sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" sha256: "1fc58edeaec4307368c60d59b7e15b9d658b57d7f3125098b6294153c75337ec"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.15.4" version: "0.15.5"
http: http:
dependency: transitive dependency: transitive
description: description:
@ -588,18 +588,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: http_parser name: http_parser
sha256: "40f592dd352890c3b60fec1b68e786cefb9603e05ff303dbc4dda49b304ecdf4" sha256: "76d306a1c3afb33fe82e2bbacad62a61f409b5634c915fceb0d799de1a913360"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.1.0" version: "4.1.1"
image: image:
dependency: transitive dependency: transitive
description: description:
name: image name: image
sha256: f31d52537dc417fdcde36088fdf11d191026fd5e4fae742491ebd40e5a8bea7d sha256: "599d08e369969bdf83138f5b4e0a7e823d3f992f23b8a64dd626877c37013533"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.3.0" version: "4.4.0"
image_picker: image_picker:
dependency: "direct main" dependency: "direct main"
description: description:
@ -612,26 +612,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: image_picker_android name: image_picker_android
sha256: "8c5abf0dcc24fe6e8e0b4a5c0b51a5cf30cefdf6407a3213dae61edc75a70f56" sha256: fa8141602fde3f7e2f81dbf043613eb44dfa325fa0bcf93c0f142c9f7a2c193e
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.8.12+12" version: "0.8.12+18"
image_picker_for_web: image_picker_for_web:
dependency: transitive dependency: transitive
description: description:
name: image_picker_for_web name: image_picker_for_web
sha256: "65d94623e15372c5c51bebbcb820848d7bcb323836e12dfdba60b5d3a8b39e50" sha256: "717eb042ab08c40767684327be06a5d8dbb341fe791d514e4b92c7bbe1b7bb83"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.5" version: "3.0.6"
image_picker_ios: image_picker_ios:
dependency: transitive dependency: transitive
description: description:
name: image_picker_ios name: image_picker_ios
sha256: "6703696ad49f5c3c8356d576d7ace84d1faf459afb07accbb0fae780753ff447" sha256: "4f0568120c6fcc0aaa04511cb9f9f4d29fc3d0139884b1d06be88dcec7641d6b"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.8.12" version: "0.8.12+1"
image_picker_linux: image_picker_linux:
dependency: transitive dependency: transitive
description: description:
@ -724,18 +724,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker name: leak_tracker
sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "10.0.8" version: "10.0.7"
leak_tracker_flutter_testing: leak_tracker_flutter_testing:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker_flutter_testing name: leak_tracker_flutter_testing
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.9" version: "3.0.8"
leak_tracker_testing: leak_tracker_testing:
dependency: transitive dependency: transitive
description: description:
@ -788,10 +788,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: mime name: mime
sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a" sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.6" version: "2.0.0"
nested: nested:
dependency: transitive dependency: transitive
description: description:
@ -812,34 +812,34 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: package_info_plus name: package_info_plus
sha256: a75164ade98cb7d24cfd0a13c6408927c6b217fa60dee5a7ff5c116a58f28918 sha256: "70c421fe9d9cc1a9a7f3b05ae56befd469fe4f8daa3b484823141a55442d858d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "8.0.2" version: "8.1.2"
package_info_plus_platform_interface: package_info_plus_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: package_info_plus_platform_interface name: package_info_plus_platform_interface
sha256: ac1f4a4847f1ade8e6a87d1f39f5d7c67490738642e2542f559ec38c37489a66 sha256: a5ef9986efc7bf772f2696183a3992615baa76c1ffb1189318dd8803778fb05b
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.1" version: "3.0.2"
path: path:
dependency: transitive dependency: transitive
description: description:
name: path name: path
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.1" version: "1.9.0"
path_parsing: path_parsing:
dependency: transitive dependency: transitive
description: description:
name: path_parsing name: path_parsing
sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.1" version: "1.1.0"
path_provider: path_provider:
dependency: transitive dependency: transitive
description: description:
@ -852,18 +852,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: path_provider_android name: path_provider_android
sha256: "490539678396d4c3c0b06efdaab75ae60675c3e0c66f72bc04c2e2c1e0e2abeb" sha256: "4adf4fd5423ec60a29506c76581bc05854c55e3a0b72d35bb28d661c9686edf2"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.9" version: "2.2.15"
path_provider_foundation: path_provider_foundation:
dependency: transitive dependency: transitive
description: description:
name: path_provider_foundation name: path_provider_foundation
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.0" version: "2.4.1"
path_provider_linux: path_provider_linux:
dependency: transitive dependency: transitive
description: description:
@ -900,10 +900,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: platform name: platform
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.5" version: "3.1.6"
plugin_platform_interface: plugin_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -912,6 +912,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.8" version: "2.1.8"
posix:
dependency: transitive
description:
name: posix
sha256: a0117dc2167805aa9125b82eee515cc891819bac2f538c83646d355b16f58b9a
url: "https://pub.dev"
source: hosted
version: "6.0.1"
provider: provider:
dependency: "direct main" dependency: "direct main"
description: description:
@ -932,26 +940,26 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: shared_preferences name: shared_preferences
sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051" sha256: "95f9997ca1fb9799d494d0cb2a780fd7be075818d59f00c43832ed112b158a82"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.2" version: "2.3.3"
shared_preferences_android: shared_preferences_android:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_android name: shared_preferences_android
sha256: "480ba4345773f56acda9abf5f50bd966f581dac5d514e5fc4a18c62976bbba7e" sha256: "02a7d8a9ef346c9af715811b01fbd8e27845ad2c41148eefd31321471b41863d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.2" version: "2.4.0"
shared_preferences_foundation: shared_preferences_foundation:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_foundation name: shared_preferences_foundation
sha256: c4b35f6cb8f63c147312c054ce7c2254c8066745125264f0c88739c417fc9d9f sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.5.2" version: "2.5.4"
shared_preferences_linux: shared_preferences_linux:
dependency: transitive dependency: transitive
description: description:
@ -1017,18 +1025,42 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: sqflite name: sqflite
sha256: a43e5a27235518c03ca238e7b4732cf35eabe863a369ceba6cbefa537a66f16d sha256: "2d7299468485dca85efeeadf5d38986909c5eb0cd71fd3db2c2f000e6c9454bb"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.3+1" version: "2.4.1"
sqflite_android:
dependency: transitive
description:
name: sqflite_android
sha256: "78f489aab276260cdd26676d2169446c7ecd3484bbd5fead4ca14f3ed4dd9ee3"
url: "https://pub.dev"
source: hosted
version: "2.4.0"
sqflite_common: sqflite_common:
dependency: transitive dependency: transitive
description: description:
name: sqflite_common name: sqflite_common
sha256: "4058172e418eb7e7f2058dcb7657d451a8fc264afa0dea4dbd0f304a57131611" sha256: "761b9740ecbd4d3e66b8916d784e581861fd3c3553eda85e167bc49fdb68f709"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.5.4+3" version: "2.5.4+6"
sqflite_darwin:
dependency: transitive
description:
name: sqflite_darwin
sha256: "96a698e2bc82bd770a4d6aab00b42396a7c63d9e33513a56945cbccb594c2474"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
sqflite_platform_interface:
dependency: transitive
description:
name: sqflite_platform_interface
sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920"
url: "https://pub.dev"
source: hosted
version: "2.4.0"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -1049,18 +1081,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: string_scanner name: string_scanner
sha256: "0bd04f5bb74fcd6ff0606a888a30e917af9bd52820b178eaa464beb11dca84b6" sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.0" version: "1.3.0"
synchronized: synchronized:
dependency: transitive dependency: transitive
description: description:
name: synchronized name: synchronized
sha256: "51b08572b9f091f8c3eb4d9d4be253f196ff0075d5ec9b10a884026d5b55d7bc" sha256: "69fe30f3a8b04a0be0c15ae6490fc859a78ef4c43ae2dd5e8a623d45bfcf9225"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.3.0+2" version: "3.3.0+3"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
@ -1081,10 +1113,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: typed_data name: typed_data
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.2" version: "1.4.0"
universal_html: universal_html:
dependency: transitive dependency: transitive
description: description:
@ -1113,34 +1145,34 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_android name: url_launcher_android
sha256: f0c73347dfcfa5b3db8bc06e1502668265d39c08f310c29bff4e28eea9699f79 sha256: "6fc2f56536ee873eeb867ad176ae15f304ccccc357848b351f6f0d8d4a40d193"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.3.9" version: "6.3.14"
url_launcher_ios: url_launcher_ios:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_ios name: url_launcher_ios
sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e sha256: "16a513b6c12bb419304e72ea0ae2ab4fed569920d1c7cb850263fe3acc824626"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.3.1" version: "6.3.2"
url_launcher_linux: url_launcher_linux:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_linux name: url_launcher_linux
sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.2.0" version: "3.2.1"
url_launcher_macos: url_launcher_macos:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_macos name: url_launcher_macos
sha256: "769549c999acdb42b8bcfa7c43d72bf79a382ca7441ab18a808e101149daf672" sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.2.1" version: "3.2.2"
url_launcher_platform_interface: url_launcher_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -1169,34 +1201,34 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: uuid name: uuid
sha256: f33d6bb662f0e4f79dcd7ada2e6170f3b3a2530c28fc41f49a411ddedd576a77 sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.5.0" version: "4.5.1"
vector_graphics: vector_graphics:
dependency: transitive dependency: transitive
description: description:
name: vector_graphics name: vector_graphics
sha256: "32c3c684e02f9bc0afb0ae0aa653337a2fe022e8ab064bcd7ffda27a74e288e3" sha256: "27d5fefe86fb9aace4a9f8375b56b3c292b64d8c04510df230f849850d912cb7"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.11+1" version: "1.1.15"
vector_graphics_codec: vector_graphics_codec:
dependency: transitive dependency: transitive
description: description:
name: vector_graphics_codec name: vector_graphics_codec
sha256: c86987475f162fadff579e7320c7ddda04cd2fdeffbe1129227a85d9ac9e03da sha256: "2430b973a4ca3c4dbc9999b62b8c719a160100dcbae5c819bae0cacce32c9cdb"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.11+1" version: "1.1.12"
vector_graphics_compiler: vector_graphics_compiler:
dependency: transitive dependency: transitive
description: description:
name: vector_graphics_compiler name: vector_graphics_compiler
sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81" sha256: "1b4b9e706a10294258727674a340ae0d6e64a7231980f9f9a3d12e4b42407aad"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.11+1" version: "1.1.16"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
@ -1209,50 +1241,50 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: video_player name: video_player
sha256: e30df0d226c4ef82e2c150ebf6834b3522cf3f654d8e2f9419d376cdc071425d sha256: "4a8c3492d734f7c39c2588a3206707a05ee80cef52e8c7f3b2078d430c84bc17"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.9.1" version: "2.9.2"
video_player_android: video_player_android:
dependency: transitive dependency: transitive
description: description:
name: video_player_android name: video_player_android
sha256: e343701aa890b74a863fa460f5c0e628127ed06a975d7d9af6b697133fb25bdf sha256: "391e092ba4abe2f93b3e625bd6b6a6ec7d7414279462c1c0ee42b5ab8d0a0898"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.7.1" version: "2.7.16"
video_player_avfoundation: video_player_avfoundation:
dependency: transitive dependency: transitive
description: description:
name: video_player_avfoundation name: video_player_avfoundation
sha256: d1e9a824f2b324000dc8fb2dcb2a3285b6c1c7c487521c63306cc5b394f68a7c sha256: "33224c19775fd244be2d6e3dbd8e1826ab162877bd61123bf71890772119a2b7"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.6.1" version: "2.6.5"
video_player_platform_interface: video_player_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: video_player_platform_interface name: video_player_platform_interface
sha256: "236454725fafcacf98f0f39af0d7c7ab2ce84762e3b63f2cbb3ef9a7e0550bc6" sha256: "229d7642ccd9f3dc4aba169609dd6b5f3f443bb4cc15b82f7785fcada5af9bbb"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.2.2" version: "6.2.3"
video_player_web: video_player_web:
dependency: transitive dependency: transitive
description: description:
name: video_player_web name: video_player_web
sha256: "6dcdd298136523eaf7dfc31abaf0dfba9aa8a8dbc96670e87e9d42b6f2caf774" sha256: "881b375a934d8ebf868c7fb1423b2bfaa393a0a265fa3f733079a86536064a10"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.2" version: "2.3.3"
vm_service: vm_service:
dependency: transitive dependency: transitive
description: description:
name: vm_service name: vm_service
sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "14.3.1" version: "14.3.0"
wakelock_plus: wakelock_plus:
dependency: transitive dependency: transitive
description: description:
@ -1273,26 +1305,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: web name: web
sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062 sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.0" version: "1.1.0"
webview_flutter: webview_flutter:
dependency: transitive dependency: transitive
description: description:
name: webview_flutter name: webview_flutter
sha256: "6869c8786d179f929144b4a1f86e09ac0eddfe475984951ea6c634774c16b522" sha256: "889a0a678e7c793c308c68739996227c9661590605e70b1f6cf6b9a6634f7aec"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.8.0" version: "4.10.0"
webview_flutter_android: webview_flutter_android:
dependency: transitive dependency: transitive
description: description:
name: webview_flutter_android name: webview_flutter_android
sha256: ed021f27ae621bc97a6019fb601ab16331a3db4bf8afa305e9f6689bdb3edced sha256: "3d535126f7244871542b2f0b0fcf94629c9a14883250461f9abe1a6644c1c379"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.16.8" version: "4.2.0"
webview_flutter_platform_interface: webview_flutter_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -1305,26 +1337,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: webview_flutter_wkwebview name: webview_flutter_wkwebview
sha256: "9c62cc46fa4f2d41e10ab81014c1de470a6c6f26051a2de32111b2ee55287feb" sha256: b7e92f129482460951d96ef9a46b49db34bd2e1621685de26e9eaafd9674e7eb
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.14.0" version: "3.16.3"
win32: win32:
dependency: transitive dependency: transitive
description: description:
name: win32 name: win32
sha256: "68d1e89a91ed61ad9c370f9f8b6effed9ae5e0ede22a270bdfa6daf79fc2290a" sha256: "8b338d4486ab3fbc0ba0db9f9b4f5239b6697fcee427939a40e720cbb9ee0a69"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.5.4" version: "5.9.0"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:
name: xdg_directories name: xdg_directories
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.4" version: "1.1.0"
xml: xml:
dependency: transitive dependency: transitive
description: description: