mirror of
https://github.com/foss42/apidash.git
synced 2025-06-01 14:58:28 +08:00
Widget refactoring
This commit is contained in:
@ -5,7 +5,7 @@ import 'package:apidash/utils/utils.dart';
|
|||||||
import 'package:apidash/consts.dart';
|
import 'package:apidash/consts.dart';
|
||||||
import "snackbars.dart";
|
import "snackbars.dart";
|
||||||
|
|
||||||
class CopyButton extends StatefulWidget {
|
class CopyButton extends StatelessWidget {
|
||||||
const CopyButton({
|
const CopyButton({
|
||||||
super.key,
|
super.key,
|
||||||
required this.toCopy,
|
required this.toCopy,
|
||||||
@ -15,21 +15,16 @@ class CopyButton extends StatefulWidget {
|
|||||||
final String toCopy;
|
final String toCopy;
|
||||||
final bool showLabel;
|
final bool showLabel;
|
||||||
|
|
||||||
@override
|
|
||||||
State<CopyButton> createState() => _CopyButtonState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _CopyButtonState extends State<CopyButton> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var sm = ScaffoldMessenger.of(context);
|
var sm = ScaffoldMessenger.of(context);
|
||||||
return Tooltip(
|
return Tooltip(
|
||||||
message: widget.showLabel ? '' : kLabelCopy,
|
message: showLabel ? '' : kLabelCopy,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: widget.showLabel ? null : kTextButtonMinWidth,
|
width: showLabel ? null : kTextButtonMinWidth,
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await Clipboard.setData(ClipboardData(text: widget.toCopy));
|
await Clipboard.setData(ClipboardData(text: toCopy));
|
||||||
sm.hideCurrentSnackBar();
|
sm.hideCurrentSnackBar();
|
||||||
sm.showSnackBar(getSnackBar("Copied"));
|
sm.showSnackBar(getSnackBar("Copied"));
|
||||||
},
|
},
|
||||||
@ -40,7 +35,7 @@ class _CopyButtonState extends State<CopyButton> {
|
|||||||
Icons.content_copy,
|
Icons.content_copy,
|
||||||
size: 20,
|
size: 20,
|
||||||
),
|
),
|
||||||
if (widget.showLabel) const Text(kLabelCopy)
|
if (showLabel) const Text(kLabelCopy)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -49,7 +44,7 @@ class _CopyButtonState extends State<CopyButton> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SendRequestButton extends StatefulWidget {
|
class SendRequestButton extends StatelessWidget {
|
||||||
const SendRequestButton({
|
const SendRequestButton({
|
||||||
super.key,
|
super.key,
|
||||||
required this.activeId,
|
required this.activeId,
|
||||||
@ -61,29 +56,17 @@ class SendRequestButton extends StatefulWidget {
|
|||||||
final String? sentRequestId;
|
final String? sentRequestId;
|
||||||
final void Function() onTap;
|
final void Function() onTap;
|
||||||
|
|
||||||
@override
|
|
||||||
State<SendRequestButton> createState() => _SendRequestButtonState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SendRequestButtonState extends State<SendRequestButton> {
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
bool disable = widget.sentRequestId != null;
|
bool disable = sentRequestId != null;
|
||||||
return FilledButton(
|
return FilledButton(
|
||||||
onPressed: disable ? null : widget.onTap,
|
onPressed: disable ? null : onTap,
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
disable
|
disable
|
||||||
? (widget.activeId == widget.sentRequestId
|
? (activeId == sentRequestId ? kLabelSending : kLabelBusy)
|
||||||
? kLabelSending
|
|
||||||
: kLabelBusy)
|
|
||||||
: kLabelSend,
|
: kLabelSend,
|
||||||
style: kTextStyleButton,
|
style: kTextStyleButton,
|
||||||
),
|
),
|
||||||
@ -99,7 +82,7 @@ class _SendRequestButtonState extends State<SendRequestButton> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SaveInDownloadsButton extends StatefulWidget {
|
class SaveInDownloadsButton extends StatelessWidget {
|
||||||
const SaveInDownloadsButton({
|
const SaveInDownloadsButton({
|
||||||
super.key,
|
super.key,
|
||||||
this.content,
|
this.content,
|
||||||
@ -115,29 +98,24 @@ class SaveInDownloadsButton extends StatefulWidget {
|
|||||||
final String? name;
|
final String? name;
|
||||||
final bool showLabel;
|
final bool showLabel;
|
||||||
|
|
||||||
@override
|
|
||||||
State<SaveInDownloadsButton> createState() => _SaveInDownloadsButtonState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SaveInDownloadsButtonState extends State<SaveInDownloadsButton> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var sm = ScaffoldMessenger.of(context);
|
var sm = ScaffoldMessenger.of(context);
|
||||||
return Tooltip(
|
return Tooltip(
|
||||||
message: widget.showLabel ? '' : kLabelDownload,
|
message: showLabel ? '' : kLabelDownload,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: widget.showLabel ? null : kTextButtonMinWidth,
|
width: showLabel ? null : kTextButtonMinWidth,
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
onPressed: (widget.content != null)
|
onPressed: (content != null)
|
||||||
? () async {
|
? () async {
|
||||||
var message = "";
|
var message = "";
|
||||||
var path = await getFileDownloadpath(
|
var path = await getFileDownloadpath(
|
||||||
widget.name,
|
name,
|
||||||
widget.ext ?? getFileExtension(widget.mimeType),
|
ext ?? getFileExtension(mimeType),
|
||||||
);
|
);
|
||||||
if (path != null) {
|
if (path != null) {
|
||||||
try {
|
try {
|
||||||
await saveFile(path, widget.content!);
|
await saveFile(path, content!);
|
||||||
var sp = getShortPath(path);
|
var sp = getShortPath(path);
|
||||||
message = 'Saved to $sp';
|
message = 'Saved to $sp';
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -157,7 +135,7 @@ class _SaveInDownloadsButtonState extends State<SaveInDownloadsButton> {
|
|||||||
Icons.download,
|
Icons.download,
|
||||||
size: 20,
|
size: 20,
|
||||||
),
|
),
|
||||||
if (widget.showLabel) const Text(kLabelDownload)
|
if (showLabel) const Text(kLabelDownload)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -166,7 +144,7 @@ class _SaveInDownloadsButtonState extends State<SaveInDownloadsButton> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RepoButton extends StatefulWidget {
|
class RepoButton extends StatelessWidget {
|
||||||
const RepoButton({
|
const RepoButton({
|
||||||
super.key,
|
super.key,
|
||||||
this.text,
|
this.text,
|
||||||
@ -176,15 +154,10 @@ class RepoButton extends StatefulWidget {
|
|||||||
final String? text;
|
final String? text;
|
||||||
final IconData? icon;
|
final IconData? icon;
|
||||||
|
|
||||||
@override
|
|
||||||
State<RepoButton> createState() => _RepoButtonState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _RepoButtonState extends State<RepoButton> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var label = widget.text ?? "GitHub";
|
var label = text ?? "GitHub";
|
||||||
if (widget.icon == null) {
|
if (icon == null) {
|
||||||
return FilledButton(
|
return FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
launchUrl(Uri.parse(kGitUrl));
|
launchUrl(Uri.parse(kGitUrl));
|
||||||
@ -200,7 +173,7 @@ class _RepoButtonState extends State<RepoButton> {
|
|||||||
launchUrl(Uri.parse(kGitUrl));
|
launchUrl(Uri.parse(kGitUrl));
|
||||||
},
|
},
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
widget.icon,
|
icon,
|
||||||
size: 20.0,
|
size: 20.0,
|
||||||
),
|
),
|
||||||
label: Text(
|
label: Text(
|
||||||
@ -211,7 +184,7 @@ class _RepoButtonState extends State<RepoButton> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DiscordButton extends StatefulWidget {
|
class DiscordButton extends StatelessWidget {
|
||||||
const DiscordButton({
|
const DiscordButton({
|
||||||
super.key,
|
super.key,
|
||||||
this.text,
|
this.text,
|
||||||
@ -219,14 +192,9 @@ class DiscordButton extends StatefulWidget {
|
|||||||
|
|
||||||
final String? text;
|
final String? text;
|
||||||
|
|
||||||
@override
|
|
||||||
State<DiscordButton> createState() => _DiscordButtonState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DiscordButtonState extends State<DiscordButton> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var label = widget.text ?? 'Discord Server';
|
var label = text ?? 'Discord Server';
|
||||||
return FilledButton.icon(
|
return FilledButton.icon(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
launchUrl(Uri.parse(kDiscordUrl));
|
launchUrl(Uri.parse(kDiscordUrl));
|
||||||
@ -242,3 +210,27 @@ class _DiscordButtonState extends State<DiscordButton> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SaveButton extends StatelessWidget {
|
||||||
|
const SaveButton({
|
||||||
|
super.key,
|
||||||
|
this.onPressed,
|
||||||
|
});
|
||||||
|
|
||||||
|
final VoidCallback? onPressed;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return TextButton.icon(
|
||||||
|
onPressed: onPressed,
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.save,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
label: const Text(
|
||||||
|
kLabelSave,
|
||||||
|
style: kTextStyleButton,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -129,15 +129,11 @@ class SidebarRequestCard extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RequestDetailsCard extends StatefulWidget {
|
class RequestDetailsCard extends StatelessWidget {
|
||||||
const RequestDetailsCard({super.key, this.child});
|
const RequestDetailsCard({super.key, this.child});
|
||||||
|
|
||||||
final Widget? child;
|
final Widget? child;
|
||||||
@override
|
@override
|
||||||
State<RequestDetailsCard> createState() => _RequestDetailsCardState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _RequestDetailsCardState extends State<RequestDetailsCard> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Card(
|
return Card(
|
||||||
@ -148,7 +144,7 @@ class _RequestDetailsCardState extends State<RequestDetailsCard> {
|
|||||||
borderRadius: kBorderRadius12,
|
borderRadius: kBorderRadius12,
|
||||||
),
|
),
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
child: widget.child,
|
child: child,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ List<TextSpan> generateSpans(
|
|||||||
return spans;
|
return spans;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewCodePane extends StatefulWidget {
|
class ViewCodePane extends StatelessWidget {
|
||||||
const ViewCodePane({
|
const ViewCodePane({
|
||||||
super.key,
|
super.key,
|
||||||
required this.code,
|
required this.code,
|
||||||
@ -109,11 +109,6 @@ class ViewCodePane extends StatefulWidget {
|
|||||||
final CodegenLanguage codegenLanguage;
|
final CodegenLanguage codegenLanguage;
|
||||||
final Function(CodegenLanguage?) onChangedCodegenLanguage;
|
final Function(CodegenLanguage?) onChangedCodegenLanguage;
|
||||||
|
|
||||||
@override
|
|
||||||
State<ViewCodePane> createState() => _ViewCodePaneState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ViewCodePaneState extends State<ViewCodePane> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var codeTheme = Theme.of(context).brightness == Brightness.light
|
var codeTheme = Theme.of(context).brightness == Brightness.light
|
||||||
@ -145,17 +140,17 @@ class _ViewCodePaneState extends State<ViewCodePane> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: DropdownButtonCodegenLanguage(
|
child: DropdownButtonCodegenLanguage(
|
||||||
codegenLanguage: widget.codegenLanguage,
|
codegenLanguage: codegenLanguage,
|
||||||
onChanged: widget.onChangedCodegenLanguage,
|
onChanged: onChangedCodegenLanguage,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
CopyButton(
|
CopyButton(
|
||||||
toCopy: widget.code,
|
toCopy: code,
|
||||||
showLabel: showLabel,
|
showLabel: showLabel,
|
||||||
),
|
),
|
||||||
SaveInDownloadsButton(
|
SaveInDownloadsButton(
|
||||||
content: stringToBytes(widget.code),
|
content: stringToBytes(code),
|
||||||
ext: widget.codegenLanguage.ext,
|
ext: codegenLanguage.ext,
|
||||||
showLabel: showLabel,
|
showLabel: showLabel,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
@ -168,9 +163,9 @@ class _ViewCodePaneState extends State<ViewCodePane> {
|
|||||||
padding: kP8,
|
padding: kP8,
|
||||||
decoration: textContainerdecoration,
|
decoration: textContainerdecoration,
|
||||||
child: CodeGenPreviewer(
|
child: CodeGenPreviewer(
|
||||||
code: widget.code,
|
code: code,
|
||||||
theme: codeTheme,
|
theme: codeTheme,
|
||||||
language: widget.codegenLanguage.codeHighlightLang,
|
language: codegenLanguage.codeHighlightLang,
|
||||||
textStyle: kCodeStyle,
|
textStyle: kCodeStyle,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:apidash/utils/utils.dart';
|
import 'package:apidash/utils/utils.dart';
|
||||||
import 'package:apidash/consts.dart';
|
import 'package:apidash/consts.dart';
|
||||||
|
|
||||||
class DropdownButtonHttpMethod extends StatefulWidget {
|
class DropdownButtonHttpMethod extends StatelessWidget {
|
||||||
const DropdownButtonHttpMethod({
|
const DropdownButtonHttpMethod({
|
||||||
super.key,
|
super.key,
|
||||||
this.method,
|
this.method,
|
||||||
@ -12,30 +12,19 @@ class DropdownButtonHttpMethod extends StatefulWidget {
|
|||||||
final HTTPVerb? method;
|
final HTTPVerb? method;
|
||||||
final void Function(HTTPVerb? value)? onChanged;
|
final void Function(HTTPVerb? value)? onChanged;
|
||||||
|
|
||||||
@override
|
|
||||||
State<DropdownButtonHttpMethod> createState() =>
|
|
||||||
_DropdownButtonHttpMethodState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DropdownButtonHttpMethodState extends State<DropdownButtonHttpMethod> {
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final surfaceColor = Theme.of(context).colorScheme.surface;
|
final surfaceColor = Theme.of(context).colorScheme.surface;
|
||||||
return DropdownButton<HTTPVerb>(
|
return DropdownButton<HTTPVerb>(
|
||||||
focusColor: surfaceColor,
|
focusColor: surfaceColor,
|
||||||
value: widget.method,
|
value: method,
|
||||||
icon: const Icon(Icons.unfold_more_rounded),
|
icon: const Icon(Icons.unfold_more_rounded),
|
||||||
elevation: 4,
|
elevation: 4,
|
||||||
underline: Container(
|
underline: Container(
|
||||||
height: 0,
|
height: 0,
|
||||||
),
|
),
|
||||||
borderRadius: kBorderRadius12,
|
borderRadius: kBorderRadius12,
|
||||||
onChanged: widget.onChanged,
|
onChanged: onChanged,
|
||||||
items: HTTPVerb.values.map<DropdownMenuItem<HTTPVerb>>((HTTPVerb value) {
|
items: HTTPVerb.values.map<DropdownMenuItem<HTTPVerb>>((HTTPVerb value) {
|
||||||
return DropdownMenuItem<HTTPVerb>(
|
return DropdownMenuItem<HTTPVerb>(
|
||||||
value: value,
|
value: value,
|
||||||
@ -58,7 +47,7 @@ class _DropdownButtonHttpMethodState extends State<DropdownButtonHttpMethod> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DropdownButtonContentType extends StatefulWidget {
|
class DropdownButtonContentType extends StatelessWidget {
|
||||||
const DropdownButtonContentType({
|
const DropdownButtonContentType({
|
||||||
super.key,
|
super.key,
|
||||||
this.contentType,
|
this.contentType,
|
||||||
@ -68,18 +57,12 @@ class DropdownButtonContentType extends StatefulWidget {
|
|||||||
final ContentType? contentType;
|
final ContentType? contentType;
|
||||||
final void Function(ContentType?)? onChanged;
|
final void Function(ContentType?)? onChanged;
|
||||||
|
|
||||||
@override
|
|
||||||
State<DropdownButtonContentType> createState() =>
|
|
||||||
_DropdownButtonContentTypeState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DropdownButtonContentTypeState extends State<DropdownButtonContentType> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final surfaceColor = Theme.of(context).colorScheme.surface;
|
final surfaceColor = Theme.of(context).colorScheme.surface;
|
||||||
return DropdownButton<ContentType>(
|
return DropdownButton<ContentType>(
|
||||||
focusColor: surfaceColor,
|
focusColor: surfaceColor,
|
||||||
value: widget.contentType,
|
value: contentType,
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
Icons.unfold_more_rounded,
|
Icons.unfold_more_rounded,
|
||||||
size: 16,
|
size: 16,
|
||||||
@ -91,7 +74,7 @@ class _DropdownButtonContentTypeState extends State<DropdownButtonContentType> {
|
|||||||
underline: Container(
|
underline: Container(
|
||||||
height: 0,
|
height: 0,
|
||||||
),
|
),
|
||||||
onChanged: widget.onChanged,
|
onChanged: onChanged,
|
||||||
borderRadius: kBorderRadius12,
|
borderRadius: kBorderRadius12,
|
||||||
items: ContentType.values
|
items: ContentType.values
|
||||||
.map<DropdownMenuItem<ContentType>>((ContentType value) {
|
.map<DropdownMenuItem<ContentType>>((ContentType value) {
|
||||||
@ -110,28 +93,22 @@ class _DropdownButtonContentTypeState extends State<DropdownButtonContentType> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DropdownButtonCodegenLanguage extends StatefulWidget {
|
class DropdownButtonCodegenLanguage extends StatelessWidget {
|
||||||
const DropdownButtonCodegenLanguage({
|
const DropdownButtonCodegenLanguage({
|
||||||
super.key,
|
super.key,
|
||||||
this.codegenLanguage,
|
this.codegenLanguage,
|
||||||
this.onChanged,
|
this.onChanged,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
|
||||||
State<DropdownButtonCodegenLanguage> createState() =>
|
|
||||||
_DropdownButtonCodegenLanguageState();
|
|
||||||
final CodegenLanguage? codegenLanguage;
|
final CodegenLanguage? codegenLanguage;
|
||||||
final void Function(CodegenLanguage?)? onChanged;
|
final void Function(CodegenLanguage?)? onChanged;
|
||||||
}
|
|
||||||
|
|
||||||
class _DropdownButtonCodegenLanguageState
|
|
||||||
extends State<DropdownButtonCodegenLanguage> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final surfaceColor = Theme.of(context).colorScheme.surface;
|
final surfaceColor = Theme.of(context).colorScheme.surface;
|
||||||
return DropdownButton<CodegenLanguage>(
|
return DropdownButton<CodegenLanguage>(
|
||||||
focusColor: surfaceColor,
|
focusColor: surfaceColor,
|
||||||
value: widget.codegenLanguage,
|
value: codegenLanguage,
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
Icons.unfold_more_rounded,
|
Icons.unfold_more_rounded,
|
||||||
size: 16,
|
size: 16,
|
||||||
@ -143,7 +120,7 @@ class _DropdownButtonCodegenLanguageState
|
|||||||
underline: Container(
|
underline: Container(
|
||||||
height: 0,
|
height: 0,
|
||||||
),
|
),
|
||||||
onChanged: widget.onChanged,
|
onChanged: onChanged,
|
||||||
borderRadius: kBorderRadius12,
|
borderRadius: kBorderRadius12,
|
||||||
items: CodegenLanguage.values
|
items: CodegenLanguage.values
|
||||||
.map<DropdownMenuItem<CodegenLanguage>>((CodegenLanguage value) {
|
.map<DropdownMenuItem<CodegenLanguage>>((CodegenLanguage value) {
|
||||||
|
@ -5,16 +5,11 @@ import '../consts.dart';
|
|||||||
import 'markdown.dart';
|
import 'markdown.dart';
|
||||||
import 'error_message.dart';
|
import 'error_message.dart';
|
||||||
|
|
||||||
class IntroMessage extends StatefulWidget {
|
class IntroMessage extends StatelessWidget {
|
||||||
const IntroMessage({
|
const IntroMessage({
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
|
||||||
State<IntroMessage> createState() => _IntroMessageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _IntroMessageState extends State<IntroMessage> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
late String text;
|
late String text;
|
||||||
|
@ -4,7 +4,7 @@ import 'package:markdown/markdown.dart' as md;
|
|||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'buttons.dart';
|
import 'buttons.dart';
|
||||||
|
|
||||||
class CustomMarkdown extends StatefulWidget {
|
class CustomMarkdown extends StatelessWidget {
|
||||||
const CustomMarkdown({
|
const CustomMarkdown({
|
||||||
super.key,
|
super.key,
|
||||||
required this.data,
|
required this.data,
|
||||||
@ -13,11 +13,6 @@ class CustomMarkdown extends StatefulWidget {
|
|||||||
final String data;
|
final String data;
|
||||||
final EdgeInsets padding;
|
final EdgeInsets padding;
|
||||||
|
|
||||||
@override
|
|
||||||
State<CustomMarkdown> createState() => _CustomMarkdownState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _CustomMarkdownState extends State<CustomMarkdown> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final mdStyleSheet = MarkdownStyleSheet(
|
final mdStyleSheet = MarkdownStyleSheet(
|
||||||
@ -25,9 +20,9 @@ class _CustomMarkdownState extends State<CustomMarkdown> {
|
|||||||
p: Theme.of(context).textTheme.titleMedium,
|
p: Theme.of(context).textTheme.titleMedium,
|
||||||
);
|
);
|
||||||
return Markdown(
|
return Markdown(
|
||||||
padding: widget.padding,
|
padding: padding,
|
||||||
styleSheet: mdStyleSheet,
|
styleSheet: mdStyleSheet,
|
||||||
data: widget.data,
|
data: data,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
extensionSet: md.ExtensionSet.gitHubFlavored,
|
extensionSet: md.ExtensionSet.gitHubFlavored,
|
||||||
onTapLink: (text, href, title) {
|
onTapLink: (text, href, title) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:apidash/consts.dart';
|
import 'package:apidash/consts.dart';
|
||||||
|
|
||||||
class RequestCardMenu extends StatefulWidget {
|
class RequestCardMenu extends StatelessWidget {
|
||||||
const RequestCardMenu({
|
const RequestCardMenu({
|
||||||
super.key,
|
super.key,
|
||||||
this.onSelected,
|
this.onSelected,
|
||||||
@ -9,18 +9,13 @@ class RequestCardMenu extends StatefulWidget {
|
|||||||
|
|
||||||
final Function(RequestItemMenuOption)? onSelected;
|
final Function(RequestItemMenuOption)? onSelected;
|
||||||
|
|
||||||
@override
|
|
||||||
State<RequestCardMenu> createState() => _RequestCardMenuState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _RequestCardMenuState extends State<RequestCardMenu> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return PopupMenuButton<RequestItemMenuOption>(
|
return PopupMenuButton<RequestItemMenuOption>(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
splashRadius: 14,
|
splashRadius: 14,
|
||||||
iconSize: 14,
|
iconSize: 14,
|
||||||
onSelected: widget.onSelected,
|
onSelected: onSelected,
|
||||||
itemBuilder: (BuildContext context) =>
|
itemBuilder: (BuildContext context) =>
|
||||||
<PopupMenuEntry<RequestItemMenuOption>>[
|
<PopupMenuEntry<RequestItemMenuOption>>[
|
||||||
const PopupMenuItem<RequestItemMenuOption>(
|
const PopupMenuItem<RequestItemMenuOption>(
|
||||||
|
@ -49,7 +49,7 @@ class SendingWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ResponsePaneHeader extends StatefulWidget {
|
class ResponsePaneHeader extends StatelessWidget {
|
||||||
const ResponsePaneHeader({
|
const ResponsePaneHeader({
|
||||||
super.key,
|
super.key,
|
||||||
this.responseStatus,
|
this.responseStatus,
|
||||||
@ -60,11 +60,7 @@ class ResponsePaneHeader extends StatefulWidget {
|
|||||||
final int? responseStatus;
|
final int? responseStatus;
|
||||||
final String? message;
|
final String? message;
|
||||||
final Duration? time;
|
final Duration? time;
|
||||||
@override
|
|
||||||
State<ResponsePaneHeader> createState() => _ResponsePaneHeaderState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ResponsePaneHeaderState extends State<ResponsePaneHeader> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return Padding(
|
||||||
@ -81,10 +77,10 @@ class _ResponsePaneHeaderState extends State<ResponsePaneHeader> {
|
|||||||
text: "Response (",
|
text: "Response (",
|
||||||
),
|
),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: "${widget.responseStatus}",
|
text: "$responseStatus",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: getResponseStatusCodeColor(
|
color: getResponseStatusCodeColor(
|
||||||
widget.responseStatus,
|
responseStatus,
|
||||||
brightness: Theme.of(context).brightness,
|
brightness: Theme.of(context).brightness,
|
||||||
),
|
),
|
||||||
fontFamily: kCodeStyle.fontFamily,
|
fontFamily: kCodeStyle.fontFamily,
|
||||||
@ -100,13 +96,13 @@ class _ResponsePaneHeaderState extends State<ResponsePaneHeader> {
|
|||||||
kHSpacer20,
|
kHSpacer20,
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
widget.message ?? "",
|
message ?? "",
|
||||||
softWrap: false,
|
softWrap: false,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: Theme.of(context).textTheme.titleMedium!.copyWith(
|
style: Theme.of(context).textTheme.titleMedium!.copyWith(
|
||||||
fontFamily: kCodeStyle.fontFamily,
|
fontFamily: kCodeStyle.fontFamily,
|
||||||
color: getResponseStatusCodeColor(
|
color: getResponseStatusCodeColor(
|
||||||
widget.responseStatus,
|
responseStatus,
|
||||||
brightness: Theme.of(context).brightness,
|
brightness: Theme.of(context).brightness,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -114,7 +110,7 @@ class _ResponsePaneHeaderState extends State<ResponsePaneHeader> {
|
|||||||
),
|
),
|
||||||
kHSpacer20,
|
kHSpacer20,
|
||||||
Text(
|
Text(
|
||||||
humanizeDuration(widget.time),
|
humanizeDuration(time),
|
||||||
style: Theme.of(context).textTheme.titleMedium!.copyWith(
|
style: Theme.of(context).textTheme.titleMedium!.copyWith(
|
||||||
fontFamily: kCodeStyle.fontFamily,
|
fontFamily: kCodeStyle.fontFamily,
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
@ -207,7 +203,7 @@ class _ResponseTabViewState extends State<ResponseTabView>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ResponseHeadersHeader extends StatefulWidget {
|
class ResponseHeadersHeader extends StatelessWidget {
|
||||||
const ResponseHeadersHeader({
|
const ResponseHeadersHeader({
|
||||||
super.key,
|
super.key,
|
||||||
required this.map,
|
required this.map,
|
||||||
@ -216,11 +212,7 @@ class ResponseHeadersHeader extends StatefulWidget {
|
|||||||
|
|
||||||
final Map map;
|
final Map map;
|
||||||
final String name;
|
final String name;
|
||||||
@override
|
|
||||||
State<ResponseHeadersHeader> createState() => _ResponseHeadersHeaderState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ResponseHeadersHeaderState extends State<ResponseHeadersHeader> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
@ -229,15 +221,15 @@ class _ResponseHeadersHeaderState extends State<ResponseHeadersHeader> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
"${widget.name} (${widget.map.length} items)",
|
"$name (${map.length} items)",
|
||||||
style: Theme.of(context).textTheme.labelLarge!.copyWith(
|
style: Theme.of(context).textTheme.labelLarge!.copyWith(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (widget.map.isNotEmpty)
|
if (map.isNotEmpty)
|
||||||
CopyButton(
|
CopyButton(
|
||||||
toCopy: kEncoder.convert(widget.map),
|
toCopy: kEncoder.convert(map),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -247,7 +239,7 @@ class _ResponseHeadersHeaderState extends State<ResponseHeadersHeader> {
|
|||||||
|
|
||||||
const kHeaderRow = ["Header Name", "Header Value"];
|
const kHeaderRow = ["Header Name", "Header Value"];
|
||||||
|
|
||||||
class ResponseHeaders extends StatefulWidget {
|
class ResponseHeaders extends StatelessWidget {
|
||||||
const ResponseHeaders({
|
const ResponseHeaders({
|
||||||
super.key,
|
super.key,
|
||||||
required this.responseHeaders,
|
required this.responseHeaders,
|
||||||
@ -256,11 +248,7 @@ class ResponseHeaders extends StatefulWidget {
|
|||||||
|
|
||||||
final Map responseHeaders;
|
final Map responseHeaders;
|
||||||
final Map requestHeaders;
|
final Map requestHeaders;
|
||||||
@override
|
|
||||||
State<ResponseHeaders> createState() => _ResponseHeadersState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ResponseHeadersState extends State<ResponseHeaders> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return Padding(
|
||||||
@ -268,25 +256,25 @@ class _ResponseHeadersState extends State<ResponseHeaders> {
|
|||||||
child: ListView(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
ResponseHeadersHeader(
|
ResponseHeadersHeader(
|
||||||
map: widget.responseHeaders,
|
map: responseHeaders,
|
||||||
name: "Response Headers",
|
name: "Response Headers",
|
||||||
),
|
),
|
||||||
if (widget.responseHeaders.isNotEmpty) kVSpacer5,
|
if (responseHeaders.isNotEmpty) kVSpacer5,
|
||||||
if (widget.responseHeaders.isNotEmpty)
|
if (responseHeaders.isNotEmpty)
|
||||||
MapTable(
|
MapTable(
|
||||||
map: widget.responseHeaders,
|
map: responseHeaders,
|
||||||
colNames: kHeaderRow,
|
colNames: kHeaderRow,
|
||||||
firstColumnHeaderCase: true,
|
firstColumnHeaderCase: true,
|
||||||
),
|
),
|
||||||
kVSpacer10,
|
kVSpacer10,
|
||||||
ResponseHeadersHeader(
|
ResponseHeadersHeader(
|
||||||
map: widget.requestHeaders,
|
map: requestHeaders,
|
||||||
name: "Request Headers",
|
name: "Request Headers",
|
||||||
),
|
),
|
||||||
if (widget.requestHeaders.isNotEmpty) kVSpacer5,
|
if (requestHeaders.isNotEmpty) kVSpacer5,
|
||||||
if (widget.requestHeaders.isNotEmpty)
|
if (requestHeaders.isNotEmpty)
|
||||||
MapTable(
|
MapTable(
|
||||||
map: widget.requestHeaders,
|
map: requestHeaders,
|
||||||
colNames: kHeaderRow,
|
colNames: kHeaderRow,
|
||||||
firstColumnHeaderCase: true,
|
firstColumnHeaderCase: true,
|
||||||
),
|
),
|
||||||
@ -296,21 +284,17 @@ class _ResponseHeadersState extends State<ResponseHeaders> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ResponseBody extends StatefulWidget {
|
class ResponseBody extends StatelessWidget {
|
||||||
const ResponseBody({
|
const ResponseBody({
|
||||||
super.key,
|
super.key,
|
||||||
this.activeRequestModel,
|
this.activeRequestModel,
|
||||||
});
|
});
|
||||||
|
|
||||||
final RequestModel? activeRequestModel;
|
final RequestModel? activeRequestModel;
|
||||||
@override
|
|
||||||
State<ResponseBody> createState() => _ResponseBodyState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ResponseBodyState extends State<ResponseBody> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final responseModel = widget.activeRequestModel?.responseModel;
|
final responseModel = activeRequestModel?.responseModel;
|
||||||
if (responseModel == null) {
|
if (responseModel == null) {
|
||||||
return const ErrorMessage(
|
return const ErrorMessage(
|
||||||
message:
|
message:
|
||||||
@ -348,7 +332,7 @@ class _ResponseBodyState extends State<ResponseBody> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return BodySuccess(
|
return BodySuccess(
|
||||||
key: Key("${widget.activeRequestModel!.id}-response"),
|
key: Key("${activeRequestModel!.id}-response"),
|
||||||
mediaType: mediaType,
|
mediaType: mediaType,
|
||||||
options: options,
|
options: options,
|
||||||
bytes: responseModel.bodyBytes!,
|
bytes: responseModel.bodyBytes!,
|
||||||
|
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:apidash/utils/utils.dart';
|
import 'package:apidash/utils/utils.dart';
|
||||||
import 'package:apidash/consts.dart';
|
import 'package:apidash/consts.dart';
|
||||||
|
|
||||||
class MapTable extends StatefulWidget {
|
class MapTable extends StatelessWidget {
|
||||||
const MapTable(
|
const MapTable(
|
||||||
{super.key,
|
{super.key,
|
||||||
required this.map,
|
required this.map,
|
||||||
@ -13,11 +13,6 @@ class MapTable extends StatefulWidget {
|
|||||||
final List<String> colNames;
|
final List<String> colNames;
|
||||||
final bool firstColumnHeaderCase;
|
final bool firstColumnHeaderCase;
|
||||||
|
|
||||||
@override
|
|
||||||
State<MapTable> createState() => _MapTableState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MapTableState extends State<MapTable> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Table(
|
return Table(
|
||||||
@ -33,7 +28,7 @@ class _MapTableState extends State<MapTable> {
|
|||||||
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
||||||
children: [
|
children: [
|
||||||
TableRow(
|
TableRow(
|
||||||
children: widget.colNames
|
children: colNames
|
||||||
.map<TableCell>(
|
.map<TableCell>(
|
||||||
(e) => TableCell(
|
(e) => TableCell(
|
||||||
verticalAlignment: TableCellVerticalAlignment.top,
|
verticalAlignment: TableCellVerticalAlignment.top,
|
||||||
@ -51,7 +46,7 @@ class _MapTableState extends State<MapTable> {
|
|||||||
)
|
)
|
||||||
.toList(),
|
.toList(),
|
||||||
),
|
),
|
||||||
...widget.map.entries.map<TableRow>(
|
...map.entries.map<TableRow>(
|
||||||
(entry) => TableRow(
|
(entry) => TableRow(
|
||||||
children: [
|
children: [
|
||||||
TableCell(
|
TableCell(
|
||||||
@ -59,7 +54,7 @@ class _MapTableState extends State<MapTable> {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: kP1,
|
padding: kP1,
|
||||||
child: SelectableText(
|
child: SelectableText(
|
||||||
widget.firstColumnHeaderCase
|
firstColumnHeaderCase
|
||||||
? formatHeaderCase(entry.key)
|
? formatHeaderCase(entry.key)
|
||||||
: entry.key,
|
: entry.key,
|
||||||
style: kCodeStyle.copyWith(
|
style: kCodeStyle.copyWith(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:apidash/consts.dart';
|
import 'package:apidash/consts.dart';
|
||||||
|
|
||||||
class URLField extends StatefulWidget {
|
class URLField extends StatelessWidget {
|
||||||
const URLField({
|
const URLField({
|
||||||
super.key,
|
super.key,
|
||||||
required this.activeId,
|
required this.activeId,
|
||||||
@ -13,21 +13,11 @@ class URLField extends StatefulWidget {
|
|||||||
final String? initialValue;
|
final String? initialValue;
|
||||||
final void Function(String)? onChanged;
|
final void Function(String)? onChanged;
|
||||||
|
|
||||||
@override
|
|
||||||
State<URLField> createState() => _URLFieldState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _URLFieldState extends State<URLField> {
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return TextFormField(
|
return TextFormField(
|
||||||
key: Key("url-${widget.activeId}"),
|
key: Key("url-$activeId"),
|
||||||
initialValue: widget.initialValue,
|
initialValue: initialValue,
|
||||||
style: kCodeStyle,
|
style: kCodeStyle,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: kHintTextUrlCard,
|
hintText: kHintTextUrlCard,
|
||||||
@ -38,12 +28,12 @@ class _URLFieldState extends State<URLField> {
|
|||||||
),
|
),
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
),
|
),
|
||||||
onChanged: widget.onChanged,
|
onChanged: onChanged,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CellField extends StatefulWidget {
|
class CellField extends StatelessWidget {
|
||||||
const CellField({
|
const CellField({
|
||||||
super.key,
|
super.key,
|
||||||
required this.keyId,
|
required this.keyId,
|
||||||
@ -59,41 +49,36 @@ class CellField extends StatefulWidget {
|
|||||||
final void Function(String)? onChanged;
|
final void Function(String)? onChanged;
|
||||||
final ColorScheme? colorScheme;
|
final ColorScheme? colorScheme;
|
||||||
|
|
||||||
@override
|
|
||||||
State<CellField> createState() => _CellFieldState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _CellFieldState extends State<CellField> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var colorScheme = widget.colorScheme ?? Theme.of(context).colorScheme;
|
var clrScheme = colorScheme ?? Theme.of(context).colorScheme;
|
||||||
return TextFormField(
|
return TextFormField(
|
||||||
key: Key(widget.keyId),
|
key: Key(keyId),
|
||||||
initialValue: widget.initialValue,
|
initialValue: initialValue,
|
||||||
style: kCodeStyle.copyWith(
|
style: kCodeStyle.copyWith(
|
||||||
color: colorScheme.onSurface,
|
color: clrScheme.onSurface,
|
||||||
),
|
),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintStyle: kCodeStyle.copyWith(
|
hintStyle: kCodeStyle.copyWith(
|
||||||
color: colorScheme.outline.withOpacity(
|
color: clrScheme.outline.withOpacity(
|
||||||
kHintOpacity,
|
kHintOpacity,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
hintText: widget.hintText,
|
hintText: hintText,
|
||||||
focusedBorder: UnderlineInputBorder(
|
focusedBorder: UnderlineInputBorder(
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: colorScheme.primary.withOpacity(
|
color: clrScheme.primary.withOpacity(
|
||||||
kHintOpacity,
|
kHintOpacity,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
enabledBorder: UnderlineInputBorder(
|
enabledBorder: UnderlineInputBorder(
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: colorScheme.surfaceVariant,
|
color: clrScheme.surfaceVariant,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onChanged: widget.onChanged,
|
onChanged: onChanged,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,14 @@ class MethodBox extends StatelessWidget {
|
|||||||
if (method == HTTPVerb.delete) {
|
if (method == HTTPVerb.delete) {
|
||||||
text = "DEL";
|
text = "DEL";
|
||||||
}
|
}
|
||||||
|
if (method == HTTPVerb.patch) {
|
||||||
|
text = "PAT";
|
||||||
|
}
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: 28,
|
width: 24,
|
||||||
child: Text(
|
child: Text(
|
||||||
text,
|
text,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 8,
|
fontSize: 8,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
|
Reference in New Issue
Block a user