Skip to content

Commit

Permalink
Merge branch 'main' into feat-macos-control-button
Browse files Browse the repository at this point in the history
  • Loading branch information
ErBWs committed Feb 1, 2025
2 parents 60af1a0 + f7d34bf commit a52f260
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 83 deletions.
87 changes: 68 additions & 19 deletions lib/bean/appbar/sys_app_bar.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import 'dart:io';
import 'package:kazumi/bean/dialog/dialog_helper.dart';
import 'package:kazumi/utils/utils.dart';

import 'package:flutter/material.dart';
import 'package:window_manager/window_manager.dart';
import 'package:flutter/services.dart';
import 'package:kazumi/bean/dialog/dialog_helper.dart';
import 'package:kazumi/utils/storage.dart';
import 'package:kazumi/utils/utils.dart';
import 'package:window_manager/window_manager.dart';

class SysAppBar extends StatelessWidget implements PreferredSizeWidget {
final double? toolbarHeight;
Expand Down Expand Up @@ -41,22 +42,70 @@ class SysAppBar extends StatelessWidget implements PreferredSizeWidget {
this.needTopOffset = true});

void _handleCloseEvent() {
KazumiDialog.show(builder: (context) {
return AlertDialog(
title: const Text('退出确认'),
content: const Text('您想要退出 Kazumi 吗?'),
actions: [
TextButton(onPressed: () => exit(0), child: const Text('退出 Kazumi')),
TextButton(
onPressed: () {
KazumiDialog.dismiss();
windowManager.hide();
},
child: const Text('最小化至托盘')),
const TextButton(onPressed: KazumiDialog.dismiss, child: Text('取消')),
],
);
});
final setting = GStorage.setting;
final exitBehavior =
setting.get(SettingBoxKey.exitBehavior, defaultValue: 2);

switch (exitBehavior) {
case 0:
exit(0);
case 1:
KazumiDialog.dismiss();
windowManager.hide();
break;
default:
KazumiDialog.show(builder: (context) {
bool saveExitBehavior = false; // 下次不再询问?

return AlertDialog(
title: const Text('退出确认'),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Text('您想要退出 Kazumi 吗?'),
const SizedBox(height: 24),
StatefulBuilder(builder: (context, setState) {
onChanged(value) {
saveExitBehavior = value ?? false;
setState(() {});
}

return Wrap(
crossAxisAlignment: WrapCrossAlignment.center,
spacing: 8,
children: [
Checkbox(value: saveExitBehavior, onChanged: onChanged),
const Text('下次不再询问'),
],
);
}),
],
),
actions: [
TextButton(
onPressed: () async {
if (saveExitBehavior) {
await setting.put(SettingBoxKey.exitBehavior, 0);
}
exit(0);
},
child: const Text('退出 Kazumi')),
TextButton(
onPressed: () async {
if (saveExitBehavior) {
await setting.put(SettingBoxKey.exitBehavior, 1);
}
KazumiDialog.dismiss();
windowManager.hide();
},
child: const Text('最小化至托盘')),
const TextButton(
onPressed: KazumiDialog.dismiss, child: Text('取消')),
],
);
});
}
}

bool showWindowButton() {
Expand Down
70 changes: 58 additions & 12 deletions lib/pages/about/about_page.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import 'dart:io';

import 'package:card_settings_ui/card_settings_ui.dart';
import 'package:flutter/material.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'package:hive/hive.dart';
import 'package:kazumi/pages/my/my_controller.dart';
import 'package:kazumi/request/api.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:kazumi/bean/appbar/sys_app_bar.dart';
import 'package:path_provider/path_provider.dart';
import 'package:kazumi/bean/dialog/dialog_helper.dart';
import 'package:card_settings_ui/card_settings_ui.dart';
import 'package:kazumi/utils/storage.dart';
import 'package:kazumi/pages/my/my_controller.dart';
import 'package:kazumi/request/api.dart';
import 'package:kazumi/utils/mortis.dart';
import 'package:kazumi/utils/storage.dart';
import 'package:kazumi/utils/utils.dart';
import 'package:path_provider/path_provider.dart';
import 'package:url_launcher/url_launcher.dart';

class AboutPage extends StatefulWidget {
const AboutPage({super.key});
Expand All @@ -20,19 +22,22 @@ class AboutPage extends StatefulWidget {
}

class _AboutPageState extends State<AboutPage> {
final exitBehaviorTitles = <String>['退出 Kazumi', '最小化至托盘', '每次都询问'];

late dynamic defaultDanmakuArea;
late dynamic defaultThemeMode;
late dynamic defaultThemeColor;
Box setting = GStorage.setting;
late int exitBehavior =
setting.get(SettingBoxKey.exitBehavior, defaultValue: 2);
late bool autoUpdate;
double _cacheSizeMB = -1;
final MyController myController = Modular.get<MyController>();

@override
void initState() {
super.initState();
autoUpdate =
setting.get(SettingBoxKey.autoUpdate, defaultValue: true);
autoUpdate = setting.get(SettingBoxKey.autoUpdate, defaultValue: true);
_getCacheSize();
}

Expand Down Expand Up @@ -142,7 +147,9 @@ class _AboutPageState extends State<AboutPage> {
},
title: const Text('开源许可证'),
description: const Text('查看所有开源许可证'),
),],),
),
],
),
SettingsSection(
title: const Text('外部链接'),
tiles: [
Expand Down Expand Up @@ -178,15 +185,52 @@ class _AboutPageState extends State<AboutPage> {
title: const Text('弹幕来源'),
description: Text('ID: ${mortis['id']}'),
value: const Text('DanDanPlay'),
),],),
),
],
),
if (Utils.isDesktop()) // 之后如果有非桌面平台的新选项可以移除
SettingsSection(
title: const Text('默认行为'),
tiles: [
// if (Utils.isDesktop())
SettingsTile.navigation(
title: const Text('关闭时'),
value: Text(exitBehaviorTitles[exitBehavior]),
onPressed: (_) {
KazumiDialog.show(builder: (context) {
return SimpleDialog(
title: const Text('关闭时'),
children: [
for (int i = 0; i < 3; i++)
RadioListTile(
value: i,
groupValue: exitBehavior,
onChanged: (int? value) {
exitBehavior = value ?? 2;
setting.put(
SettingBoxKey.exitBehavior, value);
KazumiDialog.dismiss();
setState(() {});
},
title: Text(exitBehaviorTitles[i]),
),
],
);
});
},
),
],
),
SettingsSection(
tiles: [
SettingsTile.navigation(
onPressed: (_) {
Modular.to.pushNamed('/settings/about/logs');
},
title: const Text('错误日志'),
),],),
),
],
),
SettingsSection(
tiles: [
SettingsTile.navigation(
Expand All @@ -197,7 +241,9 @@ class _AboutPageState extends State<AboutPage> {
value: _cacheSizeMB == -1
? const Text('统计中...')
: Text('${_cacheSizeMB.toStringAsFixed(2)}MB'),
),],),
),
],
),
SettingsSection(
title: const Text('应用更新'),
tiles: [
Expand Down
2 changes: 1 addition & 1 deletion lib/pages/my/my_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import 'package:card_settings_ui/card_settings_ui.dart';
import 'package:flutter/material.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'package:kazumi/bean/appbar/sys_app_bar.dart';
import 'package:provider/provider.dart';
import 'package:kazumi/pages/menu/menu.dart';
import 'package:kazumi/pages/menu/side_menu.dart';
import 'package:kazumi/utils/utils.dart';
import 'package:provider/provider.dart';

class MyPage extends StatefulWidget {
const MyPage({super.key});
Expand Down
101 changes: 58 additions & 43 deletions lib/pages/player/episode_comments_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,12 @@ class EpisodeCommentsSheet extends StatefulWidget {
State<EpisodeCommentsSheet> createState() => _EpisodeCommentsSheetState();
}

class _EpisodeCommentsSheetState extends State<EpisodeCommentsSheet> {
class _EpisodeCommentsSheetState extends State<EpisodeCommentsSheet>
with AutomaticKeepAliveClientMixin {
final infoController = Modular.get<InfoController>();
bool isLoading = false;
bool commentsQueryTimeout = false;

@override
void initState() {
super.initState();
if (infoController.episodeCommentsList.isEmpty) {
setState(() {
isLoading = true;
});
loadComments(widget.episode);
}
}

Future<void> loadComments(int episode) async {
commentsQueryTimeout = false;
infoController
Expand All @@ -56,39 +46,60 @@ class _EpisodeCommentsSheetState extends State<EpisodeCommentsSheet> {
}

Widget get episodeCommentsBody {
return SelectionArea(
child: CustomScrollView(
slivers: [
SliverPadding(
padding: const EdgeInsets.fromLTRB(4, 0, 4, 4),
sliver: Observer(builder: (context) {
if (isLoading) {
return const SliverFillRemaining(
child: Center(
child: CircularProgressIndicator(),
),
);
}
if (commentsQueryTimeout) {
return const SliverFillRemaining(
child: Center(
child: Text('空空如也'),
),
);
}
return SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
return EpisodeCommentsCard(
commentItem: infoController.episodeCommentsList[index]);
},
childCount: infoController.episodeCommentsList.length,
if (infoController.episodeCommentsList.isEmpty) {
setState(() {
isLoading = true;
});
loadComments(widget.episode);
}
return CustomScrollView(
// Scrollbars' movement is not linear so hide it.
scrollBehavior: const ScrollBehavior().copyWith(scrollbars: false),
slivers: [
SliverPadding(
padding: const EdgeInsets.fromLTRB(4, 0, 4, 4),
sliver: Observer(builder: (context) {
if (isLoading) {
return const SliverFillRemaining(
child: Center(
child: CircularProgressIndicator(),
),
);
}),
),
],
),
}
if (commentsQueryTimeout) {
return const SliverFillRemaining(
child: Center(
child: Text('空空如也'),
),
);
}
return SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
// Fix scroll issue caused by height change of network images
// by keeping loaded cards alive.
return KeepAlive(
keepAlive: true,
child: IndexedSemantics(
index: index,
child: SelectionArea(
child: EpisodeCommentsCard(
commentItem:
infoController.episodeCommentsList[index],
),
),
),
);
},
childCount: infoController.episodeCommentsList.length,
addAutomaticKeepAlives: false,
addRepaintBoundaries: false,
addSemanticIndexes: false,
),
);
}),
),
],
);
}

Expand Down Expand Up @@ -192,11 +203,15 @@ class _EpisodeCommentsSheetState extends State<EpisodeCommentsSheet> {

@override
Widget build(BuildContext context) {
super.build(context);
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [commentsInfo, Expanded(child: episodeCommentsBody)],
),
);
}

@override
bool get wantKeepAlive => true;
}
2 changes: 1 addition & 1 deletion lib/pages/settings/danmaku/danmaku_settings_window.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class _DanmakuSettingsWindowState extends State<DanmakuSettingsWindow> {
value: widget.danmakuController.option.fontSize,
min: 10,
max: Utils.isCompact() ? 32 : 48,
divisions: 22,
divisions: Utils.isCompact() ? 22 : 38,
label: widget.danmakuController.option.fontSize.toString(),
onChanged: (value) {
setState(() => widget.danmakuController.updateOption(
Expand Down
Loading

0 comments on commit a52f260

Please sign in to comment.