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

View File

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