mirror of
https://github.com/foss42/apidash.git
synced 2025-06-04 17:37:05 +08:00
wip: mobile support
This commit is contained in:
@ -94,6 +94,7 @@ const kPb10 = EdgeInsets.only(
|
|||||||
bottom: 10,
|
bottom: 10,
|
||||||
);
|
);
|
||||||
const kPr8CollectionPane = EdgeInsets.only(right: 8.0);
|
const kPr8CollectionPane = EdgeInsets.only(right: 8.0);
|
||||||
|
const kPr8b90CollectionPane = EdgeInsets.only(right: 8.0, bottom: 90);
|
||||||
const kpsV5 = EdgeInsets.symmetric(vertical: 2);
|
const kpsV5 = EdgeInsets.symmetric(vertical: 2);
|
||||||
const kHSpacer4 = SizedBox(width: 4);
|
const kHSpacer4 = SizedBox(width: 4);
|
||||||
const kHSpacer5 = SizedBox(width: 5);
|
const kHSpacer5 = SizedBox(width: 5);
|
||||||
|
@ -109,7 +109,7 @@ class _RequestListState extends ConsumerState<RequestList> {
|
|||||||
thumbVisibility: alwaysShowCollectionPaneScrollbar ? true : null,
|
thumbVisibility: alwaysShowCollectionPaneScrollbar ? true : null,
|
||||||
radius: const Radius.circular(12),
|
radius: const Radius.circular(12),
|
||||||
child: ReorderableListView.builder(
|
child: ReorderableListView.builder(
|
||||||
padding: kPr8CollectionPane,
|
padding: kIsMobile ? kPr8b90CollectionPane : kPr8CollectionPane,
|
||||||
scrollController: controller,
|
scrollController: controller,
|
||||||
buildDefaultDragHandles: false,
|
buildDefaultDragHandles: false,
|
||||||
itemCount: requestSequence.length,
|
itemCount: requestSequence.length,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:apidash/screens/home_page/editor_pane/details_card/request_pane/request_pane.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:apidash/consts.dart';
|
import 'package:apidash/consts.dart';
|
||||||
import 'details_card/details_card.dart';
|
import 'details_card/details_card.dart';
|
||||||
@ -8,12 +9,14 @@ class RequestEditor extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return const Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
EditorPaneRequestURLCard(),
|
const EditorPaneRequestURLCard(),
|
||||||
kVSpacer10,
|
kVSpacer10,
|
||||||
Expanded(
|
Expanded(
|
||||||
child: EditorPaneRequestDetailsCard(),
|
child: kIsMobile
|
||||||
|
? const EditRequestPane()
|
||||||
|
: const EditorPaneRequestDetailsCard(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
@ -17,23 +17,25 @@ class EditorPaneRequestURLCard extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
borderRadius: kBorderRadius12,
|
borderRadius: kBorderRadius12,
|
||||||
),
|
),
|
||||||
child: const Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
vertical: 5,
|
vertical: 5,
|
||||||
horizontal: 20,
|
horizontal: !kIsMobile ? 20 : 10,
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
DropdownButtonHTTPMethod(),
|
const DropdownButtonHTTPMethod(),
|
||||||
kHSpacer20,
|
!kIsMobile ? kHSpacer20 : kHSpacer5,
|
||||||
Expanded(
|
const Expanded(
|
||||||
child: URLTextField(),
|
child: URLTextField(),
|
||||||
),
|
),
|
||||||
kHSpacer20,
|
!kIsMobile ? kHSpacer20 : const SizedBox.shrink(),
|
||||||
SizedBox(
|
!kIsMobile
|
||||||
height: 36,
|
? const SizedBox(
|
||||||
child: SendButton(),
|
height: 36,
|
||||||
),
|
child: SendButton(),
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -86,8 +88,10 @@ class URLTextField extends ConsumerWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class SendButton extends ConsumerWidget {
|
class SendButton extends ConsumerWidget {
|
||||||
|
final Function()? onTap;
|
||||||
const SendButton({
|
const SendButton({
|
||||||
super.key,
|
super.key,
|
||||||
|
this.onTap,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -98,6 +102,7 @@ class SendButton extends ConsumerWidget {
|
|||||||
selectedId: selectedId,
|
selectedId: selectedId,
|
||||||
sentRequestId: sentRequestId,
|
sentRequestId: sentRequestId,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
onTap?.call();
|
||||||
ref
|
ref
|
||||||
.read(collectionStateNotifierProvider.notifier)
|
.read(collectionStateNotifierProvider.notifier)
|
||||||
.sendRequest(selectedId!);
|
.sendRequest(selectedId!);
|
||||||
|
148
lib/screens/mobile/bottom_navbar.dart
Normal file
148
lib/screens/mobile/bottom_navbar.dart
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
import 'package:apidash/providers/ui_providers.dart';
|
||||||
|
import 'package:apidash/screens/mobile/page_base.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import '../settings_page.dart';
|
||||||
|
import '../intro_page.dart';
|
||||||
|
|
||||||
|
class BottomNavBar extends ConsumerWidget {
|
||||||
|
const BottomNavBar({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final railIdx = ref.watch(navRailIndexStateProvider);
|
||||||
|
return Container(
|
||||||
|
alignment: Alignment.topCenter,
|
||||||
|
height: 70 + MediaQuery.of(context).padding.bottom,
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
padding: EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.onInverseSurface,
|
||||||
|
),
|
||||||
|
child: Material(
|
||||||
|
type: MaterialType.transparency,
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: customNavigationDestination(context, ref, railIdx, 0,
|
||||||
|
Icons.dashboard, Icons.dashboard_outlined, 'Requests'),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: customNavigationDestination(
|
||||||
|
context,
|
||||||
|
ref,
|
||||||
|
railIdx,
|
||||||
|
1,
|
||||||
|
Icons.laptop_windows,
|
||||||
|
Icons.laptop_windows_outlined,
|
||||||
|
'Variables'),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: customNavigationDestination(context, ref, railIdx, 2,
|
||||||
|
Icons.help, Icons.help_outline, 'About', isNavigator: true,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).push(
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const PageBase(
|
||||||
|
title: 'About',
|
||||||
|
scaffoldBody: IntroPage(),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: customNavigationDestination(context, ref, railIdx, 3,
|
||||||
|
Icons.settings, Icons.settings_outlined, 'Settings',
|
||||||
|
isNavigator: true, onTap: () {
|
||||||
|
Navigator.of(context).push(
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const PageBase(
|
||||||
|
title: 'Settings',
|
||||||
|
scaffoldBody: SettingsPage(),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget customNavigationDestination(
|
||||||
|
BuildContext context,
|
||||||
|
WidgetRef ref,
|
||||||
|
int railIdx,
|
||||||
|
int buttonIdx,
|
||||||
|
IconData selectedIcon,
|
||||||
|
IconData icon,
|
||||||
|
String label, {
|
||||||
|
bool isNavigator = false,
|
||||||
|
Function()? onTap,
|
||||||
|
}) {
|
||||||
|
bool isSelected = railIdx == buttonIdx;
|
||||||
|
return Tooltip(
|
||||||
|
message: label,
|
||||||
|
triggerMode: TooltipTriggerMode.longPress,
|
||||||
|
verticalOffset: 42,
|
||||||
|
child: GestureDetector(
|
||||||
|
behavior: HitTestBehavior.translucent,
|
||||||
|
onTap: isSelected
|
||||||
|
? null
|
||||||
|
: () {
|
||||||
|
if (!isNavigator) {
|
||||||
|
ref.read(navRailIndexStateProvider.notifier).state = buttonIdx;
|
||||||
|
}
|
||||||
|
onTap?.call();
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Ink(
|
||||||
|
width: 65,
|
||||||
|
height: 32,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: isSelected
|
||||||
|
? Theme.of(context).colorScheme.secondaryContainer
|
||||||
|
: Colors.transparent,
|
||||||
|
borderRadius: BorderRadius.circular(30),
|
||||||
|
),
|
||||||
|
child: InkWell(
|
||||||
|
borderRadius: BorderRadius.circular(30),
|
||||||
|
onTap: isSelected
|
||||||
|
? null
|
||||||
|
: () {
|
||||||
|
if (!isNavigator) {
|
||||||
|
ref.read(navRailIndexStateProvider.notifier).state =
|
||||||
|
buttonIdx;
|
||||||
|
}
|
||||||
|
onTap?.call();
|
||||||
|
},
|
||||||
|
child: Icon(
|
||||||
|
icon,
|
||||||
|
color: isSelected
|
||||||
|
? Theme.of(context).colorScheme.onSecondaryContainer
|
||||||
|
: Theme.of(context).colorScheme.onSurface.withOpacity(0.65),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
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),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
@ -1,7 +1,12 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import '../intro_page.dart';
|
import 'package:inner_drawer/inner_drawer.dart';
|
||||||
import '../settings_page.dart';
|
import 'package:flex_color_scheme/flex_color_scheme.dart';
|
||||||
|
import 'bottom_navbar.dart';
|
||||||
|
import 'left_drawer.dart';
|
||||||
|
import 'requestspage/requests_page.dart';
|
||||||
|
import 'requestspage/response_drawer.dart';
|
||||||
import '../home_page/collection_pane.dart';
|
import '../home_page/collection_pane.dart';
|
||||||
|
|
||||||
class MobileDashboard extends ConsumerStatefulWidget {
|
class MobileDashboard extends ConsumerStatefulWidget {
|
||||||
@ -16,67 +21,105 @@ class MobileDashboard extends ConsumerStatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MobileDashboardState extends ConsumerState<MobileDashboard> {
|
class _MobileDashboardState extends ConsumerState<MobileDashboard> {
|
||||||
|
final GlobalKey<InnerDrawerState> _innerDrawerKey =
|
||||||
|
GlobalKey<InnerDrawerState>();
|
||||||
|
late Color backgroundColor;
|
||||||
|
bool isLeftDrawerOpen = false;
|
||||||
|
ValueNotifier<double> dragPosition = ValueNotifier(0);
|
||||||
|
ValueNotifier<InnerDrawerDirection?> drawerDirection =
|
||||||
|
ValueNotifier(InnerDrawerDirection.start);
|
||||||
|
|
||||||
|
Color calculateBackgroundColor(double dragPosition) {
|
||||||
|
Color start = Theme.of(context).colorScheme.surface;
|
||||||
|
Color end = Theme.of(context).colorScheme.onInverseSurface;
|
||||||
|
return dragPosition == 0 ? start : end;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
backgroundColor = Theme.of(context).colorScheme.surface;
|
||||||
|
super.didChangeDependencies();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||||
appBar: AppBar(
|
value: FlexColorScheme.themedSystemNavigationBar(
|
||||||
title: Text(widget.title),
|
context,
|
||||||
|
opacity: 0,
|
||||||
|
noAppBar: true,
|
||||||
),
|
),
|
||||||
drawer: Drawer(
|
child: Stack(
|
||||||
child: ListView(
|
alignment: AlignmentDirectional.bottomCenter,
|
||||||
padding: EdgeInsets.zero,
|
children: [
|
||||||
children: [
|
InnerDrawer(
|
||||||
const SizedBox(
|
key: _innerDrawerKey,
|
||||||
height: 70,
|
swipe: true,
|
||||||
|
swipeChild: true,
|
||||||
|
onTapClose: true,
|
||||||
|
offset: const IDOffset.only(left: 0.7, right: 1),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
offset: const Offset(1, 0),
|
||||||
|
color: Theme.of(context).colorScheme.onInverseSurface,
|
||||||
|
blurRadius: 0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
colorTransitionChild: Colors.transparent,
|
||||||
|
colorTransitionScaffold: Colors.transparent,
|
||||||
|
rightAnimationType: InnerDrawerAnimation.linear,
|
||||||
|
backgroundDecoration:
|
||||||
|
BoxDecoration(color: Theme.of(context).colorScheme.surface),
|
||||||
|
onDragUpdate: (value, direction) {
|
||||||
|
drawerDirection.value = direction;
|
||||||
|
if (value > 0.98) {
|
||||||
|
dragPosition.value = 1;
|
||||||
|
} else {
|
||||||
|
dragPosition.value = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
innerDrawerCallback: (isOpened) {
|
||||||
|
if (drawerDirection.value == InnerDrawerDirection.start) {
|
||||||
|
setState(() {
|
||||||
|
isLeftDrawerOpen = isOpened;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
leftChild: const LeftDrawer(
|
||||||
|
drawerContent: CollectionPane(),
|
||||||
),
|
),
|
||||||
ListTile(
|
rightChild: const ResponseDrawer(),
|
||||||
title: const Text('Home'),
|
scaffold: ValueListenableBuilder<double>(
|
||||||
leading: const Icon(Icons.home_outlined),
|
valueListenable: dragPosition,
|
||||||
onTap: () {
|
builder: (context, value, child) {
|
||||||
Navigator.of(context).pushAndRemoveUntil(
|
return Container(
|
||||||
MaterialPageRoute(
|
color: calculateBackgroundColor(value),
|
||||||
builder: (context) => const MobileDashboard(
|
child: child,
|
||||||
title: 'Home',
|
);
|
||||||
scaffoldBody: IntroPage(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(Route<dynamic> route) => false);
|
|
||||||
},
|
},
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius:
|
||||||
|
const BorderRadius.vertical(top: Radius.circular(8)),
|
||||||
|
child: SafeArea(
|
||||||
|
bottom: false,
|
||||||
|
child: RequestsPage(
|
||||||
|
innerDrawerKey: _innerDrawerKey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
ListTile(
|
),
|
||||||
title: const Text('Requests'),
|
AnimatedPositioned(
|
||||||
leading: const Icon(Icons.auto_awesome_mosaic_outlined),
|
bottom: isLeftDrawerOpen
|
||||||
onTap: () {
|
? 0
|
||||||
Navigator.of(context).pushAndRemoveUntil(
|
: -(72 + MediaQuery.of(context).padding.bottom),
|
||||||
MaterialPageRoute(
|
left: 0,
|
||||||
builder: (context) => const MobileDashboard(
|
right: 0,
|
||||||
title: 'Requests',
|
height: 70 + MediaQuery.of(context).padding.bottom,
|
||||||
scaffoldBody: CollectionPane(),
|
duration: const Duration(milliseconds: 200),
|
||||||
),
|
child: const BottomNavBar(),
|
||||||
),
|
),
|
||||||
(Route<dynamic> route) => false);
|
],
|
||||||
},
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: const Text('Settings'),
|
|
||||||
leading: const Icon(Icons.settings_outlined),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.of(context).pushAndRemoveUntil(
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => const MobileDashboard(
|
|
||||||
title: 'Settings',
|
|
||||||
scaffoldBody: SettingsPage(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(Route<dynamic> route) => false);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const Divider(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: SafeArea(
|
|
||||||
child: widget.scaffoldBody,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
34
lib/screens/mobile/left_drawer.dart
Normal file
34
lib/screens/mobile/left_drawer.dart
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class LeftDrawer extends StatelessWidget {
|
||||||
|
final Widget drawerContent;
|
||||||
|
const LeftDrawer({super.key, required this.drawerContent});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
|
||||||
|
color: Theme.of(context).colorScheme.onInverseSurface,
|
||||||
|
child: Drawer(
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
surfaceTintColor: Colors.transparent,
|
||||||
|
child: Padding(
|
||||||
|
padding:
|
||||||
|
EdgeInsets.only(right: MediaQuery.of(context).size.width * 0.03),
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
bottom: 70 + MediaQuery.of(context).padding.bottom),
|
||||||
|
clipBehavior: Clip.hardEdge,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
borderRadius:
|
||||||
|
const BorderRadius.only(topRight: Radius.circular(8)),
|
||||||
|
),
|
||||||
|
child: drawerContent,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
26
lib/screens/mobile/page_base.dart
Normal file
26
lib/screens/mobile/page_base.dart
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class PageBase extends StatelessWidget {
|
||||||
|
final String title;
|
||||||
|
final Widget scaffoldBody;
|
||||||
|
const PageBase({super.key, required this.title, required this.scaffoldBody});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.background,
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.background,
|
||||||
|
primary: true,
|
||||||
|
title: Text(title),
|
||||||
|
centerTitle: true,
|
||||||
|
),
|
||||||
|
body: Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
bottom: MediaQuery.of(context).padding.bottom,
|
||||||
|
),
|
||||||
|
child: scaffoldBody,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
97
lib/screens/mobile/requestspage/requests_page.dart
Normal file
97
lib/screens/mobile/requestspage/requests_page.dart
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
import 'package:apidash/screens/home_page/editor_pane/details_card/code_pane.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:inner_drawer/inner_drawer.dart';
|
||||||
|
import '../../home_page/editor_pane/editor_pane.dart';
|
||||||
|
import '../../home_page/editor_pane/url_card.dart';
|
||||||
|
import '../page_base.dart';
|
||||||
|
|
||||||
|
class RequestsPage extends StatelessWidget {
|
||||||
|
final GlobalKey<InnerDrawerState> innerDrawerKey;
|
||||||
|
|
||||||
|
const RequestsPage({super.key, required this.innerDrawerKey});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||||
|
primary: true,
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.vertical(top: Radius.circular(8)),
|
||||||
|
),
|
||||||
|
leading: IconButton(
|
||||||
|
icon: const Icon(Icons.format_list_bulleted_rounded),
|
||||||
|
onPressed: () {
|
||||||
|
innerDrawerKey.currentState!
|
||||||
|
.open(direction: InnerDrawerDirection.start);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
title: const Text("Requests"),
|
||||||
|
centerTitle: true,
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
Icons.mode_comment_outlined,
|
||||||
|
color: Theme.of(context).colorScheme.onBackground,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
innerDrawerKey.currentState!
|
||||||
|
.open(direction: InnerDrawerDirection.end);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: Container(
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
child: const RequestEditorPane(),
|
||||||
|
),
|
||||||
|
bottomNavigationBar: Container(
|
||||||
|
height: 60 + MediaQuery.of(context).padding.bottom,
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
bottom: MediaQuery.of(context).padding.bottom,
|
||||||
|
left: 16,
|
||||||
|
right: 16,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
border: Border(
|
||||||
|
top: BorderSide(
|
||||||
|
color: Theme.of(context).colorScheme.onInverseSurface,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
FilledButton.tonalIcon(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).push(
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const PageBase(
|
||||||
|
title: 'View Code',
|
||||||
|
scaffoldBody: CodePane(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.code_rounded),
|
||||||
|
label: const SizedBox(
|
||||||
|
width: 75,
|
||||||
|
child: Text("View Code"),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SendButton(
|
||||||
|
onTap: () {
|
||||||
|
innerDrawerKey.currentState!
|
||||||
|
.open(direction: InnerDrawerDirection.end);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
33
lib/screens/mobile/requestspage/response_drawer.dart
Normal file
33
lib/screens/mobile/requestspage/response_drawer.dart
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import '../../home_page/editor_pane/details_card/response_pane.dart';
|
||||||
|
|
||||||
|
class ResponseDrawer extends StatelessWidget {
|
||||||
|
const ResponseDrawer({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||||
|
primary: true,
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.vertical(top: Radius.circular(8)),
|
||||||
|
),
|
||||||
|
leading: IconButton(
|
||||||
|
icon: const Icon(Icons.arrow_back_rounded),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
title: const Text("Response"),
|
||||||
|
centerTitle: true,
|
||||||
|
),
|
||||||
|
body: Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
bottom: MediaQuery.of(context).padding.bottom,
|
||||||
|
),
|
||||||
|
child: const ResponsePane(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -16,13 +16,15 @@ class SettingsPage extends ConsumerWidget {
|
|||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
!kIsMobile
|
||||||
padding: kPh20t40,
|
? Padding(
|
||||||
child: kIsDesktop
|
padding: kPh20t40,
|
||||||
? Text("Settings",
|
child: kIsDesktop
|
||||||
style: Theme.of(context).textTheme.headlineLarge)
|
? Text("Settings",
|
||||||
: const SizedBox.shrink(),
|
style: Theme.of(context).textTheme.headlineLarge)
|
||||||
),
|
: const SizedBox.shrink(),
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink(),
|
||||||
kIsDesktop
|
kIsDesktop
|
||||||
? const Padding(
|
? const Padding(
|
||||||
padding: kPh20,
|
padding: kPh20,
|
||||||
|
@ -29,10 +29,11 @@ class DropdownButtonHttpMethod extends StatelessWidget {
|
|||||||
return DropdownMenuItem<HTTPVerb>(
|
return DropdownMenuItem<HTTPVerb>(
|
||||||
value: value,
|
value: value,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 16),
|
padding: EdgeInsets.only(left: kIsMobile ? 4 : 16),
|
||||||
child: Text(
|
child: Text(
|
||||||
value.name.toUpperCase(),
|
value.name.toUpperCase(),
|
||||||
style: kCodeStyle.copyWith(
|
style: kCodeStyle.copyWith(
|
||||||
|
fontSize: kIsMobile ? 13 : null,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: getHTTPMethodColor(
|
color: getHTTPMethodColor(
|
||||||
value,
|
value,
|
||||||
|
@ -47,34 +47,37 @@ class _RequestPaneState extends State<RequestPane>
|
|||||||
}
|
}
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
(kIsMobile
|
||||||
padding: kPh20v10,
|
? const SizedBox.shrink()
|
||||||
child: SizedBox(
|
: Padding(
|
||||||
height: kHeaderHeight,
|
padding: kPh20v10,
|
||||||
child: Row(
|
child: SizedBox(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
height: kHeaderHeight,
|
||||||
children: [
|
child: Row(
|
||||||
Text(
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
"Request",
|
children: [
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
Text(
|
||||||
),
|
"Request",
|
||||||
FilledButton.tonalIcon(
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
onPressed: widget.onPressedCodeButton,
|
),
|
||||||
icon: Icon(
|
FilledButton.tonalIcon(
|
||||||
widget.codePaneVisible
|
onPressed: widget.onPressedCodeButton,
|
||||||
? Icons.code_off_rounded
|
icon: Icon(
|
||||||
: Icons.code_rounded,
|
widget.codePaneVisible
|
||||||
),
|
? Icons.code_off_rounded
|
||||||
label: SizedBox(
|
: Icons.code_rounded,
|
||||||
width: 75,
|
),
|
||||||
child: Text(
|
label: SizedBox(
|
||||||
widget.codePaneVisible ? "Hide Code" : "View Code"),
|
width: 75,
|
||||||
|
child: Text(widget.codePaneVisible
|
||||||
|
? "Hide Code"
|
||||||
|
: "View Code"),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
)),
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
TabBar(
|
TabBar(
|
||||||
key: Key(widget.selectedId!),
|
key: Key(widget.selectedId!),
|
||||||
controller: _controller,
|
controller: _controller,
|
||||||
@ -112,3 +115,12 @@ class _RequestPaneState extends State<RequestPane>
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ViewCodeButton extends StatelessWidget {
|
||||||
|
const ViewCodeButton({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
64
pubspec.lock
64
pubspec.lock
@ -297,6 +297,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
|
flex_color_scheme:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flex_color_scheme
|
||||||
|
sha256: "32914024a4f404d90ff449f58d279191675b28e7c08824046baf06826e99d984"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "7.3.1"
|
||||||
|
flex_seed_scheme:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flex_seed_scheme
|
||||||
|
sha256: "29c12aba221eb8a368a119685371381f8035011d18de5ba277ad11d7dfb8657f"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -528,6 +544,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.3"
|
version: "4.1.3"
|
||||||
|
inner_drawer:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: inner_drawer
|
||||||
|
sha256: "19df8813ccb6aa1b6db76f2f976c93befbbae67452d019f5267209b15deb0772"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0+1"
|
||||||
io:
|
io:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -625,30 +649,6 @@ 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:
|
||||||
@ -685,26 +685,26 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
|
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.16+1"
|
version: "0.12.16"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.8.0"
|
version: "0.5.0"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
|
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.11.0"
|
version: "1.10.0"
|
||||||
mime:
|
mime:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -781,10 +781,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: path
|
name: path
|
||||||
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
|
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.0"
|
version: "1.8.3"
|
||||||
path_parsing:
|
path_parsing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -54,6 +54,8 @@ dependencies:
|
|||||||
code_builder: ^4.9.0
|
code_builder: ^4.9.0
|
||||||
dart_style: ^2.3.4
|
dart_style: ^2.3.4
|
||||||
json_text_field: ^1.1.0
|
json_text_field: ^1.1.0
|
||||||
|
inner_drawer: ^1.0.0+1
|
||||||
|
flex_color_scheme: ^7.3.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Reference in New Issue
Block a user