### 详细变更:
1. **文档与配置**:更新AGENTS.md添加命令超时约束,升级Rive依赖至0.14.7并替换平台插件引用
2. **UI优化**:重构AppInfo页面布局、移除图表冗余配置、锁定部分系统设置项
3. **功能增强**:
- 新增工具面板拖拽状态管理与介绍弹窗
- 新增进度页面编辑/重排/清空用户进度功能
- 新增摇一摇路由作用域拦截逻辑
4. **体验优化**:
- 统一外部链接跳转弹窗,添加文件打开确认逻辑
- 修复设备卡片IP溢出、Android权限声明问题
- 后台任务初始化增加协议校验
5. **代码重构**:拆分工具面板配置、拖拽逻辑与动画参数,优化状态管理代码
6. **工具脚本**:新增协议文件上传脚本
71 lines
2.3 KiB
Dart
71 lines
2.3 KiB
Dart
/// ============================================================
|
||
/// 闲言APP — 外部跳转确认弹窗
|
||
/// 创建时间: 2026-05-27
|
||
/// 更新时间: 2026-05-30
|
||
/// 作用: 统一外部链接跳转确认弹窗,防止用户误触跳转到外部浏览器/应用
|
||
/// 上次更新: 新增appName参数,优化弹窗提示文案
|
||
/// ============================================================
|
||
|
||
import 'package:flutter/cupertino.dart';
|
||
import 'package:url_launcher/url_launcher.dart';
|
||
import 'package:xianyan/core/utils/logger.dart';
|
||
|
||
class ExternalLinkDialog {
|
||
ExternalLinkDialog._();
|
||
|
||
static Future<bool> show(
|
||
BuildContext context, {
|
||
required Uri uri,
|
||
String? appName,
|
||
}) async {
|
||
final displayUrl = uri.toString().length > 100
|
||
? '${uri.toString().substring(0, 100)}...'
|
||
: uri.toString();
|
||
final contentText = appName != null && appName.isNotEmpty
|
||
? '将打开$appName查看更多内容'
|
||
: '将打开外部链接:\n$displayUrl';
|
||
final result = await showCupertinoDialog<bool>(
|
||
context: context,
|
||
builder: (ctx) => CupertinoAlertDialog(
|
||
title: const Text('即将离开闲言'),
|
||
content: Padding(
|
||
padding: const EdgeInsets.only(top: 8),
|
||
child: Text(contentText, style: const TextStyle(fontSize: 13)),
|
||
),
|
||
actions: [
|
||
CupertinoDialogAction(
|
||
child: const Text('取消'),
|
||
onPressed: () => Navigator.of(ctx).pop(false),
|
||
),
|
||
CupertinoDialogAction(
|
||
isDefaultAction: true,
|
||
child: const Text('打开'),
|
||
onPressed: () => Navigator.of(ctx).pop(true),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
return result ?? false;
|
||
}
|
||
|
||
static Future<bool> launchWithConfirm(
|
||
BuildContext context, {
|
||
required Uri uri,
|
||
String? appName,
|
||
LaunchMode mode = LaunchMode.externalApplication,
|
||
}) async {
|
||
final confirmed = await show(context, uri: uri, appName: appName);
|
||
if (!confirmed) return false;
|
||
try {
|
||
final launched = await launchUrl(uri, mode: mode);
|
||
if (!launched) {
|
||
Log.w('ExternalLinkDialog: 无法打开链接: $uri');
|
||
}
|
||
return launched;
|
||
} catch (e) {
|
||
Log.e('ExternalLinkDialog: 打开链接失败', e);
|
||
return false;
|
||
}
|
||
}
|
||
}
|