主要变更: 1. 全局修复类型转换问题,将多处`as int?`改为`(num?)?.toInt()`兼容浮点/字符串类型的数字字段 2. 移除废弃的nearby_p2p配对方式和对应的依赖包 3. 优化鸿蒙端快捷方式、引导页、路由导航的稳定性 4. 合并日志输出避免鸿蒙端IDE卡顿 5. 修复安卓端蓝牙权限冗余声明
210 lines
6.4 KiB
Dart
210 lines
6.4 KiB
Dart
// ============================================================
|
|
// 闲言APP — 文件传输助手枚举定义
|
|
// 创建时间: 2026-05-09
|
|
// 更新时间: 2026-06-05
|
|
// 作用: 文件传输助手所有枚举类型 — 配对方式/传输方式/任务状态/设备类型/传输方向
|
|
// 上次更新: 新增wsP2p传输方式(WebSocket P2P直连)
|
|
// ============================================================
|
|
|
|
enum PairingMethod {
|
|
lan('lan', '局域网', '📶'),
|
|
qrCode('qr_code', '扫码', '📷'),
|
|
account('account', '账户', '👤'),
|
|
manual('manual', '手动IP', '✍️'),
|
|
usb('usb', 'USB有线', '🔌'),
|
|
hotspot('hotspot', 'WiFi热点', '📶'),
|
|
wifiDirect('wifi_direct', 'Wi-Fi直连', '📶'),
|
|
harmonyNearby('harmony_nearby', '鸿蒙Nearby', '📡');
|
|
|
|
const PairingMethod(this.id, this.label, this.emoji);
|
|
final String id;
|
|
final String label;
|
|
final String emoji;
|
|
|
|
static PairingMethod fromId(String id) {
|
|
return PairingMethod.values.firstWhere(
|
|
(m) => m.id == id,
|
|
orElse: () => PairingMethod.lan,
|
|
);
|
|
}
|
|
|
|
static PairingMethod? tryFromId(String? id) {
|
|
if (id == null) return null;
|
|
return PairingMethod.values.cast<PairingMethod?>().firstWhere(
|
|
(m) => m?.id == id,
|
|
orElse: () => null,
|
|
);
|
|
}
|
|
|
|
bool get requiresInternet => this == PairingMethod.account;
|
|
bool get requiresCamera => this == PairingMethod.qrCode;
|
|
bool get requiresUsb => this == PairingMethod.usb;
|
|
bool get worksOffline => !requiresInternet;
|
|
}
|
|
|
|
enum TransportType {
|
|
localsendHttp('localsend_http', 'LocalSend HTTP', '🔗'),
|
|
tcpSocket('tcp_socket', 'TCP直连', '⚡'),
|
|
wsP2p('ws_p2p', 'WS P2P直连', '🔗'),
|
|
webrtcP2p('webrtc_p2p', 'WebRTC P2P', '🌐'),
|
|
webrtcRelay('webrtc_relay', 'WebRTC中继', '🔄'),
|
|
wsRelay('ws_relay', 'WebSocket中转', '📡'),
|
|
wifiDirect('wifi_direct', 'Wi-Fi直连', '📶'),
|
|
usbTether('usb_tether', 'USB有线', '🔌');
|
|
|
|
const TransportType(this.id, this.label, this.emoji);
|
|
final String id;
|
|
final String label;
|
|
final String emoji;
|
|
|
|
static TransportType fromId(String id) {
|
|
return TransportType.values.firstWhere(
|
|
(t) => t.id == id,
|
|
orElse: () => TransportType.localsendHttp,
|
|
);
|
|
}
|
|
|
|
static TransportType? tryFromId(String? id) {
|
|
if (id == null) return null;
|
|
return TransportType.values.cast<TransportType?>().firstWhere(
|
|
(t) => t?.id == id,
|
|
orElse: () => null,
|
|
);
|
|
}
|
|
|
|
bool get isLan =>
|
|
this == TransportType.localsendHttp ||
|
|
this == TransportType.tcpSocket ||
|
|
this == TransportType.wsP2p ||
|
|
this == TransportType.wifiDirect;
|
|
bool get isRemote =>
|
|
this == TransportType.webrtcP2p ||
|
|
this == TransportType.webrtcRelay ||
|
|
this == TransportType.wsRelay;
|
|
bool get isWired => this == TransportType.usbTether;
|
|
bool get isRelay =>
|
|
this == TransportType.webrtcRelay || this == TransportType.wsRelay;
|
|
bool get requiresInternet => isRemote;
|
|
bool get worksOffline => !requiresInternet;
|
|
}
|
|
|
|
enum TransferTaskStatus {
|
|
waiting('waiting', '等待中', '⏳'),
|
|
preparing('preparing', '准备中', '📋'),
|
|
transferring('transferring', '传输中', '📤'),
|
|
paused('paused', '已暂停', '⏸️'),
|
|
completed('completed', '已完成', '✅'),
|
|
failed('failed', '失败', '❌'),
|
|
cancelled('cancelled', '已取消', '🚫'),
|
|
rejected('rejected', '被拒绝', '🙅');
|
|
|
|
const TransferTaskStatus(this.id, this.label, this.emoji);
|
|
final String id;
|
|
final String label;
|
|
final String emoji;
|
|
|
|
static TransferTaskStatus fromId(String id) {
|
|
return TransferTaskStatus.values.firstWhere(
|
|
(s) => s.id == id,
|
|
orElse: () => TransferTaskStatus.waiting,
|
|
);
|
|
}
|
|
|
|
static TransferTaskStatus? tryFromId(String? id) {
|
|
if (id == null) return null;
|
|
return TransferTaskStatus.values.cast<TransferTaskStatus?>().firstWhere(
|
|
(s) => s?.id == id,
|
|
orElse: () => null,
|
|
);
|
|
}
|
|
|
|
bool get isTerminal =>
|
|
this == TransferTaskStatus.completed ||
|
|
this == TransferTaskStatus.failed ||
|
|
this == TransferTaskStatus.cancelled ||
|
|
this == TransferTaskStatus.rejected;
|
|
|
|
bool get isActive =>
|
|
this == TransferTaskStatus.transferring ||
|
|
this == TransferTaskStatus.preparing;
|
|
|
|
bool canTransitionTo(TransferTaskStatus next) {
|
|
if (isTerminal) return false;
|
|
if (next == TransferTaskStatus.cancelled) return true;
|
|
if (next == TransferTaskStatus.failed) return true;
|
|
switch (this) {
|
|
case TransferTaskStatus.waiting:
|
|
return next == TransferTaskStatus.preparing ||
|
|
next == TransferTaskStatus.cancelled;
|
|
case TransferTaskStatus.preparing:
|
|
return next == TransferTaskStatus.transferring ||
|
|
next == TransferTaskStatus.cancelled;
|
|
case TransferTaskStatus.transferring:
|
|
return next == TransferTaskStatus.paused ||
|
|
next == TransferTaskStatus.completed ||
|
|
next == TransferTaskStatus.cancelled;
|
|
case TransferTaskStatus.paused:
|
|
return next == TransferTaskStatus.transferring ||
|
|
next == TransferTaskStatus.cancelled;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
enum DeviceType {
|
|
mobile('mobile', '📱', '手机'),
|
|
desktop('desktop', '💻', '桌面'),
|
|
web('web', '🌐', 'Web浏览器'),
|
|
headless('headless', '🖥️', '无头'),
|
|
server('server', '☁️', '服务器');
|
|
|
|
const DeviceType(this.id, this.emoji, this.label);
|
|
final String id;
|
|
final String emoji;
|
|
final String label;
|
|
|
|
static DeviceType fromId(String id) {
|
|
return DeviceType.values.firstWhere(
|
|
(d) => d.id == id,
|
|
orElse: () => DeviceType.mobile,
|
|
);
|
|
}
|
|
}
|
|
|
|
enum TransferDirection {
|
|
send('send', '发送', '📤'),
|
|
receive('receive', '接收', '📥');
|
|
|
|
const TransferDirection(this.id, this.label, this.emoji);
|
|
final String id;
|
|
final String label;
|
|
final String emoji;
|
|
|
|
static TransferDirection fromId(String id) {
|
|
return TransferDirection.values.firstWhere(
|
|
(d) => d.id == id,
|
|
orElse: () => TransferDirection.send,
|
|
);
|
|
}
|
|
}
|
|
|
|
enum UsbVersion {
|
|
usb20('usb20', 'USB 2.0', 64 * 1024),
|
|
usb30('usb30', 'USB 3.0', 256 * 1024),
|
|
usb31('usb31', 'USB 3.1', 512 * 1024),
|
|
unknown('unknown', '未知', 64 * 1024);
|
|
|
|
const UsbVersion(this.id, this.label, this.chunkSize);
|
|
final String id;
|
|
final String label;
|
|
final int chunkSize;
|
|
|
|
static UsbVersion fromId(String id) {
|
|
return UsbVersion.values.firstWhere(
|
|
(v) => v.id == id,
|
|
orElse: () => UsbVersion.unknown,
|
|
);
|
|
}
|
|
}
|