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

@ -1,49 +1,62 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
// import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:momo/material/router.dart';
import 'package:momo/provider/token.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:provider/provider.dart';
class MyMaterialApp extends ConsumerWidget {
const MyMaterialApp({Key? key}) : super(key: key);
Future<String?> loadToken() async {
final prefs = await SharedPreferences.getInstance();
String? tk = await prefs.getString("token");
String? tk = prefs.getString("token");
return tk;
}
@override
Widget build(BuildContext context, WidgetRef ref) {
return FutureBuilder(
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(token);
String? token = ref.watch(tokenProvider);
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(),
),
);
}
});
return MaterialApp.router(
routerConfig: myMaterialRouterConfig.router,
debugShowCheckedModeBanner: false,
theme:
ThemeData(useMaterial3: true, scaffoldBackgroundColor: Colors.white),
);
// return FutureBuilder(
// 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(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_riverpod/flutter_riverpod.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: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 {
const Gallery({Key? key}) : super(key: key);
@ -11,17 +21,47 @@ class Gallery extends ConsumerStatefulWidget {
}
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
Widget build(BuildContext context) {
String token = ref.watch(tokenProvider);
print(token);
return Center(
child: ElevatedButton(
onPressed: () {
// ref.watch(tokenProvider.notifier).removeToken();
context.go("/login");
},
child: Text("exit")),
);
String? tk = ref.watch(tokenProvider);
if (tk != null) {
loadImages(tk).then((bd) {
if (mounted) {
setState(() {
imageList = ImageListResp.fromJson(jsonDecode(bd)).list;
});
}
});
}
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: 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_riverpod/flutter_riverpod.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 {
const HomePage({Key? key}) : super(key: key);
class HomePage extends ConsumerStatefulWidget {
const HomePage({Key? key, required this.content}) : super(key: key);
final Widget content;
@override
State<HomePage> createState() => _HomePageState();
ConsumerState<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
class _HomePageState extends ConsumerState<HomePage> {
int selectedIndex = 0;
final tabList = [
{
"path": "/",
},
{"path": "/profile"}
];
@override
Widget build(BuildContext context) {
String? token = ref.watch(tokenProvider);
return Scaffold(
appBar: AppBar(
title: const Text(
@ -22,6 +35,39 @@ class _HomePageState extends State<HomePage> {
),
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(
children: [
MediaQuery.of(context).size.width > 640
@ -39,6 +85,7 @@ class _HomePageState extends State<HomePage> {
setState(() {
selectedIndex = idx;
});
context.go(tabList[idx]["path"] ?? "");
},
destinations: const [
NavigationRailDestination(
@ -51,7 +98,7 @@ class _HomePageState extends State<HomePage> {
: const SizedBox(
width: 0,
),
Expanded(child: pageList[selectedIndex])
Expanded(child: widget.content)
],
),
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_riverpod/flutter_riverpod.dart';
// import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:http/http.dart' as http;
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';
class LoginPage extends StatelessWidget {
@ -75,24 +78,24 @@ class _LoginFormState extends ConsumerState<LoginForm> {
onPressed: () async {
if (usernameController.text.isNotEmpty &&
passwordController.text.isNotEmpty) {
http.Response resp = await http.post(
Uri.parse("http://localhost:8080/user/login"),
headers: {"Content-Type": "application/json"},
body: jsonEncode({
"username": usernameController.text,
"password": passwordController.text
}));
if (resp.statusCode == HttpStatus.ok) {
LoginResp loginResp =
LoginResp.fromJson(jsonDecode(resp.body));
SharedPreferences prefs =
await SharedPreferences.getInstance();
// ref.watch(tokenProvider.notifier).setToken(loginResp.token);
prefs.setString("token", loginResp.token).then((value) {
context.go("/");
});
}
http
.post(Uri.parse("http://192.168.110.156:8080/user/login"),
headers: {"Content-Type": "application/json"},
body: jsonEncode({
"username": usernameController.text,
"password": passwordController.text
}))
.then((resp) {
if (resp.statusCode == HttpStatus.ok) {
LoginResp loginResp =
LoginResp.fromJson(jsonDecode(resp.body));
ref.watch(tokenProvider.notifier).setToken(loginResp.token);
// 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:go_router/go_router.dart';
import 'package:momo/material/gallery.dart';
import 'package:momo/material/home.dart';
import 'package:momo/material/login.dart';
import 'package:momo/material/profile.dart';
class MyMaterialRouterConfig {
late GoRouter router;
@ -9,23 +11,65 @@ class MyMaterialRouterConfig {
MyMaterialRouterConfig(String? token) {
router = GoRouter(
routes: <RouteBase>[
ShellRoute(
builder: (BuildContext context, GoRouterState state, Widget child) {
return HomePage(
content: child,
);
},
routes: [
GoRoute(
path: "/",
pageBuilder: (BuildContext context, GoRouterState state) =>
const NoTransitionPage(child: Gallery()),
redirect: (BuildContext context, GoRouterState state) {
if (token == null || token.isEmpty) {
return '/login';
}
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(
path: '/',
path: "/login",
builder: (BuildContext context, GoRouterState state) {
return const HomePage();
return const LoginPage();
},
redirect: (BuildContext context, GoRouterState state) {
if (token == null || token.isEmpty) {
return '/login';
if (token != null && token.isNotEmpty) {
return '/';
}
return null;
}),
GoRoute(
path: "/login",
builder: (BuildContext context, GoRouterState state) {
return const LoginPage();
},
)
// 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"),
// );
// })
// ]),
],
);
}