diff --git a/app/lib/models/local_schemes.dart b/app/lib/models/local_schemes.dart index 9a79be2..2f6684c 100644 --- a/app/lib/models/local_schemes.dart +++ b/app/lib/models/local_schemes.dart @@ -27,4 +27,8 @@ abstract class LocalSchemeEntry implements Comparable { abstract class LocalSchemesInterface { Future> get schemeEntries; + + Future create(); + + void remove(String path); } diff --git a/app/lib/models/local_schemes_linux.dart b/app/lib/models/local_schemes_linux.dart index e74d98e..aefe39b 100644 --- a/app/lib/models/local_schemes_linux.dart +++ b/app/lib/models/local_schemes_linux.dart @@ -6,6 +6,7 @@ import 'package:dde_gesture_manager/extensions.dart'; import 'package:dde_gesture_manager/models/scheme.dart'; import 'package:path/path.dart' show join; import 'package:path_provider/path_provider.dart'; +import 'package:uuid/uuid.dart'; import 'local_schemes.dart'; import 'local_schemes_provider.dart'; @@ -43,6 +44,21 @@ class LocalSchemes implements LocalSchemesInterface { @ProviderModelProp() List? schemes; + + @override + Future create() async { + var _supportDirectory = await getApplicationSupportDirectory(); + return LocalSchemeEntryLinux( + path: join(_supportDirectory.path, 'schemes', '${Uuid().v1()}.json'), + scheme: Scheme.create(), + lastModifyTime: DateTime.now(), + ); + } + + @override + void remove(String path) { + File(path).delete(); + } } class LocalSchemeEntryLinux implements LocalSchemeEntry { diff --git a/app/lib/models/local_schemes_web.dart b/app/lib/models/local_schemes_web.dart index 582141c..efa4cbf 100644 --- a/app/lib/models/local_schemes_web.dart +++ b/app/lib/models/local_schemes_web.dart @@ -5,6 +5,7 @@ import 'package:dde_gesture_manager/builder/provider_annotation.dart'; import 'package:dde_gesture_manager/extensions.dart'; import 'package:dde_gesture_manager/models/local_schemes_provider.dart'; import 'package:dde_gesture_manager/models/scheme.dart'; +import 'package:uuid/uuid.dart'; import 'local_schemes.dart'; @@ -43,6 +44,18 @@ class LocalSchemes implements LocalSchemesInterface { @ProviderModelProp() List? schemes; + + @override + Future create() => Future.value( + LocalSchemeEntryWeb( + path: Uuid().v1(), + scheme: Scheme.create(), + lastModifyTime: DateTime.now(), + ), + ); + + @override + remove(String path) => window.localStorage.remove(path); } class LocalSchemeEntryWeb implements LocalSchemeEntry { @@ -70,8 +83,9 @@ class LocalSchemeEntryWeb implements LocalSchemeEntry { @override save(LocalSchemesProvider provider) { - // TODO: implement save - throw UnimplementedError(); + window.localStorage[path] = JsonEncoder.withIndent(' ' * 4).convert(scheme); + provider.schemes!.firstWhere((ele) => ele.scheme.id == scheme.id).lastModifyTime = DateTime.now(); + provider.setProps(schemes: [...provider.schemes!]..sort()); } @override diff --git a/app/lib/models/scheme.dart b/app/lib/models/scheme.dart index d6cfde6..7482b83 100644 --- a/app/lib/models/scheme.dart +++ b/app/lib/models/scheme.dart @@ -148,6 +148,9 @@ class Scheme { Scheme.create({this.name, this.description, this.gestures}) { this.id = Uuid().v1(); + this.gestures = []; + this.readOnly = false; + this.name = 'new xxx'; } SchemeTree buildSchemeTree() { diff --git a/app/lib/pages/local_manager.dart b/app/lib/pages/local_manager.dart index da3fbe9..e8dcb72 100644 --- a/app/lib/pages/local_manager.dart +++ b/app/lib/pages/local_manager.dart @@ -8,6 +8,7 @@ import 'package:dde_gesture_manager/models/settings.provider.dart'; import 'package:dde_gesture_manager/widgets/dde_button.dart'; import 'package:flutter/animation.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/painting.dart'; import 'package:uuid/uuid.dart'; @@ -24,21 +25,21 @@ class LocalManager extends StatefulWidget { class _LocalManagerState extends State { late ScrollController _scrollController; String? _hoveringItem; - late String _selectedItem; + late String _selectedItemPath; @override void initState() { super.initState(); /// todo: load from sp - _selectedItem = Uuid.NAMESPACE_NIL; + _selectedItemPath = ''; _scrollController = ScrollController(); } - Color _getItemBackgroundColor(int index, String itemId) { + Color _getItemBackgroundColor(int index, String itemPath) { Color _color = index % 2 == 0 ? context.t.scaffoldBackgroundColor : context.t.backgroundColor; - if (itemId == _hoveringItem) _color = context.t.scaffoldBackgroundColor; - if (itemId == _selectedItem) _color = context.read().currentActiveColor; + if (itemPath == _hoveringItem) _color = context.t.scaffoldBackgroundColor; + if (itemPath == _selectedItemPath) _color = context.read().currentActiveColor; return _color; } @@ -111,7 +112,7 @@ class _LocalManagerState extends State { onTap: () { context.read().copyFrom(localSchemes[index].scheme); setState(() { - _selectedItem = localSchemes[index].scheme.id!; + _selectedItemPath = localSchemes[index].path; }); context.read().copyFrom(GestureProp.empty()); }, @@ -123,13 +124,12 @@ class _LocalManagerState extends State { }); }, child: Container( - color: _getItemBackgroundColor(index, localSchemes[index].scheme.id!), + color: _getItemBackgroundColor(index, localSchemes[index].path), child: Padding( padding: const EdgeInsets.only(left: 6, right: 12.0), child: DefaultTextStyle( style: context.t.textTheme.bodyText2!.copyWith( - color: - _selectedItem == localSchemes[index].scheme.id! ? Colors.white : null, + color: _selectedItemPath == localSchemes[index].path ? Colors.white : null, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -153,10 +153,31 @@ class _LocalManagerState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - DButton.add(enabled: true), - DButton.delete(enabled: _selectedItem != Uuid.NAMESPACE_NIL), - DButton.duplicate(enabled: _selectedItem != Uuid.NAMESPACE_NIL), - DButton.apply(enabled: _selectedItem != Uuid.NAMESPACE_NIL), + DButton.add( + enabled: true, + onTap: () async { + var localSchemesProvider = context.read(); + var newSchemes = [...?localSchemesProvider.schemes]; + newSchemes.add(await localSchemesProvider.create()); + localSchemesProvider.setProps(schemes: newSchemes..sort()); + }, + ), + DButton.delete( + enabled: _selectedItemPath.notNull, + onTap: () { + var localSchemesProvider = context.read(); + var newSchemes = [...?localSchemesProvider.schemes]; + var index = newSchemes.indexWhere((element) => element.path == _selectedItemPath); + newSchemes.removeAt(index); + localSchemesProvider.setProps(schemes: newSchemes); + localSchemesProvider.remove(_selectedItemPath); + setState(() { + _selectedItemPath = newSchemes[(index - 1).clamp(1, newSchemes.length)].path; + }); + }, + ), + DButton.duplicate(enabled: _selectedItemPath.notNull), + DButton.apply(enabled: _selectedItemPath.notNull), ] .map((e) => Padding( padding: const EdgeInsets.only(right: 4),