import 'package:anitrack/i18n/strings.g.dart'; import 'package:anitrack/src/ui/bloc/settings_bloc.dart'; import 'package:anitrack/src/ui/constants.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:get_it/get_it.dart'; import 'package:go_router/go_router.dart'; import 'package:permission_handler/permission_handler.dart'; class SettingsPage extends StatelessWidget { const SettingsPage({super.key}); static MaterialPageRoute get route => MaterialPageRoute( builder: (_) => const SettingsPage(), settings: const RouteSettings( name: settingsRoute, ), ); @override Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { return WillPopScope( onWillPop: () async { return !state.importSpinnerVisible; }, child: Stack( children: [ Positioned( left: 0, right: 0, top: 0, bottom: 0, child: Scaffold( appBar: AppBar( title: Text(t.settings.title), leading: IconButton( icon: const Icon(Icons.arrow_back), onPressed: () { GoRouter.of(context).pop(); }, ), ), body: ListView( children: [ ListTile( title: Text(t.settings.importAnime), subtitle: Text(t.settings.importAnimeDesc), onTap: () async { // Pick the file final result = await FilePicker.pickFiles(); if (result == null) return; if (!result.files.first.path!.endsWith('.xml.gz')) { await showDialog( context: context, builder: (_) => AlertDialog( title: Text(t.settings.invalidAnimeListTitle), content: Text(t.settings.invalidAnimeListBody), ), ); return; } GetIt.I.get().add( AnimeListImportedEvent( result.files.first.path!, ImportListType.mal, ), ); }, ), ListTile( title: Text(t.settings.importManga), subtitle: Text(t.settings.importMangaDesc), onTap: () async { // Pick the file final result = await FilePicker.pickFiles(); if (result == null) return; if (!result.files.first.path!.endsWith('.xml.gz')) { await showDialog( context: context, builder: (_) => AlertDialog( title: Text(t.settings.invalidMangaListTitle), content: Text(t.settings.invalidMangaListBody), ), ); return; } GetIt.I.get().add( MangaListImportedEvent( result.files.first.path!, ImportListType.mal, ), ); }, ), ListTile( title: Text(t.settings.exportData), onTap: () async { // Pick the file final result = await FilePicker.getDirectoryPath(); if (result == null) return; if (!(await Permission.manageExternalStorage .request()) .isGranted) return; GetIt.I.get().add( DataExportedEvent( result, ), ); }, ), ListTile( title: Text(t.settings.importData), onTap: () async { // Pick the file final result = await FilePicker.pickFiles(); if (result == null) return; if (!result.files.first.path!.endsWith('.json.gz')) { await showDialog( context: context, builder: (_) => AlertDialog( title: Text(t.settings.importInvalidData.title), content: Text( t.settings.importInvalidData.content, ), ), ); return; } GetIt.I.get().add( DataImportedEvent( result.files.first.path!, ), ); }, ), ], ), ), ), if (state.importSpinnerVisible) const Positioned( left: 0, right: 0, top: 0, bottom: 0, child: ModalBarrier( dismissible: false, color: Colors.black54, ), ), if (state.importSpinnerVisible) Positioned( left: 0, right: 0, top: 0, bottom: 0, child: Center( child: SizedBox( width: 150, height: 150, child: DecoratedBox( decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: Colors.grey.shade800, ), child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ const Padding( padding: EdgeInsets.all(25), child: CircularProgressIndicator(), ), Text( t.settings.importIndicator( current: state.importCurrent, total: state.importTotal, ), style: Theme.of(context).textTheme.bodyMedium, ), ], ), ), ), ), ), ], ), ); }, ); } }