| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 | import 'dart:io';import 'package:appflowy/util/file_picker/file_picker_service.dart';import 'package:easy_localization/easy_localization.dart';import 'package:flowy_infra_ui/style_widget/text.dart';import 'package:flowy_infra_ui/style_widget/text_field.dart';import 'package:flowy_infra_ui/widget/rounded_button.dart';import 'package:flutter/material.dart';import 'package:fluttertoast/fluttertoast.dart';import '../../../generated/locale_keys.g.dart';import '../../../startup/startup.dart';import '../../../workspace/application/settings/settings_location_cubit.dart';import '../../../workspace/presentation/home/toast.dart';enum _FolderPage {  options,  create,  open,}class FolderWidget extends StatefulWidget {  const FolderWidget({    Key? key,    required this.createFolderCallback,  }) : super(key: key);  final Future<void> Function() createFolderCallback;  @override  State<FolderWidget> createState() => _FolderWidgetState();}class _FolderWidgetState extends State<FolderWidget> {  var page = _FolderPage.options;  @override  Widget build(BuildContext context) {    return SizedBox(      height: 250,      child: _mapIndexToWidget(context),    );  }  Widget _mapIndexToWidget(BuildContext context) {    switch (page) {      case _FolderPage.options:        return FolderOptionsWidget(          onPressedCreate: () {            setState(() => page = _FolderPage.create);          },          onPressedOpen: () {            _openFolder();          },        );      case _FolderPage.create:        return CreateFolderWidget(          onPressedBack: () {            setState(() => page = _FolderPage.options);          },          onPressedCreate: widget.createFolderCallback,        );      case _FolderPage.open:        return Container();    }  }  Future<void> _openFolder() async {    final directory = await getIt<FilePickerService>().getDirectoryPath();    if (directory != null) {      await getIt<SettingsLocationCubit>().setLocation(directory);      await widget.createFolderCallback();    }  }}class FolderOptionsWidget extends StatelessWidget {  const FolderOptionsWidget({    Key? key,    required this.onPressedCreate,    required this.onPressedOpen,  }) : super(key: key);  final VoidCallback onPressedCreate;  final VoidCallback onPressedOpen;  @override  Widget build(BuildContext context) {    return ListView(      shrinkWrap: true,      children: <Widget>[        Card(          child: ListTile(            title: FlowyText.medium(              LocaleKeys.settings_files_createNewFolder.tr(),            ),            subtitle: FlowyText.regular(              LocaleKeys.settings_files_createNewFolderDesc.tr(),            ),            trailing: _buildTextButton(              context,              LocaleKeys.settings_files_create.tr(),              onPressedCreate,            ),          ),        ),        Card(          child: ListTile(            title: FlowyText.medium(              LocaleKeys.settings_files_openFolder.tr(),            ),            subtitle: FlowyText.regular(              LocaleKeys.settings_files_openFolderDesc.tr(),            ),            trailing: _buildTextButton(              context,              LocaleKeys.settings_files_open.tr(),              onPressedOpen,            ),          ),        ),      ],    );  }}class CreateFolderWidget extends StatefulWidget {  const CreateFolderWidget({    Key? key,    required this.onPressedBack,    required this.onPressedCreate,  }) : super(key: key);  final VoidCallback onPressedBack;  final Future<void> Function() onPressedCreate;  @override  State<CreateFolderWidget> createState() => CreateFolderWidgetState();}@visibleForTestingclass CreateFolderWidgetState extends State<CreateFolderWidget> {  var _folderName = 'appflowy';  @visibleForTesting  var directory = '';  final _fToast = FToast();  @override  void initState() {    super.initState();    _fToast.init(context);  }  @override  Widget build(BuildContext context) {    return Column(      children: [        Align(          alignment: Alignment.centerLeft,          child: TextButton.icon(            onPressed: widget.onPressedBack,            icon: const Icon(Icons.arrow_back_rounded),            label: const Text('Back'),          ),        ),        Card(          child: ListTile(            title: FlowyText.medium(              LocaleKeys.settings_files_location.tr(),            ),            subtitle: FlowyText.regular(              LocaleKeys.settings_files_locationDesc.tr(),            ),            trailing: SizedBox(              width: 100,              height: 36,              child: FlowyTextField(                hintText: LocaleKeys.settings_files_folderHintText.tr(),                onChanged: (name) {                  _folderName = name;                },                onSubmitted: (name) {                  setState(() {                    _folderName = name;                  });                },              ),            ),          ),        ),        Card(          child: ListTile(            title: FlowyText.medium(LocaleKeys.settings_files_folderPath.tr()),            subtitle: FlowyText.regular(_path),            trailing: _buildTextButton(                context, LocaleKeys.settings_files_browser.tr(), () async {              final dir = await getIt<FilePickerService>().getDirectoryPath();              if (dir != null) {                setState(() {                  directory = dir;                });              }            }),          ),        ),        Card(          child: _buildTextButton(              context, LocaleKeys.settings_files_create.tr(), () async {            if (_path.isEmpty) {              _showToast(LocaleKeys.settings_files_locationCannotBeEmpty.tr());            } else {              await getIt<SettingsLocationCubit>().setLocation(_path);              await widget.onPressedCreate();            }          }),        )      ],    );  }  String get _path {    if (directory.isEmpty) return '';    final String path;    if (Platform.isMacOS) {      path = directory.replaceAll('/Volumes/Macintosh HD', '');    } else {      path = directory;    }    return '$path/$_folderName';  }  void _showToast(String message) {    _fToast.showToast(      child: FlowyMessageToast(message: message),      gravity: ToastGravity.CENTER,    );  }}Widget _buildTextButton(    BuildContext context, String title, VoidCallback onPressed) {  return SizedBox(    width: 70,    height: 36,    child: RoundedTextButton(      title: title,      onPressed: onPressed,    ),  );}
 |