From c0e0948f41a7c394310a66dad1d9bf5ad4f8b82e Mon Sep 17 00:00:00 2001 From: DenserMeerkat Date: Fri, 15 Mar 2024 20:25:31 +0530 Subject: [PATCH] chore: appbar request title --- .../home_page/editor_pane/editor_request.dart | 84 ++++++++++--------- lib/screens/mobile/bottom_navbar.dart | 29 ++++--- lib/screens/mobile/dashboard.dart | 6 -- .../mobile/requests_page/requests_page.dart | 75 ++++++++++++++++- lib/utils/http_utils.dart | 6 +- lib/widgets/menus.dart | 13 ++- pubspec.lock | 40 +++++++-- 7 files changed, 180 insertions(+), 73 deletions(-) diff --git a/lib/screens/home_page/editor_pane/editor_request.dart b/lib/screens/home_page/editor_pane/editor_request.dart index a89c8bdd..9b20f639 100644 --- a/lib/screens/home_page/editor_pane/editor_request.dart +++ b/lib/screens/home_page/editor_pane/editor_request.dart @@ -19,7 +19,7 @@ class RequestEditor extends StatelessWidget { : kPb10, child: Column( children: [ - const RequestEditorTopBar(), + !kIsMobile ? const RequestEditorTopBar() : const SizedBox.shrink(), Padding( padding: !kIsMobile ? EdgeInsets.zero : kPh8, child: const EditorPaneRequestURLCard()), @@ -71,44 +71,11 @@ class RequestEditorTopBar extends ConsumerWidget { padding: MaterialStatePropertyAll(EdgeInsets.zero), ), onPressed: () { - 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: [ - 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')), - ], - ); - }); + showRenameDialog(context, name, (val) { + ref + .read(collectionStateNotifierProvider.notifier) + .update(id!, name: val); + }); }, icon: const Icon( 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: [ + 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')), + ], + ); + }); +} diff --git a/lib/screens/mobile/bottom_navbar.dart b/lib/screens/mobile/bottom_navbar.dart index dd91eed5..28c85815 100644 --- a/lib/screens/mobile/bottom_navbar.dart +++ b/lib/screens/mobile/bottom_navbar.dart @@ -90,6 +90,7 @@ Widget customNavigationDestination( IconData icon, String label, { bool isNavigator = false, + bool showLabel = true, Function()? onTap, }) { bool isSelected = railIdx == buttonIdx; @@ -138,19 +139,21 @@ Widget customNavigationDestination( ), ), ), - const SizedBox(height: 4), - Text( - label, - style: Theme.of(context).textTheme.labelSmall!.copyWith( - fontWeight: FontWeight.w600, - color: isSelected - ? Theme.of(context).colorScheme.onSecondaryContainer - : Theme.of(context) - .colorScheme - .onSurface - .withOpacity(0.65), - ), - ), + showLabel ? const SizedBox(height: 4) : const SizedBox.shrink(), + showLabel + ? Text( + label, + style: Theme.of(context).textTheme.labelSmall!.copyWith( + fontWeight: FontWeight.w600, + color: isSelected + ? Theme.of(context).colorScheme.onSecondaryContainer + : Theme.of(context) + .colorScheme + .onSurface + .withOpacity(0.65), + ), + ) + : const SizedBox.shrink(), ], ), ), diff --git a/lib/screens/mobile/dashboard.dart b/lib/screens/mobile/dashboard.dart index 5c4f8949..e2f9f97b 100644 --- a/lib/screens/mobile/dashboard.dart +++ b/lib/screens/mobile/dashboard.dart @@ -30,12 +30,6 @@ class _MobileDashboardState extends ConsumerState { return dragPosition == 0 ? start : end; } - @override - void didChangeDependencies() { - backgroundColor = Theme.of(context).colorScheme.surface; - super.didChangeDependencies(); - } - @override Widget build( BuildContext context, diff --git a/lib/screens/mobile/requests_page/requests_page.dart b/lib/screens/mobile/requests_page/requests_page.dart index cbee06ab..9b4784c1 100644 --- a/lib/screens/mobile/requests_page/requests_page.dart +++ b/lib/screens/mobile/requests_page/requests_page.dart @@ -1,5 +1,11 @@ import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.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/url_card.dart'; import '../../home_page/editor_pane/details_card/code_pane.dart'; @@ -27,13 +33,14 @@ class RequestsPage extends StatelessWidget { .open(direction: InnerDrawerDirection.start); }, ), - title: const Text("Requests"), - centerTitle: true, + title: const RequestTitle(), + titleSpacing: 0, actions: [ IconButton( icon: Icon( - Icons.mode_comment_outlined, + Icons.send_outlined, color: Theme.of(context).colorScheme.onBackground, + size: 20, ), onPressed: () { innerDrawerKey.currentState! @@ -51,6 +58,68 @@ class RequestsPage extends StatelessWidget { } } +class RequestTitle extends ConsumerStatefulWidget { + const RequestTitle({super.key}); + + @override + ConsumerState createState() => _RequestTitleState(); +} + +class _RequestTitleState extends ConsumerState { + @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 { const RequestPageBottombar({ super.key, diff --git a/lib/utils/http_utils.dart b/lib/utils/http_utils.dart index 63aa6181..aee771d0 100644 --- a/lib/utils/http_utils.dart +++ b/lib/utils/http_utils.dart @@ -7,14 +7,14 @@ import '../models/models.dart'; import 'convert_utils.dart' show rowsToMap; import '../consts.dart'; -String getRequestTitleFromUrl(String? url) { +String getRequestTitleFromUrl(String? url, {bool capitalize = false}) { if (url == null || url.trim() == "") { - return "untitled"; + return !capitalize ? "untitled" : "Untitled"; } if (url.contains("://")) { String rem = url.split("://")[1]; if (rem.trim() == "") { - return "untitled"; + return !capitalize ? "untitled" : "Untitled"; } return rem; } diff --git a/lib/widgets/menus.dart b/lib/widgets/menus.dart index 81958a02..e206e1f2 100644 --- a/lib/widgets/menus.dart +++ b/lib/widgets/menus.dart @@ -5,16 +5,26 @@ class RequestCardMenu extends StatelessWidget { const RequestCardMenu({ super.key, 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; @override Widget build(BuildContext context) { return PopupMenuButton( + tooltip: tooltip, padding: EdgeInsets.zero, - splashRadius: 14, + splashRadius: splashRadius, iconSize: 14, + offset: offset, onSelected: onSelected, itemBuilder: (BuildContext context) => >[ @@ -31,6 +41,7 @@ class RequestCardMenu extends StatelessWidget { child: Text('Duplicate'), ), ], + child: child, ); } } diff --git a/pubspec.lock b/pubspec.lock index 2f6e1a36..16dc19db 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -657,6 +657,30 @@ packages: url: "https://pub.dev" source: hosted 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: dependency: transitive description: @@ -693,26 +717,26 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" mime: dependency: transitive description: @@ -789,10 +813,10 @@ packages: dependency: "direct main" description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_parsing: dependency: transitive description: