add disk page
This commit is contained in:
		@@ -5,13 +5,13 @@ rust-latest:
 | 
				
			|||||||
  stage: build
 | 
					  stage: build
 | 
				
			||||||
  image: rust:latest
 | 
					  image: rust:latest
 | 
				
			||||||
  script:
 | 
					  script:
 | 
				
			||||||
    - cargo build -r --mainifest-path=lib/Cargo.toml
 | 
					    - cargo build -r --manifest-path=lib/Cargo.toml
 | 
				
			||||||
    - cargo test -r --mainifest-path=lib/Cargo.toml
 | 
					    - cargo test -r --manifest-path=lib/Cargo.toml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rust-nightly:
 | 
					rust-nightly:
 | 
				
			||||||
  stage: build
 | 
					  stage: build
 | 
				
			||||||
  image: rustlang/rust:nightly
 | 
					  image: rustlang/rust:nightly
 | 
				
			||||||
  script:
 | 
					  script:
 | 
				
			||||||
    - cargo build -r --mainifest-path=lib/Cargo.toml
 | 
					    - cargo build -r --manifest-path=lib/Cargo.toml
 | 
				
			||||||
    - cargo test -r --mainifest-path=lib/Cargo.toml
 | 
					    - cargo test -r --manifest-path=lib/Cargo.toml
 | 
				
			||||||
  allow_failure: true
 | 
					  allow_failure: true
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								app/lib/api/request.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								app/lib/api/request.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					import 'dart:convert';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import 'package:flutter/foundation.dart';
 | 
				
			||||||
 | 
					import 'package:http/http.dart' as http;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Future<Map<String, dynamic>> getJson(String uri) async {
 | 
				
			||||||
 | 
					  if (!kIsWeb) {
 | 
				
			||||||
 | 
					    uri = "http://127.0.0.1:8000$uri";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  final resp = await http.get(Uri.parse(uri));
 | 
				
			||||||
 | 
					  return jsonDecode(resp.body);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										53
									
								
								app/lib/disk_page.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								app/lib/disk_page.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:raid_manager/api/request.dart';
 | 
				
			||||||
 | 
					import 'package:raid_manager/types/disk.dart';
 | 
				
			||||||
 | 
					import 'package:raid_manager/utils/file_formatter.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DiskPage extends StatefulWidget {
 | 
				
			||||||
 | 
					  const DiskPage({Key? key}) : super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  State<DiskPage> createState() => _DiskPageState();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _DiskPageState extends State<DiskPage> {
 | 
				
			||||||
 | 
					  Future<List<Disk>> fetchDisks() async {
 | 
				
			||||||
 | 
					    return (await getJson('/api/disks') as List)
 | 
				
			||||||
 | 
					        .map((e) => Disk.fromJson(e))
 | 
				
			||||||
 | 
					        .toList(growable: false);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  late final myFetch = fetchDisks();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return FutureBuilder(
 | 
				
			||||||
 | 
					      future: myFetch,
 | 
				
			||||||
 | 
					      builder: (context, snapshot) {
 | 
				
			||||||
 | 
					        if (snapshot.hasData) {
 | 
				
			||||||
 | 
					          final data = snapshot.data!;
 | 
				
			||||||
 | 
					          return ListView.builder(
 | 
				
			||||||
 | 
					            itemCount: data.length,
 | 
				
			||||||
 | 
					            itemBuilder: (context, idx) {
 | 
				
			||||||
 | 
					              return ListTile(
 | 
				
			||||||
 | 
					                title: Text(
 | 
				
			||||||
 | 
					                  data[idx].name,
 | 
				
			||||||
 | 
					                  style: Theme.of(context).textTheme.headlineMedium,
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                subtitle: Text(
 | 
				
			||||||
 | 
					                  data[idx].size.readableFileSize(),
 | 
				
			||||||
 | 
					                  style: Theme.of(context).textTheme.labelMedium,
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                onTap: () {},
 | 
				
			||||||
 | 
					              );
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
 | 
					        } else if (snapshot.hasError) {
 | 
				
			||||||
 | 
					          return const Text("errored");
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          return const Text("loading...");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:raid_manager/disk_page.dart';
 | 
				
			||||||
import 'package:raid_manager/raid_page.dart';
 | 
					import 'package:raid_manager/raid_page.dart';
 | 
				
			||||||
import 'package:sidebarx/sidebarx.dart';
 | 
					import 'package:sidebarx/sidebarx.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -21,22 +22,20 @@ class SidebarXExampleApp extends StatelessWidget {
 | 
				
			|||||||
        canvasColor: canvasColor,
 | 
					        canvasColor: canvasColor,
 | 
				
			||||||
        scaffoldBackgroundColor: scaffoldBackgroundColor,
 | 
					        scaffoldBackgroundColor: scaffoldBackgroundColor,
 | 
				
			||||||
        textTheme: const TextTheme(
 | 
					        textTheme: const TextTheme(
 | 
				
			||||||
          headlineSmall: TextStyle(
 | 
					            headlineSmall: TextStyle(
 | 
				
			||||||
            color: Colors.white,
 | 
					              color: Colors.white,
 | 
				
			||||||
            fontSize: 12,
 | 
					              fontSize: 12,
 | 
				
			||||||
            fontWeight: FontWeight.w800,
 | 
					              fontWeight: FontWeight.w800,
 | 
				
			||||||
          ),
 | 
					            ),
 | 
				
			||||||
          headlineMedium: TextStyle(
 | 
					            headlineMedium: TextStyle(
 | 
				
			||||||
            color: Colors.white,
 | 
					              color: Colors.white,
 | 
				
			||||||
            fontSize: 17,
 | 
					              fontSize: 17,
 | 
				
			||||||
            fontWeight: FontWeight.w500,
 | 
					              fontWeight: FontWeight.w500,
 | 
				
			||||||
          ),
 | 
					            ),
 | 
				
			||||||
          labelMedium: TextStyle(
 | 
					            labelMedium: TextStyle(
 | 
				
			||||||
            color: Colors.white,
 | 
					                color: Colors.white,
 | 
				
			||||||
            fontSize: 14,
 | 
					                fontSize: 14,
 | 
				
			||||||
            fontWeight: FontWeight.w200
 | 
					                fontWeight: FontWeight.w200)),
 | 
				
			||||||
          )
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
      home: Builder(
 | 
					      home: Builder(
 | 
				
			||||||
        builder: (context) {
 | 
					        builder: (context) {
 | 
				
			||||||
@@ -45,18 +44,18 @@ class SidebarXExampleApp extends StatelessWidget {
 | 
				
			|||||||
            key: _key,
 | 
					            key: _key,
 | 
				
			||||||
            appBar: isSmallScreen
 | 
					            appBar: isSmallScreen
 | 
				
			||||||
                ? AppBar(
 | 
					                ? AppBar(
 | 
				
			||||||
              backgroundColor: canvasColor,
 | 
					                    backgroundColor: canvasColor,
 | 
				
			||||||
              title: Text(_getTitleByIndex(_controller.selectedIndex)),
 | 
					                    title: Text(_getTitleByIndex(_controller.selectedIndex)),
 | 
				
			||||||
              leading: IconButton(
 | 
					                    leading: IconButton(
 | 
				
			||||||
                onPressed: () {
 | 
					                      onPressed: () {
 | 
				
			||||||
                  // if (!Platform.isAndroid && !Platform.isIOS) {
 | 
					                        // if (!Platform.isAndroid && !Platform.isIOS) {
 | 
				
			||||||
                  //   _controller.setExtended(true);
 | 
					                        //   _controller.setExtended(true);
 | 
				
			||||||
                  // }
 | 
					                        // }
 | 
				
			||||||
                  _key.currentState?.openDrawer();
 | 
					                        _key.currentState?.openDrawer();
 | 
				
			||||||
                },
 | 
					                      },
 | 
				
			||||||
                icon: const Icon(Icons.menu),
 | 
					                      icon: const Icon(Icons.menu),
 | 
				
			||||||
              ),
 | 
					                    ),
 | 
				
			||||||
            )
 | 
					                  )
 | 
				
			||||||
                : null,
 | 
					                : null,
 | 
				
			||||||
            drawer: ExampleSidebarX(controller: _controller),
 | 
					            drawer: ExampleSidebarX(controller: _controller),
 | 
				
			||||||
            body: Row(
 | 
					            body: Row(
 | 
				
			||||||
@@ -138,9 +137,7 @@ class ExampleSidebarX extends StatelessWidget {
 | 
				
			|||||||
      ),
 | 
					      ),
 | 
				
			||||||
      footerDivider: divider,
 | 
					      footerDivider: divider,
 | 
				
			||||||
      headerBuilder: (context, extended) {
 | 
					      headerBuilder: (context, extended) {
 | 
				
			||||||
        return const SizedBox(
 | 
					        return const SizedBox(height: 20);
 | 
				
			||||||
          height: 20
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      items: const [
 | 
					      items: const [
 | 
				
			||||||
        SidebarXItem(
 | 
					        SidebarXItem(
 | 
				
			||||||
@@ -175,19 +172,7 @@ class _ScreensExample extends StatelessWidget {
 | 
				
			|||||||
          case 0:
 | 
					          case 0:
 | 
				
			||||||
            return const RaidPage();
 | 
					            return const RaidPage();
 | 
				
			||||||
          case 1:
 | 
					          case 1:
 | 
				
			||||||
            return ListView.builder(
 | 
					            return const DiskPage();
 | 
				
			||||||
              padding: const EdgeInsets.only(top: 10),
 | 
					 | 
				
			||||||
              itemBuilder: (context, index) => Container(
 | 
					 | 
				
			||||||
                height: 100,
 | 
					 | 
				
			||||||
                width: double.infinity,
 | 
					 | 
				
			||||||
                margin: const EdgeInsets.only(bottom: 10, right: 10, left: 10),
 | 
					 | 
				
			||||||
                decoration: BoxDecoration(
 | 
					 | 
				
			||||||
                  borderRadius: BorderRadius.circular(20),
 | 
					 | 
				
			||||||
                  color: Theme.of(context).canvasColor,
 | 
					 | 
				
			||||||
                  boxShadow: const [BoxShadow()],
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
              ),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
          default:
 | 
					          default:
 | 
				
			||||||
            return Text(
 | 
					            return Text(
 | 
				
			||||||
              pageTitle,
 | 
					              pageTitle,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,7 @@
 | 
				
			|||||||
import 'dart:convert';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:raid_manager/api/request.dart';
 | 
				
			||||||
import 'package:raid_manager/raid_info_page.dart';
 | 
					import 'package:raid_manager/raid_info_page.dart';
 | 
				
			||||||
import 'package:raid_manager/types/md_raid_system.dart';
 | 
					import 'package:raid_manager/types/md_raid_system.dart';
 | 
				
			||||||
import 'package:http/http.dart' as http;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RaidPage extends StatefulWidget {
 | 
					class RaidPage extends StatefulWidget {
 | 
				
			||||||
  const RaidPage({Key? key}) : super(key: key);
 | 
					  const RaidPage({Key? key}) : super(key: key);
 | 
				
			||||||
@@ -14,9 +12,7 @@ class RaidPage extends StatefulWidget {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class _RaidPageState extends State<RaidPage> {
 | 
					class _RaidPageState extends State<RaidPage> {
 | 
				
			||||||
  Future<MdRaidSystem> fetchRaids() async {
 | 
					  Future<MdRaidSystem> fetchRaids() async {
 | 
				
			||||||
    final resp =
 | 
					    return MdRaidSystem.fromJson(await getJson('/api/raiddevices'));
 | 
				
			||||||
        await http.get(Uri.parse('http://127.0.0.1:8000/api/raiddevices'));
 | 
					 | 
				
			||||||
    return MdRaidSystem.fromJson(jsonDecode(resp.body));
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  late final myFetch = fetchRaids();
 | 
					  late final myFetch = fetchRaids();
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										13
									
								
								app/lib/types/disk.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								app/lib/types/disk.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					import 'package:json_annotation/json_annotation.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					part 'disk.g.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@JsonSerializable()
 | 
				
			||||||
 | 
					class Disk {
 | 
				
			||||||
 | 
					  String name;
 | 
				
			||||||
 | 
					  int size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Disk(this.name, this.size);
 | 
				
			||||||
 | 
					  factory Disk.fromJson(Map<String, dynamic> json) => _$DiskFromJson(json);
 | 
				
			||||||
 | 
					  Map<String, dynamic> toJson() => _$DiskToJson(this);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										17
									
								
								app/lib/types/disk.g.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								app/lib/types/disk.g.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					// GENERATED CODE - DO NOT MODIFY BY HAND
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					part of 'disk.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// **************************************************************************
 | 
				
			||||||
 | 
					// JsonSerializableGenerator
 | 
				
			||||||
 | 
					// **************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Disk _$DiskFromJson(Map<String, dynamic> json) => Disk(
 | 
				
			||||||
 | 
					      json['name'] as String,
 | 
				
			||||||
 | 
					      json['size'] as int,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Map<String, dynamic> _$DiskToJson(Disk instance) => <String, dynamic>{
 | 
				
			||||||
 | 
					      'name': instance.name,
 | 
				
			||||||
 | 
					      'size': instance.size,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
							
								
								
									
										15
									
								
								app/lib/utils/file_formatter.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								app/lib/utils/file_formatter.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					import 'dart:math';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					double _log10(num x) => log(x) / ln10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extension FileFormatter on num {
 | 
				
			||||||
 | 
					  String readableFileSize({bool base1024 = true}) {
 | 
				
			||||||
 | 
					    if (this <= 0) return "0";
 | 
				
			||||||
 | 
					    final base = base1024 ? 1024 : 1000;
 | 
				
			||||||
 | 
					    final units = base1024
 | 
				
			||||||
 | 
					        ? ["Bi", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"]
 | 
				
			||||||
 | 
					        : ["B", "KB", "MB", "GB", "TB", "PB", "EB"];
 | 
				
			||||||
 | 
					    final digitGroups = (_log10(this) / _log10(base)).floor();
 | 
				
			||||||
 | 
					    return "${(this / pow(base, digitGroups)).toStringAsFixed(2)} ${units[digitGroups]}";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user