- Android端注入按键时显式设置SOURCE_KEYBOARD,修复IME丢弃事件导致输入框无法输入文字的问题 - Flutter端新增Flutter逻辑键到Android keyCode的转换映射,避免功能键误触发 - 重构RemoteController,分离信令连接与远程控制逻辑,支持设备列表选择与配对码兑换 - AuthRepository接口新增getBindings、getOnlineDevices、redeemPairingCode方法 - DioAuthRepository实现401自动刷新token重试机制 - ConnectionSessionState扩展设备列表、在线状态、配对码等状态字段
597 lines
17 KiB
Dart
597 lines
17 KiB
Dart
import 'dart:async';
|
||
|
||
import 'package:flutter/foundation.dart';
|
||
import 'package:flutter/widgets.dart';
|
||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||
import 'package:intl/intl.dart' as intl;
|
||
|
||
import 'app_localizations_en.dart';
|
||
import 'app_localizations_zh.dart';
|
||
|
||
// ignore_for_file: type=lint
|
||
|
||
/// Callers can lookup localized strings with an instance of AppLocalizations
|
||
/// returned by `AppLocalizations.of(context)`.
|
||
///
|
||
/// Applications need to include `AppLocalizations.delegate()` in their app's
|
||
/// `localizationDelegates` list, and the locales they support in the app's
|
||
/// `supportedLocales` list. For example:
|
||
///
|
||
/// ```dart
|
||
/// import 'l10n/app_localizations.dart';
|
||
///
|
||
/// return MaterialApp(
|
||
/// localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||
/// supportedLocales: AppLocalizations.supportedLocales,
|
||
/// home: MyApplicationHome(),
|
||
/// );
|
||
/// ```
|
||
///
|
||
/// ## Update pubspec.yaml
|
||
///
|
||
/// Please make sure to update your pubspec.yaml to include the following
|
||
/// packages:
|
||
///
|
||
/// ```yaml
|
||
/// dependencies:
|
||
/// # Internationalization support.
|
||
/// flutter_localizations:
|
||
/// sdk: flutter
|
||
/// intl: any # Use the pinned version from flutter_localizations
|
||
///
|
||
/// # Rest of dependencies
|
||
/// ```
|
||
///
|
||
/// ## iOS Applications
|
||
///
|
||
/// iOS applications define key application metadata, including supported
|
||
/// locales, in an Info.plist file that is built into the application bundle.
|
||
/// To configure the locales supported by your app, you’ll need to edit this
|
||
/// file.
|
||
///
|
||
/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file.
|
||
/// Then, in the Project Navigator, open the Info.plist file under the Runner
|
||
/// project’s Runner folder.
|
||
///
|
||
/// Next, select the Information Property List item, select Add Item from the
|
||
/// Editor menu, then select Localizations from the pop-up menu.
|
||
///
|
||
/// Select and expand the newly-created Localizations item then, for each
|
||
/// locale your application supports, add a new item and select the locale
|
||
/// you wish to add from the pop-up menu in the Value field. This list should
|
||
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
|
||
/// property.
|
||
abstract class AppLocalizations {
|
||
AppLocalizations(String locale)
|
||
: localeName = intl.Intl.canonicalizedLocale(locale.toString());
|
||
|
||
final String localeName;
|
||
|
||
static AppLocalizations of(BuildContext context) {
|
||
return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
|
||
}
|
||
|
||
static const LocalizationsDelegate<AppLocalizations> delegate =
|
||
_AppLocalizationsDelegate();
|
||
|
||
/// A list of this localizations delegate along with the default localizations
|
||
/// delegates.
|
||
///
|
||
/// Returns a list of localizations delegates containing this delegate along with
|
||
/// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
|
||
/// and GlobalWidgetsLocalizations.delegate.
|
||
///
|
||
/// Additional delegates can be added by appending to this list in
|
||
/// MaterialApp. This list does not have to be used at all if a custom list
|
||
/// of delegates is preferred or required.
|
||
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
|
||
<LocalizationsDelegate<dynamic>>[
|
||
delegate,
|
||
GlobalMaterialLocalizations.delegate,
|
||
GlobalCupertinoLocalizations.delegate,
|
||
GlobalWidgetsLocalizations.delegate,
|
||
];
|
||
|
||
/// A list of this localizations delegate's supported locales.
|
||
static const List<Locale> supportedLocales = <Locale>[
|
||
Locale('en'),
|
||
Locale('zh'),
|
||
];
|
||
|
||
/// No description provided for @appTitle.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'WebRTC 控制端'**
|
||
String get appTitle;
|
||
|
||
/// No description provided for @login.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'登录'**
|
||
String get login;
|
||
|
||
/// No description provided for @logout.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'退出登录'**
|
||
String get logout;
|
||
|
||
/// No description provided for @registerAccount.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'注册新账号'**
|
||
String get registerAccount;
|
||
|
||
/// No description provided for @registerSuccess.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'注册成功,请登录'**
|
||
String get registerSuccess;
|
||
|
||
/// No description provided for @registerFailed.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'注册失败:{error}'**
|
||
String registerFailed(Object error);
|
||
|
||
/// No description provided for @loginSubtitle.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'登录后可连接已绑定的被控设备'**
|
||
String get loginSubtitle;
|
||
|
||
/// No description provided for @cancel.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'取消'**
|
||
String get cancel;
|
||
|
||
/// No description provided for @confirm.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'确定'**
|
||
String get confirm;
|
||
|
||
/// No description provided for @connect.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'连接'**
|
||
String get connect;
|
||
|
||
/// No description provided for @connecting.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'正在连接...'**
|
||
String get connecting;
|
||
|
||
/// No description provided for @loginAccount.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'登录账号'**
|
||
String get loginAccount;
|
||
|
||
/// No description provided for @connectDevice.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'连接被控设备'**
|
||
String get connectDevice;
|
||
|
||
/// No description provided for @deviceId.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'本机设备ID(连接后由服务端下发,无需填写):'**
|
||
String get deviceId;
|
||
|
||
/// No description provided for @deviceIdPlaceholder.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'连接后由服务端下发'**
|
||
String get deviceIdPlaceholder;
|
||
|
||
/// No description provided for @targetDeviceId.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'目标被控设备ID:'**
|
||
String get targetDeviceId;
|
||
|
||
/// No description provided for @targetDeviceIdPlaceholder.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'被控端设备ID'**
|
||
String get targetDeviceIdPlaceholder;
|
||
|
||
/// No description provided for @username.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'用户名'**
|
||
String get username;
|
||
|
||
/// No description provided for @password.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'密码'**
|
||
String get password;
|
||
|
||
/// No description provided for @loginFailed.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'登录失败:{error}'**
|
||
String loginFailed(Object error);
|
||
|
||
/// No description provided for @usernamePasswordRequired.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'请输入用户名和密码'**
|
||
String get usernamePasswordRequired;
|
||
|
||
/// No description provided for @targetRequired.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'请填写目标设备ID'**
|
||
String get targetRequired;
|
||
|
||
/// No description provided for @authTitle.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'连接鉴权'**
|
||
String get authTitle;
|
||
|
||
/// No description provided for @authNone.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'免密连接'**
|
||
String get authNone;
|
||
|
||
/// No description provided for @authNoneDesc.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'被控端弹出手动确认框,无需验证码或密码'**
|
||
String get authNoneDesc;
|
||
|
||
/// No description provided for @authCode.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'动态验证码'**
|
||
String get authCode;
|
||
|
||
/// No description provided for @authCodeDesc.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'使用一次性动态验证码鉴权'**
|
||
String get authCodeDesc;
|
||
|
||
/// No description provided for @authPassword.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'固定密码'**
|
||
String get authPassword;
|
||
|
||
/// No description provided for @authPasswordDesc.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'使用固定连接密码鉴权'**
|
||
String get authPasswordDesc;
|
||
|
||
/// No description provided for @authNonePlaceholder.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'免密连接,无需填写'**
|
||
String get authNonePlaceholder;
|
||
|
||
/// No description provided for @authPasswordPlaceholder.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'请输入固定密码'**
|
||
String get authPasswordPlaceholder;
|
||
|
||
/// No description provided for @authCodePlaceholder.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'请输入动态验证码'**
|
||
String get authCodePlaceholder;
|
||
|
||
/// No description provided for @authValueRequired.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'请输入验证码或密码'**
|
||
String get authValueRequired;
|
||
|
||
/// No description provided for @statusStopped.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'状态: 已停止'**
|
||
String get statusStopped;
|
||
|
||
/// No description provided for @statusConnectingSignal.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'状态: 正在连接信令服务器...'**
|
||
String get statusConnectingSignal;
|
||
|
||
/// No description provided for @statusConnected.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'状态: 已连接 - 远程控制中'**
|
||
String get statusConnected;
|
||
|
||
/// No description provided for @statusDisconnected.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'状态: 远端已断开'**
|
||
String get statusDisconnected;
|
||
|
||
/// No description provided for @statusSignalConnected.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'状态: 已连接信令服务器,等待注册...'**
|
||
String get statusSignalConnected;
|
||
|
||
/// No description provided for @statusRegistered.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'状态: 已注册 ({deviceId}),正在发起连接...'**
|
||
String statusRegistered(Object deviceId);
|
||
|
||
/// No description provided for @statusAuthFailed.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'状态: 认证失败 - {error}'**
|
||
String statusAuthFailed(Object error);
|
||
|
||
/// No description provided for @statusConnectError.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'状态: 连接错误 - {error}'**
|
||
String statusConnectError(Object error);
|
||
|
||
/// No description provided for @statusTargetAccept.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'状态: 被控端已接受连接,正在建立连接...'**
|
||
String get statusTargetAccept;
|
||
|
||
/// No description provided for @statusTokenRefreshFailed.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'状态: 令牌刷新失败 - {error}'**
|
||
String statusTokenRefreshFailed(Object error);
|
||
|
||
/// No description provided for @statusForceLogout.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'状态: 账号已在其他位置登录,已强制下线'**
|
||
String get statusForceLogout;
|
||
|
||
/// No description provided for @connectedBindings.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'已绑定设备: {uids}'**
|
||
String connectedBindings(Object uids);
|
||
|
||
/// No description provided for @resolutionSwitch.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'切换分辨率'**
|
||
String get resolutionSwitch;
|
||
|
||
/// No description provided for @fpsSwitch.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'切换帧率'**
|
||
String get fpsSwitch;
|
||
|
||
/// No description provided for @selfCodec.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'自编码'**
|
||
String get selfCodec;
|
||
|
||
/// No description provided for @record.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'录制'**
|
||
String get record;
|
||
|
||
/// No description provided for @stop.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'停止'**
|
||
String get stop;
|
||
|
||
/// No description provided for @recording.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'录制中...'**
|
||
String get recording;
|
||
|
||
/// No description provided for @recordSaved.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'已保存:{path}'**
|
||
String recordSaved(Object path);
|
||
|
||
/// No description provided for @recordStopped.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'录制已停止'**
|
||
String get recordStopped;
|
||
|
||
/// No description provided for @recordNoStream.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'尚未连接或没有视频画面,无法录制'**
|
||
String get recordNoStream;
|
||
|
||
/// No description provided for @recordSwitchToStd.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'正在切回标准模式以开始录制...'**
|
||
String get recordSwitchToStd;
|
||
|
||
/// No description provided for @recordStartFailed.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'开始录制失败:{error}'**
|
||
String recordStartFailed(Object error);
|
||
|
||
/// No description provided for @recordNoVideoTrack.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'尚未接收到视频画面,无法录制'**
|
||
String get recordNoVideoTrack;
|
||
|
||
/// No description provided for @selfCodecNotSupported.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'当前平台不支持自编码硬解,已回退到 WebRTC 媒体流。'**
|
||
String get selfCodecNotSupported;
|
||
|
||
/// No description provided for @iceDisconnected.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'ICE 连接已断开'**
|
||
String get iceDisconnected;
|
||
|
||
/// No description provided for @targetOffline.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'目标被控端不在线,请确认设备已开启并连接服务器'**
|
||
String get targetOffline;
|
||
|
||
/// No description provided for @connectionFailed.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'连接失败:{error}'**
|
||
String connectionFailed(Object error);
|
||
|
||
/// No description provided for @tokenExpired.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'登录已失效,请重新登录后再连接。'**
|
||
String get tokenExpired;
|
||
|
||
/// No description provided for @forceLogout.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'账号已在其他位置登录,已强制下线。'**
|
||
String get forceLogout;
|
||
|
||
/// No description provided for @loginFirst.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'请先登录后再连接'**
|
||
String get loginFirst;
|
||
|
||
/// No description provided for @pleaseFillAuth.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'请输入验证码或密码'**
|
||
String get pleaseFillAuth;
|
||
|
||
/// No description provided for @streamModeSelfCodecDesc.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'当前平台不支持自编码硬解。'**
|
||
String get streamModeSelfCodecDesc;
|
||
|
||
/// No description provided for @boundDevices.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'已绑定设备'**
|
||
String get boundDevices;
|
||
|
||
/// No description provided for @online.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'在线'**
|
||
String get online;
|
||
|
||
/// No description provided for @offline.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'离线'**
|
||
String get offline;
|
||
|
||
/// No description provided for @noBoundDevices.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'暂无已绑定设备'**
|
||
String get noBoundDevices;
|
||
|
||
/// No description provided for @refreshDevices.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'刷新'**
|
||
String get refreshDevices;
|
||
|
||
/// No description provided for @redeemPairingCode.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'使用配对码绑定'**
|
||
String get redeemPairingCode;
|
||
|
||
/// No description provided for @pairingCodeHint.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'请输入被控端显示的配对码'**
|
||
String get pairingCodeHint;
|
||
|
||
/// No description provided for @bindingFailed.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'绑定失败:{error}'**
|
||
String bindingFailed(Object error);
|
||
|
||
/// No description provided for @deviceOfflineCannotConnect.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'设备「{name}」当前不在线,无法连接'**
|
||
String deviceOfflineCannotConnect(Object name);
|
||
|
||
/// No description provided for @pleaseSelectDevice.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'请先选择一个绑定的设备'**
|
||
String get pleaseSelectDevice;
|
||
|
||
/// No description provided for @bindSuccess.
|
||
///
|
||
/// In zh, this message translates to:
|
||
/// **'绑定成功'**
|
||
String get bindSuccess;
|
||
}
|
||
|
||
class _AppLocalizationsDelegate
|
||
extends LocalizationsDelegate<AppLocalizations> {
|
||
const _AppLocalizationsDelegate();
|
||
|
||
@override
|
||
Future<AppLocalizations> load(Locale locale) {
|
||
return SynchronousFuture<AppLocalizations>(lookupAppLocalizations(locale));
|
||
}
|
||
|
||
@override
|
||
bool isSupported(Locale locale) =>
|
||
<String>['en', 'zh'].contains(locale.languageCode);
|
||
|
||
@override
|
||
bool shouldReload(_AppLocalizationsDelegate old) => false;
|
||
}
|
||
|
||
AppLocalizations lookupAppLocalizations(Locale locale) {
|
||
// Lookup logic when only language code is specified.
|
||
switch (locale.languageCode) {
|
||
case 'en':
|
||
return AppLocalizationsEn();
|
||
case 'zh':
|
||
return AppLocalizationsZh();
|
||
}
|
||
|
||
throw FlutterError(
|
||
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
|
||
'an issue with the localizations generation tool. Please file an issue '
|
||
'on GitHub with a reproducible sample app and the gen-l10n configuration '
|
||
'that was used.',
|
||
);
|
||
}
|