mirror of
https://github.com/foss42/apidash.git
synced 2025-06-25 17:47:02 +08:00
Merge pull request #53 from mmjsmohit/add-feature-codegendropdown
Adding a dropdown for language(library) selection & Kotlin codegen
This commit is contained in:
@ -1 +1,22 @@
|
|||||||
export 'dart/pkg_http.dart';
|
import 'package:apidash/codegen/kotlin/pkg_okhttp.dart';
|
||||||
|
import 'package:apidash/consts.dart';
|
||||||
|
|
||||||
|
import 'package:apidash/models/models.dart' show RequestModel;
|
||||||
|
import 'dart/pkg_http.dart';
|
||||||
|
|
||||||
|
class Codegen {
|
||||||
|
String? getCode(
|
||||||
|
CodegenLanguage codegenLanguage,
|
||||||
|
RequestModel requestModel,
|
||||||
|
String defaultUriScheme,
|
||||||
|
) {
|
||||||
|
switch (codegenLanguage) {
|
||||||
|
case CodegenLanguage.dartHttp:
|
||||||
|
return DartHttpCodeGen().getCode(requestModel, defaultUriScheme);
|
||||||
|
case CodegenLanguage.kotlinOkHttp:
|
||||||
|
return KotlinOkHttpCodeGen().getCode(requestModel);
|
||||||
|
default:
|
||||||
|
throw ArgumentError('Invalid codegenLanguage');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
80
lib/codegen/kotlin/pkg_okhttp.dart
Normal file
80
lib/codegen/kotlin/pkg_okhttp.dart
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import 'package:apidash/consts.dart';
|
||||||
|
|
||||||
|
import '../../models/request_model.dart';
|
||||||
|
|
||||||
|
class KotlinOkHttpCodeGen {
|
||||||
|
final String headerSnippet = """import okhttp3.MediaType.Companion.toMediaType
|
||||||
|
import okhttp3.MultipartBody
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
|
import okhttp3.RequestBody.Companion.asRequestBody
|
||||||
|
import java.io.File
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
val client = OkHttpClient()
|
||||||
|
""";
|
||||||
|
|
||||||
|
final String footerSnippet = """ .build()
|
||||||
|
val response = client.newCall(request).execute()
|
||||||
|
|
||||||
|
println(response.body!!.string())
|
||||||
|
""";
|
||||||
|
String getCode(RequestModel requestModel) {
|
||||||
|
String result = "";
|
||||||
|
result = result + headerSnippet;
|
||||||
|
if (requestModel.method != HTTPVerb.get &&
|
||||||
|
requestModel.method != HTTPVerb.head) {
|
||||||
|
result =
|
||||||
|
"""${result}val mediaType = "${requestModel.requestBodyContentType == ContentType.json ? "application/json" : "text/plain"}".toMediaType()
|
||||||
|
val body = "${requestModel.requestBody}".toRequestBody(mediaType)\n""";
|
||||||
|
}
|
||||||
|
result = "${result}val request = Request.Builder()\n";
|
||||||
|
|
||||||
|
result = "$result .url(\"${requestModel.url}\")\n";
|
||||||
|
result = result + addQueryParams(requestModel);
|
||||||
|
result = result + addRequestMethod(requestModel);
|
||||||
|
result = result + addHeaders(requestModel);
|
||||||
|
result = result + footerSnippet;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String addQueryParams(RequestModel requestModel) {
|
||||||
|
String result = "";
|
||||||
|
if (requestModel.requestParams == null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
for (final queryParam in requestModel.requestParams!) {
|
||||||
|
result =
|
||||||
|
"""$result .addQueryParameter("${queryParam.k}", "${queryParam.v}")\n""";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String addHeaders(RequestModel requestModel) {
|
||||||
|
String result = "";
|
||||||
|
if (requestModel.requestHeaders == null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
for (final header in requestModel.requestHeaders!) {
|
||||||
|
result = """$result .addHeader("${header.k}", "${header.v}")\n""";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String addRequestMethod(RequestModel requestModel) {
|
||||||
|
String result = "";
|
||||||
|
if (requestModel.method != HTTPVerb.get &&
|
||||||
|
requestModel.method != HTTPVerb.head &&
|
||||||
|
requestModel.method != HTTPVerb.delete) {
|
||||||
|
result = """$result .${requestModel.method.name}(body)\n""";
|
||||||
|
} else if (requestModel.method == HTTPVerb.head) {
|
||||||
|
result = """$result .${requestModel.method.name}()\n""";
|
||||||
|
}
|
||||||
|
if (requestModel.method == HTTPVerb.delete) {
|
||||||
|
result = """$result .method("DELETE", body)\n""";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -228,6 +228,14 @@ const kMethodsWithBody = [
|
|||||||
const kDefaultHttpMethod = HTTPVerb.get;
|
const kDefaultHttpMethod = HTTPVerb.get;
|
||||||
const kDefaultContentType = ContentType.json;
|
const kDefaultContentType = ContentType.json;
|
||||||
|
|
||||||
|
enum CodegenLanguage {
|
||||||
|
dartHttp("Dart (http)"),
|
||||||
|
kotlinOkHttp("Kotlin (OkHttp)");
|
||||||
|
|
||||||
|
const CodegenLanguage(this.label);
|
||||||
|
final String label;
|
||||||
|
}
|
||||||
|
|
||||||
const JsonEncoder kEncoder = JsonEncoder.withIndent(' ');
|
const JsonEncoder kEncoder = JsonEncoder.withIndent(' ');
|
||||||
const LineSplitter kSplitter = LineSplitter();
|
const LineSplitter kSplitter = LineSplitter();
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:apidash/consts.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
final navRailIndexStateProvider = StateProvider<int?>((ref) => 0);
|
final navRailIndexStateProvider = StateProvider<int?>((ref) => 0);
|
||||||
@ -7,3 +8,4 @@ final sentRequestIdStateProvider = StateProvider<String?>((ref) => null);
|
|||||||
final codePaneVisibleStateProvider = StateProvider<bool>((ref) => false);
|
final codePaneVisibleStateProvider = StateProvider<bool>((ref) => false);
|
||||||
final saveDataStateProvider = StateProvider<bool>((ref) => false);
|
final saveDataStateProvider = StateProvider<bool>((ref) => false);
|
||||||
final clearDataStateProvider = StateProvider<bool>((ref) => false);
|
final clearDataStateProvider = StateProvider<bool>((ref) => false);
|
||||||
|
final codegenLanguageStateProvider = StateProvider<CodegenLanguage>((ref) => CodegenLanguage.dartHttp);
|
@ -13,7 +13,7 @@ class CodePane extends ConsumerStatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _CodePaneState extends ConsumerState<CodePane> {
|
class _CodePaneState extends ConsumerState<CodePane> {
|
||||||
final DartHttpCodeGen dartHttpCodeGen = DartHttpCodeGen();
|
final Codegen codegen = Codegen();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -22,10 +22,15 @@ class _CodePaneState extends ConsumerState<CodePane> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final CodegenLanguage codegenLanguage =
|
||||||
|
ref.watch(codegenLanguageStateProvider);
|
||||||
|
|
||||||
final activeRequestModel = ref.watch(activeRequestModelProvider);
|
final activeRequestModel = ref.watch(activeRequestModelProvider);
|
||||||
final defaultUriScheme =
|
final defaultUriScheme =
|
||||||
ref.watch(settingsProvider.select((value) => value.defaultUriScheme));
|
ref.watch(settingsProvider.select((value) => value.defaultUriScheme));
|
||||||
final code = dartHttpCodeGen.getCode(activeRequestModel!, defaultUriScheme);
|
|
||||||
|
final code =
|
||||||
|
codegen.getCode(codegenLanguage, activeRequestModel!, defaultUriScheme);
|
||||||
if (code == null) {
|
if (code == null) {
|
||||||
return const ErrorMessage(
|
return const ErrorMessage(
|
||||||
message: "An error was encountered while generating code. $kRaiseIssue",
|
message: "An error was encountered while generating code. $kRaiseIssue",
|
||||||
@ -33,6 +38,12 @@ class _CodePaneState extends ConsumerState<CodePane> {
|
|||||||
}
|
}
|
||||||
return ViewCodePane(
|
return ViewCodePane(
|
||||||
code: code,
|
code: code,
|
||||||
|
codegenLanguage: codegenLanguage,
|
||||||
|
onChangedCodegenLanguage: (CodegenLanguage? value) {
|
||||||
|
ref
|
||||||
|
.read(codegenLanguageStateProvider.notifier)
|
||||||
|
.update((state) => value!);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,9 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:highlighter/highlighter.dart' show highlight;
|
import 'package:highlighter/highlighter.dart' show highlight;
|
||||||
import 'package:apidash/consts.dart';
|
import 'package:apidash/consts.dart';
|
||||||
import 'package:apidash/utils/utils.dart';
|
import 'package:apidash/utils/utils.dart';
|
||||||
import 'code_previewer.dart' show convert;
|
import 'code_previewer.dart';
|
||||||
import 'buttons.dart';
|
import 'widgets.dart'
|
||||||
|
show CopyButton, DropdownButtonCodegenLanguage, SaveInDownloadsButton;
|
||||||
|
|
||||||
class CodeGenPreviewer extends StatefulWidget {
|
class CodeGenPreviewer extends StatefulWidget {
|
||||||
const CodeGenPreviewer({
|
const CodeGenPreviewer({
|
||||||
@ -105,9 +106,13 @@ class ViewCodePane extends StatefulWidget {
|
|||||||
const ViewCodePane({
|
const ViewCodePane({
|
||||||
super.key,
|
super.key,
|
||||||
required this.code,
|
required this.code,
|
||||||
|
required this.codegenLanguage,
|
||||||
|
required this.onChangedCodegenLanguage,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String code;
|
final String code;
|
||||||
|
final CodegenLanguage codegenLanguage;
|
||||||
|
final Function(CodegenLanguage?) onChangedCodegenLanguage;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<ViewCodePane> createState() => _ViewCodePaneState();
|
State<ViewCodePane> createState() => _ViewCodePaneState();
|
||||||
@ -144,6 +149,10 @@ class _ViewCodePaneState extends State<ViewCodePane> {
|
|||||||
style: Theme.of(context).textTheme.titleMedium,
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
DropdownButtonCodegenLanguage(
|
||||||
|
codegenLanguage: widget.codegenLanguage,
|
||||||
|
onChanged: widget.onChangedCodegenLanguage,
|
||||||
|
),
|
||||||
CopyButton(toCopy: widget.code),
|
CopyButton(toCopy: widget.code),
|
||||||
SaveInDownloadsButton(
|
SaveInDownloadsButton(
|
||||||
content: stringToBytes(widget.code),
|
content: stringToBytes(widget.code),
|
||||||
|
@ -109,3 +109,55 @@ class _DropdownButtonContentTypeState extends State<DropdownButtonContentType> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DropdownButtonCodegenLanguage extends StatefulWidget {
|
||||||
|
const DropdownButtonCodegenLanguage({
|
||||||
|
Key? key,
|
||||||
|
this.codegenLanguage,
|
||||||
|
this.onChanged,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<DropdownButtonCodegenLanguage> createState() =>
|
||||||
|
_DropdownButtonCodegenLanguageState();
|
||||||
|
final CodegenLanguage? codegenLanguage;
|
||||||
|
final void Function(CodegenLanguage?)? onChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DropdownButtonCodegenLanguageState
|
||||||
|
extends State<DropdownButtonCodegenLanguage> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final surfaceColor = Theme.of(context).colorScheme.surface;
|
||||||
|
return DropdownButton<CodegenLanguage>(
|
||||||
|
focusColor: surfaceColor,
|
||||||
|
value: widget.codegenLanguage,
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.unfold_more_rounded,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
elevation: 4,
|
||||||
|
style: kCodeStyle.copyWith(
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
underline: Container(
|
||||||
|
height: 0,
|
||||||
|
),
|
||||||
|
onChanged: widget.onChanged,
|
||||||
|
borderRadius: kBorderRadius12,
|
||||||
|
items: CodegenLanguage.values
|
||||||
|
.map<DropdownMenuItem<CodegenLanguage>>((CodegenLanguage value) {
|
||||||
|
return DropdownMenuItem<CodegenLanguage>(
|
||||||
|
value: value,
|
||||||
|
child: Padding(
|
||||||
|
padding: kPs8,
|
||||||
|
child: Text(
|
||||||
|
value.label,
|
||||||
|
style: kTextStyleButton,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
163
test/codegen/kotlin_okhttp_codegen_test.dart
Normal file
163
test/codegen/kotlin_okhttp_codegen_test.dart
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
import 'package:apidash/codegen/kotlin/pkg_okhttp.dart';
|
||||||
|
import 'package:apidash/models/models.dart' show KVRow, RequestModel;
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
import 'package:apidash/consts.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('KotlinOkHttpCodeGen', () {
|
||||||
|
final kotlinOkHttpCodeGen = KotlinOkHttpCodeGen();
|
||||||
|
|
||||||
|
test('getCode returns valid code for GET request', () {
|
||||||
|
const requestModel = RequestModel(
|
||||||
|
url: 'https://jsonplaceholder.typicode.com/todos/1',
|
||||||
|
method: HTTPVerb.get,
|
||||||
|
id: '',
|
||||||
|
);
|
||||||
|
const expectedCode = """import okhttp3.MediaType.Companion.toMediaType
|
||||||
|
import okhttp3.MultipartBody
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
|
import okhttp3.RequestBody.Companion.asRequestBody
|
||||||
|
import java.io.File
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
val client = OkHttpClient()
|
||||||
|
val request = Request.Builder()
|
||||||
|
.url("https://jsonplaceholder.typicode.com/todos/1")
|
||||||
|
.build()
|
||||||
|
val response = client.newCall(request).execute()
|
||||||
|
|
||||||
|
println(response.body!!.string())
|
||||||
|
""";
|
||||||
|
expect(kotlinOkHttpCodeGen.getCode(requestModel), expectedCode);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getCode returns valid code for POST request', () {
|
||||||
|
const requestModel = RequestModel(
|
||||||
|
url: 'https://jsonplaceholder.typicode.com/posts',
|
||||||
|
method: HTTPVerb.post,
|
||||||
|
requestBody: '{"title": "foo","body": "bar","userId": 1}',
|
||||||
|
requestBodyContentType: ContentType.json,
|
||||||
|
id: '1',
|
||||||
|
);
|
||||||
|
const expectedCode = """import okhttp3.MediaType.Companion.toMediaType
|
||||||
|
import okhttp3.MultipartBody
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
|
import okhttp3.RequestBody.Companion.asRequestBody
|
||||||
|
import java.io.File
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
val client = OkHttpClient()
|
||||||
|
val mediaType = "application/json".toMediaType()
|
||||||
|
val body = "{\"title\": \"foo\",\"body\": \"bar\",\"userId\": 1}".toRequestBody(mediaType)
|
||||||
|
val request = Request.Builder()
|
||||||
|
.url("https://jsonplaceholder.typicode.com/posts")
|
||||||
|
.post(body)
|
||||||
|
.build()
|
||||||
|
val response = client.newCall(request).execute()
|
||||||
|
|
||||||
|
println(response.body!!.string())
|
||||||
|
""";
|
||||||
|
expect(kotlinOkHttpCodeGen.getCode(requestModel), expectedCode);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getCode returns valid code for DELETE request', () {
|
||||||
|
const requestModel = RequestModel(
|
||||||
|
url: 'https://jsonplaceholder.typicode.com/posts/1',
|
||||||
|
method: HTTPVerb.delete,
|
||||||
|
requestBody: '{"title": "foo","body": "bar","userId": 1}',
|
||||||
|
requestBodyContentType: ContentType.json,
|
||||||
|
id: '1',
|
||||||
|
);
|
||||||
|
const expectedCode = """import okhttp3.MediaType.Companion.toMediaType
|
||||||
|
import okhttp3.MultipartBody
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
|
import okhttp3.RequestBody.Companion.asRequestBody
|
||||||
|
import java.io.File
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
val client = OkHttpClient()
|
||||||
|
val mediaType = "application/json".toMediaType()
|
||||||
|
val body = "{\"title\": \"foo\",\"body\": \"bar\",\"userId\": 1}".toRequestBody(mediaType)
|
||||||
|
val request = Request.Builder()
|
||||||
|
.url("https://jsonplaceholder.typicode.com/posts/1")
|
||||||
|
.method("DELETE", body)
|
||||||
|
.build()
|
||||||
|
val response = client.newCall(request).execute()
|
||||||
|
|
||||||
|
println(response.body!!.string())
|
||||||
|
""";
|
||||||
|
expect(kotlinOkHttpCodeGen.getCode(requestModel), expectedCode);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getCode returns valid code for HEAD request', () {
|
||||||
|
const requestModel = RequestModel(
|
||||||
|
url: 'https://jsonplaceholder.typicode.com/posts/1',
|
||||||
|
method: HTTPVerb.head,
|
||||||
|
id: '1',
|
||||||
|
);
|
||||||
|
const expectedCode = """import okhttp3.MediaType.Companion.toMediaType
|
||||||
|
import okhttp3.MultipartBody
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
|
import okhttp3.RequestBody.Companion.asRequestBody
|
||||||
|
import java.io.File
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
val client = OkHttpClient()
|
||||||
|
val request = Request.Builder()
|
||||||
|
.url("https://jsonplaceholder.typicode.com/posts/1")
|
||||||
|
.head()
|
||||||
|
.build()
|
||||||
|
val response = client.newCall(request).execute()
|
||||||
|
|
||||||
|
println(response.body!!.string())
|
||||||
|
""";
|
||||||
|
expect(kotlinOkHttpCodeGen.getCode(requestModel), expectedCode);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'getCode returns valid code for requests with headers and query parameters',
|
||||||
|
() {
|
||||||
|
const requestModel = RequestModel(
|
||||||
|
url: 'https://jsonplaceholder.typicode.com/posts',
|
||||||
|
method: HTTPVerb.get,
|
||||||
|
requestParams: [
|
||||||
|
KVRow('userId', 1),
|
||||||
|
],
|
||||||
|
requestHeaders: [
|
||||||
|
KVRow('Custom-Header-1', 'Value-1'),
|
||||||
|
KVRow('Custom-Header-2', 'Value-2')
|
||||||
|
],
|
||||||
|
id: '1',
|
||||||
|
);
|
||||||
|
const expectedCode = """import okhttp3.MediaType.Companion.toMediaType
|
||||||
|
import okhttp3.MultipartBody
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
|
import okhttp3.RequestBody.Companion.asRequestBody
|
||||||
|
import java.io.File
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
val client = OkHttpClient()
|
||||||
|
val request = Request.Builder()
|
||||||
|
.url("https://jsonplaceholder.typicode.com/posts")
|
||||||
|
.addQueryParameter("userId", "1")
|
||||||
|
.addHeader("Custom-Header-1", "Value-1")
|
||||||
|
.addHeader("Custom-Header-2", "Value-2")
|
||||||
|
.build()
|
||||||
|
val response = client.newCall(request).execute()
|
||||||
|
|
||||||
|
println(response.body!!.string())
|
||||||
|
""";
|
||||||
|
expect(kotlinOkHttpCodeGen.getCode(requestModel), expectedCode);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
|
import 'package:apidash/widgets/widgets.dart'
|
||||||
|
show ViewCodePane, CodeGenPreviewer;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:apidash/widgets/codegen_previewer.dart';
|
|
||||||
import 'package:apidash/consts.dart';
|
import 'package:apidash/consts.dart';
|
||||||
import '../test_consts.dart';
|
import '../test_consts.dart';
|
||||||
|
|
||||||
@ -58,6 +59,8 @@ void main() async {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: ViewCodePane(
|
child: ViewCodePane(
|
||||||
code: code,
|
code: code,
|
||||||
|
codegenLanguage: CodegenLanguage.dartHttp,
|
||||||
|
onChangedCodegenLanguage: (p0) {},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -84,6 +87,8 @@ void main() async {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: ViewCodePane(
|
child: ViewCodePane(
|
||||||
code: code,
|
code: code,
|
||||||
|
codegenLanguage: CodegenLanguage.dartHttp,
|
||||||
|
onChangedCodegenLanguage: (p0) {},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
Reference in New Issue
Block a user