add providers per page
show only 10 packages new page for all packages
This commit is contained in:
		@@ -2,8 +2,9 @@ import '../models/package.dart';
 | 
				
			|||||||
import 'api_client.dart';
 | 
					import 'api_client.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extension PackagesAPI on ApiClient {
 | 
					extension PackagesAPI on ApiClient {
 | 
				
			||||||
  Future<List<Package>> listPackages() async {
 | 
					  Future<List<Package>> listPackages({int? limit}) async {
 | 
				
			||||||
    final resp = await getRawClient().get("/packages/list");
 | 
					    final resp = await getRawClient()
 | 
				
			||||||
 | 
					        .get("/packages/list", queryParameters: {'limit': limit});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final responseObject = resp.data as List;
 | 
					    final responseObject = resp.data as List;
 | 
				
			||||||
    final List<Package> packages =
 | 
					    final List<Package> packages =
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,6 @@ import 'dart:async';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:provider/provider.dart';
 | 
					import 'package:provider/provider.dart';
 | 
				
			||||||
import 'package:visibility_detector/visibility_detector.dart';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import '../../providers/BaseProvider.dart';
 | 
					import '../../providers/BaseProvider.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -26,7 +25,6 @@ class APIBuilder<T extends BaseProvider, K, DTO> extends StatefulWidget {
 | 
				
			|||||||
class _APIBuilderState<T extends BaseProvider, K, DTO>
 | 
					class _APIBuilderState<T extends BaseProvider, K, DTO>
 | 
				
			||||||
    extends State<APIBuilder<T, K, DTO>> {
 | 
					    extends State<APIBuilder<T, K, DTO>> {
 | 
				
			||||||
  Timer? timer;
 | 
					  Timer? timer;
 | 
				
			||||||
  bool visible = true;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  void initState() {
 | 
					  void initState() {
 | 
				
			||||||
@@ -35,10 +33,8 @@ class _APIBuilderState<T extends BaseProvider, K, DTO>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (widget.interval != null) {
 | 
					    if (widget.interval != null) {
 | 
				
			||||||
      timer = Timer.periodic(widget.interval!, (Timer t) {
 | 
					      timer = Timer.periodic(widget.interval!, (Timer t) {
 | 
				
			||||||
        if (visible) {
 | 
					 | 
				
			||||||
        Provider.of<T>(context, listen: false)
 | 
					        Provider.of<T>(context, listen: false)
 | 
				
			||||||
            .refresh(context, dto: widget.dto);
 | 
					            .refresh(context, dto: widget.dto);
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -53,21 +49,7 @@ class _APIBuilderState<T extends BaseProvider, K, DTO>
 | 
				
			|||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    final Future<K> fut = Provider.of<T>(context).data as Future<K>;
 | 
					    final Future<K> fut = Provider.of<T>(context).data as Future<K>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return VisibilityDetector(
 | 
					    return FutureBuilder<K>(
 | 
				
			||||||
      key: widget.key ?? const Key("APIBuilder"),
 | 
					 | 
				
			||||||
      onVisibilityChanged: (visibilityInfo) {
 | 
					 | 
				
			||||||
        var visiblePercentage = visibilityInfo.visibleFraction * 100;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (mounted) {
 | 
					 | 
				
			||||||
          setState(() {
 | 
					 | 
				
			||||||
            visible = visiblePercentage != 0;
 | 
					 | 
				
			||||||
          });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        debugPrint(
 | 
					 | 
				
			||||||
            'Widget ${visibilityInfo.key} is ${visiblePercentage}% visible');
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      child: FutureBuilder<K>(
 | 
					 | 
				
			||||||
      future: fut,
 | 
					      future: fut,
 | 
				
			||||||
      builder: (context, snapshot) {
 | 
					      builder: (context, snapshot) {
 | 
				
			||||||
        if (snapshot.hasData) {
 | 
					        if (snapshot.hasData) {
 | 
				
			||||||
@@ -76,7 +58,6 @@ class _APIBuilderState<T extends BaseProvider, K, DTO>
 | 
				
			|||||||
          return widget.onLoad();
 | 
					          return widget.onLoad();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      ),
 | 
					 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,16 +1,9 @@
 | 
				
			|||||||
import 'dart:async';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import 'package:aurcache/api/builds.dart';
 | 
					 | 
				
			||||||
import 'package:aurcache/components/builds_table.dart';
 | 
					import 'package:aurcache/components/builds_table.dart';
 | 
				
			||||||
import 'package:aurcache/models/build.dart';
 | 
					import 'package:aurcache/models/build.dart';
 | 
				
			||||||
import 'package:aurcache/components/dashboard/your_packages.dart';
 | 
					 | 
				
			||||||
import 'package:aurcache/components/api/APIBuilder.dart';
 | 
					import 'package:aurcache/components/api/APIBuilder.dart';
 | 
				
			||||||
import 'package:aurcache/providers/builds_provider.dart';
 | 
					import 'package:aurcache/providers/builds_provider.dart';
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:go_router/go_router.dart';
 | 
					import 'package:go_router/go_router.dart';
 | 
				
			||||||
import 'package:provider/provider.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import '../../api/API.dart';
 | 
					 | 
				
			||||||
import '../../constants/color_constants.dart';
 | 
					import '../../constants/color_constants.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RecentBuilds extends StatefulWidget {
 | 
					class RecentBuilds extends StatefulWidget {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,18 +1,10 @@
 | 
				
			|||||||
import 'dart:async';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import 'package:aurcache/api/packages.dart';
 | 
					 | 
				
			||||||
import 'package:aurcache/components/api/APIBuilder.dart';
 | 
					import 'package:aurcache/components/api/APIBuilder.dart';
 | 
				
			||||||
 | 
					import 'package:aurcache/components/packages_table.dart';
 | 
				
			||||||
import 'package:aurcache/providers/packages_provider.dart';
 | 
					import 'package:aurcache/providers/packages_provider.dart';
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:go_router/go_router.dart';
 | 
					import 'package:go_router/go_router.dart';
 | 
				
			||||||
import 'package:provider/provider.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import '../../api/API.dart';
 | 
					 | 
				
			||||||
import '../../constants/color_constants.dart';
 | 
					import '../../constants/color_constants.dart';
 | 
				
			||||||
import '../../models/package.dart';
 | 
					import '../../models/package.dart';
 | 
				
			||||||
import '../../providers/builds_provider.dart';
 | 
					 | 
				
			||||||
import '../../providers/stats_provider.dart';
 | 
					 | 
				
			||||||
import '../confirm_popup.dart';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class YourPackages extends StatefulWidget {
 | 
					class YourPackages extends StatefulWidget {
 | 
				
			||||||
  const YourPackages({
 | 
					  const YourPackages({
 | 
				
			||||||
@@ -39,111 +31,31 @@ class _YourPackagesState extends State<YourPackages> {
 | 
				
			|||||||
            "Your Packages",
 | 
					            "Your Packages",
 | 
				
			||||||
            style: Theme.of(context).textTheme.subtitle1,
 | 
					            style: Theme.of(context).textTheme.subtitle1,
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
          SingleChildScrollView(
 | 
					          Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
 | 
				
			||||||
            //scrollDirection: Axis.horizontal,
 | 
					            SizedBox(
 | 
				
			||||||
            child: SizedBox(
 | 
					 | 
				
			||||||
              width: double.infinity,
 | 
					              width: double.infinity,
 | 
				
			||||||
              child: APIBuilder<PackagesProvider, List<Package>, Object>(
 | 
					              child: APIBuilder<PackagesProvider, List<Package>, PackagesDTO>(
 | 
				
			||||||
                key: Key("Packages on dashboard"),
 | 
					                key: const Key("Packages on dashboard"),
 | 
				
			||||||
                interval: const Duration(seconds: 10),
 | 
					                interval: const Duration(seconds: 10),
 | 
				
			||||||
 | 
					                dto: PackagesDTO(limit: 10),
 | 
				
			||||||
                onData: (data) {
 | 
					                onData: (data) {
 | 
				
			||||||
                  return DataTable(
 | 
					                  return PackagesTable(data: data);
 | 
				
			||||||
                      horizontalMargin: 0,
 | 
					 | 
				
			||||||
                      columnSpacing: defaultPadding,
 | 
					 | 
				
			||||||
                      columns: const [
 | 
					 | 
				
			||||||
                        DataColumn(
 | 
					 | 
				
			||||||
                          label: Text("Package ID"),
 | 
					 | 
				
			||||||
                        ),
 | 
					 | 
				
			||||||
                        DataColumn(
 | 
					 | 
				
			||||||
                          label: Text("Package Name"),
 | 
					 | 
				
			||||||
                        ),
 | 
					 | 
				
			||||||
                        DataColumn(
 | 
					 | 
				
			||||||
                          label: Text("Version"),
 | 
					 | 
				
			||||||
                        ),
 | 
					 | 
				
			||||||
                        DataColumn(
 | 
					 | 
				
			||||||
                          label: Text("Up-To-Date"),
 | 
					 | 
				
			||||||
                        ),
 | 
					 | 
				
			||||||
                        DataColumn(
 | 
					 | 
				
			||||||
                          label: Text("Status"),
 | 
					 | 
				
			||||||
                        ),
 | 
					 | 
				
			||||||
                        DataColumn(
 | 
					 | 
				
			||||||
                          label: Text("Action"),
 | 
					 | 
				
			||||||
                        ),
 | 
					 | 
				
			||||||
                      ],
 | 
					 | 
				
			||||||
                      rows: data
 | 
					 | 
				
			||||||
                          .map((e) => buildDataRow(e))
 | 
					 | 
				
			||||||
                          .toList(growable: false));
 | 
					 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                onLoad: () => const Text("No data"),
 | 
					                onLoad: () => const Text("No data"),
 | 
				
			||||||
              ),
 | 
					              ),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
          ),
 | 
					            ElevatedButton(
 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      ),
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  DataRow buildDataRow(Package package) {
 | 
					 | 
				
			||||||
    return DataRow(
 | 
					 | 
				
			||||||
      cells: [
 | 
					 | 
				
			||||||
        DataCell(Text(package.id.toString())),
 | 
					 | 
				
			||||||
        DataCell(Text(package.name)),
 | 
					 | 
				
			||||||
        DataCell(Text(package.latest_version.toString())),
 | 
					 | 
				
			||||||
        DataCell(IconButton(
 | 
					 | 
				
			||||||
          icon: Icon(
 | 
					 | 
				
			||||||
            package.outofdate ? Icons.update : Icons.verified,
 | 
					 | 
				
			||||||
            color: package.outofdate ? Color(0xFF6B43A4) : Color(0xFF0A6900),
 | 
					 | 
				
			||||||
          ),
 | 
					 | 
				
			||||||
          onPressed: package.outofdate
 | 
					 | 
				
			||||||
              ? () {
 | 
					 | 
				
			||||||
                  // todo open build info with logs
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              : null,
 | 
					 | 
				
			||||||
        )),
 | 
					 | 
				
			||||||
        DataCell(IconButton(
 | 
					 | 
				
			||||||
          icon: Icon(
 | 
					 | 
				
			||||||
            switchSuccessIcon(package.status),
 | 
					 | 
				
			||||||
            color: switchSuccessColor(package.status),
 | 
					 | 
				
			||||||
          ),
 | 
					 | 
				
			||||||
              onPressed: () {
 | 
					              onPressed: () {
 | 
				
			||||||
            //context.push("/build/${package.latest_version_id}");
 | 
					                context.push("/packages");
 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        )),
 | 
					 | 
				
			||||||
        DataCell(
 | 
					 | 
				
			||||||
          Row(
 | 
					 | 
				
			||||||
            children: [
 | 
					 | 
				
			||||||
              TextButton(
 | 
					 | 
				
			||||||
                child: const Text('View', style: TextStyle(color: greenColor)),
 | 
					 | 
				
			||||||
                onPressed: () {
 | 
					 | 
				
			||||||
                  context.push("/package/${package.id}");
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
              ),
 | 
					 | 
				
			||||||
              const SizedBox(
 | 
					 | 
				
			||||||
                width: 6,
 | 
					 | 
				
			||||||
              ),
 | 
					 | 
				
			||||||
              TextButton(
 | 
					 | 
				
			||||||
                child: const Text("Delete",
 | 
					 | 
				
			||||||
                    style: TextStyle(color: Colors.redAccent)),
 | 
					 | 
				
			||||||
                onPressed: () async {
 | 
					 | 
				
			||||||
                  final confirmResult =
 | 
					 | 
				
			||||||
                      await showDeleteConfirmationDialog(context);
 | 
					 | 
				
			||||||
                  if (!confirmResult) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                  final succ = await API.deletePackage(package.id);
 | 
					 | 
				
			||||||
                  if (succ) {
 | 
					 | 
				
			||||||
                    Provider.of<PackagesProvider>(context, listen: false)
 | 
					 | 
				
			||||||
                        .refresh(context);
 | 
					 | 
				
			||||||
                    Provider.of<BuildsProvider>(context, listen: false)
 | 
					 | 
				
			||||||
                        .refresh(context);
 | 
					 | 
				
			||||||
                    Provider.of<StatsProvider>(context, listen: false)
 | 
					 | 
				
			||||||
                        .refresh(context);
 | 
					 | 
				
			||||||
                  }
 | 
					 | 
				
			||||||
              },
 | 
					              },
 | 
				
			||||||
 | 
					              child: Text(
 | 
				
			||||||
 | 
					                "List all Packages",
 | 
				
			||||||
 | 
					                style: TextStyle(color: Colors.white.withOpacity(0.8)),
 | 
				
			||||||
              ),
 | 
					              ),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					          ]),
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										111
									
								
								frontend/lib/components/packages_table.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								frontend/lib/components/packages_table.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,111 @@
 | 
				
			|||||||
 | 
					import 'package:aurcache/api/packages.dart';
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:go_router/go_router.dart';
 | 
				
			||||||
 | 
					import 'package:provider/provider.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import '../api/API.dart';
 | 
				
			||||||
 | 
					import '../constants/color_constants.dart';
 | 
				
			||||||
 | 
					import '../models/package.dart';
 | 
				
			||||||
 | 
					import '../providers/builds_provider.dart';
 | 
				
			||||||
 | 
					import '../providers/packages_provider.dart';
 | 
				
			||||||
 | 
					import '../providers/stats_provider.dart';
 | 
				
			||||||
 | 
					import 'confirm_popup.dart';
 | 
				
			||||||
 | 
					import 'dashboard/your_packages.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PackagesTable extends StatelessWidget {
 | 
				
			||||||
 | 
					  const PackagesTable({super.key, required this.data});
 | 
				
			||||||
 | 
					  final List<Package> data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return DataTable(
 | 
				
			||||||
 | 
					        horizontalMargin: 0,
 | 
				
			||||||
 | 
					        columnSpacing: defaultPadding,
 | 
				
			||||||
 | 
					        columns: const [
 | 
				
			||||||
 | 
					          DataColumn(
 | 
				
			||||||
 | 
					            label: Text("Package ID"),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          DataColumn(
 | 
				
			||||||
 | 
					            label: Text("Package Name"),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          DataColumn(
 | 
				
			||||||
 | 
					            label: Text("Version"),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          DataColumn(
 | 
				
			||||||
 | 
					            label: Text("Up-To-Date"),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          DataColumn(
 | 
				
			||||||
 | 
					            label: Text("Status"),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          DataColumn(
 | 
				
			||||||
 | 
					            label: Text("Action"),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        rows:
 | 
				
			||||||
 | 
					            data.map((e) => buildDataRow(e, context)).toList(growable: false));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  DataRow buildDataRow(Package package, BuildContext context) {
 | 
				
			||||||
 | 
					    return DataRow(
 | 
				
			||||||
 | 
					      cells: [
 | 
				
			||||||
 | 
					        DataCell(Text(package.id.toString())),
 | 
				
			||||||
 | 
					        DataCell(Text(package.name)),
 | 
				
			||||||
 | 
					        DataCell(Text(package.latest_version.toString())),
 | 
				
			||||||
 | 
					        DataCell(IconButton(
 | 
				
			||||||
 | 
					          icon: Icon(
 | 
				
			||||||
 | 
					            package.outofdate ? Icons.update : Icons.verified,
 | 
				
			||||||
 | 
					            color: package.outofdate ? Color(0xFF6B43A4) : Color(0xFF0A6900),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          onPressed: package.outofdate
 | 
				
			||||||
 | 
					              ? () {
 | 
				
			||||||
 | 
					                  // todo open build info with logs
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              : null,
 | 
				
			||||||
 | 
					        )),
 | 
				
			||||||
 | 
					        DataCell(IconButton(
 | 
				
			||||||
 | 
					          icon: Icon(
 | 
				
			||||||
 | 
					            switchSuccessIcon(package.status),
 | 
				
			||||||
 | 
					            color: switchSuccessColor(package.status),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          onPressed: () {
 | 
				
			||||||
 | 
					            //context.push("/build/${package.latest_version_id}");
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        )),
 | 
				
			||||||
 | 
					        DataCell(
 | 
				
			||||||
 | 
					          Row(
 | 
				
			||||||
 | 
					            children: [
 | 
				
			||||||
 | 
					              TextButton(
 | 
				
			||||||
 | 
					                child: const Text('View', style: TextStyle(color: greenColor)),
 | 
				
			||||||
 | 
					                onPressed: () {
 | 
				
			||||||
 | 
					                  context.push("/package/${package.id}");
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
 | 
					              const SizedBox(
 | 
				
			||||||
 | 
					                width: 6,
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
 | 
					              TextButton(
 | 
				
			||||||
 | 
					                child: const Text("Delete",
 | 
				
			||||||
 | 
					                    style: TextStyle(color: Colors.redAccent)),
 | 
				
			||||||
 | 
					                onPressed: () async {
 | 
				
			||||||
 | 
					                  final confirmResult =
 | 
				
			||||||
 | 
					                      await showDeleteConfirmationDialog(context);
 | 
				
			||||||
 | 
					                  if (!confirmResult) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                  final succ = await API.deletePackage(package.id);
 | 
				
			||||||
 | 
					                  if (succ) {
 | 
				
			||||||
 | 
					                    Provider.of<PackagesProvider>(context, listen: false)
 | 
				
			||||||
 | 
					                        .refresh(context);
 | 
				
			||||||
 | 
					                    Provider.of<BuildsProvider>(context, listen: false)
 | 
				
			||||||
 | 
					                        .refresh(context);
 | 
				
			||||||
 | 
					                    Provider.of<StatsProvider>(context, listen: false)
 | 
				
			||||||
 | 
					                        .refresh(context);
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -3,6 +3,7 @@ import 'package:aurcache/screens/builds_screen.dart';
 | 
				
			|||||||
import 'package:aurcache/screens/dashboard_screen.dart';
 | 
					import 'package:aurcache/screens/dashboard_screen.dart';
 | 
				
			||||||
import 'package:aurcache/components/routing/menu_shell.dart';
 | 
					import 'package:aurcache/components/routing/menu_shell.dart';
 | 
				
			||||||
import 'package:aurcache/screens/package_screen.dart';
 | 
					import 'package:aurcache/screens/package_screen.dart';
 | 
				
			||||||
 | 
					import 'package:aurcache/screens/packages_screen.dart';
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:go_router/go_router.dart';
 | 
					import 'package:go_router/go_router.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -35,6 +36,10 @@ final appRouter = GoRouter(
 | 
				
			|||||||
          path: '/builds',
 | 
					          path: '/builds',
 | 
				
			||||||
          builder: (context, state) => const BuildsScreen(),
 | 
					          builder: (context, state) => const BuildsScreen(),
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
 | 
					        GoRoute(
 | 
				
			||||||
 | 
					          path: '/packages',
 | 
				
			||||||
 | 
					          builder: (context, state) => const PackagesScreen(),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
        GoRoute(
 | 
					        GoRoute(
 | 
				
			||||||
          path: '/package/:id',
 | 
					          path: '/package/:id',
 | 
				
			||||||
          builder: (context, state) {
 | 
					          builder: (context, state) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,7 @@
 | 
				
			|||||||
import 'package:aurcache/components/routing/router.dart';
 | 
					import 'package:aurcache/components/routing/router.dart';
 | 
				
			||||||
import 'package:aurcache/providers/build_provider.dart';
 | 
					 | 
				
			||||||
import 'package:aurcache/providers/builds_provider.dart';
 | 
					 | 
				
			||||||
import 'package:aurcache/providers/package_provider.dart';
 | 
					 | 
				
			||||||
import 'package:aurcache/providers/packages_provider.dart';
 | 
					 | 
				
			||||||
import 'package:aurcache/providers/stats_provider.dart';
 | 
					 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:go_router/go_router.dart';
 | 
					import 'package:go_router/go_router.dart';
 | 
				
			||||||
import 'package:google_fonts/google_fonts.dart';
 | 
					import 'package:google_fonts/google_fonts.dart';
 | 
				
			||||||
import 'package:provider/provider.dart';
 | 
					 | 
				
			||||||
import 'constants/color_constants.dart';
 | 
					import 'constants/color_constants.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void main() {
 | 
					void main() {
 | 
				
			||||||
@@ -20,23 +14,12 @@ class MyApp extends StatelessWidget {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return MultiProvider(
 | 
					    return MaterialApp.router(
 | 
				
			||||||
      providers: [
 | 
					 | 
				
			||||||
        ChangeNotifierProvider<StatsProvider>(create: (_) => StatsProvider()),
 | 
					 | 
				
			||||||
        ChangeNotifierProvider<PackagesProvider>(
 | 
					 | 
				
			||||||
            create: (_) => PackagesProvider()),
 | 
					 | 
				
			||||||
        ChangeNotifierProvider<BuildsProvider>(create: (_) => BuildsProvider()),
 | 
					 | 
				
			||||||
        ChangeNotifierProvider<PackageProvider>(
 | 
					 | 
				
			||||||
            create: (_) => PackageProvider()),
 | 
					 | 
				
			||||||
        ChangeNotifierProvider<BuildProvider>(create: (_) => BuildProvider()),
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      child: MaterialApp.router(
 | 
					 | 
				
			||||||
      routerConfig: appRouter,
 | 
					      routerConfig: appRouter,
 | 
				
			||||||
      debugShowCheckedModeBanner: false,
 | 
					      debugShowCheckedModeBanner: false,
 | 
				
			||||||
      title: 'AURCache',
 | 
					      title: 'AURCache',
 | 
				
			||||||
      theme: ThemeData.dark().copyWith(
 | 
					      theme: ThemeData.dark().copyWith(
 | 
				
			||||||
          appBarTheme:
 | 
					        appBarTheme: const AppBarTheme(backgroundColor: bgColor, elevation: 0),
 | 
				
			||||||
              const AppBarTheme(backgroundColor: bgColor, elevation: 0),
 | 
					 | 
				
			||||||
        scaffoldBackgroundColor: bgColor,
 | 
					        scaffoldBackgroundColor: bgColor,
 | 
				
			||||||
        primaryColor: greenColor,
 | 
					        primaryColor: greenColor,
 | 
				
			||||||
        dialogBackgroundColor: secondaryColor,
 | 
					        dialogBackgroundColor: secondaryColor,
 | 
				
			||||||
@@ -44,7 +27,6 @@ class MyApp extends StatelessWidget {
 | 
				
			|||||||
            .apply(bodyColor: Colors.white),
 | 
					            .apply(bodyColor: Colors.white),
 | 
				
			||||||
        canvasColor: secondaryColor,
 | 
					        canvasColor: secondaryColor,
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
      ),
 | 
					 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,10 +2,17 @@ import 'package:aurcache/api/packages.dart';
 | 
				
			|||||||
import 'package:aurcache/providers/BaseProvider.dart';
 | 
					import 'package:aurcache/providers/BaseProvider.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import '../api/API.dart';
 | 
					import '../api/API.dart';
 | 
				
			||||||
 | 
					import '../models/package.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PackagesProvider extends BaseProvider {
 | 
					class PackagesDTO {
 | 
				
			||||||
 | 
					  final int limit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  PackagesDTO({required this.limit});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PackagesProvider extends BaseProvider<List<Package>, PackagesDTO> {
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  loadFuture(context, {dto}) {
 | 
					  loadFuture(context, {dto}) {
 | 
				
			||||||
    data = API.listPackages();
 | 
					    data = API.listPackages(limit: dto?.limit);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@ import 'package:aurcache/providers/build_provider.dart';
 | 
				
			|||||||
import 'package:aurcache/utils/time_formatter.dart';
 | 
					import 'package:aurcache/utils/time_formatter.dart';
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:go_router/go_router.dart';
 | 
					import 'package:go_router/go_router.dart';
 | 
				
			||||||
 | 
					import 'package:provider/provider.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import '../components/dashboard/your_packages.dart';
 | 
					import '../components/dashboard/your_packages.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -21,7 +22,11 @@ class _BuildScreenState extends State<BuildScreen> {
 | 
				
			|||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return Scaffold(
 | 
					    return Scaffold(
 | 
				
			||||||
      body: APIBuilder<BuildProvider, Build, BuildDTO>(
 | 
					      body: MultiProvider(
 | 
				
			||||||
 | 
					        providers: [
 | 
				
			||||||
 | 
					          ChangeNotifierProvider<BuildProvider>(create: (_) => BuildProvider()),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        child: APIBuilder<BuildProvider, Build, BuildDTO>(
 | 
				
			||||||
            key: const Key("Build on seperate page"),
 | 
					            key: const Key("Build on seperate page"),
 | 
				
			||||||
            dto: BuildDTO(buildID: widget.buildID),
 | 
					            dto: BuildDTO(buildID: widget.buildID),
 | 
				
			||||||
            interval: const Duration(seconds: 10),
 | 
					            interval: const Duration(seconds: 10),
 | 
				
			||||||
@@ -69,6 +74,7 @@ class _BuildScreenState extends State<BuildScreen> {
 | 
				
			|||||||
                ],
 | 
					                ],
 | 
				
			||||||
              );
 | 
					              );
 | 
				
			||||||
            }),
 | 
					            }),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
      appBar: AppBar(),
 | 
					      appBar: AppBar(),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@ import 'package:aurcache/components/builds_table.dart';
 | 
				
			|||||||
import 'package:aurcache/components/api/APIBuilder.dart';
 | 
					import 'package:aurcache/components/api/APIBuilder.dart';
 | 
				
			||||||
import 'package:aurcache/providers/builds_provider.dart';
 | 
					import 'package:aurcache/providers/builds_provider.dart';
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:provider/provider.dart';
 | 
				
			||||||
import '../constants/color_constants.dart';
 | 
					import '../constants/color_constants.dart';
 | 
				
			||||||
import '../models/build.dart';
 | 
					import '../models/build.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -12,7 +13,12 @@ class BuildsScreen extends StatelessWidget {
 | 
				
			|||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return Scaffold(
 | 
					    return Scaffold(
 | 
				
			||||||
      appBar: AppBar(),
 | 
					      appBar: AppBar(),
 | 
				
			||||||
      body: Padding(
 | 
					      body: MultiProvider(
 | 
				
			||||||
 | 
					        providers: [
 | 
				
			||||||
 | 
					          ChangeNotifierProvider<BuildsProvider>(
 | 
				
			||||||
 | 
					              create: (_) => BuildsProvider()),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        child: Padding(
 | 
				
			||||||
          padding: const EdgeInsets.all(defaultPadding),
 | 
					          padding: const EdgeInsets.all(defaultPadding),
 | 
				
			||||||
          child: Container(
 | 
					          child: Container(
 | 
				
			||||||
            padding: const EdgeInsets.all(defaultPadding),
 | 
					            padding: const EdgeInsets.all(defaultPadding),
 | 
				
			||||||
@@ -43,6 +49,7 @@ class BuildsScreen extends StatelessWidget {
 | 
				
			|||||||
            ),
 | 
					            ),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,12 @@
 | 
				
			|||||||
import 'package:aurcache/api/statistics.dart';
 | 
					 | 
				
			||||||
import 'package:aurcache/components/api/APIBuilder.dart';
 | 
					import 'package:aurcache/components/api/APIBuilder.dart';
 | 
				
			||||||
import 'package:aurcache/providers/stats_provider.dart';
 | 
					import 'package:aurcache/providers/stats_provider.dart';
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:provider/provider.dart';
 | 
					import 'package:provider/provider.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import '../api/API.dart';
 | 
					 | 
				
			||||||
import '../components/dashboard/header.dart';
 | 
					import '../components/dashboard/header.dart';
 | 
				
			||||||
import '../constants/color_constants.dart';
 | 
					import '../constants/color_constants.dart';
 | 
				
			||||||
 | 
					import '../providers/builds_provider.dart';
 | 
				
			||||||
 | 
					import '../providers/packages_provider.dart';
 | 
				
			||||||
import '../utils/responsive.dart';
 | 
					import '../utils/responsive.dart';
 | 
				
			||||||
import '../models/stats.dart';
 | 
					import '../models/stats.dart';
 | 
				
			||||||
import '../components/dashboard/quick_info_banner.dart';
 | 
					import '../components/dashboard/quick_info_banner.dart';
 | 
				
			||||||
@@ -22,7 +22,14 @@ class DashboardScreen extends StatefulWidget {
 | 
				
			|||||||
class _DashboardScreenState extends State<DashboardScreen> {
 | 
					class _DashboardScreenState extends State<DashboardScreen> {
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return APIBuilder<StatsProvider, Stats, Object>(
 | 
					    return MultiProvider(
 | 
				
			||||||
 | 
					      providers: [
 | 
				
			||||||
 | 
					        ChangeNotifierProvider<StatsProvider>(create: (_) => StatsProvider()),
 | 
				
			||||||
 | 
					        ChangeNotifierProvider<PackagesProvider>(
 | 
				
			||||||
 | 
					            create: (_) => PackagesProvider()),
 | 
				
			||||||
 | 
					        ChangeNotifierProvider<BuildsProvider>(create: (_) => BuildsProvider()),
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      child: APIBuilder<StatsProvider, Stats, Object>(
 | 
				
			||||||
        interval: const Duration(seconds: 10),
 | 
					        interval: const Duration(seconds: 10),
 | 
				
			||||||
        onData: (stats) {
 | 
					        onData: (stats) {
 | 
				
			||||||
          return SafeArea(
 | 
					          return SafeArea(
 | 
				
			||||||
@@ -79,6 +86,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
 | 
				
			|||||||
        onLoad: () {
 | 
					        onLoad: () {
 | 
				
			||||||
          return Text("loading");
 | 
					          return Text("loading");
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,14 @@ class _PackageScreenState extends State<PackageScreen> {
 | 
				
			|||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return Scaffold(
 | 
					    return Scaffold(
 | 
				
			||||||
      appBar: AppBar(),
 | 
					      appBar: AppBar(),
 | 
				
			||||||
      body: APIBuilder<PackageProvider, Package, PackageDTO>(
 | 
					      body: MultiProvider(
 | 
				
			||||||
 | 
					        providers: [
 | 
				
			||||||
 | 
					          ChangeNotifierProvider<BuildsProvider>(
 | 
				
			||||||
 | 
					              create: (_) => BuildsProvider()),
 | 
				
			||||||
 | 
					          ChangeNotifierProvider<PackageProvider>(
 | 
				
			||||||
 | 
					              create: (_) => PackageProvider()),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        child: APIBuilder<PackageProvider, Package, PackageDTO>(
 | 
				
			||||||
            dto: PackageDTO(pkgID: widget.pkgID),
 | 
					            dto: PackageDTO(pkgID: widget.pkgID),
 | 
				
			||||||
            onLoad: () => const Text("loading"),
 | 
					            onLoad: () => const Text("loading"),
 | 
				
			||||||
            onData: (pkg) {
 | 
					            onData: (pkg) {
 | 
				
			||||||
@@ -67,7 +74,8 @@ class _PackageScreenState extends State<PackageScreen> {
 | 
				
			|||||||
                                Provider.of<BuildsProvider>(context,
 | 
					                                Provider.of<BuildsProvider>(context,
 | 
				
			||||||
                                        listen: false)
 | 
					                                        listen: false)
 | 
				
			||||||
                                    .refresh(context);
 | 
					                                    .refresh(context);
 | 
				
			||||||
                              Provider.of<StatsProvider>(context, listen: false)
 | 
					                                Provider.of<StatsProvider>(context,
 | 
				
			||||||
 | 
					                                        listen: false)
 | 
				
			||||||
                                    .refresh(context);
 | 
					                                    .refresh(context);
 | 
				
			||||||
                              }
 | 
					                              }
 | 
				
			||||||
                            },
 | 
					                            },
 | 
				
			||||||
@@ -117,6 +125,7 @@ class _PackageScreenState extends State<PackageScreen> {
 | 
				
			|||||||
                ),
 | 
					                ),
 | 
				
			||||||
              );
 | 
					              );
 | 
				
			||||||
            }),
 | 
					            }),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										56
									
								
								frontend/lib/screens/packages_screen.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								frontend/lib/screens/packages_screen.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					import 'package:aurcache/components/packages_table.dart';
 | 
				
			||||||
 | 
					import 'package:aurcache/providers/packages_provider.dart';
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:provider/provider.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import '../components/api/APIBuilder.dart';
 | 
				
			||||||
 | 
					import '../constants/color_constants.dart';
 | 
				
			||||||
 | 
					import '../models/package.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PackagesScreen extends StatelessWidget {
 | 
				
			||||||
 | 
					  const PackagesScreen({super.key});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return Scaffold(
 | 
				
			||||||
 | 
					      appBar: AppBar(),
 | 
				
			||||||
 | 
					      body: MultiProvider(
 | 
				
			||||||
 | 
					        providers: [
 | 
				
			||||||
 | 
					          ChangeNotifierProvider<PackagesProvider>(
 | 
				
			||||||
 | 
					              create: (_) => PackagesProvider()),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        child: Padding(
 | 
				
			||||||
 | 
					          padding: const EdgeInsets.all(defaultPadding),
 | 
				
			||||||
 | 
					          child: Container(
 | 
				
			||||||
 | 
					            padding: const EdgeInsets.all(defaultPadding),
 | 
				
			||||||
 | 
					            decoration: const BoxDecoration(
 | 
				
			||||||
 | 
					              color: secondaryColor,
 | 
				
			||||||
 | 
					              borderRadius: BorderRadius.all(Radius.circular(10)),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            child: SingleChildScrollView(
 | 
				
			||||||
 | 
					              child: Column(
 | 
				
			||||||
 | 
					                crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
 | 
					                children: [
 | 
				
			||||||
 | 
					                  Text(
 | 
				
			||||||
 | 
					                    "All Packages",
 | 
				
			||||||
 | 
					                    style: Theme.of(context).textTheme.subtitle1,
 | 
				
			||||||
 | 
					                  ),
 | 
				
			||||||
 | 
					                  SizedBox(
 | 
				
			||||||
 | 
					                    width: double.infinity,
 | 
				
			||||||
 | 
					                    child: APIBuilder<PackagesProvider, List<Package>, Object>(
 | 
				
			||||||
 | 
					                        key: const Key("Builds on seperate screen"),
 | 
				
			||||||
 | 
					                        interval: const Duration(seconds: 10),
 | 
				
			||||||
 | 
					                        onLoad: () => const Text("no data"),
 | 
				
			||||||
 | 
					                        onData: (data) {
 | 
				
			||||||
 | 
					                          return PackagesTable(data: data);
 | 
				
			||||||
 | 
					                        }),
 | 
				
			||||||
 | 
					                  )
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user