use shared AddressBookTag widget & hide _editTagAction when tags is empty

This commit is contained in:
csf 2022-10-08 17:39:05 +09:00
parent a13c4c5907
commit 6a92212216
2 changed files with 61 additions and 124 deletions

View File

@ -153,9 +153,10 @@ class _AddressBookState extends State<AddressBook> {
child: Obx( child: Obx(
() => Wrap( () => Wrap(
children: gFFI.abModel.tags children: gFFI.abModel.tags
.map((e) => buildTag(e, gFFI.abModel.selectedTags, .map((e) => AddressBookTag(
onTap: () { name: e,
// tags: gFFI.abModel.selectedTags,
onTap: () {
if (gFFI.abModel.selectedTags.contains(e)) { if (gFFI.abModel.selectedTags.contains(e)) {
gFFI.abModel.selectedTags.remove(e); gFFI.abModel.selectedTags.remove(e);
} else { } else {
@ -183,41 +184,6 @@ class _AddressBookState extends State<AddressBook> {
); );
} }
Widget buildTag(String tagName, RxList<dynamic> rxTags, {Function()? onTap}) {
return ContextMenuArea(
width: 100,
builder: (context) => [
ListTile(
title: Text(translate("Delete")),
onTap: () {
gFFI.abModel.deleteTag(tagName);
gFFI.abModel.pushAb();
Future.delayed(Duration.zero, () => Get.back());
},
)
],
child: GestureDetector(
onTap: onTap,
child: Obx(
() => Container(
decoration: BoxDecoration(
color: rxTags.contains(tagName) ? Colors.blue : null,
border: Border.all(color: MyTheme.darkGray),
borderRadius: BorderRadius.circular(6)),
margin: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 8.0),
padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 8.0),
child: Text(
tagName,
style: TextStyle(
color:
rxTags.contains(tagName) ? Colors.white : null), // TODO
),
),
),
),
);
}
/// tag operation /// tag operation
void handleAbOp(String value) { void handleAbOp(String value) {
if (value == 'add-id') { if (value == 'add-id') {
@ -366,54 +332,55 @@ class _AddressBookState extends State<AddressBook> {
); );
}); });
} }
}
void abEditTag(String id) { class AddressBookTag extends StatelessWidget {
var isInProgress = false; final String name;
final RxList<dynamic> tags;
final Function()? onTap;
final bool useContextMenuArea;
final tags = List.of(gFFI.abModel.tags); const AddressBookTag(
var selectedTag = gFFI.abModel.getPeerTags(id).obs; {Key? key,
required this.name,
required this.tags,
this.onTap,
this.useContextMenuArea = true})
: super(key: key);
gFFI.dialogManager.show((setState, close) { @override
submit() async { Widget build(BuildContext context) {
setState(() { final body = GestureDetector(
isInProgress = true; onTap: onTap,
}); child: Obx(
gFFI.abModel.changeTagForPeer(id, selectedTag); () => Container(
await gFFI.abModel.pushAb(); decoration: BoxDecoration(
close(); color: tags.contains(name) ? Colors.blue : null,
} border: Border.all(color: MyTheme.darkGray),
borderRadius: BorderRadius.circular(6)),
return CustomAlertDialog( margin: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 8.0),
title: Text(translate("Edit Tag")), padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 8.0),
content: Column( child: Text(name,
crossAxisAlignment: CrossAxisAlignment.start, style:
children: [ TextStyle(color: tags.contains(name) ? Colors.white : null)),
Container(
padding:
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Wrap(
children: tags
.map((e) => buildTag(e, selectedTag, onTap: () {
if (selectedTag.contains(e)) {
selectedTag.remove(e);
} else {
selectedTag.add(e);
}
}))
.toList(growable: false),
),
),
Offstage(
offstage: !isInProgress, child: const LinearProgressIndicator())
],
), ),
actions: [ ),
TextButton(onPressed: close, child: Text(translate("Cancel"))), );
TextButton(onPressed: submit, child: Text(translate("OK"))), return useContextMenuArea
], ? ContextMenuArea(
onSubmit: submit, width: 100,
onCancel: close, builder: (context) => [
); ListTile(
}); title: Text(translate("Delete")),
onTap: () {
gFFI.abModel.deleteTag(name);
gFFI.abModel.pushAb();
Future.delayed(Duration.zero, () => Get.back());
},
)
],
child: body,
)
: body;
} }
} }

View File

@ -1,6 +1,6 @@
import 'package:contextmenu/contextmenu.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_hbb/common/widgets/address_book.dart';
import 'package:flutter_hbb/consts.dart'; import 'package:flutter_hbb/consts.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@ -774,7 +774,9 @@ class AddressBookPeerCard extends BasePeerCard {
if (await bind.mainPeerHasPassword(id: peer.id)) { if (await bind.mainPeerHasPassword(id: peer.id)) {
menuItems.add(_unrememberPasswordAction(peer.id)); menuItems.add(_unrememberPasswordAction(peer.id));
} }
menuItems.add(_editTagAction(peer.id)); if (gFFI.abModel.tags.isNotEmpty) {
menuItems.add(_editTagAction(peer.id));
}
return menuItems; return menuItems;
} }
@ -836,17 +838,20 @@ class AddressBookPeerCard extends BasePeerCard {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Container( Container(
padding: padding: const EdgeInsets.symmetric(vertical: 8.0),
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Wrap( child: Wrap(
children: tags children: tags
.map((e) => _buildTag(e, selectedTag, onTap: () { .map((e) => AddressBookTag(
name: e,
tags: selectedTag,
onTap: () {
if (selectedTag.contains(e)) { if (selectedTag.contains(e)) {
selectedTag.remove(e); selectedTag.remove(e);
} else { } else {
selectedTag.add(e); selectedTag.add(e);
} }
})) },
useContextMenuArea: false))
.toList(growable: false), .toList(growable: false),
), ),
), ),
@ -863,41 +868,6 @@ class AddressBookPeerCard extends BasePeerCard {
); );
}); });
} }
Widget _buildTag(String tagName, RxList<dynamic> rxTags,
{Function()? onTap}) {
return ContextMenuArea(
width: 100,
builder: (context) => [
ListTile(
title: Text(translate("Delete")),
onTap: () {
gFFI.abModel.deleteTag(tagName);
gFFI.abModel.pushAb();
Future.delayed(Duration.zero, () => Get.back());
},
)
],
child: GestureDetector(
onTap: onTap,
child: Obx(
() => Container(
decoration: BoxDecoration(
color: rxTags.contains(tagName) ? Colors.blue : null,
border: Border.all(color: MyTheme.darkGray),
borderRadius: BorderRadius.circular(10)),
margin: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 8.0),
padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 8.0),
child: Text(
tagName,
style: TextStyle(
color: rxTags.contains(tagName) ? Colors.white : null),
),
),
),
),
);
}
} }
void _rdpDialog(String id) async { void _rdpDialog(String id) async {