fix: extension install by deeplink (#1510)

This commit is contained in:
Levi authored and GitHub committed 2026-09-13 23:40:59 +08:00
1 parent a760290213
commit cee5f3336e
36 files changed
+869 -143

No files matched your search

@@ -20,6 +20,7 @@ import '../../../../shared/widgets/detail/app_detail_surface.dart';
import '../../../../util/util.dart';
import '../../application/extensions_controller.dart';
import 'extension_icon.dart';
import 'extension_update_dialog.dart';
class ExtensionDetailDrawer extends StatelessWidget {
const ExtensionDetailDrawer({super.key, required this.item, required this.onClose});
@@ -132,14 +133,10 @@ class ExtensionDetailView extends ConsumerWidget {
if (installed != null && canUpdate)
AppLoadingButton(
key: const ValueKey('extension-details-update'),
loading: busy,
loading: false,
variant: AppLoadingButtonVariant.primary,
icon: const Icon(Icons.refresh, size: 16),
onPressed: () => _runAction(
context,
() => ref.read(extensionsControllerProvider.notifier).upgradeExtension(installed),
successMessage: context.l10n.extensionUpdateSuccess,
),
onPressed: busy ? null : () => showExtensionUpdateDialog(context, installed),
child: Text(context.l10n.newVersionUpdate),
),
if (installed != null && !canUpdate)
@@ -0,0 +1,90 @@
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../../api/model/extension.dart' as api;
import '../../../../l10n/l10n.dart';
import '../../../../shared/widgets/app_loading_button.dart';
import '../../../../shared/widgets/app_toast.dart';
import '../../application/extensions_controller.dart';
Future<void> showExtensionUpdateDialog(BuildContext context, api.Extension extension) async {
final overlay = const DialogOverlayHandler().show<bool>(
context: context,
alignment: Alignment.center,
barrierDismissable: false,
builder: (_) => _ExtensionUpdateDialog(extension: extension),
);
final updated = await overlay.future;
if (updated == true && context.mounted) {
showAppToast(context, context.l10n.extensionUpdateSuccess);
}
}
class _ExtensionUpdateDialog extends ConsumerStatefulWidget {
const _ExtensionUpdateDialog({required this.extension});
final api.Extension extension;
@override
ConsumerState<_ExtensionUpdateDialog> createState() => _ExtensionUpdateDialogState();
}
class _ExtensionUpdateDialogState extends ConsumerState<_ExtensionUpdateDialog> {
bool _updating = false;
bool _failed = false;
Future<void> _update() async {
if (_updating) return;
setState(() {
_updating = true;
_failed = false;
});
try {
await ref.read(extensionsControllerProvider.notifier).upgradeExtension(widget.extension);
} catch (_) {
if (!mounted) return;
setState(() {
_updating = false;
_failed = true;
});
return;
}
if (mounted) await closeOverlay(context, true);
}
@override
Widget build(BuildContext context) {
return PopScope(
canPop: !_updating,
child: AlertDialog(
key: const ValueKey('extension-update-dialog'),
title: Text(context.l10n.extensionCanUpdate),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(context.l10n.extensionUpdateConfirm(widget.extension.title)),
if (_failed) ...[
const SizedBox(height: 12),
Text(context.l10n.updateFailed, key: const ValueKey('extension-update-error')),
],
],
),
actions: [
SecondaryButton(
key: const ValueKey('cancel-update-extension-button'),
onPressed: _updating ? null : () => closeOverlay(context, false),
child: Text(context.l10n.cancel),
),
AppLoadingButton(
key: const ValueKey('confirm-update-extension-button'),
variant: AppLoadingButtonVariant.primary,
loading: _updating,
onPressed: _update,
child: Text(context.l10n.newVersionUpdate),
),
],
),
);
}
}