Compare commits

..

1 Commits

Author SHA1 Message Date
chen08209
060e1b5392 Optimize desktop view
Optimize logs, requests, connection pages

Optimize windows tray auto hide

Update core
2025-07-25 15:20:17 +08:00
14 changed files with 38 additions and 42 deletions

View File

@@ -1,13 +1,3 @@
## v0.8.86
- Fix windows tun issues
- Optimize android get system dns
- Optimize more details
- Update changelog
## v0.8.85
- Support override script

View File

@@ -117,7 +117,7 @@ class Request {
}
}).catchError((e) {
failureCount++;
if (e is DioException && e.type == DioExceptionType.cancel) {
if (e == DioExceptionType.cancel) {
completer.complete(Result.error('cancelled'));
}
handleFailRes();

View File

@@ -97,7 +97,6 @@ class System {
final shell = Platform.environment['SHELL'] ?? 'bash';
final password = await globalState.showCommonDialog<String>(
child: InputDialog(
obscureText: true,
title: appLocalizations.pleaseInputAdminPassword,
value: '',
),

View File

@@ -93,11 +93,6 @@ class _AppStateManagerState extends ConsumerState<AppStateManager>
} else {
render?.resume();
}
if (state == AppLifecycleState.inactive) {
WidgetsBinding.instance.addPostFrameCallback((_) {
detectionState.tryStartCheck();
});
}
}
@override

View File

@@ -1061,6 +1061,7 @@ abstract class _ProfilesSelectorState implements ProfilesSelectorState {
/// @nodoc
mixin _$NetworkDetectionState {
bool get isLoading => throw _privateConstructorUsedError;
bool get isTesting => throw _privateConstructorUsedError;
IpInfo? get ipInfo => throw _privateConstructorUsedError;
/// Create a copy of NetworkDetectionState
@@ -1076,7 +1077,7 @@ abstract class $NetworkDetectionStateCopyWith<$Res> {
$Res Function(NetworkDetectionState) then) =
_$NetworkDetectionStateCopyWithImpl<$Res, NetworkDetectionState>;
@useResult
$Res call({bool isLoading, IpInfo? ipInfo});
$Res call({bool isLoading, bool isTesting, IpInfo? ipInfo});
}
/// @nodoc
@@ -1096,6 +1097,7 @@ class _$NetworkDetectionStateCopyWithImpl<$Res,
@override
$Res call({
Object? isLoading = null,
Object? isTesting = null,
Object? ipInfo = freezed,
}) {
return _then(_value.copyWith(
@@ -1103,6 +1105,10 @@ class _$NetworkDetectionStateCopyWithImpl<$Res,
? _value.isLoading
: isLoading // ignore: cast_nullable_to_non_nullable
as bool,
isTesting: null == isTesting
? _value.isTesting
: isTesting // ignore: cast_nullable_to_non_nullable
as bool,
ipInfo: freezed == ipInfo
? _value.ipInfo
: ipInfo // ignore: cast_nullable_to_non_nullable
@@ -1120,7 +1126,7 @@ abstract class _$$NetworkDetectionStateImplCopyWith<$Res>
__$$NetworkDetectionStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({bool isLoading, IpInfo? ipInfo});
$Res call({bool isLoading, bool isTesting, IpInfo? ipInfo});
}
/// @nodoc
@@ -1138,6 +1144,7 @@ class __$$NetworkDetectionStateImplCopyWithImpl<$Res>
@override
$Res call({
Object? isLoading = null,
Object? isTesting = null,
Object? ipInfo = freezed,
}) {
return _then(_$NetworkDetectionStateImpl(
@@ -1145,6 +1152,10 @@ class __$$NetworkDetectionStateImplCopyWithImpl<$Res>
? _value.isLoading
: isLoading // ignore: cast_nullable_to_non_nullable
as bool,
isTesting: null == isTesting
? _value.isTesting
: isTesting // ignore: cast_nullable_to_non_nullable
as bool,
ipInfo: freezed == ipInfo
? _value.ipInfo
: ipInfo // ignore: cast_nullable_to_non_nullable
@@ -1157,16 +1168,18 @@ class __$$NetworkDetectionStateImplCopyWithImpl<$Res>
class _$NetworkDetectionStateImpl implements _NetworkDetectionState {
const _$NetworkDetectionStateImpl(
{required this.isLoading, required this.ipInfo});
{required this.isLoading, required this.isTesting, required this.ipInfo});
@override
final bool isLoading;
@override
final bool isTesting;
@override
final IpInfo? ipInfo;
@override
String toString() {
return 'NetworkDetectionState(isLoading: $isLoading, ipInfo: $ipInfo)';
return 'NetworkDetectionState(isLoading: $isLoading, isTesting: $isTesting, ipInfo: $ipInfo)';
}
@override
@@ -1176,11 +1189,13 @@ class _$NetworkDetectionStateImpl implements _NetworkDetectionState {
other is _$NetworkDetectionStateImpl &&
(identical(other.isLoading, isLoading) ||
other.isLoading == isLoading) &&
(identical(other.isTesting, isTesting) ||
other.isTesting == isTesting) &&
(identical(other.ipInfo, ipInfo) || other.ipInfo == ipInfo));
}
@override
int get hashCode => Object.hash(runtimeType, isLoading, ipInfo);
int get hashCode => Object.hash(runtimeType, isLoading, isTesting, ipInfo);
/// Create a copy of NetworkDetectionState
/// with the given fields replaced by the non-null parameter values.
@@ -1195,11 +1210,14 @@ class _$NetworkDetectionStateImpl implements _NetworkDetectionState {
abstract class _NetworkDetectionState implements NetworkDetectionState {
const factory _NetworkDetectionState(
{required final bool isLoading,
required final bool isTesting,
required final IpInfo? ipInfo}) = _$NetworkDetectionStateImpl;
@override
bool get isLoading;
@override
bool get isTesting;
@override
IpInfo? get ipInfo;
/// Create a copy of NetworkDetectionState

View File

@@ -66,6 +66,7 @@ class ProfilesSelectorState with _$ProfilesSelectorState {
class NetworkDetectionState with _$NetworkDetectionState {
const factory NetworkDetectionState({
required bool isLoading,
required bool isTesting,
required IpInfo? ipInfo,
}) = _NetworkDetectionState;
}

View File

@@ -41,7 +41,7 @@ final currentGroupsStateProvider = AutoDisposeProvider<GroupsState>.internal(
// ignore: unused_element
typedef CurrentGroupsStateRef = AutoDisposeProviderRef<GroupsState>;
String _$navigationItemsStateHash() =>
r'1fc37c14d129f9725b0e62fd53f6b25382f51102';
r'53133c67446f91a2bb499d24dae3e9a7dc00f60f';
/// See also [navigationItemsState].
@ProviderFor(navigationItemsState)

View File

@@ -64,8 +64,6 @@ GroupsState currentGroupsState(Ref ref) {
@riverpod
NavigationItemsState navigationItemsState(Ref ref) {
final openLogs = ref.watch(appSettingProvider).openLogs;
final hasProfiles =
ref.watch(profilesProvider.select((state) => state.isNotEmpty));
final hasProxies = ref.watch(currentGroupsStateProvider.select(
(state) => state.value.isNotEmpty,
));
@@ -73,7 +71,7 @@ NavigationItemsState navigationItemsState(Ref ref) {
return NavigationItemsState(
value: navigation.getItems(
openLogs: openLogs,
hasProxies: !isInit ? hasProfiles : hasProxies,
hasProxies: !isInit ? true : hasProxies,
),
);
}

View File

@@ -465,6 +465,7 @@ class DetectionState {
final state = ValueNotifier<NetworkDetectionState>(
const NetworkDetectionState(
isTesting: false,
isLoading: true,
ipInfo: null,
),
@@ -487,12 +488,6 @@ class DetectionState {
);
}
void tryStartCheck() {
if (state.value.isLoading == false && state.value.ipInfo == null) {
startCheck();
}
}
Future<void> _checkIp() async {
final appState = globalState.appState;
final isInit = appState.isInit;
@@ -514,6 +509,9 @@ class DetectionState {
cancelToken = null;
}
cancelToken = CancelToken();
state.value = state.value.copyWith(
isTesting: true,
);
final res = await request.checkIp(cancelToken: cancelToken);
if (res.isError) {
state.value = state.value.copyWith(
@@ -523,6 +521,9 @@ class DetectionState {
return;
}
final ipInfo = res.data;
state.value = state.value.copyWith(
isTesting: false,
);
if (ipInfo != null) {
state.value = state.value.copyWith(
isLoading: false,

View File

@@ -109,11 +109,7 @@ class _ConnectionsViewState extends ConsumerState<ConnectionsView> {
context.commonScaffoldState?.addKeyword(value);
},
trailing: IconButton(
padding: EdgeInsets.zero,
visualDensity: VisualDensity.compact,
style: ButtonStyle(
minimumSize: WidgetStatePropertyAll(Size.zero),
),
icon: const Icon(Icons.block),
onPressed: () {
_handleBlockConnection(trackerInfo.id);

View File

@@ -68,6 +68,7 @@ class TrackerInfoItem extends ConsumerWidget {
spacing: 8,
children: [
Flexible(
flex: 1,
child: Text(
trackerInfo.desc,
maxLines: 1,

View File

@@ -51,7 +51,7 @@ class _ProxiesListViewState extends State<ProxiesListView> {
void _adjustHeader() {
_headerStateNotifier.value = _getProxiesListHeaderSelectorState(
!_controller.hasClients ? 0 : _controller.offset,
_controller.offset,
);
}

View File

@@ -92,7 +92,6 @@ class InputDialog extends StatefulWidget {
final String? hintText;
final FormFieldValidator<String>? validator;
final AutovalidateMode? autovalidateMode;
final bool? obscureText;
const InputDialog({
super.key,
@@ -102,7 +101,6 @@ class InputDialog extends StatefulWidget {
this.resetValue,
this.hintText,
this.validator,
this.obscureText,
this.labelText,
this.autovalidateMode = AutovalidateMode.onUserInteraction,
});
@@ -170,9 +168,8 @@ class _InputDialogState extends State<InputDialog> {
runSpacing: 16,
children: [
TextFormField(
obscureText: widget.obscureText ?? false,
keyboardType: TextInputType.url,
maxLines: widget.obscureText == true ? 1 : 5,
maxLines: 5,
minLines: 1,
controller: textController,
onFieldSubmitted: (_) {

View File

@@ -1,7 +1,7 @@
name: fl_clash
description: A multi-platform proxy client based on ClashMeta, simple and easy to use, open-source and ad-free.
publish_to: 'none'
version: 0.8.87+2025072902
version: 0.8.87+2025072401
environment:
sdk: '>=3.1.0 <4.0.0'