This commit is contained in:
cxc
2023-02-08 17:20:16 +08:00
parent 06ff4a41f4
commit 53ff2fc59b
23 changed files with 458 additions and 104 deletions

View File

@ -3,7 +3,7 @@
<application <application
android:label="momo" android:label="momo"
android:name="${applicationName}" android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/launcher_icon">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@ -1,6 +1,8 @@
flutter_icons: flutter_icons:
android: "launcher_icon"
ios: true ios: true
image_path: "assets/icon/icon.jpeg" image_path: "assets/icon/icon.jpeg"
min_sdk_android: 21 # android min sdk min:16, default 21
windows: windows:
generate: true generate: true
image_path: "assets/icon/icon.jpeg" image_path: "assets/icon/icon.jpeg"

View File

@ -1,10 +1,6 @@
import 'package:fluent_ui/fluent_ui.dart'; import 'package:fluent_ui/fluent_ui.dart';
// import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:momo/fluent/login.dart';
import 'package:momo/fluent/router.dart'; import 'package:momo/fluent/router.dart';
import 'package:momo/provider/token.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
class MyFluentApp extends ConsumerWidget { class MyFluentApp extends ConsumerWidget {
@ -12,10 +8,10 @@ class MyFluentApp extends ConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final String token = ref.watch(tokenProvider); // final String token = ref.watch(tokenProvider);
Future<String?> loadToken() async { Future<String?> loadToken() async {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
String? tk = await prefs.getString("token"); String? tk = prefs.getString("token");
return tk; return tk;
} }

View File

@ -6,6 +6,8 @@ import 'package:fluent_ui/fluent_ui.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:momo/models/login_resp.dart'; import 'package:momo/models/login_resp.dart';
import 'package:momo/provider/token.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
class LoginPage extends StatelessWidget { class LoginPage extends StatelessWidget {
@ -59,21 +61,25 @@ class _LoginFormState extends State<LoginForm> {
if (usernameController.text.isNotEmpty && if (usernameController.text.isNotEmpty &&
passwordController.text.isNotEmpty) { passwordController.text.isNotEmpty) {
http http
.post(Uri.parse("http://localhost:8080/user/login"), .post(Uri.parse("http://192.168.110.156:8080/user/login"),
headers: {"Content-Type": "application/json"}, headers: {"Content-Type": "application/json"},
body: jsonEncode({ body: jsonEncode({
"username": usernameController.text, "username": usernameController.text,
"password": passwordController.text "password": passwordController.text
})) }))
.then((resp) { .then((resp) {
print(resp.body);
if (resp.statusCode == HttpStatus.ok) { if (resp.statusCode == HttpStatus.ok) {
LoginResp loginResp = LoginResp loginResp =
LoginResp.fromJson(jsonDecode(resp.body)); LoginResp.fromJson(jsonDecode(resp.body));
SharedPreferences.getInstance().then((prefs) { print(loginResp.token);
return prefs.setString("token", loginResp.token); // Provider.of<Secret>(context).setToken(loginResp.token);
}).then((value) {
context.go("/"); context.go("/");
}); // SharedPreferences.getInstance().then((prefs) {
// prefs.setString("token", loginResp.token);
// });
// .then((value) {
// });
} }
}); });
} }

View File

@ -2,9 +2,13 @@ import 'dart:io';
import 'package:fluent_ui/fluent_ui.dart'; import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
// import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:momo/material/app.dart'; import 'package:momo/material/app.dart';
import 'package:momo/provider/token.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:window_manager/window_manager.dart'; import 'package:window_manager/window_manager.dart';
import 'package:tray_manager/tray_manager.dart'; // import 'package:tray_manager/tray_manager.dart';
void main() async { void main() async {
if (Platform.isLinux || Platform.isWindows || Platform.isMacOS) { if (Platform.isLinux || Platform.isWindows || Platform.isMacOS) {
@ -24,14 +28,38 @@ void main() async {
await windowManager.focus(); await windowManager.focus();
}); });
} }
runApp(const ProviderScope(child: MyApp())); final prefs = await SharedPreferences.getInstance();
String? tk = prefs.getString("token");
final container = ProviderContainer();
container.read(tokenProvider.notifier).setToken(tk);
runApp(
UncontrolledProviderScope(
container: container,
child: const MyApp(),
),
);
// runApp((child: MyApp(token: tk)));
// runApp(MultiProvider(
// providers: [
// ChangeNotifierProvider(
// create: (context) => Secret(),
// ),
// ],
// child: MyApp(
// token: tk,
// ),
// ));
} }
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
const MyApp({super.key}); const MyApp({super.key, this.token});
final String? token;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// Provider.of<Secret>(context, listen: false).setToken(token);
return const MyMaterialApp(); return const MyMaterialApp();
} }
} }

View File

@ -1,49 +1,62 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
// import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:momo/material/router.dart'; import 'package:momo/material/router.dart';
import 'package:momo/provider/token.dart'; import 'package:momo/provider/token.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:provider/provider.dart';
class MyMaterialApp extends ConsumerWidget { class MyMaterialApp extends ConsumerWidget {
const MyMaterialApp({Key? key}) : super(key: key); const MyMaterialApp({Key? key}) : super(key: key);
Future<String?> loadToken() async { Future<String?> loadToken() async {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
String? tk = await prefs.getString("token"); String? tk = prefs.getString("token");
return tk; return tk;
} }
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
return FutureBuilder( String? token = ref.watch(tokenProvider);
future: loadToken(),
builder: (BuildContext context, AsyncSnapshot<String?> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
String? token = snapshot.data;
if (token != null) {
// ref
// .watch(
// tokenProvider.notifier,
// )
// .setToken(token);
}
MyMaterialRouterConfig myMaterialRouterConfig = MyMaterialRouterConfig myMaterialRouterConfig =
MyMaterialRouterConfig(token); MyMaterialRouterConfig(token);
return MaterialApp.router( return MaterialApp.router(
routerConfig: myMaterialRouterConfig.router, routerConfig: myMaterialRouterConfig.router,
theme: ThemeData( debugShowCheckedModeBanner: false,
useMaterial3: true, scaffoldBackgroundColor: Colors.white), theme:
ThemeData(useMaterial3: true, scaffoldBackgroundColor: Colors.white),
); );
} else { // return FutureBuilder(
return MaterialApp( // future: loadToken(),
theme: ThemeData( // builder: (BuildContext context, AsyncSnapshot<String?> snapshot) {
useMaterial3: true, scaffoldBackgroundColor: Colors.white), // if (snapshot.connectionState == ConnectionState.done) {
home: const Center( // String? token = snapshot.data;
child: CircularProgressIndicator(), // if (token != null) {
), // // ref
); // // .watch(
} // // tokenProvider.notifier,
}); // // )
// // .setToken(token);
// }
// MyMaterialRouterConfig myMaterialRouterConfig =
// MyMaterialRouterConfig(token);
//
// return MaterialApp.router(
// routerConfig: myMaterialRouterConfig.router,
// theme: ThemeData(
// useMaterial3: true, scaffoldBackgroundColor: Colors.white),
// );
// } else {
// return MaterialApp(
// theme: ThemeData(
// useMaterial3: true, scaffoldBackgroundColor: Colors.white),
// home: const Center(
// child: CircularProgressIndicator(),
// ),
// );
// }
// });
} }
} }

View File

@ -1,8 +1,18 @@
import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:http/http.dart' as http;
import 'package:momo/models/image_list_resp.dart';
import 'package:momo/models/image_resp.dart';
import 'package:momo/provider/token.dart'; import 'package:momo/provider/token.dart';
// import 'package:flutter_riverpod/flutter_riverpod.dart';
// import 'package:go_router/go_router.dart';
// import 'package:momo/provider/token.dart';
// import 'package:provider/provider.dart';
class Gallery extends ConsumerStatefulWidget { class Gallery extends ConsumerStatefulWidget {
const Gallery({Key? key}) : super(key: key); const Gallery({Key? key}) : super(key: key);
@ -11,17 +21,47 @@ class Gallery extends ConsumerStatefulWidget {
} }
class _GalleryState extends ConsumerState<Gallery> { class _GalleryState extends ConsumerState<Gallery> {
Future<dynamic> loadImages(tk) async {
http.Response resp = await http.get(
Uri.parse("http://192.168.110.156:8080/image/history"),
headers: {"Authorization": tk});
return resp.body;
}
List<ImageResp> imageList = [];
@override
void dispose() {
// TODO: implement dispose
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
String token = ref.watch(tokenProvider); String? tk = ref.watch(tokenProvider);
print(token); if (tk != null) {
return Center( loadImages(tk).then((bd) {
child: ElevatedButton( if (mounted) {
onPressed: () { setState(() {
// ref.watch(tokenProvider.notifier).removeToken(); imageList = ImageListResp.fromJson(jsonDecode(bd)).list;
context.go("/login"); });
}
});
}
return GridView.builder(
itemCount: imageList.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: MediaQuery.of(context).size.width > 640 ? 5 : 3),
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: () {
context.go("/detail");
}, },
child: Text("exit")), child: Image.network(
"http://192.168.110.156:8080/image/thumbnail/${imageList[index].file_path}",
fit: BoxFit.cover,
),
); );
});
} }
} }

View File

@ -1,19 +1,32 @@
import 'package:dio/dio.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:momo/material/gallery.dart'; import 'package:http_parser/http_parser.dart';
import 'package:mime/mime.dart';
import 'package:momo/provider/token.dart';
class HomePage extends StatefulWidget { class HomePage extends ConsumerStatefulWidget {
const HomePage({Key? key}) : super(key: key); const HomePage({Key? key, required this.content}) : super(key: key);
final Widget content;
@override @override
State<HomePage> createState() => _HomePageState(); ConsumerState<HomePage> createState() => _HomePageState();
} }
class _HomePageState extends State<HomePage> { class _HomePageState extends ConsumerState<HomePage> {
int selectedIndex = 0; int selectedIndex = 0;
final tabList = [
{
"path": "/",
},
{"path": "/profile"}
];
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
String? token = ref.watch(tokenProvider);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text( title: const Text(
@ -22,6 +35,39 @@ class _HomePageState extends State<HomePage> {
), ),
elevation: 10, elevation: 10,
), ),
floatingActionButton: selectedIndex == 0
? FloatingActionButton(
onPressed: () async {
if (token == null) {
return;
}
FilePickerResult? result =
await FilePicker.platform.pickFiles(type: FileType.image);
if (result != null) {
String? filePath = result.files.first.path;
if (filePath == null) {
return;
}
Dio dio = Dio();
String? mimeType = lookupMimeType(filePath);
FormData data = FormData.fromMap({
"pic": await MultipartFile.fromFile(filePath,
filename: result.files.first.name,
contentType: MediaType(mimeType!.split("/").first,
mimeType.split("/").last))
});
Response resp = await dio.post(
"http://192.168.110.156:8080/image/upload",
data: data,
options: Options(headers: {"Authorization": token}));
} else {}
// context.go("/login");
},
child: const Icon(Icons.add),
)
: null,
body: Row( body: Row(
children: [ children: [
MediaQuery.of(context).size.width > 640 MediaQuery.of(context).size.width > 640
@ -39,6 +85,7 @@ class _HomePageState extends State<HomePage> {
setState(() { setState(() {
selectedIndex = idx; selectedIndex = idx;
}); });
context.go(tabList[idx]["path"] ?? "");
}, },
destinations: const [ destinations: const [
NavigationRailDestination( NavigationRailDestination(
@ -51,7 +98,7 @@ class _HomePageState extends State<HomePage> {
: const SizedBox( : const SizedBox(
width: 0, width: 0,
), ),
Expanded(child: pageList[selectedIndex]) Expanded(child: widget.content)
], ],
), ),
bottomNavigationBar: MediaQuery.of(context).size.width <= 640 bottomNavigationBar: MediaQuery.of(context).size.width <= 640
@ -72,10 +119,3 @@ class _HomePageState extends State<HomePage> {
); );
} }
} }
List<Widget> pageList = [
Gallery(),
Scaffold(
body: Placeholder(),
)
];

View File

@ -3,10 +3,13 @@ import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
// import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:momo/models/login_resp.dart'; import 'package:momo/models/login_resp.dart';
import 'package:momo/provider/token.dart'; import 'package:momo/provider/token.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
class LoginPage extends StatelessWidget { class LoginPage extends StatelessWidget {
@ -75,24 +78,24 @@ class _LoginFormState extends ConsumerState<LoginForm> {
onPressed: () async { onPressed: () async {
if (usernameController.text.isNotEmpty && if (usernameController.text.isNotEmpty &&
passwordController.text.isNotEmpty) { passwordController.text.isNotEmpty) {
http.Response resp = await http.post( http
Uri.parse("http://localhost:8080/user/login"), .post(Uri.parse("http://192.168.110.156:8080/user/login"),
headers: {"Content-Type": "application/json"}, headers: {"Content-Type": "application/json"},
body: jsonEncode({ body: jsonEncode({
"username": usernameController.text, "username": usernameController.text,
"password": passwordController.text "password": passwordController.text
})); }))
.then((resp) {
if (resp.statusCode == HttpStatus.ok) { if (resp.statusCode == HttpStatus.ok) {
LoginResp loginResp = LoginResp loginResp =
LoginResp.fromJson(jsonDecode(resp.body)); LoginResp.fromJson(jsonDecode(resp.body));
SharedPreferences prefs = ref.watch(tokenProvider.notifier).setToken(loginResp.token);
await SharedPreferences.getInstance(); // context.go("/");
// ref.watch(tokenProvider.notifier).setToken(loginResp.token); // });
prefs.setString("token", loginResp.token).then((value) {
context.go("/");
});
} }
}).catchError((err) {
print(err.toString());
});
} }
}), }),
], ],

18
lib/material/profile.dart Normal file
View File

@ -0,0 +1,18 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:momo/provider/token.dart';
class Profile extends ConsumerWidget {
const Profile({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
return Center(
child: ElevatedButton(
onPressed: () {
ref.watch(tokenProvider.notifier).removeToken();
},
child: const Text('quit')),
);
}
}

View File

@ -1,7 +1,9 @@
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:momo/material/gallery.dart';
import 'package:momo/material/home.dart'; import 'package:momo/material/home.dart';
import 'package:momo/material/login.dart'; import 'package:momo/material/login.dart';
import 'package:momo/material/profile.dart';
class MyMaterialRouterConfig { class MyMaterialRouterConfig {
late GoRouter router; late GoRouter router;
@ -9,23 +11,65 @@ class MyMaterialRouterConfig {
MyMaterialRouterConfig(String? token) { MyMaterialRouterConfig(String? token) {
router = GoRouter( router = GoRouter(
routes: <RouteBase>[ routes: <RouteBase>[
GoRoute( ShellRoute(
path: '/', builder: (BuildContext context, GoRouterState state, Widget child) {
builder: (BuildContext context, GoRouterState state) { return HomePage(
return const HomePage(); content: child,
);
}, },
routes: [
GoRoute(
path: "/",
pageBuilder: (BuildContext context, GoRouterState state) =>
const NoTransitionPage(child: Gallery()),
redirect: (BuildContext context, GoRouterState state) { redirect: (BuildContext context, GoRouterState state) {
if (token == null || token.isEmpty) { if (token == null || token.isEmpty) {
return '/login'; return '/login';
} }
return null; return null;
}), }),
GoRoute(
path: "/profile",
pageBuilder: (BuildContext context, GoRouterState state) =>
const NoTransitionPage(child: Profile())),
GoRoute(
path: "/detail",
pageBuilder: (BuildContext context, GoRouterState state) =>
const NoTransitionPage(
child: Center(
child: Text("detail"),
)))
],
),
GoRoute( GoRoute(
path: "/login", path: "/login",
builder: (BuildContext context, GoRouterState state) { builder: (BuildContext context, GoRouterState state) {
return const LoginPage(); return const LoginPage();
}, },
) redirect: (BuildContext context, GoRouterState state) {
if (token != null && token.isNotEmpty) {
return '/';
}
return null;
}),
// ShellRoute(
// builder: (BuildContext context, GoRouterState state, Widget child) {
// return Scaffold(
// appBar: AppBar(
// title: Text("nest"),
// ),
// body: child,
// );
// },
// routes: [
// GoRoute(
// path: '/',
// builder: (BuildContext context, GoRouterState state) {
// return Center(
// child: Text("login"),
// );
// })
// ]),
], ],
); );
} }

View File

@ -0,0 +1,17 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:momo/models/image_resp.dart';
part 'image_list_resp.g.dart';
@JsonSerializable()
class ImageListResp {
List<ImageResp> list;
int total;
ImageListResp(this.list, this.total);
factory ImageListResp.fromJson(Map<String, dynamic> json) =>
_$ImageListRespFromJson(json);
Map<String, dynamic> toJson() => _$ImageListRespToJson(this);
}

View File

@ -0,0 +1,21 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'image_list_resp.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ImageListResp _$ImageListRespFromJson(Map<String, dynamic> json) =>
ImageListResp(
(json['list'] as List<dynamic>)
.map((e) => ImageResp.fromJson(e as Map<String, dynamic>))
.toList(),
json['total'] as int,
);
Map<String, dynamic> _$ImageListRespToJson(ImageListResp instance) =>
<String, dynamic>{
'list': instance.list,
'total': instance.total,
};

View File

@ -0,0 +1,30 @@
import 'dart:ffi';
import 'package:json_annotation/json_annotation.dart';
part 'image_resp.g.dart';
@JsonSerializable()
class ImageResp {
int id;
String file_name;
String file_path;
int upload_time;
int size;
int width;
int height;
ImageResp(this.id, this.file_name, this.file_path, this.upload_time,
this.size, this.width, this.height);
/// A necessary factory constructor for creating a new Configs instance
/// from a map. Pass the map to the generated `_$ConfigsFromJson()` constructor.
/// The constructor is named after the source class, in this case, Configs.
factory ImageResp.fromJson(Map<String, dynamic> json) =>
_$ImageRespFromJson(json);
/// `toJson` is the convention for a class to declare support for serialization
/// to JSON. The implementation simply calls the private, generated
/// helper method `_$ImageRespToJson`.
Map<String, dynamic> toJson() => _$ImageRespToJson(this);
}

View File

@ -0,0 +1,27 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'image_resp.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ImageResp _$ImageRespFromJson(Map<String, dynamic> json) => ImageResp(
json['id'] as int,
json['file_name'] as String,
json['file_path'] as String,
json['upload_time'] as int,
json['size'] as int,
json['width'] as int,
json['height'] as int,
);
Map<String, dynamic> _$ImageRespToJson(ImageResp instance) => <String, dynamic>{
'id': instance.id,
'file_name': instance.file_name,
'file_path': instance.file_path,
'upload_time': instance.upload_time,
'size': instance.size,
'width': instance.width,
'height': instance.height,
};

View File

@ -1,16 +1,16 @@
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
class TokenNotifier extends Notifier<String> { class TokenNotifier extends Notifier<String?> {
@override @override
String build() { String? build() {
return ""; return "";
} }
setToken(String token) { setToken(String? token) {
state = token; state = token;
SharedPreferences.getInstance().then((prefs) { SharedPreferences.getInstance().then((prefs) {
prefs.setString("token", token); prefs.setString("token", token ?? "");
}); });
} }
@ -23,4 +23,28 @@ class TokenNotifier extends Notifier<String> {
} }
final tokenProvider = final tokenProvider =
NotifierProvider<TokenNotifier, String>(() => TokenNotifier()); NotifierProvider<TokenNotifier, String?>(() => TokenNotifier());
// import 'package:fluent_ui/fluent_ui.dart';
// import 'package:fluent_ui/fluent_ui.dart';
// import 'package:shared_preferences/shared_preferences.dart';
//
// class Secret extends ChangeNotifier {
// String? token;
//
// void setToken(String? data) {
// token = data;
// SharedPreferences.getInstance().then((prefs) {
// prefs.setString("token", data ?? "");
// });
// // notifyListeners();
// // notifyListeners();
// }
//
// void removeToken() {
// token = "";
// SharedPreferences.getInstance().then((prefs) {
// prefs.setString("token", "");
// });
// }
// }

View File

@ -201,6 +201,14 @@ packages:
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted source: hosted
version: "2.2.4" version: "2.2.4"
dio:
dependency: "direct main"
description:
name: dio
sha256: "7d328c4d898a61efc3cd93655a0955858e29a0aa647f0f9e02d59b3bb275e2e8"
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "4.0.6"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@ -225,6 +233,14 @@ packages:
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted source: hosted
version: "6.1.4" version: "6.1.4"
file_picker:
dependency: "direct main"
description:
name: file_picker
sha256: d090ae03df98b0247b82e5928f44d1b959867049d18d73635e2e0bc3f49542b9
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "5.2.5"
fixnum: fixnum:
dependency: transitive dependency: transitive
description: description:
@ -275,6 +291,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: "60fc7b78455b94e6de2333d2f95196d32cf5c22f4b0b0520a628804cb463503b"
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "2.0.7"
flutter_riverpod: flutter_riverpod:
dependency: "direct main" dependency: "direct main"
description: description:
@ -350,7 +374,7 @@ packages:
source: hosted source: hosted
version: "3.2.1" version: "3.2.1"
http_parser: http_parser:
dependency: transitive dependency: "direct main"
description: description:
name: http_parser name: http_parser
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
@ -454,7 +478,7 @@ packages:
source: hosted source: hosted
version: "1.8.0" version: "1.8.0"
mime: mime:
dependency: transitive dependency: "direct main"
description: description:
name: mime name: mime
sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e
@ -469,6 +493,14 @@ packages:
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted source: hosted
version: "3.7.0" version: "3.7.0"
nested:
dependency: transitive
description:
name: nested
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "1.0.0"
package_config: package_config:
dependency: transitive dependency: transitive
description: description:
@ -557,6 +589,14 @@ packages:
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted source: hosted
version: "4.2.4" version: "4.2.4"
provider:
dependency: "direct main"
description:
name: provider
sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "6.0.5"
pub_semver: pub_semver:
dependency: transitive dependency: transitive
description: description:

View File

@ -46,6 +46,11 @@ dependencies:
flutter_riverpod: ^2.1.3 flutter_riverpod: ^2.1.3
window_manager: ^0.3.0 window_manager: ^0.3.0
tray_manager: ^0.2.0 tray_manager: ^0.2.0
provider: ^6.0.5
file_picker: ^5.2.5
dio: ^4.0.6
http_parser: ^4.0.2
mime: ^1.0.4
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: