mirror of
https://github.com/foss42/apidash.git
synced 2025-06-20 05:51:58 +08:00
State Management + UI Updates
This commit is contained in:
@ -1,17 +1,19 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import '../models/models.dart';
|
||||||
|
import '../providers/providers.dart';
|
||||||
|
import '../consts.dart';
|
||||||
|
|
||||||
class CollectionPane extends StatefulWidget {
|
class CollectionPane extends ConsumerStatefulWidget {
|
||||||
const CollectionPane({
|
const CollectionPane({
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<CollectionPane> createState() => _CollectionPaneState();
|
ConsumerState<CollectionPane> createState() => _CollectionPaneState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _CollectionPaneState extends State<CollectionPane> {
|
class _CollectionPaneState extends ConsumerState<CollectionPane> {
|
||||||
int len = 0;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@ -29,9 +31,11 @@ class _CollectionPaneState extends State<CollectionPane> {
|
|||||||
children: [
|
children: [
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
String newId =
|
||||||
len += 1;
|
ref.read(collectionStateNotifierProvider.notifier).add();
|
||||||
});
|
ref
|
||||||
|
.read(activeItemIdStateProvider.notifier)
|
||||||
|
.update((state) => newId);
|
||||||
},
|
},
|
||||||
child: const Text('+ New'),
|
child: const Text('+ New'),
|
||||||
),
|
),
|
||||||
@ -40,9 +44,9 @@ class _CollectionPaneState extends State<CollectionPane> {
|
|||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 8,
|
height: 8,
|
||||||
),
|
),
|
||||||
Expanded(
|
const Expanded(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: RequestList(l: len),
|
child: RequestList(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -51,21 +55,16 @@ class _CollectionPaneState extends State<CollectionPane> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RequestList extends StatefulWidget {
|
class RequestList extends ConsumerStatefulWidget {
|
||||||
const RequestList({
|
const RequestList({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.l,
|
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final int l;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<RequestList> createState() => _RequestListState();
|
ConsumerState<RequestList> createState() => _RequestListState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _RequestListState extends State<RequestList> {
|
class _RequestListState extends ConsumerState<RequestList> {
|
||||||
List<String> requestItems = [];
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@ -73,9 +72,7 @@ class _RequestListState extends State<RequestList> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (requestItems.length != widget.l) {
|
final requestItems = ref.watch(collectionStateNotifierProvider);
|
||||||
requestItems = List.generate(widget.l, (index) => "request${index + 1}");
|
|
||||||
}
|
|
||||||
return ReorderableListView.builder(
|
return ReorderableListView.builder(
|
||||||
buildDefaultDragHandles: false,
|
buildDefaultDragHandles: false,
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
@ -85,19 +82,17 @@ class _RequestListState extends State<RequestList> {
|
|||||||
newIndex -= 1;
|
newIndex -= 1;
|
||||||
}
|
}
|
||||||
if (oldIndex != newIndex) {
|
if (oldIndex != newIndex) {
|
||||||
var t = requestItems[oldIndex];
|
ref
|
||||||
requestItems[oldIndex] = requestItems[newIndex];
|
.read(collectionStateNotifierProvider.notifier)
|
||||||
requestItems[newIndex] = t;
|
.reorder(oldIndex, newIndex);
|
||||||
setState(() {
|
|
||||||
requestItems = [...requestItems];
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
return ReorderableDragStartListener(
|
return ReorderableDragStartListener(
|
||||||
key: Key(requestItems[index]),
|
key: Key(requestItems[index].id),
|
||||||
index: index,
|
index: index,
|
||||||
child: RequestItem(id: requestItems[index]),
|
child: RequestItem(
|
||||||
|
id: requestItems[index].id, requestModel: requestItems[index]),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -106,19 +101,21 @@ class _RequestListState extends State<RequestList> {
|
|||||||
|
|
||||||
enum RequestItemMenuOption { delete, duplicate }
|
enum RequestItemMenuOption { delete, duplicate }
|
||||||
|
|
||||||
class RequestItem extends StatefulWidget {
|
class RequestItem extends ConsumerStatefulWidget {
|
||||||
const RequestItem({
|
const RequestItem({
|
||||||
required this.id,
|
required this.id,
|
||||||
|
required this.requestModel,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final String id;
|
final String id;
|
||||||
|
final RequestModel requestModel;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<RequestItem> createState() => _RequestItemState();
|
ConsumerState<RequestItem> createState() => _RequestItemState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _RequestItemState extends State<RequestItem> {
|
class _RequestItemState extends ConsumerState<RequestItem> {
|
||||||
late Color _color;
|
late Color _color;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -129,17 +126,23 @@ class _RequestItemState extends State<RequestItem> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final activeRequest = ref.watch(activeItemIdStateProvider);
|
||||||
|
bool isActiveId = activeRequest == widget.id;
|
||||||
return Material(
|
return Material(
|
||||||
borderRadius: BorderRadius.circular(10.0),
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
elevation: 1,
|
elevation: isActiveId ? 2 : 0,
|
||||||
color: Colors.grey.shade50,
|
color: isActiveId ? Colors.grey.shade300 : _color,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
borderRadius: BorderRadius.circular(10.0),
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
onTap: () {},
|
onTap: () {
|
||||||
|
ref
|
||||||
|
.read(activeItemIdStateProvider.notifier)
|
||||||
|
.update((state) => widget.id);
|
||||||
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
left: 10,
|
left: 10,
|
||||||
right: 0,
|
right: isActiveId ? 0 : 20,
|
||||||
top: 5,
|
top: 5,
|
||||||
bottom: 5,
|
bottom: 5,
|
||||||
),
|
),
|
||||||
@ -147,19 +150,38 @@ class _RequestItemState extends State<RequestItem> {
|
|||||||
height: 22,
|
height: 22,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
MethodBox(),
|
MethodBox(method: widget.requestModel.method),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 5,
|
width: 5,
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
widget.id,
|
widget.requestModel.id,
|
||||||
|
softWrap: false,
|
||||||
|
overflow: TextOverflow.fade,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
PopupMenuButton<RequestItemMenuOption>(
|
Visibility(
|
||||||
|
visible: isActiveId,
|
||||||
|
child: PopupMenuButton<RequestItemMenuOption>(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
splashRadius: 14,
|
splashRadius: 14,
|
||||||
iconSize: 14,
|
iconSize: 14,
|
||||||
|
onSelected: (RequestItemMenuOption item) {
|
||||||
|
if (item == RequestItemMenuOption.delete) {
|
||||||
|
ref
|
||||||
|
.read(activeItemIdStateProvider.notifier)
|
||||||
|
.update((state) => null);
|
||||||
|
ref
|
||||||
|
.read(collectionStateNotifierProvider.notifier)
|
||||||
|
.remove(widget.id);
|
||||||
|
}
|
||||||
|
if (item == RequestItemMenuOption.duplicate) {
|
||||||
|
ref
|
||||||
|
.read(collectionStateNotifierProvider.notifier)
|
||||||
|
.duplicate(widget.id);
|
||||||
|
}
|
||||||
|
},
|
||||||
itemBuilder: (BuildContext context) =>
|
itemBuilder: (BuildContext context) =>
|
||||||
<PopupMenuEntry<RequestItemMenuOption>>[
|
<PopupMenuEntry<RequestItemMenuOption>>[
|
||||||
const PopupMenuItem<RequestItemMenuOption>(
|
const PopupMenuItem<RequestItemMenuOption>(
|
||||||
@ -172,6 +194,7 @@ class _RequestItemState extends State<RequestItem> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -182,11 +205,15 @@ class _RequestItemState extends State<RequestItem> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MethodBox extends StatelessWidget {
|
class MethodBox extends StatelessWidget {
|
||||||
const MethodBox({super.key});
|
const MethodBox({super.key, required this.method});
|
||||||
|
final HTTPVerb method;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
String text = "get".toUpperCase();
|
String text = method.name.toUpperCase();
|
||||||
|
if (method == HTTPVerb.delete) {
|
||||||
|
text = "DEL";
|
||||||
|
}
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: 25,
|
width: 25,
|
||||||
child: Text(
|
child: Text(
|
||||||
|
@ -1 +1,2 @@
|
|||||||
|
export 'editor_pane.dart';
|
||||||
export 'collection_pane.dart';
|
export 'collection_pane.dart';
|
||||||
|
36
lib/components/editor_pane.dart
Normal file
36
lib/components/editor_pane.dart
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import '../providers/providers.dart';
|
||||||
|
|
||||||
|
class RequestEditorPane extends ConsumerStatefulWidget {
|
||||||
|
const RequestEditorPane({
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
ConsumerState<RequestEditorPane> createState() => _RequestEditorPaneState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _RequestEditorPaneState extends ConsumerState<RequestEditorPane> {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final activeId = ref.watch(activeItemIdStateProvider);
|
||||||
|
if (activeId == null) {
|
||||||
|
return Text("Select One");
|
||||||
|
} else {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Container(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
lib/consts.dart
Normal file
3
lib/consts.dart
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
enum HTTPVerb { get, head, post, put, patch, delete }
|
||||||
|
|
||||||
|
const DEFAULT_METHOD = HTTPVerb.get;
|
@ -1,14 +1,20 @@
|
|||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:desktop_window/desktop_window.dart';
|
import 'package:desktop_window/desktop_window.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'screens/screens.dart';
|
import 'screens/screens.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
Size size = await DesktopWindow.getWindowSize();
|
if (!kIsWeb) {
|
||||||
print(size);
|
|
||||||
await DesktopWindow.setWindowSize(Size(1400, 800));
|
await DesktopWindow.setWindowSize(Size(1400, 800));
|
||||||
await DesktopWindow.setMinWindowSize(Size(1200, 800));
|
await DesktopWindow.setMinWindowSize(Size(1200, 800));
|
||||||
runApp(App());
|
}
|
||||||
|
runApp(
|
||||||
|
const ProviderScope(
|
||||||
|
child: App(),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class App extends StatelessWidget {
|
class App extends StatelessWidget {
|
||||||
|
46
lib/models/models.dart
Normal file
46
lib/models/models.dart
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import '../consts.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
class RequestModel {
|
||||||
|
const RequestModel({
|
||||||
|
required this.id,
|
||||||
|
this.method = DEFAULT_METHOD,
|
||||||
|
this.url = "",
|
||||||
|
});
|
||||||
|
|
||||||
|
final String id;
|
||||||
|
final HTTPVerb method;
|
||||||
|
final String url;
|
||||||
|
|
||||||
|
RequestModel duplicate({
|
||||||
|
required String id,
|
||||||
|
}) {
|
||||||
|
return RequestModel(
|
||||||
|
id: id,
|
||||||
|
method: method,
|
||||||
|
url: url,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
RequestModel copyWith({
|
||||||
|
String? id,
|
||||||
|
HTTPVerb? method,
|
||||||
|
String? url,
|
||||||
|
}) {
|
||||||
|
return RequestModel(
|
||||||
|
id: id ?? this.id,
|
||||||
|
method: method ?? this.method,
|
||||||
|
url: url ?? this.url,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return [
|
||||||
|
id,
|
||||||
|
method.name,
|
||||||
|
"URL: $url",
|
||||||
|
].join("\n");
|
||||||
|
}
|
||||||
|
}
|
74
lib/providers/providers.dart
Normal file
74
lib/providers/providers.dart
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:uuid/uuid.dart';
|
||||||
|
import '../models/models.dart';
|
||||||
|
import '../consts.dart';
|
||||||
|
|
||||||
|
const _uuid = Uuid();
|
||||||
|
|
||||||
|
final activeItemIdStateProvider = StateProvider<String?>((ref) => null);
|
||||||
|
|
||||||
|
final StateNotifierProvider<CollectionStateNotifier, List<RequestModel>>
|
||||||
|
collectionStateNotifierProvider =
|
||||||
|
StateNotifierProvider((ref) => CollectionStateNotifier());
|
||||||
|
|
||||||
|
class CollectionStateNotifier extends StateNotifier<List<RequestModel>> {
|
||||||
|
CollectionStateNotifier()
|
||||||
|
: super([
|
||||||
|
RequestModel(
|
||||||
|
id: _uuid.v1(),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
|
int idxOfId(String id) => state.indexWhere((element) => element.id == id);
|
||||||
|
|
||||||
|
RequestModel getRequestModel(String id) {
|
||||||
|
final idx = idxOfId(id);
|
||||||
|
return state[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
String add() {
|
||||||
|
final newRequestModel = RequestModel(
|
||||||
|
id: _uuid.v1(),
|
||||||
|
);
|
||||||
|
state = [newRequestModel, ...state];
|
||||||
|
return newRequestModel.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reorder(int oldIdx, int newIdx) {
|
||||||
|
final item = state.removeAt(oldIdx);
|
||||||
|
state.insert(newIdx, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove(String id) {
|
||||||
|
state = [
|
||||||
|
for (final model in state)
|
||||||
|
if (model.id != id) model,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
void duplicate(String id) {
|
||||||
|
final idx = idxOfId(id);
|
||||||
|
final newModel = state[idx].duplicate(
|
||||||
|
id: _uuid.v1(),
|
||||||
|
);
|
||||||
|
state = [...state.sublist(0, idx + 1), newModel, ...state.sublist(idx + 1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(
|
||||||
|
String id, {
|
||||||
|
HTTPVerb? method,
|
||||||
|
String? url,
|
||||||
|
int? requestTabIndex,
|
||||||
|
dynamic requestBody,
|
||||||
|
int? responseStatus,
|
||||||
|
Map<String, String>? responseHeaders,
|
||||||
|
String? responseBody,
|
||||||
|
}) {
|
||||||
|
final idx = idxOfId(id);
|
||||||
|
final newModel = state[idx].copyWith(
|
||||||
|
method: method,
|
||||||
|
url: url,
|
||||||
|
);
|
||||||
|
state = [...state.sublist(0, idx), newModel, ...state.sublist(idx + 1)];
|
||||||
|
}
|
||||||
|
}
|
59
lib/screens/home_page.dart
Normal file
59
lib/screens/home_page.dart
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:multi_split_view/multi_split_view.dart';
|
||||||
|
import '../components/components.dart';
|
||||||
|
|
||||||
|
class HomePage extends StatefulWidget {
|
||||||
|
const HomePage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
HomePageState createState() => HomePageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class HomePageState extends State<HomePage> {
|
||||||
|
final MultiSplitViewController _controller = MultiSplitViewController(
|
||||||
|
areas: [
|
||||||
|
Area(size: 300, minimalSize: 200),
|
||||||
|
Area(minimalWeight: 0.7),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: MultiSplitViewTheme(
|
||||||
|
data: MultiSplitViewThemeData(
|
||||||
|
dividerThickness: 4,
|
||||||
|
dividerPainter: DividerPainters.background(
|
||||||
|
color: Colors.grey.shade200,
|
||||||
|
highlightedColor: Colors.grey.shade400,
|
||||||
|
animationEnabled: false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: MultiSplitView(
|
||||||
|
controller: _controller,
|
||||||
|
children: const [
|
||||||
|
CollectionPane(),
|
||||||
|
RequestEditorPane(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_controller.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
}
|
@ -1,60 +1 @@
|
|||||||
import 'package:flutter/material.dart';
|
export "home_page.dart";
|
||||||
import 'package:multi_split_view/multi_split_view.dart';
|
|
||||||
import '../components/components.dart';
|
|
||||||
|
|
||||||
class HomePage extends StatefulWidget {
|
|
||||||
const HomePage({Key? key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
HomePageState createState() => HomePageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class HomePageState extends State<HomePage> {
|
|
||||||
final MultiSplitViewController _controller = MultiSplitViewController(
|
|
||||||
areas: [
|
|
||||||
Area(size: 300, minimalSize: 200),
|
|
||||||
Area(minimalWeight: 0.7),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
// appBar: AppBar(title: const Text('Multi Split View Example')),
|
|
||||||
body: Column(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: MultiSplitViewTheme(
|
|
||||||
data: MultiSplitViewThemeData(
|
|
||||||
dividerThickness: 4,
|
|
||||||
dividerPainter: DividerPainters.background(
|
|
||||||
color: Colors.grey.shade200,
|
|
||||||
highlightedColor: Colors.grey.shade400,
|
|
||||||
animationEnabled: false,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: MultiSplitView(
|
|
||||||
controller: _controller,
|
|
||||||
children: [
|
|
||||||
CollectionPane(),
|
|
||||||
Container(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_controller.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
50
pubspec.lock
50
pubspec.lock
@ -41,6 +41,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.17.0"
|
version: "1.17.0"
|
||||||
|
crypto:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: crypto
|
||||||
|
sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.2"
|
||||||
desktop_window:
|
desktop_window:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -70,6 +78,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
|
flutter_riverpod:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_riverpod
|
||||||
|
sha256: "40c0d7d03ccd24fa32ea08dcfc4df9bb92c4c26c9a91938945da3be10ed8ca83"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.0"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -131,6 +147,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.2"
|
version: "1.8.2"
|
||||||
|
riverpod:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: riverpod
|
||||||
|
sha256: c5aea6c3fed340707f013a023a37ab388bf45611a8a4f7e76b5e9007eb76cd25
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.0"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -152,6 +176,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.11.0"
|
version: "1.11.0"
|
||||||
|
state_notifier:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: state_notifier
|
||||||
|
sha256: "8fe42610f179b843b12371e40db58c9444f8757f8b69d181c97e50787caed289"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.2+1"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -184,6 +216,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.16"
|
version: "0.4.16"
|
||||||
|
typed_data:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: typed_data
|
||||||
|
sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.1"
|
||||||
|
uuid:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: uuid
|
||||||
|
sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.7"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -194,4 +242,4 @@ packages:
|
|||||||
version: "2.1.4"
|
version: "2.1.4"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.19.2 <3.0.0"
|
dart: ">=2.19.2 <3.0.0"
|
||||||
flutter: ">=1.20.0"
|
flutter: ">=3.0.0"
|
||||||
|
@ -11,6 +11,8 @@ dependencies:
|
|||||||
sdk: flutter
|
sdk: flutter
|
||||||
multi_split_view: ^2.4.0
|
multi_split_view: ^2.4.0
|
||||||
desktop_window: ^0.4.0
|
desktop_window: ^0.4.0
|
||||||
|
flutter_riverpod: ^2.1.3
|
||||||
|
uuid: ^3.0.7
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Reference in New Issue
Block a user