mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-09 10:00:27 +00:00
feat(ui): unify child surfaces and show web task creation in a modal (#1633)
This commit is contained in:
30 files changed
+618
-85
No files matched your search
@@ -11,7 +11,7 @@ import '../../../../app/application/app_runtime_controller.dart';
|
||||
import '../../../../core/capabilities/app_capabilities.dart';
|
||||
import '../../../../core/utils/breakpoints.dart';
|
||||
import '../../../../core/utils/file_explorer.dart';
|
||||
import '../../../../core/window/app_window_launcher.dart';
|
||||
import '../../../../app/router/app_router.dart';
|
||||
import '../../../../core/window/app_window_chrome.dart';
|
||||
import '../../../../shared/theme/app_design_tokens.dart';
|
||||
import '../../../../shared/theme/app_palette.dart';
|
||||
@@ -580,19 +580,7 @@ class _HomePageState extends ConsumerState<HomePage> {
|
||||
}
|
||||
}
|
||||
|
||||
void _handleAddTask() {
|
||||
if (!Util.isDesktop()) {
|
||||
context.go('/create');
|
||||
return;
|
||||
}
|
||||
unawaited(
|
||||
AppWindowLauncher.openCreateTaskWindow().then((opened) {
|
||||
if (!opened && mounted) {
|
||||
context.go('/create');
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
void _handleAddTask() => unawaited(AppRouter.openCreateTask());
|
||||
|
||||
Future<void> _runTaskAction(Future<void> Function() action) async {
|
||||
try {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'package:flutter/material.dart' show Icons;
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:shadcn_flutter/shadcn_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import '../../../../core/window/app_window_chrome.dart';
|
||||
@@ -28,7 +27,21 @@ class PrimaryRail extends StatelessWidget {
|
||||
children: [
|
||||
SizedBox(
|
||||
height: AppDesignTokens.contentHeaderHeight,
|
||||
child: const Center(child: GopeedAppMark(key: ValueKey('primary-rail-app-mark'))),
|
||||
child: Center(
|
||||
child: AppTooltip(
|
||||
message: context.l10n.task,
|
||||
child: Semantics(
|
||||
label: context.l10n.task,
|
||||
button: true,
|
||||
child: GhostButton(
|
||||
key: const ValueKey('primary-rail-home-button'),
|
||||
density: ButtonDensity.icon,
|
||||
onPressed: () => context.go('/'),
|
||||
child: const ExcludeSemantics(child: GopeedAppMark(key: ValueKey('primary-rail-app-mark'))),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppDesignTokens.space8),
|
||||
_RailItem(
|
||||
|
||||
@@ -44,10 +44,12 @@ import '../widgets/create_task_action_buttons.dart';
|
||||
import '../widgets/resolve_download_dialog.dart';
|
||||
|
||||
class CreateTaskWindowPage extends ConsumerStatefulWidget {
|
||||
const CreateTaskWindowPage({super.key, this.windowController, this.initialTask});
|
||||
const CreateTaskWindowPage({super.key, this.windowController, this.initialTask, this.onClose, this.modal = false});
|
||||
|
||||
final multi_window.WindowController? windowController;
|
||||
final CreateTask? initialTask;
|
||||
final ValueChanged<bool>? onClose;
|
||||
final bool modal;
|
||||
|
||||
@override
|
||||
ConsumerState<CreateTaskWindowPage> createState() => _CreateTaskWindowPageState();
|
||||
@@ -133,7 +135,7 @@ class _CreateTaskWindowPageState extends ConsumerState<CreateTaskWindowPage> {
|
||||
if (widget.initialTask == null) {
|
||||
ref.read(pendingCreateTaskProvider.notifier).clear();
|
||||
}
|
||||
if (widget.windowController == null && widget.initialTask == null) {
|
||||
if (widget.windowController == null) {
|
||||
// Navigating to /create again reuses this page, so consume subsequent
|
||||
// browser/share requests as well as the initial pending task.
|
||||
ref.listenManual(pendingCreateTaskProvider, (_, next) {
|
||||
@@ -371,7 +373,9 @@ class _CreateTaskWindowPageState extends ConsumerState<CreateTaskWindowPage> {
|
||||
child: Padding(
|
||||
key: const ValueKey('create-task-safe-content'),
|
||||
padding: EdgeInsets.only(
|
||||
top: AppWindowChrome.reservesHeaderInset
|
||||
top: widget.modal
|
||||
? 0
|
||||
: AppWindowChrome.reservesHeaderInset
|
||||
? AppDesignTokens.windowHeaderHeight
|
||||
: MediaQuery.paddingOf(context).top,
|
||||
),
|
||||
@@ -867,6 +871,10 @@ class _CreateTaskWindowPageState extends ConsumerState<CreateTaskWindowPage> {
|
||||
}
|
||||
|
||||
Future<void> _closeWindow() async {
|
||||
if (widget.onClose != null) {
|
||||
widget.onClose!(false);
|
||||
return;
|
||||
}
|
||||
if (widget.windowController == null && mounted) {
|
||||
context.go('/');
|
||||
return;
|
||||
@@ -888,6 +896,10 @@ class _CreateTaskWindowPageState extends ConsumerState<CreateTaskWindowPage> {
|
||||
}
|
||||
}
|
||||
if (!mounted || session != _createSession) return;
|
||||
if (widget.onClose != null) {
|
||||
widget.onClose!(true);
|
||||
return;
|
||||
}
|
||||
if (widget.windowController != null) {
|
||||
// Navigation is best-effort after a successful submission. A navigation
|
||||
// failure must not leave a completed form available for resubmission.
|
||||
|
||||
Reference in new issue
Block a user