feat: history of requests

This commit is contained in:
DenserMeerkat
2024-07-21 19:55:32 +05:30
parent d9d60961f7
commit 2fc02eadd1
16 changed files with 355 additions and 124 deletions

View File

@@ -25,7 +25,7 @@ class _HistoryDetailsState extends ConsumerState<HistoryDetails>
final codePaneVisible = ref.watch(historyCodePaneVisibleStateProvider);
final TabController controller =
useTabController(initialLength: 2, vsync: this);
useTabController(initialLength: 3, vsync: this);
return selectedHistoryRequest != null
? LayoutBuilder(
@@ -42,28 +42,45 @@ class _HistoryDetailsState extends ConsumerState<HistoryDetails>
)),
kVSpacer10,
if (isCompact) ...[
RequestResponseTabbar(
SegmentedTabbar(
controller: controller,
tabs: const [
Tab(text: kLabelRequest),
Tab(text: kLabelResponse),
Tab(text: kLabelCode),
],
),
kVSpacer10,
Expanded(
child: TabBarView(
controller: controller,
children: [
HistoryRequestPane(
isCompact: isCompact,
),
const HistoryResponsePane(),
],
))
child: TabBarView(
controller: controller,
children: [
HistoryRequestPane(
isCompact: isCompact,
),
const HistoryResponsePane(),
const CodePane(
isHistoryRequest: true,
),
],
),
),
const HistoryPageBottombar()
] else ...[
Expanded(
child: Padding(
padding: kPh4,
child: RequestDetailsCard(
child: EqualSplitView(
leftWidget: HistoryRequestPane(
isCompact: isCompact,
leftWidget: Column(
children: [
Expanded(
child: HistoryRequestPane(
isCompact: isCompact,
),
),
const HistoryPageBottombar(),
],
),
rightWidget: codePaneVisible
? const CodePane(isHistoryRequest: true)

View File

@@ -6,7 +6,6 @@ import 'package:apidash/providers/providers.dart';
import 'package:apidash/utils/utils.dart';
import 'history_pane.dart';
import 'history_viewer.dart';
import 'history_widgets/history_widgets.dart';
class HistoryPage extends ConsumerWidget {
const HistoryPage({
@@ -23,14 +22,14 @@ class HistoryPage extends ConsumerWidget {
: 'History';
if (context.isMediumWindow) {
return DrawerSplitView(
scaffoldKey: scaffoldKey,
mainContent: const HistoryViewer(),
title: Text(title),
leftDrawerContent: const HistoryPane(),
actions: const [SizedBox(width: 16)],
onDrawerChanged: (value) =>
ref.read(leftDrawerStateProvider.notifier).state = value,
bottomNavigationBar: const HistoryPageBottombar());
scaffoldKey: scaffoldKey,
mainContent: const HistoryViewer(),
title: Text(title),
leftDrawerContent: const HistoryPane(),
actions: const [SizedBox(width: 16)],
onDrawerChanged: (value) =>
ref.read(leftDrawerStateProvider.notifier).state = value,
);
}
return const Column(
children: [

View File

@@ -65,6 +65,7 @@ class HistoryList extends HookConsumerWidget {
child: HistoryExpansionTile(
date: sortedHistoryKeys[index],
requestGroups: requestGroups,
initiallyExpanded: index == 0,
),
);
},
@@ -78,10 +79,12 @@ class HistoryExpansionTile extends StatefulHookConsumerWidget {
super.key,
required this.requestGroups,
required this.date,
this.initiallyExpanded = false,
});
final Map<String, List<HistoryMetaModel>> requestGroups;
final DateTime date;
final bool initiallyExpanded;
@override
ConsumerState<HistoryExpansionTile> createState() =>
@@ -95,8 +98,9 @@ class _HistoryExpansionTileState extends ConsumerState<HistoryExpansionTile>
final animationController = useAnimationController(
duration: const Duration(milliseconds: 200),
vsync: this,
initialValue: widget.initiallyExpanded ? 1.0 : 0.0,
);
final animation = Tween(begin: 0.25, end: 0.0).animate(animationController);
final animation = Tween(begin: 0.0, end: 0.25).animate(animationController);
final colorScheme = Theme.of(context).colorScheme;
final selectedGroupId = ref.watch(selectedRequestGroupIdStateProvider);
return ExpansionTile(
@@ -122,16 +126,16 @@ class _HistoryExpansionTileState extends ConsumerState<HistoryExpansionTile>
),
onExpansionChanged: (value) {
if (value) {
animationController.reverse();
} else {
animationController.forward();
} else {
animationController.reverse();
}
},
trailing: const SizedBox.shrink(),
tilePadding: kPh8,
shape: const RoundedRectangleBorder(),
collapsedBackgroundColor: colorScheme.surfaceContainerLow,
initiallyExpanded: true,
initiallyExpanded: widget.initiallyExpanded,
childrenPadding: kPv8 + kPe4,
children: widget.requestGroups.values.map((item) {
return Padding(

View File

@@ -0,0 +1,47 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:apidash/providers/providers.dart';
import 'package:apidash/widgets/widgets.dart';
import 'package:apidash/models/models.dart';
import 'package:apidash/consts.dart';
class HistoryActionButtons extends ConsumerWidget {
const HistoryActionButtons({super.key, this.historyRequestModel});
final HistoryRequestModel? historyRequestModel;
@override
Widget build(BuildContext context, WidgetRef ref) {
final collectionStateNotifier = ref.watch(collectionStateNotifierProvider);
final isAvailable = collectionStateNotifier?.values.any((element) =>
element.id == historyRequestModel?.metaData.requestId) ??
false;
final requestId = historyRequestModel?.metaData.requestId;
return FilledButtonGroup(buttons: [
ButtonData(
icon: Icons.copy_rounded,
label: kLabelDuplicate,
onPressed: requestId != null
? () {
ref
.read(collectionStateNotifierProvider.notifier)
.duplicateFromHistory(historyRequestModel!);
ref.read(navRailIndexStateProvider.notifier).state = 0;
}
: null,
tooltip: "Duplicate Request",
),
ButtonData(
icon: Icons.north_east_rounded,
label: kLabelRequest,
onPressed: isAvailable && requestId != null
? () {
ref.read(selectedIdStateProvider.notifier).state = requestId;
ref.read(navRailIndexStateProvider.notifier).state = 0;
}
: null,
tooltip: isAvailable ? "Go to Request" : "Couldn't find Request",
),
]);
}
}

View File

@@ -1,8 +1,11 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:apidash/extensions/extensions.dart';
import 'package:apidash/providers/providers.dart';
import 'package:apidash/utils/utils.dart';
import 'package:apidash/consts.dart';
import '../history_requests.dart';
import 'his_action_buttons.dart';
class HistoryPageBottombar extends ConsumerWidget {
const HistoryPageBottombar({
@@ -16,59 +19,87 @@ class HistoryPageBottombar extends ConsumerWidget {
final requestGroup = getRequestGroup(
historyMetas?.values.toList(), selectedRequestModel?.metaData);
final requestCount = requestGroup.length;
return Padding(
padding: MediaQuery.of(context).viewInsets,
child: Container(
height: 60 + MediaQuery.paddingOf(context).bottom,
width: MediaQuery.sizeOf(context).width,
padding: EdgeInsets.only(
bottom: MediaQuery.paddingOf(context).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,
),
return Container(
height: 60 + MediaQuery.paddingOf(context).bottom,
width: MediaQuery.sizeOf(context).width,
padding: EdgeInsets.only(
bottom: MediaQuery.paddingOf(context).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: [
requestCount > 1
? Badge(
label: Text(
requestCount > 9 ? '9 +' : requestCount.toString(),
style: const TextStyle(fontWeight: FontWeight.bold),
),
child: IconButton(
style: IconButton.styleFrom(
backgroundColor:
Theme.of(context).colorScheme.secondaryContainer,
),
onPressed: () {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) {
return ConstrainedBox(
constraints:
const BoxConstraints(maxWidth: 500),
child: const HistorRequestsScrollableSheet());
},
);
},
icon: const Icon(
Icons.keyboard_arrow_up_rounded,
),
),
)
: const SizedBox.shrink(),
],
),
child: context.isMediumWindow
? Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
HistoryActionButtons(historyRequestModel: selectedRequestModel),
HistorySheetButton(requestCount: requestCount)
],
)
: Center(
child: HistoryActionButtons(
historyRequestModel: selectedRequestModel)),
);
}
}
class HistorySheetButton extends StatelessWidget {
const HistorySheetButton({
super.key,
required this.requestCount,
});
final int requestCount;
@override
Widget build(BuildContext context) {
final isCompact = context.isCompactWindow;
const icon = Icon(Icons.keyboard_arrow_up_rounded);
return Badge(
isLabelVisible: requestCount > 1,
label: Text(
requestCount > 9 ? '9+' : requestCount.toString(),
style: const TextStyle(fontWeight: FontWeight.bold),
),
child: FilledButton.tonal(
style: FilledButton.styleFrom(
minimumSize: const Size(44, 44),
padding: isCompact ? kP4 : const EdgeInsets.fromLTRB(16, 12, 8, 12),
),
onPressed: requestCount > 1
? () {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) {
return ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 500),
child: const HistorRequestsScrollableSheet());
},
);
}
: null,
child: isCompact
? icon
: const Row(
children: [
Text(
"Show All",
style: kTextStyleButton,
),
kHSpacer5,
icon,
],
),
),
);
}