mirror of
https://github.com/foss42/apidash.git
synced 2025-05-22 16:57:07 +08:00
wip: history details pane
This commit is contained in:
@ -128,6 +128,9 @@ const kPt8 = EdgeInsets.only(
|
|||||||
const kPt20 = EdgeInsets.only(
|
const kPt20 = EdgeInsets.only(
|
||||||
top: 20,
|
top: 20,
|
||||||
);
|
);
|
||||||
|
const kPt24 = EdgeInsets.only(
|
||||||
|
top: 24,
|
||||||
|
);
|
||||||
const kPt28 = EdgeInsets.only(
|
const kPt28 = EdgeInsets.only(
|
||||||
top: 28,
|
top: 28,
|
||||||
);
|
);
|
||||||
|
@ -5,12 +5,12 @@ import '../utils/history_utils.dart';
|
|||||||
|
|
||||||
final selectedHistoryIdStateProvider = StateProvider<String?>((ref) => null);
|
final selectedHistoryIdStateProvider = StateProvider<String?>((ref) => null);
|
||||||
|
|
||||||
final selectedRequestGroupStateProvider = StateProvider<String?>((ref) {
|
final selectedRequestGroupIdStateProvider = StateProvider<String?>((ref) {
|
||||||
final selectedHistoryId = ref.watch(selectedHistoryIdStateProvider);
|
final selectedHistoryId = ref.watch(selectedHistoryIdStateProvider);
|
||||||
|
final historyMetaState = ref.read(historyMetaStateNotifier);
|
||||||
if (selectedHistoryId == null) {
|
if (selectedHistoryId == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final historyMetaState = ref.read(historyMetaStateNotifier);
|
|
||||||
return getHistoryRequestKey(historyMetaState![selectedHistoryId]!);
|
return getHistoryRequestKey(historyMetaState![selectedHistoryId]!);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ class NavbarButton extends ConsumerWidget {
|
|||||||
if (buttonIdx != null) {
|
if (buttonIdx != null) {
|
||||||
ref.read(navRailIndexStateProvider.notifier).state =
|
ref.read(navRailIndexStateProvider.notifier).state =
|
||||||
buttonIdx!;
|
buttonIdx!;
|
||||||
if (railIdx > 1 && buttonIdx! <= 1) {
|
if (railIdx > 2 && buttonIdx! <= 2) {
|
||||||
ref.read(leftDrawerStateProvider.notifier).state = false;
|
ref.read(leftDrawerStateProvider.notifier).state = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ class NavbarButton extends ConsumerWidget {
|
|||||||
if (buttonIdx != null) {
|
if (buttonIdx != null) {
|
||||||
ref.read(navRailIndexStateProvider.notifier).state =
|
ref.read(navRailIndexStateProvider.notifier).state =
|
||||||
buttonIdx!;
|
buttonIdx!;
|
||||||
if (railIdx > 1 && buttonIdx! <= 1) {
|
if (railIdx > 2 && buttonIdx! <= 2) {
|
||||||
ref.read(leftDrawerStateProvider.notifier).state =
|
ref.read(leftDrawerStateProvider.notifier).state =
|
||||||
false;
|
false;
|
||||||
}
|
}
|
||||||
|
@ -70,13 +70,16 @@ class EnvironmentEditor extends ConsumerWidget {
|
|||||||
margin: EdgeInsets.zero,
|
margin: EdgeInsets.zero,
|
||||||
color: kColorTransparent,
|
color: kColorTransparent,
|
||||||
surfaceTintColor: kColorTransparent,
|
surfaceTintColor: kColorTransparent,
|
||||||
shape: RoundedRectangleBorder(
|
shape: context.isMediumWindow
|
||||||
side: BorderSide(
|
? null
|
||||||
color:
|
: RoundedRectangleBorder(
|
||||||
Theme.of(context).colorScheme.surfaceContainerHighest,
|
side: BorderSide(
|
||||||
),
|
color: Theme.of(context)
|
||||||
borderRadius: kBorderRadius12,
|
.colorScheme
|
||||||
),
|
.surfaceContainerHighest,
|
||||||
|
),
|
||||||
|
borderRadius: kBorderRadius12,
|
||||||
|
),
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
child: const Padding(
|
child: const Padding(
|
||||||
padding: kPv6,
|
padding: kPv6,
|
||||||
|
66
lib/screens/history/details_pane/url_card.dart
Normal file
66
lib/screens/history/details_pane/url_card.dart
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:apidash/widgets/widgets.dart';
|
||||||
|
import 'package:apidash/utils/utils.dart';
|
||||||
|
import 'package:apidash/consts.dart';
|
||||||
|
|
||||||
|
class HistoryURLCard extends StatelessWidget {
|
||||||
|
const HistoryURLCard({
|
||||||
|
super.key,
|
||||||
|
required this.method,
|
||||||
|
required this.url,
|
||||||
|
});
|
||||||
|
|
||||||
|
final HTTPVerb method;
|
||||||
|
final String url;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final fontSize = Theme.of(context).textTheme.titleMedium?.fontSize;
|
||||||
|
return LayoutBuilder(builder: (context, constraints) {
|
||||||
|
final isCompact = constraints.maxWidth <= kMinWindowSize.width;
|
||||||
|
return Card(
|
||||||
|
color: kColorTransparent,
|
||||||
|
surfaceTintColor: kColorTransparent,
|
||||||
|
elevation: 0,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
side: BorderSide(
|
||||||
|
color: Theme.of(context).colorScheme.surfaceContainerHighest,
|
||||||
|
),
|
||||||
|
borderRadius: kBorderRadius8,
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 12,
|
||||||
|
horizontal: isCompact ? 10 : 16,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
isCompact ? const SizedBox.shrink() : kHSpacer10,
|
||||||
|
Text(
|
||||||
|
method.name.toUpperCase(),
|
||||||
|
style: kCodeStyle.copyWith(
|
||||||
|
fontSize: fontSize,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: getHTTPMethodColor(
|
||||||
|
method,
|
||||||
|
brightness: Theme.of(context).brightness,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
isCompact ? kHSpacer10 : kHSpacer20,
|
||||||
|
Expanded(
|
||||||
|
child: RawTextField(
|
||||||
|
readOnly: true,
|
||||||
|
controller: TextEditingController(text: url),
|
||||||
|
style: kCodeStyle.copyWith(
|
||||||
|
fontSize: fontSize,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,42 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:apidash/providers/providers.dart';
|
||||||
|
import 'package:apidash/widgets/widgets.dart';
|
||||||
|
import 'package:apidash/consts.dart';
|
||||||
|
import './details_pane/url_card.dart';
|
||||||
|
|
||||||
class HistoryDetails extends StatelessWidget {
|
class HistoryDetails extends StatefulHookConsumerWidget {
|
||||||
const HistoryDetails({super.key});
|
const HistoryDetails({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
ConsumerState<HistoryDetails> createState() => _HistoryDetailsState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HistoryDetailsState extends ConsumerState<HistoryDetails>
|
||||||
|
with TickerProviderStateMixin {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container();
|
final selectedHistoryRequest =
|
||||||
|
ref.watch(selectedHistoryRequestModelProvider);
|
||||||
|
final metaData = selectedHistoryRequest?.metaData;
|
||||||
|
|
||||||
|
final TabController controller =
|
||||||
|
useTabController(initialLength: 2, vsync: this);
|
||||||
|
|
||||||
|
return selectedHistoryRequest != null
|
||||||
|
? Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: kP4,
|
||||||
|
child: HistoryURLCard(
|
||||||
|
method: metaData!.method, url: metaData.url)),
|
||||||
|
kVSpacer10,
|
||||||
|
RequestResponseTabbar(
|
||||||
|
controller: controller,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: const Text("No Request Selected");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,7 @@ class HistoryPane extends ConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: (!context.isMediumWindow && kIsMacOS
|
padding: (!context.isMediumWindow && kIsMacOS ? kPt24 : kPt8) +
|
||||||
? kP24CollectionPane
|
|
||||||
: kP8CollectionPane) +
|
|
||||||
(context.isMediumWindow ? kPb70 : EdgeInsets.zero),
|
(context.isMediumWindow ? kPb70 : EdgeInsets.zero),
|
||||||
child: const Column(
|
child: const Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
@ -34,6 +32,7 @@ class HistoryList extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final selectedGroupId = ref.watch(selectedRequestGroupIdStateProvider);
|
||||||
final historySequence = ref.watch(historySequenceProvider);
|
final historySequence = ref.watch(historySequenceProvider);
|
||||||
final alwaysShowHistoryPaneScrollbar = ref.watch(settingsProvider
|
final alwaysShowHistoryPaneScrollbar = ref.watch(settingsProvider
|
||||||
.select((value) => value.alwaysShowCollectionPaneScrollbar));
|
.select((value) => value.alwaysShowCollectionPaneScrollbar));
|
||||||
@ -45,12 +44,7 @@ class HistoryList extends HookConsumerWidget {
|
|||||||
thumbVisibility: alwaysShowHistoryPaneScrollbar,
|
thumbVisibility: alwaysShowHistoryPaneScrollbar,
|
||||||
radius: const Radius.circular(12),
|
radius: const Radius.circular(12),
|
||||||
child: ListView(
|
child: ListView(
|
||||||
padding: context.isMediumWindow
|
padding: EdgeInsets.only(bottom: MediaQuery.paddingOf(context).bottom),
|
||||||
? EdgeInsets.only(
|
|
||||||
bottom: MediaQuery.paddingOf(context).bottom,
|
|
||||||
right: 8,
|
|
||||||
)
|
|
||||||
: kPe8,
|
|
||||||
controller: scrollController,
|
controller: scrollController,
|
||||||
children: sortedHistoryKeys != null
|
children: sortedHistoryKeys != null
|
||||||
? sortedHistoryKeys.map((date) {
|
? sortedHistoryKeys.map((date) {
|
||||||
@ -69,8 +63,8 @@ class HistoryList extends HookConsumerWidget {
|
|||||||
id: item.first.historyId,
|
id: item.first.historyId,
|
||||||
models: item,
|
models: item,
|
||||||
method: item.first.method,
|
method: item.first.method,
|
||||||
selectedId:
|
isSelected: selectedGroupId ==
|
||||||
ref.watch(selectedRequestGroupStateProvider),
|
getHistoryRequestKey(item.first),
|
||||||
requestGroupSize: item.length,
|
requestGroupSize: item.length,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
ref
|
ref
|
||||||
|
@ -1,10 +1,32 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:apidash/providers/history_providers.dart';
|
||||||
|
import 'package:apidash/utils/history_utils.dart';
|
||||||
|
import 'package:apidash/widgets/widgets.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
class HistoryRequests extends StatelessWidget {
|
class HistoryRequests extends ConsumerWidget {
|
||||||
const HistoryRequests({super.key});
|
const HistoryRequests({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
return Container();
|
final selectedRequestId = ref.watch(selectedHistoryIdStateProvider);
|
||||||
|
final selectedRequest = ref.read(selectedHistoryRequestModelProvider);
|
||||||
|
final historyMetas = ref.read(historyMetaStateNotifier);
|
||||||
|
final requestGroup = getRequestGroup(
|
||||||
|
historyMetas?.values.toList(), selectedRequest?.metaData);
|
||||||
|
return Column(
|
||||||
|
children: requestGroup
|
||||||
|
.map((request) => SidebarHistoryCard(
|
||||||
|
id: request.historyId,
|
||||||
|
method: request.method,
|
||||||
|
isSelected: selectedRequestId == request.historyId,
|
||||||
|
onTap: () {
|
||||||
|
ref.read(selectedHistoryIdStateProvider.notifier).state =
|
||||||
|
request.historyId;
|
||||||
|
},
|
||||||
|
models: [request],
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,15 +57,6 @@ class BottomNavBar extends ConsumerWidget {
|
|||||||
label: 'History',
|
label: 'History',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// Expanded(
|
|
||||||
// child: NavbarButton(
|
|
||||||
// railIdx: railIdx,
|
|
||||||
// buttonIdx: 2,
|
|
||||||
// selectedIcon: Icons.history,
|
|
||||||
// icon: Icons.history_outlined,
|
|
||||||
// label: 'History',
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: NavbarButton(
|
child: NavbarButton(
|
||||||
railIdx: railIdx,
|
railIdx: railIdx,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:apidash/widgets/widgets.dart';
|
||||||
import 'package:apidash/consts.dart';
|
import 'package:apidash/consts.dart';
|
||||||
import '../../home_page/editor_pane/details_card/response_pane.dart';
|
import '../../home_page/editor_pane/details_card/response_pane.dart';
|
||||||
import '../../home_page/editor_pane/editor_request.dart';
|
import '../../home_page/editor_pane/editor_request.dart';
|
||||||
@ -30,72 +31,21 @@ class RequestResponseTabs extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RequestResponseTabbar extends StatelessWidget {
|
|
||||||
const RequestResponseTabbar({
|
|
||||||
super.key,
|
|
||||||
required this.controller,
|
|
||||||
});
|
|
||||||
|
|
||||||
final TabController controller;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Center(
|
|
||||||
child: Container(
|
|
||||||
width: kReqResTabWidth,
|
|
||||||
height: kReqResTabHeight,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: kBorderRadius20,
|
|
||||||
border: Border.all(
|
|
||||||
color: Theme.of(context).colorScheme.outlineVariant,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: ClipRRect(
|
|
||||||
borderRadius: kBorderRadius20,
|
|
||||||
child: TabBar(
|
|
||||||
dividerColor: Colors.transparent,
|
|
||||||
indicatorWeight: 0.0,
|
|
||||||
indicatorSize: TabBarIndicatorSize.tab,
|
|
||||||
unselectedLabelColor:
|
|
||||||
Theme.of(context).colorScheme.onSurface.withOpacity(0.4),
|
|
||||||
labelStyle: kTextStyleTab.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: Theme.of(context).colorScheme.onPrimary,
|
|
||||||
),
|
|
||||||
unselectedLabelStyle: kTextStyleTab,
|
|
||||||
splashBorderRadius: kBorderRadius20,
|
|
||||||
indicator: BoxDecoration(
|
|
||||||
borderRadius: kBorderRadius20,
|
|
||||||
color: Theme.of(context).colorScheme.primary,
|
|
||||||
),
|
|
||||||
controller: controller,
|
|
||||||
tabs: const <Widget>[
|
|
||||||
Tab(
|
|
||||||
text: kLabelRequest,
|
|
||||||
),
|
|
||||||
Tab(
|
|
||||||
text: kLabelResponse,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class RequestResponseTabviews extends StatelessWidget {
|
class RequestResponseTabviews extends StatelessWidget {
|
||||||
const RequestResponseTabviews({super.key, required this.controller});
|
const RequestResponseTabviews({super.key, required this.controller});
|
||||||
final TabController controller;
|
final TabController controller;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return TabBarView(controller: controller, children: const [
|
return TabBarView(
|
||||||
RequestEditor(),
|
controller: controller,
|
||||||
Padding(
|
children: const [
|
||||||
padding: kPt8,
|
RequestEditor(),
|
||||||
child: ResponsePane(),
|
Padding(
|
||||||
),
|
padding: kPt8,
|
||||||
]);
|
child: ResponsePane(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,3 +84,20 @@ Map<String, List<HistoryMetaModel>> getRequestGroups(
|
|||||||
});
|
});
|
||||||
return historyGroups;
|
return historyGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<HistoryMetaModel> getRequestGroup(
|
||||||
|
List<HistoryMetaModel>? models, HistoryMetaModel? selectedModel) {
|
||||||
|
List<HistoryMetaModel> requestGroup = [];
|
||||||
|
if (selectedModel == null || (models?.isEmpty ?? true)) {
|
||||||
|
return requestGroup;
|
||||||
|
}
|
||||||
|
String selectedModelKey = getHistoryRequestKey(selectedModel);
|
||||||
|
for (HistoryMetaModel model in models!) {
|
||||||
|
String key = getHistoryRequestKey(model);
|
||||||
|
if (key == selectedModelKey) {
|
||||||
|
requestGroup.add(model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
requestGroup.sort((a, b) => b.timeStamp.compareTo(a.timeStamp));
|
||||||
|
return requestGroup;
|
||||||
|
}
|
||||||
|
@ -10,7 +10,7 @@ class SidebarHistoryCard extends StatelessWidget {
|
|||||||
required this.id,
|
required this.id,
|
||||||
required this.models,
|
required this.models,
|
||||||
required this.method,
|
required this.method,
|
||||||
this.selectedId,
|
this.isSelected = false,
|
||||||
this.requestGroupSize = 1,
|
this.requestGroupSize = 1,
|
||||||
this.onTap,
|
this.onTap,
|
||||||
});
|
});
|
||||||
@ -18,7 +18,7 @@ class SidebarHistoryCard extends StatelessWidget {
|
|||||||
final String id;
|
final String id;
|
||||||
final List<HistoryMetaModel> models;
|
final List<HistoryMetaModel> models;
|
||||||
final HTTPVerb method;
|
final HTTPVerb method;
|
||||||
final String? selectedId;
|
final bool isSelected;
|
||||||
final int requestGroupSize;
|
final int requestGroupSize;
|
||||||
final Function()? onTap;
|
final Function()? onTap;
|
||||||
|
|
||||||
@ -29,7 +29,6 @@ class SidebarHistoryCard extends StatelessWidget {
|
|||||||
Theme.of(context).colorScheme.surfaceContainerHighest.withOpacity(0.5);
|
Theme.of(context).colorScheme.surfaceContainerHighest.withOpacity(0.5);
|
||||||
final model = models.first;
|
final model = models.first;
|
||||||
final Color surfaceTint = Theme.of(context).colorScheme.primary;
|
final Color surfaceTint = Theme.of(context).colorScheme.primary;
|
||||||
bool isSelected = selectedId == getHistoryRequestKey(model);
|
|
||||||
final String name = getHistoryRequestName(model);
|
final String name = getHistoryRequestName(model);
|
||||||
return Tooltip(
|
return Tooltip(
|
||||||
message: name,
|
message: name,
|
||||||
@ -84,9 +83,9 @@ class SidebarHistoryCard extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
requestGroupSize == 2
|
requestGroupSize > 9
|
||||||
? requestGroupSize.toString()
|
? "9+"
|
||||||
: "9+",
|
: requestGroupSize.toString(),
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
.labelSmall
|
.labelSmall
|
||||||
|
@ -20,38 +20,40 @@ class ErrorMessage extends StatelessWidget {
|
|||||||
return Padding(
|
return Padding(
|
||||||
padding: kPh20v10,
|
padding: kPh20v10,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Column(
|
child: SingleChildScrollView(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
child: Column(
|
||||||
children: [
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
showIcon
|
children: [
|
||||||
? Icon(
|
showIcon
|
||||||
Icons.warning_rounded,
|
? Icon(
|
||||||
size: 40,
|
Icons.warning_rounded,
|
||||||
color: color,
|
size: 40,
|
||||||
)
|
color: color,
|
||||||
: const SizedBox(),
|
)
|
||||||
SelectableText(
|
: const SizedBox(),
|
||||||
message ?? 'An error occurred. $kUnexpectedRaiseIssue',
|
SelectableText(
|
||||||
textAlign: TextAlign.center,
|
message ?? 'An error occurred. $kUnexpectedRaiseIssue',
|
||||||
style: Theme.of(context)
|
textAlign: TextAlign.center,
|
||||||
.textTheme
|
style: Theme.of(context)
|
||||||
.titleMedium
|
.textTheme
|
||||||
?.copyWith(color: color),
|
.titleMedium
|
||||||
),
|
?.copyWith(color: color),
|
||||||
kVSpacer20,
|
),
|
||||||
showIssueButton
|
kVSpacer20,
|
||||||
? FilledButton.tonalIcon(
|
showIssueButton
|
||||||
onPressed: () {
|
? FilledButton.tonalIcon(
|
||||||
launchUrl(Uri.parse(kGitUrl));
|
onPressed: () {
|
||||||
},
|
launchUrl(Uri.parse(kGitUrl));
|
||||||
icon: const Icon(Icons.arrow_outward_rounded),
|
},
|
||||||
label: Text(
|
icon: const Icon(Icons.arrow_outward_rounded),
|
||||||
'Raise Issue',
|
label: Text(
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
'Raise Issue',
|
||||||
),
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
)
|
),
|
||||||
: const SizedBox(),
|
)
|
||||||
],
|
: const SizedBox(),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -8,16 +8,19 @@ class RawTextField extends StatelessWidget {
|
|||||||
this.controller,
|
this.controller,
|
||||||
this.hintText,
|
this.hintText,
|
||||||
this.style,
|
this.style,
|
||||||
|
this.readOnly = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
final void Function(String)? onChanged;
|
final void Function(String)? onChanged;
|
||||||
final TextEditingController? controller;
|
final TextEditingController? controller;
|
||||||
final String? hintText;
|
final String? hintText;
|
||||||
final TextStyle? style;
|
final TextStyle? style;
|
||||||
|
final bool readOnly;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return TextField(
|
return TextField(
|
||||||
|
readOnly: readOnly,
|
||||||
controller: controller,
|
controller: controller,
|
||||||
onChanged: onChanged,
|
onChanged: onChanged,
|
||||||
style: style,
|
style: style,
|
||||||
|
@ -19,7 +19,7 @@ class HistorySplitView extends StatefulWidget {
|
|||||||
class HistorySplitViewState extends State<HistorySplitView> {
|
class HistorySplitViewState extends State<HistorySplitView> {
|
||||||
final MultiSplitViewController _controller = MultiSplitViewController(
|
final MultiSplitViewController _controller = MultiSplitViewController(
|
||||||
areas: [
|
areas: [
|
||||||
Area(id: "sidebar", min: 200, size: 220, max: 300),
|
Area(id: "sidebar", min: 200, size: 250, max: 300),
|
||||||
Area(id: "main"),
|
Area(id: "main"),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
56
lib/widgets/tabbar_request_response.dart
Normal file
56
lib/widgets/tabbar_request_response.dart
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:apidash/consts.dart';
|
||||||
|
|
||||||
|
class RequestResponseTabbar extends StatelessWidget {
|
||||||
|
const RequestResponseTabbar({
|
||||||
|
super.key,
|
||||||
|
required this.controller,
|
||||||
|
});
|
||||||
|
|
||||||
|
final TabController controller;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Center(
|
||||||
|
child: Container(
|
||||||
|
width: kReqResTabWidth,
|
||||||
|
height: kReqResTabHeight,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: kBorderRadius20,
|
||||||
|
border: Border.all(
|
||||||
|
color: Theme.of(context).colorScheme.outlineVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: kBorderRadius20,
|
||||||
|
child: TabBar(
|
||||||
|
dividerColor: Colors.transparent,
|
||||||
|
indicatorWeight: 0.0,
|
||||||
|
indicatorSize: TabBarIndicatorSize.tab,
|
||||||
|
unselectedLabelColor:
|
||||||
|
Theme.of(context).colorScheme.onSurface.withOpacity(0.4),
|
||||||
|
labelStyle: kTextStyleTab.copyWith(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Theme.of(context).colorScheme.onPrimary,
|
||||||
|
),
|
||||||
|
unselectedLabelStyle: kTextStyleTab,
|
||||||
|
splashBorderRadius: kBorderRadius20,
|
||||||
|
indicator: BoxDecoration(
|
||||||
|
borderRadius: kBorderRadius20,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
controller: controller,
|
||||||
|
tabs: const <Widget>[
|
||||||
|
Tab(
|
||||||
|
text: kLabelRequest,
|
||||||
|
),
|
||||||
|
Tab(
|
||||||
|
text: kLabelResponse,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -45,6 +45,7 @@ export 'splitview_dashboard.dart';
|
|||||||
export 'splitview_equal.dart';
|
export 'splitview_equal.dart';
|
||||||
export 'splitview_history.dart';
|
export 'splitview_history.dart';
|
||||||
export 'suggestions_menu.dart';
|
export 'suggestions_menu.dart';
|
||||||
|
export 'tabbar_request_response.dart';
|
||||||
export 'tables.dart';
|
export 'tables.dart';
|
||||||
export 'tabs.dart';
|
export 'tabs.dart';
|
||||||
export 'texts.dart';
|
export 'texts.dart';
|
||||||
|
Reference in New Issue
Block a user