settings page

This commit is contained in:
nyne
2024-10-11 21:47:50 +08:00
parent f228c7ee17
commit a26e5e20de
21 changed files with 1515 additions and 26 deletions

219
lib/pages/settings/app.dart Normal file
View File

@@ -0,0 +1,219 @@
part of 'settings_page.dart';
class AppSettings extends StatefulWidget {
const AppSettings({super.key});
@override
State<AppSettings> createState() => _AppSettingsState();
}
class _AppSettingsState extends State<AppSettings> {
@override
Widget build(BuildContext context) {
return SmoothCustomScrollView(
slivers: [
SliverAppbar(title: Text("App".tl)),
_SettingPartTitle(
title: "Data".tl,
icon: Icons.storage,
),
ListTile(
title: Text("Storage Path for local comics".tl),
subtitle: Text(LocalManager().path, softWrap: false),
).toSliver(),
_CallbackSetting(
title: "Set New Storage Path".tl,
actionTitle: "Set".tl,
callback: () async {
var picker = FilePicker.platform;
var result = await picker.getDirectoryPath();
if (result == null) return;
var loadingDialog = showLoadingDialog(
App.rootContext,
barrierDismissible: false,
allowCancel: false,
);
var res = await LocalManager().setNewPath(result);
loadingDialog.close();
if (res != null) {
context.showMessage(message: res);
} else {
context.showMessage(message: "Path set successfully".tl);
setState(() {});
}
},
).toSliver(),
ListTile(
title: Text("Cache Size".tl),
subtitle: Text(bytesToReadableString(CacheManager().currentSize)),
).toSliver(),
_CallbackSetting(
title: "Clear Cache".tl,
actionTitle: "Clear".tl,
callback: () async {
var loadingDialog = showLoadingDialog(
App.rootContext,
barrierDismissible: false,
allowCancel: false,
);
await CacheManager().clear();
loadingDialog.close();
context.showMessage(message: "Cache cleared".tl);
setState(() {});
},
).toSliver(),
_SettingPartTitle(
title: "Log".tl,
icon: Icons.error_outline,
),
_CallbackSetting(
title: "Open Log".tl,
callback: () {
context.to(() => const LogsPage());
},
actionTitle: 'Open'.tl,
).toSliver(),
_SettingPartTitle(
title: "User".tl,
icon: Icons.person_outline,
),
SelectSetting(
title: "Language".tl,
settingKey: "language",
optionTranslation: const {
"system": "System",
"zh-CN": "简体中文",
"zh-TW": "繁體中文",
"en-US": "English",
},
onChanged: () {
App.forceRebuild();
},
).toSliver(),
],
);
}
}
class LogsPage extends StatefulWidget {
const LogsPage({super.key});
@override
State<LogsPage> createState() => _LogsPageState();
}
class _LogsPageState extends State<LogsPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: Appbar(
title: const Text("Logs"),
actions: [
IconButton(
onPressed: () => setState(() {
final RelativeRect position = RelativeRect.fromLTRB(
MediaQuery.of(context).size.width,
MediaQuery.of(context).padding.top + kToolbarHeight,
0.0,
0.0,
);
showMenu(context: context, position: position, items: [
PopupMenuItem(
child: Text("Clear".tl),
onTap: () => setState(() => Log.clear()),
),
PopupMenuItem(
child: Text("Disable Length Limitation".tl),
onTap: () {
Log.ignoreLimitation = true;
context.showMessage(
message: "Only valid for this run");
},
),
PopupMenuItem(
child: Text("Export".tl),
onTap: () => saveLog(Log().toString()),
),
]);
}),
icon: const Icon(Icons.more_horiz))
],
),
body: ListView.builder(
reverse: true,
controller: ScrollController(),
itemCount: Log.logs.length,
itemBuilder: (context, index) {
index = Log.logs.length - index - 1;
return Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 8),
child: SelectionArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
decoration: BoxDecoration(
color: Theme.of(context)
.colorScheme
.surfaceContainerHighest,
borderRadius:
const BorderRadius.all(Radius.circular(16)),
),
child: Padding(
padding: const EdgeInsets.fromLTRB(5, 0, 5, 1),
child: Text(Log.logs[index].title),
),
),
const SizedBox(
width: 3,
),
Container(
decoration: BoxDecoration(
color: [
Theme.of(context).colorScheme.error,
Theme.of(context).colorScheme.errorContainer,
Theme.of(context).colorScheme.primaryContainer
][Log.logs[index].level.index],
borderRadius:
const BorderRadius.all(Radius.circular(16)),
),
child: Padding(
padding: const EdgeInsets.fromLTRB(5, 0, 5, 1),
child: Text(
Log.logs[index].level.name,
style: TextStyle(
color: Log.logs[index].level.index == 0
? Colors.white
: Colors.black),
),
),
),
],
),
Text(Log.logs[index].content),
Text(Log.logs[index].time
.toString()
.replaceAll(RegExp(r"\.\w+"), "")),
TextButton(
onPressed: () {
Clipboard.setData(
ClipboardData(text: Log.logs[index].content));
},
child: Text("Copy".tl),
),
const Divider(),
],
),
),
);
},
),
);
}
void saveLog(String log) async {
saveFile(data: utf8.encode(log), filename: 'log.txt');
}
}