diff --git a/fire_atlas_editor/lib/screens/editor_screen/widgets/rename_atlas_modal.dart b/fire_atlas_editor/lib/screens/editor_screen/widgets/rename_atlas_modal.dart new file mode 100644 index 0000000..79d1b49 --- /dev/null +++ b/fire_atlas_editor/lib/screens/editor_screen/widgets/rename_atlas_modal.dart @@ -0,0 +1,82 @@ +import 'package:fire_atlas_editor/store/actions/atlas_actions.dart'; +import 'package:fire_atlas_editor/store/actions/editor_actions.dart'; +import 'package:fire_atlas_editor/store/store.dart'; +import 'package:fire_atlas_editor/widgets/button.dart'; +import 'package:fire_atlas_editor/widgets/input_text_row.dart'; +import 'package:fire_atlas_editor/widgets/text.dart'; +import 'package:flutter/widgets.dart'; +import 'package:slices/slices.dart'; + +class RenameAtlasModal extends StatefulWidget { + final String? currentName; + + const RenameAtlasModal({Key? key, required this.currentName}) + : super(key: key); + + @override + State createState() => _RenameAtlasModalState(); +} + +class _RenameAtlasModalState extends State { + final newNameController = TextEditingController(); + + @override + void initState() { + super.initState(); + newNameController.text = widget.currentName ?? ''; + } + + @override + Widget build(BuildContext ctx) { + return Container( + padding: const EdgeInsets.only(left: 20, right: 20), + child: Column( + children: [ + const FSubtitleTitle(title: 'Rename atlas'), + InputTextRow( + label: 'New name:', + inputController: newNameController, + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + FButton( + label: 'Cancel', + onSelect: () => _closeModal(ctx), + ), + const SizedBox(width: 20), + FButton( + label: 'Rename', + onSelect: () => _renameAtlas(ctx), + ), + ], + ), + const SizedBox(height: 20), + ], + ), + ); + } + + Future _renameAtlas(BuildContext ctx) async { + final store = SlicesProvider.of(ctx); + final newName = newNameController.text; + if (newName.isEmpty) { + store.dispatch( + CreateMessageAction( + type: MessageType.ERROR, + message: 'The new name is required.', + ), + ); + } else { + final action = RenameAtlasAction(newAtlasId: newName); + await store.dispatchAsync(action); + await _closeModal(ctx); + } + } + + Future _closeModal(BuildContext ctx) async { + final store = SlicesProvider.of(ctx); + store.dispatch(CloseEditorModal()); + } +} diff --git a/fire_atlas_editor/lib/screens/editor_screen/widgets/toolbar.dart b/fire_atlas_editor/lib/screens/editor_screen/widgets/toolbar.dart index 650e722..246cfca 100644 --- a/fire_atlas_editor/lib/screens/editor_screen/widgets/toolbar.dart +++ b/fire_atlas_editor/lib/screens/editor_screen/widgets/toolbar.dart @@ -1,6 +1,7 @@ import 'package:equatable/equatable.dart'; import 'package:fire_atlas_editor/screens/editor_screen/widgets/change_image_modal.dart'; import 'package:fire_atlas_editor/screens/editor_screen/widgets/concat_image_modal.dart'; +import 'package:fire_atlas_editor/screens/editor_screen/widgets/rename_atlas_modal.dart'; import 'package:fire_atlas_editor/screens/widgets/toggle_theme_button.dart'; import 'package:fire_atlas_editor/services/storage/storage.dart'; import 'package:fire_atlas_editor/store/actions/atlas_actions.dart'; @@ -62,6 +63,21 @@ class Toolbar extends StatelessWidget { }, tooltip: 'Save project', ), + FIconButton( + iconData: Icons.edit, + onPress: () { + store.dispatch( + OpenEditorModal( + RenameAtlasModal( + currentName: store.state.currentAtlas?.id, + ), + 400, + 500, + ), + ); + }, + tooltip: 'Rename project', + ), FIconButton( iconData: Icons.image, onPress: () { diff --git a/fire_atlas_editor/lib/store/actions/atlas_actions.dart b/fire_atlas_editor/lib/store/actions/atlas_actions.dart index 93acd8a..6950e57 100644 --- a/fire_atlas_editor/lib/store/actions/atlas_actions.dart +++ b/fire_atlas_editor/lib/store/actions/atlas_actions.dart @@ -177,6 +177,33 @@ class SaveAction extends AsyncSlicesAction { } } +class RenameAtlasAction extends AsyncSlicesAction { + final String newAtlasId; + + RenameAtlasAction({required this.newAtlasId}); + + @override + Future perform( + SlicesStore store, + FireAtlasState state, + ) async { + final atlas = state.currentAtlas; + if (atlas == null) { + return state; + } + + atlas.id = newAtlasId; + return state.copyWith( + hasChanges: true, + loadedProject: Nullable( + state.loadedProject.value?.copyWith( + project: atlas, + ), + ), + ); + } +} + class LoadAtlasAction extends AsyncSlicesAction { final String path;