Compare commits
3 Commits
2d5039486f
...
b97e672dfe
| Author | SHA1 | Date | |
|---|---|---|---|
| b97e672dfe | |||
| 9932293b62 | |||
| d5cf29fa13 |
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:yimaru_app/models/option.dart';
|
||||
|
||||
part 'learn_question.g.dart';
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class VoiceRecorderService with ListenableServiceMixin {
|
|||
|
||||
WaveformRecorderController get waveController => _waveController;
|
||||
|
||||
bool _isRecording = false;
|
||||
final bool _isRecording = false;
|
||||
|
||||
bool get isRecording => _isRecording;
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ enum DuolingoAssessments { speaking, reading, writing, listening }
|
|||
enum StateObjects {
|
||||
none,
|
||||
courses,
|
||||
homeView,
|
||||
startupView,
|
||||
register,
|
||||
verifyOtp,
|
||||
resendOtp,
|
||||
|
|
|
|||
|
|
@ -240,8 +240,8 @@ class AssessmentViewModel extends BaseViewModel {
|
|||
// Navigation
|
||||
void pop() => _navigationService.back();
|
||||
|
||||
Future<void> replaceWithHome() async =>
|
||||
await _navigationService.clearStackAndShow(Routes.homeView);
|
||||
Future<void> replaceWithStartUp() async =>
|
||||
await _navigationService.clearStackAndShow(Routes.startupView);
|
||||
|
||||
Future<void> navigateToLanguage() async =>
|
||||
await _navigationService.navigateToLanguageView();
|
||||
|
|
@ -259,7 +259,7 @@ class AssessmentViewModel extends BaseViewModel {
|
|||
await _apiService.completeProfile(_userData);
|
||||
if (response['status'] == ResponseStatus.success) {
|
||||
clearUserData();
|
||||
await replaceWithHome();
|
||||
await replaceWithStartUp();
|
||||
showSuccessToast(response['message']);
|
||||
} else {
|
||||
showErrorToast(response['message']);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
|
|||
import 'package:stacked/stacked.dart';
|
||||
import 'package:yimaru_app/ui/common/app_colors.dart';
|
||||
import 'package:yimaru_app/ui/common/enmus.dart';
|
||||
import 'package:yimaru_app/ui/views/course_category/course_category_view.dart';
|
||||
import 'package:yimaru_app/ui/views/learn_program/learn_program_view.dart';
|
||||
import 'package:yimaru_app/ui/views/profile/profile_view.dart';
|
||||
import 'package:yimaru_app/ui/views/startup/startup_view.dart';
|
||||
|
|
@ -16,27 +15,12 @@ class HomeView extends StackedView<HomeViewModel> {
|
|||
@override
|
||||
HomeViewModel viewModelBuilder(BuildContext context) => HomeViewModel();
|
||||
|
||||
@override
|
||||
void onViewModelReady(HomeViewModel viewModel) async {
|
||||
// Removable
|
||||
await _init(viewModel);
|
||||
super.onViewModelReady(viewModel);
|
||||
}
|
||||
|
||||
Future<void> _init(HomeViewModel viewModel) async =>
|
||||
await viewModel.initialize();
|
||||
|
||||
@override
|
||||
Widget builder(
|
||||
BuildContext context, HomeViewModel viewModel, Widget? child) =>
|
||||
_buildScaffoldWrapper(viewModel);
|
||||
_buildScaffold(viewModel);
|
||||
|
||||
Widget _buildScaffoldWrapper(HomeViewModel viewModel) =>
|
||||
viewModel.busy(StateObjects.homeView)
|
||||
? _buildStartUpView()
|
||||
: _buildScaffold(viewModel);
|
||||
|
||||
Widget _buildStartUpView() => const StartupView(label: 'Checking user info');
|
||||
|
||||
Widget _buildScaffold(HomeViewModel viewModel) => Scaffold(
|
||||
body: getViewForIndex(viewModel.currentPage),
|
||||
|
|
|
|||
|
|
@ -14,12 +14,9 @@ import '../../common/enmus.dart';
|
|||
import '../../common/ui_helpers.dart';
|
||||
|
||||
class HomeViewModel extends ReactiveViewModel {
|
||||
final _apiService = locator<ApiService>();
|
||||
final _statusChecker = locator<StatusCheckerService>();
|
||||
final _navigationService = locator<NavigationService>();
|
||||
|
||||
final _bottomSheetService = locator<BottomSheetService>();
|
||||
final _authenticationService = locator<AuthenticationService>();
|
||||
final _imageDownloaderService = locator<ImageDownloaderService>();
|
||||
|
||||
@override
|
||||
List<ListenableServiceMixin> get listenableServices =>
|
||||
|
|
@ -49,75 +46,9 @@ class HomeViewModel extends ReactiveViewModel {
|
|||
rebuildUi();
|
||||
}
|
||||
|
||||
// Save profile status
|
||||
Future<void> saveProfileStatus(bool value) async =>
|
||||
await _authenticationService.saveProfileStatus(value);
|
||||
|
||||
// Navigation
|
||||
Future<void> replaceWithFailure() async => await _navigationService
|
||||
.replaceWithFailureView(label: 'Check you internet connection');
|
||||
|
||||
Future<void> replaceWithOnboarding() async =>
|
||||
await _navigationService.replaceWithOnboardingView();
|
||||
|
||||
// Remote api calls
|
||||
|
||||
// Initialize user data
|
||||
Future<void> initialize() async =>
|
||||
await runBusyFuture(_initialize(), busyObject: StateObjects.homeView);
|
||||
|
||||
Future<void> _initialize() async {
|
||||
await _getProfileStatus();
|
||||
await _getProfileData();
|
||||
}
|
||||
|
||||
// Get profile data
|
||||
Future<void> _getProfileData() async {
|
||||
if (!(_user?.userInfoLoaded ?? false)) {
|
||||
Map<String, dynamic> response = {};
|
||||
|
||||
if (_user?.profileCompleted != null &&
|
||||
(_user?.profileCompleted ?? false)) {
|
||||
if (await _statusChecker.checkConnection()) {
|
||||
response = await _apiService.getProfileData(_user?.userId);
|
||||
|
||||
if (response['status'] == ResponseStatus.success) {
|
||||
User user = response['data'] as User;
|
||||
|
||||
await _authenticationService.saveUserData(user);
|
||||
|
||||
String image =
|
||||
await _imageDownloaderService.downloader(user.profilePicture);
|
||||
|
||||
await _authenticationService.saveProfilePicture(image);
|
||||
}
|
||||
} else {
|
||||
await replaceWithFailure();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get profile status
|
||||
Future<void> _getProfileStatus() async {
|
||||
Map<String, dynamic> response = {};
|
||||
if (_user?.profileCompleted == null) {
|
||||
if (await _statusChecker.checkConnection()) {
|
||||
response = await _apiService.getProfileStatus(_user);
|
||||
} else {
|
||||
await Future.delayed(kDuration);
|
||||
await replaceWithFailure();
|
||||
}
|
||||
} else if (!(_user?.profileCompleted ?? false)) {
|
||||
response = {'data': false, 'status': ResponseStatus.success};
|
||||
} else {
|
||||
response = {'data': true, 'status': ResponseStatus.success};
|
||||
}
|
||||
if (response['status'] == ResponseStatus.success && !response['data']) {
|
||||
await replaceWithOnboarding();
|
||||
} else if (response['status'] == ResponseStatus.success &&
|
||||
response['data']) {
|
||||
await saveProfileStatus(response['data']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
import 'package:stacked/stacked.dart';
|
||||
import 'package:stacked_services/stacked_services.dart';
|
||||
import 'package:yimaru_app/app/app.router.dart';
|
||||
import 'package:yimaru_app/ui/common/enmus.dart';
|
||||
|
||||
import '../../../app/app.locator.dart';
|
||||
|
|
|
|||
|
|
@ -5,9 +5,7 @@ import 'package:yimaru_app/ui/views/learn_practice/screens/finish_learn_practice
|
|||
import 'package:yimaru_app/ui/views/learn_practice/screens/learn_practice_completion_screen.dart';
|
||||
import 'package:yimaru_app/ui/views/learn_practice/screens/learn_practice_result_screen.dart';
|
||||
import 'package:yimaru_app/ui/views/learn_practice/screens/learn_practice_questions_screen.dart';
|
||||
import 'package:yimaru_app/ui/views/learn_practice/screens/interact_learn_practice_screen.dart';
|
||||
import 'package:yimaru_app/ui/views/learn_practice/screens/learn_practice_intro_screen.dart';
|
||||
import 'package:yimaru_app/ui/views/learn_practice/screens/start_learn_practice_screen.dart';
|
||||
import 'package:yimaru_app/ui/widgets/page_loading_indicator.dart';
|
||||
|
||||
import '../../common/app_colors.dart';
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import 'package:yimaru_app/ui/common/enmus.dart';
|
|||
|
||||
import '../../../app/app.locator.dart';
|
||||
import '../../../models/learn_question.dart';
|
||||
import '../../../models/question.dart';
|
||||
import '../../../services/api_service.dart';
|
||||
import '../../../services/audio_player_service.dart';
|
||||
import '../../../services/status_checker_service.dart';
|
||||
|
|
@ -96,7 +95,7 @@ class LearnPracticeViewModel extends ReactiveViewModel {
|
|||
List<LearnQuestion> get questions => _questions;
|
||||
|
||||
// Practice answers
|
||||
List<Map<String, dynamic>> _answers = [];
|
||||
final List<Map<String, dynamic>> _answers = [];
|
||||
|
||||
List<Map<String, dynamic>> get answers => _answers;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:stacked/stacked.dart';
|
||||
import 'package:yimaru_app/models/learn_practice.dart';
|
||||
import 'package:yimaru_app/ui/views/learn_practice/learn_practice_viewmodel.dart';
|
||||
|
||||
import '../../../common/app_colors.dart';
|
||||
|
|
|
|||
|
|
@ -1,14 +1,8 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_carousel_widget/flutter_carousel_widget.dart';
|
||||
import 'package:stacked/stacked.dart';
|
||||
import 'package:yimaru_app/models/learn_question.dart';
|
||||
import 'package:yimaru_app/models/practice.dart';
|
||||
import 'package:yimaru_app/ui/views/learn_practice/screens/start_learn_practice_screen.dart';
|
||||
import 'package:yimaru_app/ui/widgets/learn_practice_card.dart';
|
||||
|
||||
import '../../../common/app_colors.dart';
|
||||
import '../../../common/ui_helpers.dart';
|
||||
import '../../../widgets/small_app_bar.dart';
|
||||
import '../learn_practice_viewmodel.dart';
|
||||
import 'interact_learn_practice_screen.dart';
|
||||
|
||||
|
|
|
|||
|
|
@ -154,8 +154,7 @@ class LoginViewModel extends ReactiveViewModel
|
|||
}
|
||||
|
||||
// Navigation
|
||||
Future<void> replaceWithHome() async =>
|
||||
await _navigationService.clearStackAndShow(Routes.homeView);
|
||||
|
||||
|
||||
Future<void> navigateToRegister() async =>
|
||||
await _navigationService.navigateToRegisterView();
|
||||
|
|
@ -163,6 +162,12 @@ class LoginViewModel extends ReactiveViewModel
|
|||
Future<void> navigateToForgetPassword() async =>
|
||||
await _navigationService.navigateToForgetPasswordView();
|
||||
|
||||
Future<void> replaceWithStartUp() async =>
|
||||
await _navigationService.clearStackAndShow(Routes.startupView);
|
||||
|
||||
|
||||
|
||||
|
||||
// Remote api calls
|
||||
|
||||
// Login with email
|
||||
|
|
@ -182,7 +187,7 @@ class LoginViewModel extends ReactiveViewModel
|
|||
|
||||
await _authenticationService.saveUserCredential(data);
|
||||
clearUserData();
|
||||
await replaceWithHome();
|
||||
await replaceWithStartUp();
|
||||
showSuccessToast(response['message']);
|
||||
} else {
|
||||
showErrorToast(response['message']);
|
||||
|
|
@ -210,7 +215,7 @@ class LoginViewModel extends ReactiveViewModel
|
|||
};
|
||||
await _authenticationService.saveUserCredential(data);
|
||||
clearUserData();
|
||||
await replaceWithHome();
|
||||
await replaceWithStartUp();
|
||||
showSuccessToast(response['message']);
|
||||
} else {
|
||||
showErrorToast(response['message']);
|
||||
|
|
@ -251,7 +256,7 @@ class LoginViewModel extends ReactiveViewModel
|
|||
};
|
||||
|
||||
await _authenticationService.saveUserCredential(data);
|
||||
await replaceWithHome();
|
||||
await replaceWithStartUp();
|
||||
showSuccessToast(response['message']);
|
||||
} else {
|
||||
showErrorToast(response['message']);
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ class OnboardingView extends StackedView<OnboardingViewModel>
|
|||
|
||||
void _initUserData(OnboardingViewModel viewModel) {
|
||||
fullNameController.text = viewModel.googleUser?.displayName ?? '';
|
||||
print('Full-NAME: ${fullNameController.text}');
|
||||
}
|
||||
|
||||
void _initClearData() {
|
||||
|
|
|
|||
|
|
@ -614,6 +614,5 @@ class OnboardingViewModel extends ReactiveViewModel
|
|||
Future<void> navigateToAssessment() async =>
|
||||
await _navigationService.navigateToAssessmentView(data: _userData);
|
||||
|
||||
Future<void> replaceWithHome() async =>
|
||||
await _navigationService.clearStackAndShow(Routes.homeView);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@ class RegisterViewModel extends ReactiveViewModel
|
|||
implements FormViewModel {
|
||||
final _apiService = locator<ApiService>();
|
||||
|
||||
final _smartAuthService = locator<SmartAuthService>();
|
||||
|
||||
final _statusChecker = locator<StatusCheckerService>();
|
||||
|
||||
final _navigationService = locator<NavigationService>();
|
||||
|
|
@ -297,8 +295,8 @@ class RegisterViewModel extends ReactiveViewModel
|
|||
Future<void> replaceToLogin() async =>
|
||||
await _navigationService.replaceWithLoginView();
|
||||
|
||||
Future<void> replaceWithHome() async =>
|
||||
await _navigationService.clearStackAndShow(Routes.homeView);
|
||||
Future<void> replaceWithStartUp() async =>
|
||||
await _navigationService.clearStackAndShow(Routes.startupView);
|
||||
|
||||
// Remote api calls
|
||||
|
||||
|
|
@ -344,7 +342,7 @@ class RegisterViewModel extends ReactiveViewModel
|
|||
};
|
||||
await _authenticationService.saveUserCredential(data);
|
||||
clearUserData();
|
||||
await replaceWithHome();
|
||||
await replaceWithStartUp();
|
||||
showSuccessToast(response['message']);
|
||||
} else {
|
||||
showErrorToast(response['message']);
|
||||
|
|
@ -367,7 +365,7 @@ class RegisterViewModel extends ReactiveViewModel
|
|||
};
|
||||
|
||||
await _authenticationService.saveUserCredential(data);
|
||||
await replaceWithHome();
|
||||
await replaceWithStartUp();
|
||||
showSuccessToast(response['message']);
|
||||
} else {
|
||||
showErrorToast(response['message']);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import 'package:yimaru_app/ui/common/ui_helpers.dart';
|
|||
import 'package:yimaru_app/ui/widgets/custom_circular_progress_indicator.dart';
|
||||
|
||||
import '../../common/app_colors.dart';
|
||||
import '../../common/enmus.dart';
|
||||
import 'startup_viewmodel.dart';
|
||||
|
||||
class StartupView extends StackedView<StartupViewModel> {
|
||||
|
|
@ -18,13 +19,20 @@ class StartupView extends StackedView<StartupViewModel> {
|
|||
StartupViewModel viewModel,
|
||||
Widget? child,
|
||||
) =>
|
||||
_buildScaffoldWrapper();
|
||||
_buildScaffoldWrapper(viewModel);
|
||||
|
||||
Widget _buildScaffoldWrapper() => Scaffold(
|
||||
Widget _buildScaffoldWrapper(StartupViewModel viewModel) => Scaffold(
|
||||
backgroundColor: kcBackgroundColor,
|
||||
body: _buildScaffold(),
|
||||
body: _buildScaffoldState(viewModel),
|
||||
);
|
||||
|
||||
Widget _buildScaffoldState(StartupViewModel viewModel) =>
|
||||
viewModel.busy(StateObjects.startupView)
|
||||
? _buildStartUpView()
|
||||
: _buildScaffold();
|
||||
|
||||
Widget _buildStartUpView() => const StartupView(label: 'Checking user info');
|
||||
|
||||
Widget _buildScaffold() => Stack(
|
||||
children: _buildScaffoldChildren(),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -5,14 +5,31 @@ import 'package:yimaru_app/services/in_app_update_service.dart';
|
|||
|
||||
import '../../../app/app.locator.dart';
|
||||
import '../../../app/app.router.dart';
|
||||
import '../../../models/user.dart';
|
||||
import '../../../services/api_service.dart';
|
||||
import '../../../services/image_downloader_service.dart';
|
||||
import '../../../services/status_checker_service.dart';
|
||||
import '../../common/enmus.dart';
|
||||
import '../../common/ui_helpers.dart';
|
||||
|
||||
class StartupViewModel extends BaseViewModel {
|
||||
class StartupViewModel extends ReactiveViewModel {
|
||||
// Dependency injection
|
||||
final _apiService = locator<ApiService>();
|
||||
final _statusChecker = locator<StatusCheckerService>();
|
||||
final _navigationService = locator<NavigationService>();
|
||||
final _inAppUpdateService = locator<InAppUpdateService>();
|
||||
final _authenticationService = locator<AuthenticationService>();
|
||||
final _imageDownloaderService = locator<ImageDownloaderService>();
|
||||
|
||||
@override
|
||||
List<ListenableServiceMixin> get listenableServices =>
|
||||
[_authenticationService];
|
||||
|
||||
// Current user
|
||||
User? get _user => _authenticationService.user;
|
||||
|
||||
User? get user => _user;
|
||||
|
||||
|
||||
// Place anything here that needs to happen before we get into the application
|
||||
Future runStartupLogic() async {
|
||||
|
|
@ -27,7 +44,7 @@ class StartupViewModel extends BaseViewModel {
|
|||
} else {
|
||||
if (loggedIn) {
|
||||
await _authenticationService.getUser();
|
||||
await _navigationService.replaceWithHomeView();
|
||||
await _getProfileStatus();
|
||||
} else {
|
||||
// Removable
|
||||
await _navigationService.replaceWithLoginView();
|
||||
|
|
@ -35,9 +52,94 @@ class StartupViewModel extends BaseViewModel {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Navigation
|
||||
Future<void> replaceWithFailure() async => await _navigationService
|
||||
.replaceWithFailureView(label: 'Check you internet connection');
|
||||
|
||||
Future<void> replaceWithOnboarding() async =>
|
||||
await _navigationService.replaceWithOnboardingView();
|
||||
|
||||
|
||||
Future<void> replaceWithHome() async =>
|
||||
await _navigationService.replaceWithHomeView();
|
||||
|
||||
// Remote api calls
|
||||
|
||||
// In-app update
|
||||
Future<void> _inAppUpdate() async {
|
||||
if (await _statusChecker.checkConnection()) {
|
||||
await _inAppUpdateService.checkForUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
// Get profile status
|
||||
Future<void> _getProfileStatus() async {
|
||||
Map<String, dynamic> response = {};
|
||||
if (_user?.profileCompleted == null) {
|
||||
if (await _statusChecker.checkConnection()) {
|
||||
print('PATH: 1');
|
||||
response = await _apiService.getProfileStatus(_user);
|
||||
} else {
|
||||
print('PATH: 2');
|
||||
|
||||
await Future.delayed(kDuration);
|
||||
await replaceWithFailure();
|
||||
}
|
||||
} else if (!(_user?.profileCompleted ?? false)) {
|
||||
print('PATH: 3');
|
||||
|
||||
response = {'data': false, 'status': ResponseStatus.success};
|
||||
} else {
|
||||
print('PATH: 4');
|
||||
|
||||
response = {'data': true, 'status': ResponseStatus.success};
|
||||
}
|
||||
if (response['status'] == ResponseStatus.success && !response['data']) {
|
||||
print('PATH: 5');
|
||||
|
||||
await replaceWithOnboarding();
|
||||
} else if (response['status'] == ResponseStatus.success &&
|
||||
response['data']) {
|
||||
print('PATH: 6');
|
||||
|
||||
await saveProfileStatus(response['data']);
|
||||
|
||||
await _getProfileData();
|
||||
|
||||
await replaceWithHome();
|
||||
}
|
||||
}
|
||||
|
||||
// Save profile status
|
||||
Future<void> saveProfileStatus(bool value) async =>
|
||||
await _authenticationService.saveProfileStatus(value);
|
||||
|
||||
// Get profile data
|
||||
Future<void> _getProfileData() async {
|
||||
if (!(_user?.userInfoLoaded ?? false)) {
|
||||
Map<String, dynamic> response = {};
|
||||
|
||||
if (_user?.profileCompleted != null &&
|
||||
(_user?.profileCompleted ?? false)) {
|
||||
if (await _statusChecker.checkConnection()) {
|
||||
response = await _apiService.getProfileData(_user?.userId);
|
||||
|
||||
if (response['status'] == ResponseStatus.success) {
|
||||
User user = response['data'] as User;
|
||||
|
||||
await _authenticationService.saveUserData(user);
|
||||
|
||||
String image =
|
||||
await _imageDownloaderService.downloader(user.profilePicture);
|
||||
|
||||
await _authenticationService.saveProfilePicture(image);
|
||||
}
|
||||
} else {
|
||||
await replaceWithFailure();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:stacked/stacked.dart';
|
||||
import 'package:yimaru_app/ui/views/learn_practice/learn_practice_viewmodel.dart';
|
||||
import 'package:yimaru_app/ui/widgets/speaking_partner_image.dart';
|
||||
|
||||
import '../common/app_colors.dart';
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class LearnPracticeCard extends ViewModelWidget<LearnPracticeViewModel> {
|
|||
);
|
||||
|
||||
Widget _buildStartButton(LearnPracticeViewModel viewModel) =>
|
||||
CustomElevatedButton(
|
||||
const CustomElevatedButton(
|
||||
height: 50,
|
||||
width: 200,
|
||||
borderRadius: 8,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import 'package:yimaru_app/ui/common/app_colors.dart';
|
|||
import 'package:yimaru_app/ui/common/ui_helpers.dart';
|
||||
import 'package:yimaru_app/ui/views/learn_practice/learn_practice_viewmodel.dart';
|
||||
|
||||
import '../../models/learn_practice.dart';
|
||||
|
||||
class LearnPracticeTipSection extends ViewModelWidget<LearnPracticeViewModel> {
|
||||
const LearnPracticeTipSection({super.key});
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
name: yimaru_app
|
||||
version: 0.1.5+7
|
||||
version: 0.1.6+8
|
||||
publish_to: 'none'
|
||||
description: A new Flutter project.
|
||||
|
||||
|
||||
environment:
|
||||
sdk: '>=3.0.3 <4.0.0'
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user