♻️ Make bot management into sheet

This commit is contained in:
2025-11-02 21:04:35 +08:00
parent 7497b77384
commit da2d3f7f17
4 changed files with 340 additions and 246 deletions

View File

@@ -5,8 +5,11 @@ import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/bot.dart'; import 'package:island/models/bot.dart';
import 'package:island/pods/network.dart'; import 'package:island/pods/network.dart';
import 'package:island/screens/developers/edit_bot.dart';
import 'package:island/screens/developers/new_bot.dart';
import 'package:island/widgets/alert.dart'; import 'package:island/widgets/alert.dart';
import 'package:island/widgets/content/cloud_files.dart'; import 'package:island/widgets/content/cloud_files.dart';
import 'package:island/widgets/content/sheet.dart';
import 'package:island/widgets/response.dart'; import 'package:island/widgets/response.dart';
import 'package:material_symbols_icons/symbols.dart'; import 'package:material_symbols_icons/symbols.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
@@ -48,12 +51,18 @@ class BotsScreen extends HookConsumerWidget {
const SizedBox(height: 16), const SizedBox(height: 16),
ElevatedButton.icon( ElevatedButton.icon(
onPressed: () { onPressed: () {
context.pushNamed( showModalBottomSheet(
'developerBotNew', context: context,
pathParameters: { isScrollControlled: true,
'name': publisherName, builder:
'projectId': projectId, (context) => SheetScaffold(
}, titleText: 'createBot'.tr(),
child: NewBotScreen(
publisherName: publisherName,
projectId: projectId,
isModal: true,
),
),
); );
}, },
icon: const Icon(Symbols.add), icon: const Icon(Symbols.add),
@@ -74,12 +83,18 @@ class BotsScreen extends HookConsumerWidget {
title: Text('bots').tr().padding(horizontal: 8), title: Text('bots').tr().padding(horizontal: 8),
trailing: IconButton( trailing: IconButton(
onPressed: () { onPressed: () {
context.pushNamed( showModalBottomSheet(
'developerBotNew', context: context,
pathParameters: { isScrollControlled: true,
'name': publisherName, builder:
'projectId': projectId, (context) => SheetScaffold(
}, titleText: 'createBot'.tr(),
child: NewBotScreen(
publisherName: publisherName,
projectId: projectId,
isModal: true,
),
),
); );
}, },
icon: const Icon(Symbols.add), icon: const Icon(Symbols.add),
@@ -93,7 +108,6 @@ class BotsScreen extends HookConsumerWidget {
itemBuilder: (context, index) { itemBuilder: (context, index) {
final bot = data[index]; final bot = data[index];
return Card( return Card(
margin: const EdgeInsets.all(8.0),
child: ListTile( child: ListTile(
shape: const RoundedRectangleBorder( shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8.0)), borderRadius: BorderRadius.all(Radius.circular(8.0)),
@@ -140,13 +154,19 @@ class BotsScreen extends HookConsumerWidget {
], ],
onSelected: (value) { onSelected: (value) {
if (value == 'edit') { if (value == 'edit') {
context.pushNamed( showModalBottomSheet(
'developerBotEdit', context: context,
pathParameters: { isScrollControlled: true,
'name': publisherName, builder:
'projectId': projectId, (context) => SheetScaffold(
'id': bot.id, titleText: 'editBot'.tr(),
}, child: EditBotScreen(
publisherName: publisherName,
projectId: projectId,
id: bot.id,
isModal: true,
),
),
); );
} else if (value == 'delete') { } else if (value == 'delete') {
showConfirmAlert( showConfirmAlert(

View File

@@ -38,11 +38,13 @@ class EditBotScreen extends HookConsumerWidget {
final String publisherName; final String publisherName;
final String projectId; final String projectId;
final String? id; final String? id;
final bool isModal;
const EditBotScreen({ const EditBotScreen({
super.key, super.key,
required this.publisherName, required this.publisherName,
required this.projectId, required this.projectId,
this.id, this.id,
this.isModal = false,
}); });
@override @override
@@ -191,10 +193,7 @@ class EditBotScreen extends HookConsumerWidget {
} }
} }
return AppScaffold( final bodyContent =
isNoBackground: false,
appBar: AppBar(title: Text(isNew ? 'createBot'.tr() : 'editBot'.tr())),
body:
botData == null && !isNew botData == null && !isNew
? const Center(child: CircularProgressIndicator()) ? const Center(child: CircularProgressIndicator())
: botData?.hasError == true && !isNew : botData?.hasError == true && !isNew
@@ -255,7 +254,14 @@ class EditBotScreen extends HookConsumerWidget {
children: [ children: [
TextFormField( TextFormField(
controller: nameController, controller: nameController,
decoration: InputDecoration(labelText: 'name'.tr()), decoration: InputDecoration(
labelText: 'name'.tr(),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
TextFormField( TextFormField(
@@ -263,6 +269,11 @@ class EditBotScreen extends HookConsumerWidget {
decoration: InputDecoration( decoration: InputDecoration(
labelText: 'nickname'.tr(), labelText: 'nickname'.tr(),
alignLabelWithHint: true, alignLabelWithHint: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
), ),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
@@ -271,6 +282,11 @@ class EditBotScreen extends HookConsumerWidget {
decoration: InputDecoration( decoration: InputDecoration(
labelText: 'slug'.tr(), labelText: 'slug'.tr(),
helperText: 'slugHint'.tr(), helperText: 'slugHint'.tr(),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
), ),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
@@ -279,6 +295,11 @@ class EditBotScreen extends HookConsumerWidget {
decoration: InputDecoration( decoration: InputDecoration(
labelText: 'bio'.tr(), labelText: 'bio'.tr(),
alignLabelWithHint: true, alignLabelWithHint: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
), ),
maxLines: 3, maxLines: 3,
), ),
@@ -291,6 +312,11 @@ class EditBotScreen extends HookConsumerWidget {
controller: firstNameController, controller: firstNameController,
decoration: InputDecoration( decoration: InputDecoration(
labelText: 'firstName'.tr(), labelText: 'firstName'.tr(),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
), ),
), ),
), ),
@@ -299,6 +325,11 @@ class EditBotScreen extends HookConsumerWidget {
controller: middleNameController, controller: middleNameController,
decoration: InputDecoration( decoration: InputDecoration(
labelText: 'middleName'.tr(), labelText: 'middleName'.tr(),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
), ),
), ),
), ),
@@ -307,6 +338,11 @@ class EditBotScreen extends HookConsumerWidget {
controller: lastNameController, controller: lastNameController,
decoration: InputDecoration( decoration: InputDecoration(
labelText: 'lastName'.tr(), labelText: 'lastName'.tr(),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
), ),
), ),
), ),
@@ -321,6 +357,11 @@ class EditBotScreen extends HookConsumerWidget {
controller: genderController, controller: genderController,
decoration: InputDecoration( decoration: InputDecoration(
labelText: 'gender'.tr(), labelText: 'gender'.tr(),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
), ),
), ),
), ),
@@ -329,6 +370,11 @@ class EditBotScreen extends HookConsumerWidget {
controller: pronounsController, controller: pronounsController,
decoration: InputDecoration( decoration: InputDecoration(
labelText: 'pronouns'.tr(), labelText: 'pronouns'.tr(),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
), ),
), ),
), ),
@@ -343,6 +389,11 @@ class EditBotScreen extends HookConsumerWidget {
controller: locationController, controller: locationController,
decoration: InputDecoration( decoration: InputDecoration(
labelText: 'location'.tr(), labelText: 'location'.tr(),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
), ),
), ),
), ),
@@ -351,6 +402,11 @@ class EditBotScreen extends HookConsumerWidget {
controller: timeZoneController, controller: timeZoneController,
decoration: InputDecoration( decoration: InputDecoration(
labelText: 'timeZone'.tr(), labelText: 'timeZone'.tr(),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
), ),
), ),
), ),
@@ -370,13 +426,14 @@ class EditBotScreen extends HookConsumerWidget {
} }
}, },
child: Container( child: Container(
padding: const EdgeInsets.symmetric(vertical: 8), padding: const EdgeInsets.all(16),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border( border: Border.all(
bottom: BorderSide(
color: Theme.of(context).dividerColor, color: Theme.of(context).dividerColor,
width: 1, width: 1,
), ),
borderRadius: BorderRadius.all(
Radius.circular(12),
), ),
), ),
child: Column( child: Column(
@@ -403,8 +460,7 @@ class EditBotScreen extends HookConsumerWidget {
Align( Align(
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
child: TextButton.icon( child: TextButton.icon(
onPressed: onPressed: submitting.value ? null : performAction,
submitting.value ? null : performAction,
label: Text('saveChanges').tr(), label: Text('saveChanges').tr(),
icon: const Icon(Symbols.save), icon: const Icon(Symbols.save),
), ),
@@ -414,7 +470,16 @@ class EditBotScreen extends HookConsumerWidget {
), ),
], ],
), ),
), );
if (isModal) {
return bodyContent;
}
return AppScaffold(
isNoBackground: false,
appBar: AppBar(title: Text(isNew ? 'createBot'.tr() : 'editBot'.tr())),
body: bodyContent,
); );
} }
} }

View File

@@ -1,14 +1,23 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:island/screens/developers/edit_bot.dart'; import 'package:island/screens/developers/edit_bot.dart';
class NewBotScreen extends StatelessWidget { class NewBotScreen extends StatelessWidget {
final String publisherName; final String publisherName;
final String projectId; final String projectId;
const NewBotScreen({super.key, required this.publisherName, required this.projectId}); final bool isModal;
const NewBotScreen({
super.key,
required this.publisherName,
required this.projectId,
this.isModal = false,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return EditBotScreen(publisherName: publisherName, projectId: projectId); return EditBotScreen(
publisherName: publisherName,
projectId: projectId,
isModal: isModal,
);
} }
} }

View File

@@ -58,8 +58,8 @@ class ProjectDetailView extends HookConsumerWidget {
leading: Container( leading: Container(
width: 256, width: 256,
padding: EdgeInsets.only( padding: EdgeInsets.only(
left: 16, left: 24,
right: 16, right: 24,
bottom: 8, bottom: 8,
top: 2, top: 2,
), ),