mirror of
https://github.com/foss42/apidash.git
synced 2025-08-06 13:51:20 +08:00
chore: appbar request title
This commit is contained in:
@ -19,7 +19,7 @@ class RequestEditor extends StatelessWidget {
|
|||||||
: kPb10,
|
: kPb10,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
const RequestEditorTopBar(),
|
!kIsMobile ? const RequestEditorTopBar() : const SizedBox.shrink(),
|
||||||
Padding(
|
Padding(
|
||||||
padding: !kIsMobile ? EdgeInsets.zero : kPh8,
|
padding: !kIsMobile ? EdgeInsets.zero : kPh8,
|
||||||
child: const EditorPaneRequestURLCard()),
|
child: const EditorPaneRequestURLCard()),
|
||||||
@ -71,44 +71,11 @@ class RequestEditorTopBar extends ConsumerWidget {
|
|||||||
padding: MaterialStatePropertyAll(EdgeInsets.zero),
|
padding: MaterialStatePropertyAll(EdgeInsets.zero),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
showDialog(
|
showRenameDialog(context, name, (val) {
|
||||||
context: context,
|
ref
|
||||||
builder: (context) {
|
.read(collectionStateNotifierProvider.notifier)
|
||||||
final controller =
|
.update(id!, name: val);
|
||||||
TextEditingController(text: name ?? "");
|
});
|
||||||
controller.selection = TextSelection(
|
|
||||||
baseOffset: 0, extentOffset: controller.text.length);
|
|
||||||
return AlertDialog(
|
|
||||||
title: const Text('Rename Request'),
|
|
||||||
content: TextField(
|
|
||||||
autofocus: true,
|
|
||||||
controller: controller,
|
|
||||||
decoration:
|
|
||||||
const InputDecoration(hintText: "Enter new name"),
|
|
||||||
),
|
|
||||||
actions: <Widget>[
|
|
||||||
OutlinedButton(
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
child: const Text('CANCEL')),
|
|
||||||
FilledButton(
|
|
||||||
onPressed: () {
|
|
||||||
final val = controller.text.trim();
|
|
||||||
ref
|
|
||||||
.read(collectionStateNotifierProvider
|
|
||||||
.notifier)
|
|
||||||
.update(id!, name: val);
|
|
||||||
Navigator.pop(context);
|
|
||||||
Future.delayed(
|
|
||||||
const Duration(milliseconds: 100), () {
|
|
||||||
controller.dispose();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
child: const Text('OK')),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
Icons.edit,
|
Icons.edit,
|
||||||
@ -125,3 +92,42 @@ class RequestEditorTopBar extends ConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showRenameDialog(
|
||||||
|
BuildContext context,
|
||||||
|
String? name,
|
||||||
|
Function(String) onRename,
|
||||||
|
) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
final controller = TextEditingController(text: name ?? "");
|
||||||
|
controller.selection =
|
||||||
|
TextSelection(baseOffset: 0, extentOffset: controller.text.length);
|
||||||
|
return AlertDialog(
|
||||||
|
title: const Text('Rename Request'),
|
||||||
|
content: TextField(
|
||||||
|
autofocus: true,
|
||||||
|
controller: controller,
|
||||||
|
decoration: const InputDecoration(hintText: "Enter new name"),
|
||||||
|
),
|
||||||
|
actions: <Widget>[
|
||||||
|
OutlinedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
child: const Text('CANCEL')),
|
||||||
|
FilledButton(
|
||||||
|
onPressed: () {
|
||||||
|
final val = controller.text.trim();
|
||||||
|
onRename(val);
|
||||||
|
Navigator.pop(context);
|
||||||
|
Future.delayed(const Duration(milliseconds: 100), () {
|
||||||
|
controller.dispose();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: const Text('OK')),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -90,6 +90,7 @@ Widget customNavigationDestination(
|
|||||||
IconData icon,
|
IconData icon,
|
||||||
String label, {
|
String label, {
|
||||||
bool isNavigator = false,
|
bool isNavigator = false,
|
||||||
|
bool showLabel = true,
|
||||||
Function()? onTap,
|
Function()? onTap,
|
||||||
}) {
|
}) {
|
||||||
bool isSelected = railIdx == buttonIdx;
|
bool isSelected = railIdx == buttonIdx;
|
||||||
@ -138,19 +139,21 @@ Widget customNavigationDestination(
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
showLabel ? const SizedBox(height: 4) : const SizedBox.shrink(),
|
||||||
Text(
|
showLabel
|
||||||
label,
|
? Text(
|
||||||
style: Theme.of(context).textTheme.labelSmall!.copyWith(
|
label,
|
||||||
fontWeight: FontWeight.w600,
|
style: Theme.of(context).textTheme.labelSmall!.copyWith(
|
||||||
color: isSelected
|
fontWeight: FontWeight.w600,
|
||||||
? Theme.of(context).colorScheme.onSecondaryContainer
|
color: isSelected
|
||||||
: Theme.of(context)
|
? Theme.of(context).colorScheme.onSecondaryContainer
|
||||||
.colorScheme
|
: Theme.of(context)
|
||||||
.onSurface
|
.colorScheme
|
||||||
.withOpacity(0.65),
|
.onSurface
|
||||||
),
|
.withOpacity(0.65),
|
||||||
),
|
),
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -30,12 +30,6 @@ class _MobileDashboardState extends ConsumerState<MobileDashboard> {
|
|||||||
return dragPosition == 0 ? start : end;
|
return dragPosition == 0 ? start : end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
void didChangeDependencies() {
|
|
||||||
backgroundColor = Theme.of(context).colorScheme.surface;
|
|
||||||
super.didChangeDependencies();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(
|
Widget build(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:inner_drawer/inner_drawer.dart';
|
import 'package:inner_drawer/inner_drawer.dart';
|
||||||
|
import 'package:apidash/providers/providers.dart';
|
||||||
|
import 'package:apidash/utils/http_utils.dart';
|
||||||
|
import 'package:apidash/consts.dart';
|
||||||
|
import 'package:apidash/widgets/widgets.dart';
|
||||||
|
import '../../home_page/editor_pane/editor_request.dart';
|
||||||
import '../../home_page/editor_pane/editor_pane.dart';
|
import '../../home_page/editor_pane/editor_pane.dart';
|
||||||
import '../../home_page/editor_pane/url_card.dart';
|
import '../../home_page/editor_pane/url_card.dart';
|
||||||
import '../../home_page/editor_pane/details_card/code_pane.dart';
|
import '../../home_page/editor_pane/details_card/code_pane.dart';
|
||||||
@ -27,13 +33,14 @@ class RequestsPage extends StatelessWidget {
|
|||||||
.open(direction: InnerDrawerDirection.start);
|
.open(direction: InnerDrawerDirection.start);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
title: const Text("Requests"),
|
title: const RequestTitle(),
|
||||||
centerTitle: true,
|
titleSpacing: 0,
|
||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Icons.mode_comment_outlined,
|
Icons.send_outlined,
|
||||||
color: Theme.of(context).colorScheme.onBackground,
|
color: Theme.of(context).colorScheme.onBackground,
|
||||||
|
size: 20,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
innerDrawerKey.currentState!
|
innerDrawerKey.currentState!
|
||||||
@ -51,6 +58,68 @@ class RequestsPage extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RequestTitle extends ConsumerStatefulWidget {
|
||||||
|
const RequestTitle({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
ConsumerState<RequestTitle> createState() => _RequestTitleState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _RequestTitleState extends ConsumerState<RequestTitle> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final id = ref.watch(selectedIdStateProvider);
|
||||||
|
final name = getRequestTitleFromUrl(
|
||||||
|
ref.watch(selectedRequestModelProvider.select((value) => value?.name)),
|
||||||
|
capitalize: true);
|
||||||
|
return ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: RequestCardMenu(
|
||||||
|
offset: const Offset(0, 48),
|
||||||
|
splashRadius: 0,
|
||||||
|
tooltip: name,
|
||||||
|
child: Ink(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 6),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
name,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: Theme.of(context).textTheme.bodyLarge,
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Icon(
|
||||||
|
Icons.unfold_more_rounded,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onSelected: (RequestItemMenuOption item) {
|
||||||
|
if (item == RequestItemMenuOption.edit) {
|
||||||
|
showRenameDialog(context, name, (val) {
|
||||||
|
ref
|
||||||
|
.read(collectionStateNotifierProvider.notifier)
|
||||||
|
.update(id!, name: val);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (item == RequestItemMenuOption.delete) {
|
||||||
|
ref.read(collectionStateNotifierProvider.notifier).remove(id!);
|
||||||
|
}
|
||||||
|
if (item == RequestItemMenuOption.duplicate) {
|
||||||
|
ref.read(collectionStateNotifierProvider.notifier).duplicate(id!);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class RequestPageBottombar extends StatelessWidget {
|
class RequestPageBottombar extends StatelessWidget {
|
||||||
const RequestPageBottombar({
|
const RequestPageBottombar({
|
||||||
super.key,
|
super.key,
|
||||||
|
@ -7,14 +7,14 @@ import '../models/models.dart';
|
|||||||
import 'convert_utils.dart' show rowsToMap;
|
import 'convert_utils.dart' show rowsToMap;
|
||||||
import '../consts.dart';
|
import '../consts.dart';
|
||||||
|
|
||||||
String getRequestTitleFromUrl(String? url) {
|
String getRequestTitleFromUrl(String? url, {bool capitalize = false}) {
|
||||||
if (url == null || url.trim() == "") {
|
if (url == null || url.trim() == "") {
|
||||||
return "untitled";
|
return !capitalize ? "untitled" : "Untitled";
|
||||||
}
|
}
|
||||||
if (url.contains("://")) {
|
if (url.contains("://")) {
|
||||||
String rem = url.split("://")[1];
|
String rem = url.split("://")[1];
|
||||||
if (rem.trim() == "") {
|
if (rem.trim() == "") {
|
||||||
return "untitled";
|
return !capitalize ? "untitled" : "Untitled";
|
||||||
}
|
}
|
||||||
return rem;
|
return rem;
|
||||||
}
|
}
|
||||||
|
@ -5,16 +5,26 @@ class RequestCardMenu extends StatelessWidget {
|
|||||||
const RequestCardMenu({
|
const RequestCardMenu({
|
||||||
super.key,
|
super.key,
|
||||||
this.onSelected,
|
this.onSelected,
|
||||||
|
this.child,
|
||||||
|
this.offset = Offset.zero,
|
||||||
|
this.splashRadius = 14,
|
||||||
|
this.tooltip,
|
||||||
});
|
});
|
||||||
|
final Widget? child;
|
||||||
|
final Offset offset;
|
||||||
|
final double splashRadius;
|
||||||
|
final String? tooltip;
|
||||||
|
|
||||||
final Function(RequestItemMenuOption)? onSelected;
|
final Function(RequestItemMenuOption)? onSelected;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return PopupMenuButton<RequestItemMenuOption>(
|
return PopupMenuButton<RequestItemMenuOption>(
|
||||||
|
tooltip: tooltip,
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
splashRadius: 14,
|
splashRadius: splashRadius,
|
||||||
iconSize: 14,
|
iconSize: 14,
|
||||||
|
offset: offset,
|
||||||
onSelected: onSelected,
|
onSelected: onSelected,
|
||||||
itemBuilder: (BuildContext context) =>
|
itemBuilder: (BuildContext context) =>
|
||||||
<PopupMenuEntry<RequestItemMenuOption>>[
|
<PopupMenuEntry<RequestItemMenuOption>>[
|
||||||
@ -31,6 +41,7 @@ class RequestCardMenu extends StatelessWidget {
|
|||||||
child: Text('Duplicate'),
|
child: Text('Duplicate'),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
child: child,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
40
pubspec.lock
40
pubspec.lock
@ -657,6 +657,30 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.0"
|
version: "0.2.0"
|
||||||
|
leak_tracker:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker
|
||||||
|
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "10.0.0"
|
||||||
|
leak_tracker_flutter_testing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker_flutter_testing
|
||||||
|
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.1"
|
||||||
|
leak_tracker_testing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: leak_tracker_testing
|
||||||
|
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.1"
|
||||||
lints:
|
lints:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -693,26 +717,26 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
|
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.16"
|
version: "0.12.16+1"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
|
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.0"
|
version: "0.8.0"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
|
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.0"
|
version: "1.11.0"
|
||||||
mime:
|
mime:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -789,10 +813,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: path
|
name: path
|
||||||
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
|
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.3"
|
version: "1.9.0"
|
||||||
path_parsing:
|
path_parsing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
Reference in New Issue
Block a user