import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:obtainium/components/custom_app_bar.dart'; import 'package:obtainium/components/generated_form.dart'; import 'package:obtainium/pages/app.dart'; import 'package:obtainium/providers/apps_provider.dart'; import 'package:obtainium/providers/settings_provider.dart'; import 'package:obtainium/providers/source_provider.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher_string.dart'; class AddAppPage extends StatefulWidget { const AddAppPage({super.key}); @override State createState() => _AddAppPageState(); } class _AddAppPageState extends State { bool gettingAppInfo = false; String userInput = ''; AppSource? pickedSource; List additionalData = []; String customName = ''; bool validAdditionalData = true; @override Widget build(BuildContext context) { SourceProvider sourceProvider = SourceProvider(); return Scaffold( backgroundColor: Theme.of(context).colorScheme.surface, body: CustomScrollView(slivers: [ const CustomAppBar(title: 'Add App'), SliverFillRemaining( child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Row( children: [ Expanded( child: GeneratedForm( items: [ [ GeneratedFormItem( label: 'App Source Url', additionalValidators: [ (value) { try { sourceProvider .getSource(value ?? '') .standardizeURL( preStandardizeUrl( value ?? '')); } catch (e) { return e is String ? e : 'Error'; } return null; } ]) ] ], onValueChanges: (values, valid) { setState(() { userInput = values[0]; var source = valid ? sourceProvider.getSource(userInput) : null; if (pickedSource != source) { pickedSource = source; additionalData = source != null ? source.additionalDataDefaults : []; validAdditionalData = source != null ? sourceProvider .doesSourceHaveRequiredAdditionalData( source) : true; if (source == null) { customName = ''; } } }); }, defaultValues: const [])), const SizedBox( width: 16, ), ElevatedButton( onPressed: gettingAppInfo || pickedSource == null || (pickedSource!.additionalDataFormItems .isNotEmpty && !validAdditionalData) ? null : () { HapticFeedback.selectionClick(); setState(() { gettingAppInfo = true; }); sourceProvider .getApp(pickedSource!, userInput, additionalData, customName: customName) .then((app) { var appsProvider = context.read(); var settingsProvider = context.read(); if (appsProvider.apps .containsKey(app.id)) { throw 'App already added'; } settingsProvider .getInstallPermission() .then((_) { appsProvider .saveApps([app]).then((_) { Navigator.push( context, MaterialPageRoute( builder: (context) => AppPage( appId: app.id))); }); }); }).catchError((e) { ScaffoldMessenger.of(context) .showSnackBar( SnackBar(content: Text(e.toString())), ); }).whenComplete(() { setState(() { gettingAppInfo = false; }); }); }, child: const Text('Add')) ], ), if (pickedSource != null) Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const Divider( height: 64, ), Text( 'Additional Options for ${pickedSource?.runtimeType}', style: TextStyle( color: Theme.of(context).colorScheme.primary)), const SizedBox( height: 16, ), if (pickedSource! .additionalDataFormItems.isNotEmpty) GeneratedForm( items: pickedSource!.additionalDataFormItems, onValueChanges: (values, valid) { setState(() { additionalData = values; validAdditionalData = valid; }); }, defaultValues: pickedSource!.additionalDataDefaults), if (pickedSource! .additionalDataFormItems.isNotEmpty) const SizedBox( height: 8, ), if (pickedSource != null) GeneratedForm( items: [ [ GeneratedFormItem( label: 'Custom App Name', required: false) ] ], onValueChanges: (values, valid) { setState(() { customName = values[0]; }); }, defaultValues: [customName]) ], ) else Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ // const SizedBox( // height: 48, // ), const Text( 'Supported Sources:', ), const SizedBox( height: 8, ), ...sourceProvider .getSourceHosts() .map((e) => GestureDetector( onTap: () { launchUrlString('https://$e', mode: LaunchMode.externalApplication); }, child: Text( e, style: const TextStyle( decoration: TextDecoration.underline, fontStyle: FontStyle.italic), ))) .toList() ])), ])), ) ])); } }