第一次提交
This commit is contained in:
37
lib/routes/about.dart
Normal file
37
lib/routes/about.dart
Normal file
@@ -0,0 +1,37 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
|
||||
import '../../src/version.dart';
|
||||
import '../../config.dart';
|
||||
|
||||
class AboutPage extends HookWidget {
|
||||
const AboutPage({super.key});
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('关于')),
|
||||
body: ListView(
|
||||
children: [
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset('images/favicon.png', width: 120, height: 120).clipOval(),
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
'拾糖论坛',
|
||||
style: TextStyle(fontWeight: FontWeight.w600, fontSize: 24),
|
||||
),
|
||||
],
|
||||
).constrained(height: 200, width: double.infinity),
|
||||
const Divider(height: 16),
|
||||
ListTile(
|
||||
title: const Text('App 版本'),
|
||||
subtitle: Text('v${packageVersion}'),
|
||||
),
|
||||
],
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
120
lib/routes/root.dart
Normal file
120
lib/routes/root.dart
Normal file
@@ -0,0 +1,120 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
import '../config.dart';
|
||||
import '../demo.dart';
|
||||
import './root_pages/home.dart';
|
||||
import './root_pages/me.dart';
|
||||
import '../models/class_destination_item.dart';
|
||||
|
||||
const destinations = [
|
||||
DestinationItem(
|
||||
label: '首页',
|
||||
icon: Icons.home,
|
||||
child: HomePage(),
|
||||
title: '拾糖',
|
||||
),
|
||||
// DestinationItem(
|
||||
// label: '展示',
|
||||
// icon: Icons.message,
|
||||
// child: AllWidgetsDemo(),
|
||||
// title: '组件演示',
|
||||
// ),
|
||||
DestinationItem(
|
||||
label: '我的',
|
||||
icon: Icons.person,
|
||||
child: MePage(),
|
||||
),
|
||||
];
|
||||
|
||||
class RootRoute extends HookConsumerWidget {
|
||||
const RootRoute({super.key});
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final index = useState(0);
|
||||
final controller = usePageController();
|
||||
final jumping = useState(false);
|
||||
|
||||
useEffect(() {
|
||||
if (!jumping.value) return null;
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
if (controller.hasClients) {
|
||||
await controller.animateToPage(
|
||||
index.value,
|
||||
duration: AppAnimationConfig.duration,
|
||||
curve: AppAnimationConfig.pageViewCurve,
|
||||
);
|
||||
jumping.value = false;
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}, [index.value, jumping.value]);
|
||||
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final isWide = constraints.maxWidth >= AppConfig.wideWidth;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(destinations[index.value].title ?? destinations[index.value].label),
|
||||
),
|
||||
body: Row(
|
||||
children: [
|
||||
if (isWide)
|
||||
NavigationRail(
|
||||
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||
selectedIndex: index.value,
|
||||
onDestinationSelected: (i) {
|
||||
if (i != index.value) {
|
||||
index.value = i;
|
||||
jumping.value = true;
|
||||
}
|
||||
},
|
||||
labelType: NavigationRailLabelType.all,
|
||||
destinations: destinations.map((d) {
|
||||
return NavigationRailDestination(
|
||||
icon: Icon(d.icon),
|
||||
label: Text(d.label),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
// 内容区域
|
||||
Expanded(
|
||||
child: PageView(
|
||||
controller: controller,
|
||||
onPageChanged: (i) {
|
||||
if (!jumping.value) {
|
||||
index.value = i;
|
||||
}
|
||||
},
|
||||
children: <Widget>[
|
||||
for (final d in destinations) d.child,
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
bottomNavigationBar: isWide
|
||||
? null
|
||||
: NavigationBar(
|
||||
selectedIndex: index.value,
|
||||
onDestinationSelected: (i) {
|
||||
if (i != index.value) {
|
||||
index.value = i;
|
||||
jumping.value = true;
|
||||
}
|
||||
},
|
||||
destinations: destinations.map((d) {
|
||||
return NavigationDestination(
|
||||
icon: Icon(d.icon),
|
||||
label: d.label,
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
40
lib/routes/root_pages/home.dart
Normal file
40
lib/routes/root_pages/home.dart
Normal file
@@ -0,0 +1,40 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import '../../providers/api.dart';
|
||||
import '../../api/capatcha.dart';
|
||||
|
||||
class HomePage extends HookConsumerWidget {
|
||||
const HomePage({super.key});
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final cookies = ref.watch(cookieHeaderProvider);
|
||||
|
||||
final future = useMemoized(() async {
|
||||
final client = ref.read(apiClientProvider);
|
||||
final res = await client.get('');
|
||||
return res.bodyBytes;
|
||||
}, []);
|
||||
final snapshot = useFuture(future);
|
||||
|
||||
return ListView(
|
||||
padding: EdgeInsets.all(16),
|
||||
children:[
|
||||
// if (snapshot.hasData) Text('${utf8.decode(snapshot.data!)}'),
|
||||
const Text('HTTP API Client 状态:'),
|
||||
const Gap(16),
|
||||
Text('Cookies: ${cookies}'),
|
||||
if (snapshot.hasData) ...[
|
||||
const Gap(16),
|
||||
Text('${utf8.decode(snapshot.data!)}')
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
41
lib/routes/root_pages/me.dart
Normal file
41
lib/routes/root_pages/me.dart
Normal file
@@ -0,0 +1,41 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class MePage extends HookConsumerWidget {
|
||||
const MePage({super.key});
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return ListView(
|
||||
children: [
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset('images/test.png', width: 120, height: 120).clipOval(),
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
'UnknownMp',
|
||||
style: TextStyle(fontWeight: FontWeight.w600, fontSize: 24),
|
||||
),
|
||||
],
|
||||
).constrained(height: 320, width: double.infinity),
|
||||
const Divider(height: 16),
|
||||
Column(
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () => context.push('/settings'),
|
||||
child: ListTile(
|
||||
leading: const Icon(Icons.settings),
|
||||
title: const Text('设置'),
|
||||
trailing: const Icon(Icons.arrow_forward),
|
||||
),
|
||||
),
|
||||
]
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
40
lib/routes/settings.dart
Normal file
40
lib/routes/settings.dart
Normal file
@@ -0,0 +1,40 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
|
||||
import '../config.dart';
|
||||
|
||||
class SettingsPage extends HookConsumerWidget {
|
||||
const SettingsPage({super.key});
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('设置')),
|
||||
body: ListView(
|
||||
children: [
|
||||
const Gap(8),
|
||||
InkWell(
|
||||
onTap: () => context.push('/settings/theme'),
|
||||
child: ListTile(
|
||||
leading: const Icon(Icons.palette),
|
||||
title: const Text('外观'),
|
||||
// subtitle: const Text('亮 / 暗模式, 动态取色?'),
|
||||
),
|
||||
),
|
||||
const Divider(height: 16),
|
||||
InkWell(
|
||||
onTap: () => context.push('/about'),
|
||||
child: ListTile(
|
||||
leading: const Icon(Icons.info),
|
||||
title: const Text('关于'),
|
||||
subtitle: Text('拾糖论坛'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
44
lib/routes/settings/theme.dart
Normal file
44
lib/routes/settings/theme.dart
Normal file
@@ -0,0 +1,44 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
|
||||
import '../../config.dart';
|
||||
import '../../providers/theme.dart';
|
||||
import '../../models/enum_theme.dart';
|
||||
|
||||
class SettingsThemePage extends HookConsumerWidget {
|
||||
const SettingsThemePage({super.key});
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('外观')),
|
||||
body: ListView(
|
||||
children: [
|
||||
const Gap(16),
|
||||
ListTile(
|
||||
title: const Text('配色方案'),
|
||||
trailing: DropdownMenu<ThemeModeType>(
|
||||
initialSelection: ref.watch(themeModeProvider),
|
||||
onSelected: (value) { if (value != null) ref.read(themeModeProvider.notifier).set(value); },
|
||||
dropdownMenuEntries: const [
|
||||
DropdownMenuEntry(value: ThemeModeType.system, label: '跟随系统'),
|
||||
DropdownMenuEntry(value: ThemeModeType.light, label: '亮色'),
|
||||
DropdownMenuEntry(value: ThemeModeType.dark, label: '暗色'),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Gap(16),
|
||||
SwitchListTile(
|
||||
title: Text('动态配色'),
|
||||
value: ref.watch(useDynamicColorProvider),
|
||||
onChanged: (value) { ref.read(useDynamicColorProvider.notifier).set(value); },
|
||||
),
|
||||
//const Divider(height: 16),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user