refactor(ui): migrate to material_ui and streamline the overwrite flow

Changelog: Rebuilt the interface on material_ui and simplified the overwrite flow
Changelog-Type: feat
This commit is contained in:
chen08209
2026-08-24 17:54:23 +08:00
parent db6f5d9036
commit e40e8de16c
298 changed files with 1984 additions and 1517 deletions
+15 -3
View File
@@ -4,9 +4,11 @@ FlClash is a multi-platform proxy client based on ClashMeta (mihomo), built with
## Version Notes
- Release CI pins Flutter 3.44.4. Local SDK may diverge, so trust the CI
- Release CI pins Flutter 3.47.1. Local SDK may diverge, so trust the CI
version as the source of truth for release builds.
- Dart SDK constraint: `>=3.8.0 <4.0.0`.
- Dart SDK constraint: `>=3.8.0 <4.0.0`. The lower bound is load-bearing and
must not be raised to the Dart version the SDK actually ships; see
Dependency Ceilings.
## Forked Dependencies
@@ -66,11 +68,21 @@ pinned Flutter SDK resolves `analyzer` 12. `3.2.6-dev.1` is the only published
freezed release that accepts `analyzer` 12. Move to a stable release only once
one exists that accepts the analyzer the SDK actually resolves.
The `>=3.8.0` Dart lower bound is a language-version floor, not a stale minimum.
Dart 3.13 makes `final` on a parameter an error, and `freezed` still emits it in
the constructors it generates for every collection field it backs with a private
field (`const _LogsState({final List<Log> logs = const [], ...})`); 4.0.0-dev.3
emits it too. A pubspec's lower bound sets the package language version, so
`>=3.8.0` keeps that generated code legal while the SDK itself runs 3.13. Raising
the bound makes every `*.freezed.dart` fail to parse, which `flutter analyze`
does not catch because `lib/**/generated/**` is excluded. Raise it only once
freezed stops emitting the modifier.
One `analyzer` ceiling holds most of the remaining `flutter pub outdated` list.
The newest `build_runner`, `drift_dev`, `intl_utils`, `test`, and
`riverpod_generator` all require `analyzer` 13; `test` 1.31.2 additionally
requires `test_api` 0.7.13, while `flutter_test` from the pinned SDK depends on
`test_api` 0.7.11. Raising any of those bounds therefore fails version solving.
`test_api` 0.7.12. Raising any of those bounds therefore fails version solving.
The `riverpod` chain is the visible symptom. It is held at
`riverpod`/`flutter_riverpod` 3.3.2, `riverpod_annotation` 4.0.3, and
+9
View File
@@ -374,6 +374,15 @@ Do not manually edit generated files under:
After schema, model, or provider changes, run build generation and include focused tests when behavior changes.
`lib/l10n/l10n.dart` is the one file that still imports `package:flutter/material.dart`.
`intl_utils` hardcodes that import in its own template, so regenerating rewrites it and
there is nothing to fix here; `test/lint/design_package_test.dart` exempts the generated
l10n paths for that reason. It is harmless because the file only needs `Locale`,
`BuildContext`, `Localizations` and `LocalizationsDelegate`, which the legacy library and
`material_ui` both re-export from the same `package:flutter/widgets.dart`. Everything a
human writes takes Material from `material_ui`; `cupertino_ui` is banned outright and
survives only as a transitive dependency of `material_ui`.
Strings live in `arb/intl_{en,zh_CN,ja,ru}.arb` — flat JSON, no `@` metadata. Add a key to all four, then regenerate with
`dart run intl_utils:generate`, which rewrites `lib/l10n/`. A key present in only some locales silently falls back to
English at runtime, so add the translation rather than leaving it out.
+62
View File
@@ -30,6 +30,68 @@ Use this for user-facing Flutter UI changes in `lib/`, including widgets, screen
flutter test test/widgets/
```
## Corner Radii
All corner radii come from `lib/common/shape.dart`. Never write a radius literal in a widget.
The scale is picked by the component's **shortest side**, not by what looks good in isolation. A radius that reads as
a soft card at 64 logical pixels tall reads as a pill at 24 and as a square at 400, so a single radius everywhere is
the wrong kind of consistency.
| Token | Value | Shortest side | Use |
| --- | --- | --- | --- |
| `none` | 0 | - | square edges, and the flat side of a grouped run |
| `xs` | 4 | inset blocks | tiles clipped inside an already rounded surface |
| `sm` | 8 | up to 48 | chips, thumbs, swatches, small square tiles |
| `md` | 16 | up to 64 | interactive chrome: inputs, menus, buttons, popups, FAB |
| `lg` | 20 | 64 to 180 | mid-size cards: dashboard tiles, proxy node cards |
| `xl` | 24 | full-bleed | anything spanning the whole width: list rows, grouped runs, group headers |
| `xxl` | 28 | over 200 | sheets, dialogs, full-screen containers |
| `full` | 1000 | - | pills and circles: tracks, indicators, progress, avatars |
`AppCorner.fit(shortestSide)` applies that table at runtime and is the right call whenever the size comes from a
`LayoutBuilder` or scales with text size. It snaps to the largest token that stays at or under one third of the
shortest side, which is the rule the table encodes.
- `AppCorner` holds the scale as `double`, for `radius:` on `CommonCard` and for arithmetic.
- `AppRadius` mirrors it as `BorderRadius`, plus `all`, `top`, and `vertical` builders.
- `AppShape` mirrors it as `RoundedSuperellipseBorder`, plus `full` (stadium), `circle`, `input`, and the
`all`/`top`/`vertical`/`of` builders.
- `ThemeData.withAppShapes` in `lib/application.dart` applies the scale to card, dialog, bottom sheet, snack bar,
chip, menu, input, FAB, navigation indicator, and progress themes. Do not restate those shapes at call sites; in
particular, leave `InputDecoration.border` unset so inputs inherit `AppShape.input`.
The three tiers between `md` and `xxl` each answer to a different size class, and the split is what keeps one radius
from being wrong for two of them.
`xl` is for a surface that spans the full width. A wide, short strip needs a larger corner than its height alone
suggests, or it stops reading as a card. Everything full-bleed shares this token and must stay on it:
`CommonSelectedListItem`, the profiles card, the outer corners of a grouped run in `DecorationListItem`
(`generateSectionV3`), and the proxy group header in `lib/views/proxies/list.dart`. The value is deliberately under
half the height of a standard row, so nothing gets clamped and every one of them renders at the identical radius no
matter which is taller. This is the one place the one-third rule is knowingly overshot; the width is what carries
it, and `fit()` is not used here.
`lg` is for the mid-size card that is not full-bleed: dashboard tiles and proxy node cards. It exists because `xl`
does not fit all of them. A proxy node card's height follows the user's `ProxyCardType` setting, and at `min` it is
only about 64 tall, which caps its radius at 21 — so `xl` would break on a setting the user can change at any time,
while `lg` clears every one of the three heights. The same value has room to spare on the smallest dashboard tile,
about 177x80, so both surfaces can hold one token instead of branching per size.
Outlined inputs use `AppInputBorder`, not `ShapedInputBorder` from `package:material_ui`. That one subtracts the
floating label's notch from the outline as a two-pixel band along the top edge, which assumes the label sits over a
flat run of border. Any radius from 8 up puts the corner curve under the notch instead, the subtraction takes the
corner with it, and the top edge is left drawn a pixel low. `AppInputBorder` clips the notch region away and paints
the full superellipse through it, so the corner arc is truncated exactly where the notch begins. That is what
Flutter's own `OutlineInputBorder` does by shortening the corner arc's sweep, which is why the framework border
survives large radii and the package one does not. The border needs no `contentPadding` compensation; leave Material's
defaults alone.
Nested radii are derived, never tokens. Concentric corners need `outer = inner + inset`, so name the inset and
compute the outer value: `_cardRadius` in `lib/widgets/popup.dart`, `_kCornerRadius` in `lib/widgets/tab.dart`, and
the selection ring in `lib/widgets/palette.dart` all do this. Adding an intermediate token to spell one of these out
is what makes a scale grow without bound.
## Pitfalls
- Do not introduce a new visual system for one screen.
+1 -1
View File
@@ -13,7 +13,7 @@ concurrency:
env:
IS_STABLE: ${{ !contains(github.ref, '-') }}
FLUTTER_VERSION: '3.44.4'
FLUTTER_VERSION: '3.47.1'
jobs:
test:
+6
View File
@@ -6,5 +6,11 @@ analyzer:
- lib/l10n/intl/**
- lib/**/generated/**
- plugins/**
- android/**
- ios/**
- web/**
- windows/**
- macos/**
- linux/**
errors:
invalid_annotation_target: ignore
+11 -11
View File
@@ -11,10 +11,10 @@ import 'package:fl_clash/manager/manager.dart';
import 'package:fl_clash/plugins/app.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter/services.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'pages/pages.dart';
Widget buildManagerStack({
@@ -149,15 +149,15 @@ class ApplicationState extends ConsumerState<Application> {
onNavigationNotification: (_) => true,
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
...GlobalMaterialLocalizations.delegates,
],
builder: (_, child) {
return buildManagerStack(
isDesktop: system.isDesktop,
onConnectivityChanged: _handleConnectivityChanged,
child: child!,
return MaterialUiCompatibilityBridge(
child: buildManagerStack(
isDesktop: system.isDesktop,
onConnectivityChanged: _handleConnectivityChanged,
child: child!,
),
);
},
scrollBehavior: BaseScrollBehavior(),
@@ -169,14 +169,14 @@ class ApplicationState extends ConsumerState<Application> {
useMaterial3: true,
pageTransitionsTheme: _pageTransitionsTheme,
colorScheme: _getAppColorScheme(brightness: Brightness.light),
),
).withAppShapes,
darkTheme: ThemeData(
useMaterial3: true,
pageTransitionsTheme: _pageTransitionsTheme,
colorScheme: _getAppColorScheme(
brightness: Brightness.dark,
).toPureBlack(themeProps.pureBlack),
),
).withAppShapes,
home: child!,
);
},
+1 -1
View File
@@ -15,7 +15,7 @@ import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/views/navigation.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:material_color_utilities/palettes/core_palette.dart';
+1
View File
@@ -1,5 +1,6 @@
import 'package:dio/dio.dart';
import 'package:fl_clash/l10n/l10n.dart';
import 'dart:ui';
final currentAppLocalizations = AppLocalizations.current;
+1 -1
View File
@@ -1,6 +1,6 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
extension ColorExtension on Color {
Color get opacity80 {
+1
View File
@@ -39,6 +39,7 @@ export 'proxy.dart';
export 'render.dart';
export 'request.dart';
export 'scroll.dart';
export 'shape.dart';
export 'snowflake.dart';
export 'string.dart';
export 'system.dart';
+1 -1
View File
@@ -7,7 +7,7 @@ import 'package:collection/collection.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
const appName = 'FlClash';
const appHelperService = 'FlClashHelperService';
+1 -1
View File
@@ -7,7 +7,7 @@ import 'package:fl_clash/providers/app.dart';
import 'package:fl_clash/widgets/inherited.dart';
import 'package:fl_clash/widgets/scaffold.dart';
import 'package:fl_clash/widgets/sheet.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
extension BuildContextExtension on BuildContext {
+1 -1
View File
@@ -1,4 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart';
import 'context.dart';
+2 -1
View File
@@ -1,10 +1,11 @@
import 'dart:async';
import 'package:animations/animations.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:url_launcher/url_launcher.dart';
class Dialogs {
+1 -1
View File
@@ -1,4 +1,4 @@
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
class IconsExt {
static const IconData target = IconData(0xe900, fontFamily: 'Icons');
+1
View File
@@ -2,6 +2,7 @@ import 'package:flutter/services.dart';
import 'package:uni_platform/uni_platform.dart';
import 'system.dart';
import 'package:flutter/widgets.dart';
final Map<PhysicalKeyboardKey, String> _knownKeyLabels =
+25 -2
View File
@@ -19,6 +19,29 @@ int getProxiesColumns(double viewWidth, ProxiesLayout proxiesLayout) {
};
}
int getProfilesColumns(double viewWidth) {
return max((viewWidth / 280).floor(), 1);
/// The narrowest a profile card may be before the quota row inside it, which
/// puts traffic on the left and the expiry date on the right of a single line,
/// runs out of room and starts to ellipsize.
///
/// Derived from the widest realistic row rather than picked by eye:
/// `1023.9 GB / 1023.9 GB` plus a 12px gap plus a `2026-11-03` expiry needs
/// about 227px at the row's 14px type, and the card spends another 92px on
/// horizontal padding, the trailing menu button, and the gap before it.
const profileItemMinWidth = 320.0;
/// The number of columns that fit in [viewWidth] while keeping every card at
/// least [minItemWidth] wide.
///
/// [Grid] puts [spacing] between columns, so a card is not `viewWidth /
/// columns` wide but `(viewWidth + spacing) / columns - spacing`. Dividing
/// [viewWidth] by the minimum alone ignores that and overshoots by a column
/// right at each breakpoint, handing every card less room than was asked for.
/// Inverting the real stride is what makes the minimum an actual guarantee.
int getProfilesColumns(
double viewWidth, {
double spacing = 0,
double minItemWidth = profileItemMinWidth,
}) {
final columns = (viewWidth + spacing) / (minItemWidth + spacing);
return max(columns.floor(), 1);
}
+54 -8
View File
@@ -1,11 +1,23 @@
import 'package:fl_clash/common/common.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
typedef _TextMeasureKey = (
String?,
TextStyle?,
TextStyle?,
int?,
TextDirection?,
double?,
);
class Measure {
static const _textMeasureCacheLimit = 512;
final TextScaler _textScaler;
final BuildContext context;
final Map<String, dynamic> _measureMap;
final Map<_TextMeasureKey, Size> _textSizeCache = {};
final Map<_TextMeasureKey, bool> _textOverflowCache = {};
Measure.of(this.context, double textScaleFactor)
: _measureMap = {},
@@ -36,16 +48,50 @@ class Measure {
}
}
_TextMeasureKey _measureKey(Text text, TextStyle? style, double? maxWidth) {
return (
text.data,
text.style,
style,
text.maxLines,
text.textDirection,
maxWidth,
);
}
R _cached<R extends Object>(
Map<_TextMeasureKey, R> cache,
_TextMeasureKey key,
R Function() compute,
) {
final cachedValue = cache[key];
if (cachedValue != null) {
return cachedValue;
}
if (cache.length >= _textMeasureCacheLimit) {
cache.clear();
}
return cache[key] = compute();
}
Size computeTextSize(Text text, {TextStyle? style, double? maxWidth}) {
return _measuring(text, style, maxWidth, (painter) => painter.size);
return _cached(
_textSizeCache,
_measureKey(text, style, maxWidth),
() => _measuring(text, style, maxWidth, (painter) => painter.size),
);
}
bool computeTextIsOverflow(Text text, {TextStyle? style, double? maxWidth}) {
return _measuring(
text,
style,
maxWidth,
(painter) => painter.didExceedMaxLines,
return _cached(
_textOverflowCache,
_measureKey(text, style, maxWidth),
() => _measuring(
text,
style,
maxWidth,
(painter) => painter.didExceedMaxLines,
),
);
}
+2 -1
View File
@@ -1,6 +1,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart';
import 'package:riverpod/riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'snowflake.dart';
mixin AutoDisposeNotifierMixin<T> on AnyNotifier<T, T> {
+1 -1
View File
@@ -1,6 +1,6 @@
import 'package:animations/animations.dart';
import 'package:fl_clash/common/common.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
final rootNavigatorKey = GlobalKey<NavigatorState>();
+1 -1
View File
@@ -4,7 +4,7 @@ import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/common.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
extension NumExt on num {
String fixed({int decimals = 2}) {
+1 -1
View File
@@ -3,7 +3,7 @@ import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/providers/app.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
String compactError(Object error) {
if (error is DioException) {
+1 -1
View File
@@ -3,7 +3,7 @@ import 'dart:ui';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/widgets/scroll.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
class BaseScrollBehavior extends MaterialScrollBehavior {
@override
+277
View File
@@ -0,0 +1,277 @@
import 'dart:math' as math;
import 'dart:ui' show ClipOp, lerpDouble;
import 'package:material_ui/material_ui.dart';
abstract final class AppCorner {
static const double none = 0;
static const double xs = 4;
static const double sm = 8;
static const double md = 16;
static const double lg = 20;
static const double xl = 24;
static const double xxl = 28;
static const double full = 1000;
static double fit(double shortestSide) {
final limit = shortestSide / 3;
if (limit >= xxl) return xxl;
if (limit >= xl) return xl;
if (limit >= lg) return lg;
if (limit >= md) return md;
if (limit >= sm) return sm;
if (limit >= xs) return xs;
return none;
}
}
abstract final class AppRadius {
static const BorderRadius none = BorderRadius.zero;
static const BorderRadius xs = BorderRadius.all(
Radius.circular(AppCorner.xs),
);
static const BorderRadius sm = BorderRadius.all(
Radius.circular(AppCorner.sm),
);
static const BorderRadius md = BorderRadius.all(
Radius.circular(AppCorner.md),
);
static const BorderRadius lg = BorderRadius.all(
Radius.circular(AppCorner.lg),
);
static const BorderRadius xl = BorderRadius.all(
Radius.circular(AppCorner.xl),
);
static const BorderRadius xxl = BorderRadius.all(
Radius.circular(AppCorner.xxl),
);
static const BorderRadius full = BorderRadius.all(
Radius.circular(AppCorner.full),
);
static BorderRadius all(double corner) => BorderRadius.circular(corner);
static BorderRadius top(double corner) =>
BorderRadius.vertical(top: Radius.circular(corner));
static BorderRadius vertical({
double top = AppCorner.none,
double bottom = AppCorner.none,
}) => BorderRadius.vertical(
top: Radius.circular(top),
bottom: Radius.circular(bottom),
);
}
abstract final class AppShape {
static const RoundedSuperellipseBorder none = RoundedSuperellipseBorder();
static const RoundedSuperellipseBorder xs = RoundedSuperellipseBorder(
borderRadius: AppRadius.xs,
);
static const RoundedSuperellipseBorder sm = RoundedSuperellipseBorder(
borderRadius: AppRadius.sm,
);
static const RoundedSuperellipseBorder md = RoundedSuperellipseBorder(
borderRadius: AppRadius.md,
);
static const RoundedSuperellipseBorder lg = RoundedSuperellipseBorder(
borderRadius: AppRadius.lg,
);
static const RoundedSuperellipseBorder xl = RoundedSuperellipseBorder(
borderRadius: AppRadius.xl,
);
static const RoundedSuperellipseBorder xxl = RoundedSuperellipseBorder(
borderRadius: AppRadius.xxl,
);
static const StadiumBorder full = StadiumBorder();
static const CircleBorder circle = CircleBorder();
static const AppInputBorder input = AppInputBorder();
static RoundedSuperellipseBorder all(double corner) =>
RoundedSuperellipseBorder(borderRadius: AppRadius.all(corner));
static RoundedSuperellipseBorder top(double corner) =>
RoundedSuperellipseBorder(borderRadius: AppRadius.top(corner));
static RoundedSuperellipseBorder vertical({
double top = AppCorner.none,
double bottom = AppCorner.none,
}) => RoundedSuperellipseBorder(
borderRadius: AppRadius.vertical(top: top, bottom: bottom),
);
static RoundedSuperellipseBorder of(BorderRadius borderRadius) =>
RoundedSuperellipseBorder(borderRadius: borderRadius);
}
class AppInputBorder extends InputBorder {
const AppInputBorder({
super.borderSide = const BorderSide(),
this.borderRadius = AppRadius.md,
this.gapPadding = 4.0,
});
final BorderRadius borderRadius;
final double gapPadding;
RoundedSuperellipseBorder get _shape =>
RoundedSuperellipseBorder(borderRadius: borderRadius, side: borderSide);
@override
bool get isOutline => true;
@override
bool get preferPaintInterior => true;
@override
EdgeInsetsGeometry get dimensions => EdgeInsets.all(borderSide.width);
@override
AppInputBorder copyWith({
BorderSide? borderSide,
BorderRadius? borderRadius,
double? gapPadding,
}) {
return AppInputBorder(
borderSide: borderSide ?? this.borderSide,
borderRadius: borderRadius ?? this.borderRadius,
gapPadding: gapPadding ?? this.gapPadding,
);
}
@override
AppInputBorder scale(double t) {
return AppInputBorder(
borderSide: borderSide.scale(t),
borderRadius: borderRadius * t,
gapPadding: gapPadding * t,
);
}
@override
Path getInnerPath(Rect rect, {TextDirection? textDirection}) =>
_shape.getInnerPath(rect, textDirection: textDirection);
@override
Path getOuterPath(Rect rect, {TextDirection? textDirection}) =>
_shape.getOuterPath(rect, textDirection: textDirection);
@override
void paintInterior(
Canvas canvas,
Rect rect,
Paint paint, {
TextDirection? textDirection,
}) => _shape.paintInterior(canvas, rect, paint, textDirection: textDirection);
@override
ShapeBorder? lerpFrom(ShapeBorder? a, double t) {
if (a is AppInputBorder) {
return AppInputBorder(
borderSide: BorderSide.lerp(a.borderSide, borderSide, t),
borderRadius: BorderRadius.lerp(a.borderRadius, borderRadius, t)!,
gapPadding: a.gapPadding,
);
}
return super.lerpFrom(a, t);
}
@override
ShapeBorder? lerpTo(ShapeBorder? b, double t) {
if (b is AppInputBorder) {
return AppInputBorder(
borderSide: BorderSide.lerp(borderSide, b.borderSide, t),
borderRadius: BorderRadius.lerp(borderRadius, b.borderRadius, t)!,
gapPadding: b.gapPadding,
);
}
return super.lerpTo(b, t);
}
@override
void paint(
Canvas canvas,
Rect rect, {
double? gapStart,
double gapExtent = 0.0,
double gapPercentage = 0.0,
TextDirection? textDirection,
}) {
final outline = rect.deflate(borderSide.width / 2);
if (gapStart == null || gapExtent <= 0.0 || gapPercentage == 0.0) {
_shape.paint(canvas, outline, textDirection: textDirection);
return;
}
final extent = lerpDouble(
0.0,
gapExtent + gapPadding * 2.0,
gapPercentage,
)!;
final start = switch (textDirection ?? TextDirection.ltr) {
TextDirection.rtl => gapStart + gapPadding - extent,
TextDirection.ltr => gapStart - gapPadding,
};
final radii = borderRadius.resolve(textDirection);
final left = outline.left + math.max(0.0, start);
final depth =
math.max(radii.topLeft.y, radii.topRight.y) + borderSide.width;
canvas
..save()
..clipRect(
Rect.fromLTRB(
left,
outline.top - borderSide.width,
left + extent,
outline.top + depth,
),
clipOp: ClipOp.difference,
);
_shape.paint(canvas, outline, textDirection: textDirection);
canvas.restore();
}
@override
bool operator ==(Object other) {
if (identical(this, other)) {
return true;
}
return other is AppInputBorder &&
other.borderSide == borderSide &&
other.borderRadius == borderRadius &&
other.gapPadding == gapPadding;
}
@override
int get hashCode => Object.hash(borderSide, borderRadius, gapPadding);
}
extension AppShapeThemeExt on ThemeData {
ThemeData get withAppShapes => copyWith(
cardTheme: cardTheme.copyWith(shape: AppShape.md),
dialogTheme: dialogTheme.copyWith(shape: AppShape.xxl),
bottomSheetTheme: bottomSheetTheme.copyWith(
shape: AppShape.top(AppCorner.xxl),
),
snackBarTheme: snackBarTheme.copyWith(shape: AppShape.xs),
chipTheme: chipTheme.copyWith(shape: AppShape.sm),
popupMenuTheme: popupMenuTheme.copyWith(shape: AppShape.md),
menuTheme: MenuThemeData(
style: (menuTheme.style ?? const MenuStyle()).copyWith(
shape: const WidgetStatePropertyAll(AppShape.md),
),
),
inputDecorationTheme: inputDecorationTheme.copyWith(border: AppShape.input),
floatingActionButtonTheme: floatingActionButtonTheme.copyWith(
shape: AppShape.md,
),
navigationBarTheme: navigationBarTheme.copyWith(
indicatorShape: AppShape.full,
),
navigationRailTheme: navigationRailTheme.copyWith(
indicatorShape: AppShape.full,
),
progressIndicatorTheme: progressIndicatorTheme.copyWith(
borderRadius: AppRadius.full,
),
);
}
+1
View File
@@ -4,6 +4,7 @@ import 'dart:typed_data';
import 'package:crypto/crypto.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'dart:math';
extension StringExtension on String {
+17
View File
@@ -80,6 +80,23 @@ Future<List<Group>> buildGroups(ComputeGroupsState state) async {
);
}
Future<ClashConfig> clashConfigTask(Map<String, dynamic> data) async {
return compute<Map<String, dynamic>, ClashConfig>(buildClashConfig, data);
}
@visibleForTesting
ClashConfig buildClashConfig(Map<String, dynamic> configMap) {
final clashConfig = ClashConfig.fromJson(configMap);
final proxyTypeMap = <String, String>{};
for (final proxy in clashConfig.proxies) {
proxyTypeMap[proxy.name] = proxy.type;
}
for (final proxyGroup in clashConfig.proxyGroups) {
proxyTypeMap[proxyGroup.name] = proxyGroup.type.value;
}
return clashConfig.copyWith(proxyTypeMap: proxyTypeMap);
}
Future<({String yaml, String md5})> makeRealProfileTask(
MakeRealProfileState data,
) async {
+2 -1
View File
@@ -1,5 +1,6 @@
import 'package:fl_clash/enum/enum.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'color.dart';
extension TextStyleExtension on TextStyle {
+1 -1
View File
@@ -1,5 +1,5 @@
import 'package:fl_clash/common/common.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
class CommonTheme {
final BuildContext context;
+1 -1
View File
@@ -2,7 +2,7 @@ import 'dart:io';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/models/config.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:screen_retriever/screen_retriever.dart';
import 'package:window_manager/window_manager.dart';
+6 -3
View File
@@ -4,7 +4,7 @@ import 'dart:io';
import 'package:fl_clash/common/context.dart';
import 'package:fl_clash/common/system.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter/services.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
@@ -450,8 +450,11 @@ enum RuleTarget {
DIRECT,
REJECT;
static Set<String> get baseTargets =>
RuleTarget.values.map((item) => item.name).toSet();
static final List<String> baseTargetNames = List.unmodifiable(
RuleTarget.values.map((item) => item.name),
);
static final Set<String> baseTargets = Set.unmodifiable(baseTargetNames);
}
enum RestoreStrategy { compatible, override }
@@ -2,7 +2,7 @@ import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
typedef OverwriteItemBuilder<T> =
@@ -1,7 +1,7 @@
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
class InfoMessageButton extends StatelessWidget {
final String message;
@@ -1,34 +1,29 @@
import 'dart:async';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod/misc.dart' show Override;
import 'package:smooth_sheets/smooth_sheets.dart';
import 'overwrite_stage_flow.dart';
Color _sheetFillColorOf(BuildContext context) {
return SheetProvider.of(context)?.type == SheetType.bottomSheet
? context.colorScheme.surfaceContainerLow
: context.colorScheme.surface;
}
Widget fadeAndSlideTransition(
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) {
return FadeTransition(
opacity: CurveTween(curve: Curves.easeInExpo).animate(animation),
child: FadeTransition(
opacity: Tween(begin: 1.0, end: 0.4)
.chain(CurveTween(curve: Curves.easeOutExpo))
.animate(secondaryAnimation),
child: const FadeForwardsPageTransitionsBuilder().buildTransitions(
ModalRoute.of(context) as PageRoute,
context,
animation,
secondaryAnimation,
child,
),
),
);
return FadeForwardsPageTransitionsBuilder(
backgroundColor: _sheetFillColorOf(context),
).buildTransitions(null, context, animation, secondaryAnimation, child);
}
Future<void> showOverwriteNestedSheet<T>({
@@ -147,9 +142,7 @@ class _OverwriteNestedSheetState<T>
},
);
final sheetProvider = SheetProvider.of(context);
final fillColor = sheetProvider?.type == SheetType.bottomSheet
? context.colorScheme.surfaceContainerLow
: context.colorScheme.surface;
final fillColor = _sheetFillColorOf(context);
return CommonPopScope(
onPop: (_) async {
unawaited(_handlePop());
@@ -174,7 +167,7 @@ class _OverwriteNestedSheetState<T>
child: PagedSheetRouteTheme(
data: const PagedSheetRouteThemeData(
transitionsBuilder: fadeAndSlideTransition,
transitionDuration: Duration(milliseconds: 300),
transitionDuration: Duration(milliseconds: 200),
),
child: PagedSheet(
decoration: MaterialSheetDecoration(
@@ -182,10 +175,8 @@ class _OverwriteNestedSheetState<T>
size: SheetSize.stretch,
color: fillColor,
borderRadius: sheetProvider.type == SheetType.bottomSheet
? const BorderRadius.vertical(
top: Radius.circular(28),
)
: BorderRadius.zero,
? AppRadius.top(AppCorner.xxl)
: AppRadius.none,
clipBehavior: Clip.antiAlias,
),
navigator: nestedNavigator,
@@ -1,7 +1,7 @@
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class OverwriteSelectionSection<T> {
@@ -4,7 +4,7 @@ import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'overwrite_form_row.dart';
+4 -7
View File
@@ -6,7 +6,7 @@ import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/clash_config.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
final ruleItemHeight =
globalState.measure.bodyLargeHeight +
@@ -282,7 +282,7 @@ class _AddOrEditRuleDialogState extends State<AddOrEditRuleDialog> {
child: DropdownMenuTheme(
data: DropdownMenuThemeData(
inputDecorationTheme: InputDecorationTheme(
border: const OutlineInputBorder(),
border: AppShape.input,
labelStyle: context.textTheme.bodyLarge?.copyWith(
overflow: TextOverflow.ellipsis,
),
@@ -378,10 +378,7 @@ class _RuleContentField extends StatelessWidget {
onSubmitted();
},
controller: controller,
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: appLocalizations.content,
),
decoration: InputDecoration(labelText: appLocalizations.content),
validator: (_) {
if (controller.text.isEmpty) {
return appLocalizations.emptyTip(appLocalizations.content);
@@ -438,7 +435,7 @@ class _RuleFlagChip extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CommonCard(
radius: 8,
radius: AppCorner.sm,
isSelected: isSelected,
onPressed: onPressed,
child: Padding(
+1 -1
View File
@@ -3,7 +3,7 @@ import 'dart:io';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/pages/error.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:rust_api/rust_api.dart';
+1 -1
View File
@@ -5,7 +5,7 @@ import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/plugins/app.dart';
import 'package:fl_clash/plugins/service.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class AndroidManager extends ConsumerStatefulWidget {
+1 -1
View File
@@ -10,7 +10,7 @@ import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/animated_visibility.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/intl.dart';
+1 -1
View File
@@ -4,7 +4,7 @@ import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/providers/app.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:wifi_ssid/wifi_ssid.dart';
+1 -1
View File
@@ -9,7 +9,7 @@ import 'package:fl_clash/providers/app.dart';
import 'package:fl_clash/providers/config.dart';
import 'package:fl_clash/providers/core.dart';
import 'package:fl_clash/providers/state.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class CoreManager extends ConsumerStatefulWidget {
+2 -1
View File
@@ -1,11 +1,12 @@
import 'dart:async';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/common.dart';
import 'package:fl_clash/providers/action.dart';
import 'package:fl_clash/providers/config.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hotkey_manager/hotkey_manager.dart';
+1 -1
View File
@@ -3,7 +3,7 @@ import 'package:fl_clash/common/print.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/providers/state.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class ProxyManager extends ConsumerStatefulWidget {
+2 -4
View File
@@ -8,7 +8,7 @@ import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/providers/app.dart';
import 'package:fl_clash/providers/state.dart';
import 'package:fl_clash/widgets/theme.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
const _actionMinDuration = Duration(seconds: 6);
@@ -442,9 +442,7 @@ class _MessageCard extends StatelessWidget {
},
child: Card(
margin: EdgeInsets.zero,
shape: const RoundedSuperellipseBorder(
borderRadius: BorderRadius.all(Radius.circular(14)),
),
shape: AppShape.md,
elevation: 6,
color: message.level.containerColor(context),
child: ConstrainedBox(
+10 -20
View File
@@ -5,7 +5,7 @@ import 'package:fl_clash/common/theme.dart';
import 'package:fl_clash/providers/action.dart';
import 'package:fl_clash/providers/config.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -66,25 +66,15 @@ class ThemeManager extends ConsumerWidget {
top: padding.top > height * 0.3 ? 20.0 : padding.top,
),
),
child: Theme(
data: Theme.of(context).copyWith(
floatingActionButtonTheme: Theme.of(context).floatingActionButtonTheme
.copyWith(
shape: const RoundedSuperellipseBorder(
borderRadius: BorderRadius.all(Radius.circular(16.0)),
),
),
),
child: LayoutBuilder(
builder: (_, constraints) {
ref
.read(themeActionProvider.notifier)
.updateViewSize(
Size(constraints.maxWidth, constraints.maxHeight),
);
return _buildSystemUi(child);
},
),
child: LayoutBuilder(
builder: (_, constraints) {
ref
.read(themeActionProvider.notifier)
.updateViewSize(
Size(constraints.maxWidth, constraints.maxHeight),
);
return _buildSystemUi(child);
},
),
);
}
+2 -1
View File
@@ -1,10 +1,11 @@
import 'dart:async';
import 'package:fl_clash/common/app_localizations.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/plugins/app.dart';
import 'package:fl_clash/plugins/tile.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class TileManager extends ConsumerStatefulWidget {
+1 -1
View File
@@ -6,7 +6,7 @@ import 'package:fl_clash/common/window.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/providers/action.dart';
import 'package:fl_clash/providers/state.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:tray/tray.dart';
+1 -1
View File
@@ -4,7 +4,7 @@ import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/providers/action.dart';
import 'package:fl_clash/providers/state.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class VpnManager extends ConsumerStatefulWidget {
+2 -4
View File
@@ -4,7 +4,7 @@ import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/common/launch.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:window_ext/window_ext.dart';
import 'package:window_manager/window_manager.dart';
@@ -319,9 +319,7 @@ class AppIcon extends StatelessWidget {
return Container(
decoration: ShapeDecoration(
color: context.colorScheme.surfaceContainerHighest,
shape: RoundedSuperellipseBorder(
borderRadius: BorderRadius.circular(14),
),
shape: AppShape.md,
),
padding: const EdgeInsets.all(8),
child: Transform.translate(
+5 -10
View File
@@ -154,7 +154,9 @@ abstract class Proxy with _$Proxy {
@freezed
abstract class CustomOverwriteDate with _$CustomOverwriteDate {
const factory CustomOverwriteDate({
@Default([]) List<Proxy> proxies,
@Default(false) bool loaded,
@Default([]) List<String> proxyNames,
@Default({}) Map<String, String> proxyTypes,
@Default([]) List<ProxyGroup> proxyGroups,
@Default({}) Set<String> proxyProviders,
@Default({}) Set<String> ruleTargets,
@@ -166,24 +168,17 @@ abstract class CustomOverwriteDate with _$CustomOverwriteDate {
abstract class CustomOverwriteSelectorState
with _$CustomOverwriteSelectorState {
const factory CustomOverwriteSelectorState({
required bool loaded,
required List<Proxy> proxies,
required List<String> subRules,
required List<String> proxyProviders,
}) = _CustomOverwriteSelectorState;
}
@freezed
abstract class ProxiesAndGroupsSelectorState
with _$ProxiesAndGroupsSelectorState {
const factory ProxiesAndGroupsSelectorState({
required List<Proxy> proxies,
required List<ProxyGroup> proxyGroups,
}) = _ProxiesAndGroupsSelectorState;
}
@freezed
abstract class RuleTargetsSelectorState with _$RuleTargetsSelectorState {
const factory RuleTargetsSelectorState({
required bool loaded,
required Set<String> ruleTargets,
required Set<String> subRules,
}) = _RuleTargetsSelectorState;
+1 -1
View File
@@ -5,7 +5,7 @@ import 'dart:math';
import 'package:collection/collection.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'clash_config.dart';
+1 -1
View File
@@ -1,6 +1,6 @@
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'models.dart';
+84 -338
View File
@@ -625,7 +625,7 @@ as String?,
/// @nodoc
mixin _$CustomOverwriteDate {
List<Proxy> get proxies; List<ProxyGroup> get proxyGroups; Set<String> get proxyProviders; Set<String> get ruleTargets; Set<String> get subRules;
bool get loaded; List<String> get proxyNames; Map<String, String> get proxyTypes; List<ProxyGroup> get proxyGroups; Set<String> get proxyProviders; Set<String> get ruleTargets; Set<String> get subRules;
/// Create a copy of CustomOverwriteDate
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -636,16 +636,16 @@ $CustomOverwriteDateCopyWith<CustomOverwriteDate> get copyWith => _$CustomOverwr
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is CustomOverwriteDate&&const DeepCollectionEquality().equals(other.proxies, proxies)&&const DeepCollectionEquality().equals(other.proxyGroups, proxyGroups)&&const DeepCollectionEquality().equals(other.proxyProviders, proxyProviders)&&const DeepCollectionEquality().equals(other.ruleTargets, ruleTargets)&&const DeepCollectionEquality().equals(other.subRules, subRules));
return identical(this, other) || (other.runtimeType == runtimeType&&other is CustomOverwriteDate&&(identical(other.loaded, loaded) || other.loaded == loaded)&&const DeepCollectionEquality().equals(other.proxyNames, proxyNames)&&const DeepCollectionEquality().equals(other.proxyTypes, proxyTypes)&&const DeepCollectionEquality().equals(other.proxyGroups, proxyGroups)&&const DeepCollectionEquality().equals(other.proxyProviders, proxyProviders)&&const DeepCollectionEquality().equals(other.ruleTargets, ruleTargets)&&const DeepCollectionEquality().equals(other.subRules, subRules));
}
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(proxies),const DeepCollectionEquality().hash(proxyGroups),const DeepCollectionEquality().hash(proxyProviders),const DeepCollectionEquality().hash(ruleTargets),const DeepCollectionEquality().hash(subRules));
int get hashCode => Object.hash(runtimeType,loaded,const DeepCollectionEquality().hash(proxyNames),const DeepCollectionEquality().hash(proxyTypes),const DeepCollectionEquality().hash(proxyGroups),const DeepCollectionEquality().hash(proxyProviders),const DeepCollectionEquality().hash(ruleTargets),const DeepCollectionEquality().hash(subRules));
@override
String toString() {
return 'CustomOverwriteDate(proxies: $proxies, proxyGroups: $proxyGroups, proxyProviders: $proxyProviders, ruleTargets: $ruleTargets, subRules: $subRules)';
return 'CustomOverwriteDate(loaded: $loaded, proxyNames: $proxyNames, proxyTypes: $proxyTypes, proxyGroups: $proxyGroups, proxyProviders: $proxyProviders, ruleTargets: $ruleTargets, subRules: $subRules)';
}
@@ -656,7 +656,7 @@ abstract mixin class $CustomOverwriteDateCopyWith<$Res> {
factory $CustomOverwriteDateCopyWith(CustomOverwriteDate value, $Res Function(CustomOverwriteDate) _then) = _$CustomOverwriteDateCopyWithImpl;
@useResult
$Res call({
List<Proxy> proxies, List<ProxyGroup> proxyGroups, Set<String> proxyProviders, Set<String> ruleTargets, Set<String> subRules
bool loaded, List<String> proxyNames, Map<String, String> proxyTypes, List<ProxyGroup> proxyGroups, Set<String> proxyProviders, Set<String> ruleTargets, Set<String> subRules
});
@@ -673,10 +673,12 @@ class _$CustomOverwriteDateCopyWithImpl<$Res>
/// Create a copy of CustomOverwriteDate
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? proxies = null,Object? proxyGroups = null,Object? proxyProviders = null,Object? ruleTargets = null,Object? subRules = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? loaded = null,Object? proxyNames = null,Object? proxyTypes = null,Object? proxyGroups = null,Object? proxyProviders = null,Object? ruleTargets = null,Object? subRules = null,}) {
return _then(_self.copyWith(
proxies: null == proxies ? _self.proxies : proxies // ignore: cast_nullable_to_non_nullable
as List<Proxy>,proxyGroups: null == proxyGroups ? _self.proxyGroups : proxyGroups // ignore: cast_nullable_to_non_nullable
loaded: null == loaded ? _self.loaded : loaded // ignore: cast_nullable_to_non_nullable
as bool,proxyNames: null == proxyNames ? _self.proxyNames : proxyNames // ignore: cast_nullable_to_non_nullable
as List<String>,proxyTypes: null == proxyTypes ? _self.proxyTypes : proxyTypes // ignore: cast_nullable_to_non_nullable
as Map<String, String>,proxyGroups: null == proxyGroups ? _self.proxyGroups : proxyGroups // ignore: cast_nullable_to_non_nullable
as List<ProxyGroup>,proxyProviders: null == proxyProviders ? _self.proxyProviders : proxyProviders // ignore: cast_nullable_to_non_nullable
as Set<String>,ruleTargets: null == ruleTargets ? _self.ruleTargets : ruleTargets // ignore: cast_nullable_to_non_nullable
as Set<String>,subRules: null == subRules ? _self.subRules : subRules // ignore: cast_nullable_to_non_nullable
@@ -765,10 +767,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<Proxy> proxies, List<ProxyGroup> proxyGroups, Set<String> proxyProviders, Set<String> ruleTargets, Set<String> subRules)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool loaded, List<String> proxyNames, Map<String, String> proxyTypes, List<ProxyGroup> proxyGroups, Set<String> proxyProviders, Set<String> ruleTargets, Set<String> subRules)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _CustomOverwriteDate() when $default != null:
return $default(_that.proxies,_that.proxyGroups,_that.proxyProviders,_that.ruleTargets,_that.subRules);case _:
return $default(_that.loaded,_that.proxyNames,_that.proxyTypes,_that.proxyGroups,_that.proxyProviders,_that.ruleTargets,_that.subRules);case _:
return orElse();
}
@@ -786,10 +788,10 @@ return $default(_that.proxies,_that.proxyGroups,_that.proxyProviders,_that.ruleT
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<Proxy> proxies, List<ProxyGroup> proxyGroups, Set<String> proxyProviders, Set<String> ruleTargets, Set<String> subRules) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool loaded, List<String> proxyNames, Map<String, String> proxyTypes, List<ProxyGroup> proxyGroups, Set<String> proxyProviders, Set<String> ruleTargets, Set<String> subRules) $default,) {final _that = this;
switch (_that) {
case _CustomOverwriteDate():
return $default(_that.proxies,_that.proxyGroups,_that.proxyProviders,_that.ruleTargets,_that.subRules);case _:
return $default(_that.loaded,_that.proxyNames,_that.proxyTypes,_that.proxyGroups,_that.proxyProviders,_that.ruleTargets,_that.subRules);case _:
throw StateError('Unexpected subclass');
}
@@ -806,10 +808,10 @@ return $default(_that.proxies,_that.proxyGroups,_that.proxyProviders,_that.ruleT
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<Proxy> proxies, List<ProxyGroup> proxyGroups, Set<String> proxyProviders, Set<String> ruleTargets, Set<String> subRules)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool loaded, List<String> proxyNames, Map<String, String> proxyTypes, List<ProxyGroup> proxyGroups, Set<String> proxyProviders, Set<String> ruleTargets, Set<String> subRules)? $default,) {final _that = this;
switch (_that) {
case _CustomOverwriteDate() when $default != null:
return $default(_that.proxies,_that.proxyGroups,_that.proxyProviders,_that.ruleTargets,_that.subRules);case _:
return $default(_that.loaded,_that.proxyNames,_that.proxyTypes,_that.proxyGroups,_that.proxyProviders,_that.ruleTargets,_that.subRules);case _:
return null;
}
@@ -821,14 +823,22 @@ return $default(_that.proxies,_that.proxyGroups,_that.proxyProviders,_that.ruleT
class _CustomOverwriteDate implements CustomOverwriteDate {
const _CustomOverwriteDate({final List<Proxy> proxies = const [], final List<ProxyGroup> proxyGroups = const [], final Set<String> proxyProviders = const {}, final Set<String> ruleTargets = const {}, final Set<String> subRules = const {}}): _proxies = proxies,_proxyGroups = proxyGroups,_proxyProviders = proxyProviders,_ruleTargets = ruleTargets,_subRules = subRules;
const _CustomOverwriteDate({this.loaded = false, final List<String> proxyNames = const [], final Map<String, String> proxyTypes = const {}, final List<ProxyGroup> proxyGroups = const [], final Set<String> proxyProviders = const {}, final Set<String> ruleTargets = const {}, final Set<String> subRules = const {}}): _proxyNames = proxyNames,_proxyTypes = proxyTypes,_proxyGroups = proxyGroups,_proxyProviders = proxyProviders,_ruleTargets = ruleTargets,_subRules = subRules;
final List<Proxy> _proxies;
@override@JsonKey() List<Proxy> get proxies {
if (_proxies is EqualUnmodifiableListView) return _proxies;
@override@JsonKey() final bool loaded;
final List<String> _proxyNames;
@override@JsonKey() List<String> get proxyNames {
if (_proxyNames is EqualUnmodifiableListView) return _proxyNames;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_proxies);
return EqualUnmodifiableListView(_proxyNames);
}
final Map<String, String> _proxyTypes;
@override@JsonKey() Map<String, String> get proxyTypes {
if (_proxyTypes is EqualUnmodifiableMapView) return _proxyTypes;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_proxyTypes);
}
final List<ProxyGroup> _proxyGroups;
@@ -870,16 +880,16 @@ _$CustomOverwriteDateCopyWith<_CustomOverwriteDate> get copyWith => __$CustomOve
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CustomOverwriteDate&&const DeepCollectionEquality().equals(other._proxies, _proxies)&&const DeepCollectionEquality().equals(other._proxyGroups, _proxyGroups)&&const DeepCollectionEquality().equals(other._proxyProviders, _proxyProviders)&&const DeepCollectionEquality().equals(other._ruleTargets, _ruleTargets)&&const DeepCollectionEquality().equals(other._subRules, _subRules));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CustomOverwriteDate&&(identical(other.loaded, loaded) || other.loaded == loaded)&&const DeepCollectionEquality().equals(other._proxyNames, _proxyNames)&&const DeepCollectionEquality().equals(other._proxyTypes, _proxyTypes)&&const DeepCollectionEquality().equals(other._proxyGroups, _proxyGroups)&&const DeepCollectionEquality().equals(other._proxyProviders, _proxyProviders)&&const DeepCollectionEquality().equals(other._ruleTargets, _ruleTargets)&&const DeepCollectionEquality().equals(other._subRules, _subRules));
}
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_proxies),const DeepCollectionEquality().hash(_proxyGroups),const DeepCollectionEquality().hash(_proxyProviders),const DeepCollectionEquality().hash(_ruleTargets),const DeepCollectionEquality().hash(_subRules));
int get hashCode => Object.hash(runtimeType,loaded,const DeepCollectionEquality().hash(_proxyNames),const DeepCollectionEquality().hash(_proxyTypes),const DeepCollectionEquality().hash(_proxyGroups),const DeepCollectionEquality().hash(_proxyProviders),const DeepCollectionEquality().hash(_ruleTargets),const DeepCollectionEquality().hash(_subRules));
@override
String toString() {
return 'CustomOverwriteDate(proxies: $proxies, proxyGroups: $proxyGroups, proxyProviders: $proxyProviders, ruleTargets: $ruleTargets, subRules: $subRules)';
return 'CustomOverwriteDate(loaded: $loaded, proxyNames: $proxyNames, proxyTypes: $proxyTypes, proxyGroups: $proxyGroups, proxyProviders: $proxyProviders, ruleTargets: $ruleTargets, subRules: $subRules)';
}
@@ -890,7 +900,7 @@ abstract mixin class _$CustomOverwriteDateCopyWith<$Res> implements $CustomOverw
factory _$CustomOverwriteDateCopyWith(_CustomOverwriteDate value, $Res Function(_CustomOverwriteDate) _then) = __$CustomOverwriteDateCopyWithImpl;
@override @useResult
$Res call({
List<Proxy> proxies, List<ProxyGroup> proxyGroups, Set<String> proxyProviders, Set<String> ruleTargets, Set<String> subRules
bool loaded, List<String> proxyNames, Map<String, String> proxyTypes, List<ProxyGroup> proxyGroups, Set<String> proxyProviders, Set<String> ruleTargets, Set<String> subRules
});
@@ -907,10 +917,12 @@ class __$CustomOverwriteDateCopyWithImpl<$Res>
/// Create a copy of CustomOverwriteDate
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? proxies = null,Object? proxyGroups = null,Object? proxyProviders = null,Object? ruleTargets = null,Object? subRules = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? loaded = null,Object? proxyNames = null,Object? proxyTypes = null,Object? proxyGroups = null,Object? proxyProviders = null,Object? ruleTargets = null,Object? subRules = null,}) {
return _then(_CustomOverwriteDate(
proxies: null == proxies ? _self._proxies : proxies // ignore: cast_nullable_to_non_nullable
as List<Proxy>,proxyGroups: null == proxyGroups ? _self._proxyGroups : proxyGroups // ignore: cast_nullable_to_non_nullable
loaded: null == loaded ? _self.loaded : loaded // ignore: cast_nullable_to_non_nullable
as bool,proxyNames: null == proxyNames ? _self._proxyNames : proxyNames // ignore: cast_nullable_to_non_nullable
as List<String>,proxyTypes: null == proxyTypes ? _self._proxyTypes : proxyTypes // ignore: cast_nullable_to_non_nullable
as Map<String, String>,proxyGroups: null == proxyGroups ? _self._proxyGroups : proxyGroups // ignore: cast_nullable_to_non_nullable
as List<ProxyGroup>,proxyProviders: null == proxyProviders ? _self._proxyProviders : proxyProviders // ignore: cast_nullable_to_non_nullable
as Set<String>,ruleTargets: null == ruleTargets ? _self._ruleTargets : ruleTargets // ignore: cast_nullable_to_non_nullable
as Set<String>,subRules: null == subRules ? _self._subRules : subRules // ignore: cast_nullable_to_non_nullable
@@ -924,7 +936,7 @@ as Set<String>,
/// @nodoc
mixin _$CustomOverwriteSelectorState {
List<Proxy> get proxies; List<String> get subRules; List<String> get proxyProviders;
bool get loaded; List<Proxy> get proxies; List<String> get subRules; List<String> get proxyProviders;
/// Create a copy of CustomOverwriteSelectorState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -935,16 +947,16 @@ $CustomOverwriteSelectorStateCopyWith<CustomOverwriteSelectorState> get copyWith
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is CustomOverwriteSelectorState&&const DeepCollectionEquality().equals(other.proxies, proxies)&&const DeepCollectionEquality().equals(other.subRules, subRules)&&const DeepCollectionEquality().equals(other.proxyProviders, proxyProviders));
return identical(this, other) || (other.runtimeType == runtimeType&&other is CustomOverwriteSelectorState&&(identical(other.loaded, loaded) || other.loaded == loaded)&&const DeepCollectionEquality().equals(other.proxies, proxies)&&const DeepCollectionEquality().equals(other.subRules, subRules)&&const DeepCollectionEquality().equals(other.proxyProviders, proxyProviders));
}
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(proxies),const DeepCollectionEquality().hash(subRules),const DeepCollectionEquality().hash(proxyProviders));
int get hashCode => Object.hash(runtimeType,loaded,const DeepCollectionEquality().hash(proxies),const DeepCollectionEquality().hash(subRules),const DeepCollectionEquality().hash(proxyProviders));
@override
String toString() {
return 'CustomOverwriteSelectorState(proxies: $proxies, subRules: $subRules, proxyProviders: $proxyProviders)';
return 'CustomOverwriteSelectorState(loaded: $loaded, proxies: $proxies, subRules: $subRules, proxyProviders: $proxyProviders)';
}
@@ -955,7 +967,7 @@ abstract mixin class $CustomOverwriteSelectorStateCopyWith<$Res> {
factory $CustomOverwriteSelectorStateCopyWith(CustomOverwriteSelectorState value, $Res Function(CustomOverwriteSelectorState) _then) = _$CustomOverwriteSelectorStateCopyWithImpl;
@useResult
$Res call({
List<Proxy> proxies, List<String> subRules, List<String> proxyProviders
bool loaded, List<Proxy> proxies, List<String> subRules, List<String> proxyProviders
});
@@ -972,9 +984,10 @@ class _$CustomOverwriteSelectorStateCopyWithImpl<$Res>
/// Create a copy of CustomOverwriteSelectorState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? proxies = null,Object? subRules = null,Object? proxyProviders = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? loaded = null,Object? proxies = null,Object? subRules = null,Object? proxyProviders = null,}) {
return _then(_self.copyWith(
proxies: null == proxies ? _self.proxies : proxies // ignore: cast_nullable_to_non_nullable
loaded: null == loaded ? _self.loaded : loaded // ignore: cast_nullable_to_non_nullable
as bool,proxies: null == proxies ? _self.proxies : proxies // ignore: cast_nullable_to_non_nullable
as List<Proxy>,subRules: null == subRules ? _self.subRules : subRules // ignore: cast_nullable_to_non_nullable
as List<String>,proxyProviders: null == proxyProviders ? _self.proxyProviders : proxyProviders // ignore: cast_nullable_to_non_nullable
as List<String>,
@@ -1062,10 +1075,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<Proxy> proxies, List<String> subRules, List<String> proxyProviders)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool loaded, List<Proxy> proxies, List<String> subRules, List<String> proxyProviders)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _CustomOverwriteSelectorState() when $default != null:
return $default(_that.proxies,_that.subRules,_that.proxyProviders);case _:
return $default(_that.loaded,_that.proxies,_that.subRules,_that.proxyProviders);case _:
return orElse();
}
@@ -1083,10 +1096,10 @@ return $default(_that.proxies,_that.subRules,_that.proxyProviders);case _:
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<Proxy> proxies, List<String> subRules, List<String> proxyProviders) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool loaded, List<Proxy> proxies, List<String> subRules, List<String> proxyProviders) $default,) {final _that = this;
switch (_that) {
case _CustomOverwriteSelectorState():
return $default(_that.proxies,_that.subRules,_that.proxyProviders);case _:
return $default(_that.loaded,_that.proxies,_that.subRules,_that.proxyProviders);case _:
throw StateError('Unexpected subclass');
}
@@ -1103,10 +1116,10 @@ return $default(_that.proxies,_that.subRules,_that.proxyProviders);case _:
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<Proxy> proxies, List<String> subRules, List<String> proxyProviders)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool loaded, List<Proxy> proxies, List<String> subRules, List<String> proxyProviders)? $default,) {final _that = this;
switch (_that) {
case _CustomOverwriteSelectorState() when $default != null:
return $default(_that.proxies,_that.subRules,_that.proxyProviders);case _:
return $default(_that.loaded,_that.proxies,_that.subRules,_that.proxyProviders);case _:
return null;
}
@@ -1118,9 +1131,10 @@ return $default(_that.proxies,_that.subRules,_that.proxyProviders);case _:
class _CustomOverwriteSelectorState implements CustomOverwriteSelectorState {
const _CustomOverwriteSelectorState({required final List<Proxy> proxies, required final List<String> subRules, required final List<String> proxyProviders}): _proxies = proxies,_subRules = subRules,_proxyProviders = proxyProviders;
const _CustomOverwriteSelectorState({required this.loaded, required final List<Proxy> proxies, required final List<String> subRules, required final List<String> proxyProviders}): _proxies = proxies,_subRules = subRules,_proxyProviders = proxyProviders;
@override final bool loaded;
final List<Proxy> _proxies;
@override List<Proxy> get proxies {
if (_proxies is EqualUnmodifiableListView) return _proxies;
@@ -1153,16 +1167,16 @@ _$CustomOverwriteSelectorStateCopyWith<_CustomOverwriteSelectorState> get copyWi
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CustomOverwriteSelectorState&&const DeepCollectionEquality().equals(other._proxies, _proxies)&&const DeepCollectionEquality().equals(other._subRules, _subRules)&&const DeepCollectionEquality().equals(other._proxyProviders, _proxyProviders));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CustomOverwriteSelectorState&&(identical(other.loaded, loaded) || other.loaded == loaded)&&const DeepCollectionEquality().equals(other._proxies, _proxies)&&const DeepCollectionEquality().equals(other._subRules, _subRules)&&const DeepCollectionEquality().equals(other._proxyProviders, _proxyProviders));
}
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_proxies),const DeepCollectionEquality().hash(_subRules),const DeepCollectionEquality().hash(_proxyProviders));
int get hashCode => Object.hash(runtimeType,loaded,const DeepCollectionEquality().hash(_proxies),const DeepCollectionEquality().hash(_subRules),const DeepCollectionEquality().hash(_proxyProviders));
@override
String toString() {
return 'CustomOverwriteSelectorState(proxies: $proxies, subRules: $subRules, proxyProviders: $proxyProviders)';
return 'CustomOverwriteSelectorState(loaded: $loaded, proxies: $proxies, subRules: $subRules, proxyProviders: $proxyProviders)';
}
@@ -1173,7 +1187,7 @@ abstract mixin class _$CustomOverwriteSelectorStateCopyWith<$Res> implements $Cu
factory _$CustomOverwriteSelectorStateCopyWith(_CustomOverwriteSelectorState value, $Res Function(_CustomOverwriteSelectorState) _then) = __$CustomOverwriteSelectorStateCopyWithImpl;
@override @useResult
$Res call({
List<Proxy> proxies, List<String> subRules, List<String> proxyProviders
bool loaded, List<Proxy> proxies, List<String> subRules, List<String> proxyProviders
});
@@ -1190,9 +1204,10 @@ class __$CustomOverwriteSelectorStateCopyWithImpl<$Res>
/// Create a copy of CustomOverwriteSelectorState
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? proxies = null,Object? subRules = null,Object? proxyProviders = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? loaded = null,Object? proxies = null,Object? subRules = null,Object? proxyProviders = null,}) {
return _then(_CustomOverwriteSelectorState(
proxies: null == proxies ? _self._proxies : proxies // ignore: cast_nullable_to_non_nullable
loaded: null == loaded ? _self.loaded : loaded // ignore: cast_nullable_to_non_nullable
as bool,proxies: null == proxies ? _self._proxies : proxies // ignore: cast_nullable_to_non_nullable
as List<Proxy>,subRules: null == subRules ? _self._subRules : subRules // ignore: cast_nullable_to_non_nullable
as List<String>,proxyProviders: null == proxyProviders ? _self._proxyProviders : proxyProviders // ignore: cast_nullable_to_non_nullable
as List<String>,
@@ -1200,284 +1215,12 @@ as List<String>,
}
}
/// @nodoc
mixin _$ProxiesAndGroupsSelectorState {
List<Proxy> get proxies; List<ProxyGroup> get proxyGroups;
/// Create a copy of ProxiesAndGroupsSelectorState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$ProxiesAndGroupsSelectorStateCopyWith<ProxiesAndGroupsSelectorState> get copyWith => _$ProxiesAndGroupsSelectorStateCopyWithImpl<ProxiesAndGroupsSelectorState>(this as ProxiesAndGroupsSelectorState, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is ProxiesAndGroupsSelectorState&&const DeepCollectionEquality().equals(other.proxies, proxies)&&const DeepCollectionEquality().equals(other.proxyGroups, proxyGroups));
}
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(proxies),const DeepCollectionEquality().hash(proxyGroups));
@override
String toString() {
return 'ProxiesAndGroupsSelectorState(proxies: $proxies, proxyGroups: $proxyGroups)';
}
}
/// @nodoc
abstract mixin class $ProxiesAndGroupsSelectorStateCopyWith<$Res> {
factory $ProxiesAndGroupsSelectorStateCopyWith(ProxiesAndGroupsSelectorState value, $Res Function(ProxiesAndGroupsSelectorState) _then) = _$ProxiesAndGroupsSelectorStateCopyWithImpl;
@useResult
$Res call({
List<Proxy> proxies, List<ProxyGroup> proxyGroups
});
}
/// @nodoc
class _$ProxiesAndGroupsSelectorStateCopyWithImpl<$Res>
implements $ProxiesAndGroupsSelectorStateCopyWith<$Res> {
_$ProxiesAndGroupsSelectorStateCopyWithImpl(this._self, this._then);
final ProxiesAndGroupsSelectorState _self;
final $Res Function(ProxiesAndGroupsSelectorState) _then;
/// Create a copy of ProxiesAndGroupsSelectorState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? proxies = null,Object? proxyGroups = null,}) {
return _then(_self.copyWith(
proxies: null == proxies ? _self.proxies : proxies // ignore: cast_nullable_to_non_nullable
as List<Proxy>,proxyGroups: null == proxyGroups ? _self.proxyGroups : proxyGroups // ignore: cast_nullable_to_non_nullable
as List<ProxyGroup>,
));
}
}
/// Adds pattern-matching-related methods to [ProxiesAndGroupsSelectorState].
extension ProxiesAndGroupsSelectorStatePatterns on ProxiesAndGroupsSelectorState {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _ProxiesAndGroupsSelectorState value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _ProxiesAndGroupsSelectorState() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _ProxiesAndGroupsSelectorState value) $default,){
final _that = this;
switch (_that) {
case _ProxiesAndGroupsSelectorState():
return $default(_that);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _ProxiesAndGroupsSelectorState value)? $default,){
final _that = this;
switch (_that) {
case _ProxiesAndGroupsSelectorState() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<Proxy> proxies, List<ProxyGroup> proxyGroups)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _ProxiesAndGroupsSelectorState() when $default != null:
return $default(_that.proxies,_that.proxyGroups);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<Proxy> proxies, List<ProxyGroup> proxyGroups) $default,) {final _that = this;
switch (_that) {
case _ProxiesAndGroupsSelectorState():
return $default(_that.proxies,_that.proxyGroups);case _:
throw StateError('Unexpected subclass');
}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<Proxy> proxies, List<ProxyGroup> proxyGroups)? $default,) {final _that = this;
switch (_that) {
case _ProxiesAndGroupsSelectorState() when $default != null:
return $default(_that.proxies,_that.proxyGroups);case _:
return null;
}
}
}
/// @nodoc
class _ProxiesAndGroupsSelectorState implements ProxiesAndGroupsSelectorState {
const _ProxiesAndGroupsSelectorState({required final List<Proxy> proxies, required final List<ProxyGroup> proxyGroups}): _proxies = proxies,_proxyGroups = proxyGroups;
final List<Proxy> _proxies;
@override List<Proxy> get proxies {
if (_proxies is EqualUnmodifiableListView) return _proxies;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_proxies);
}
final List<ProxyGroup> _proxyGroups;
@override List<ProxyGroup> get proxyGroups {
if (_proxyGroups is EqualUnmodifiableListView) return _proxyGroups;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_proxyGroups);
}
/// Create a copy of ProxiesAndGroupsSelectorState
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$ProxiesAndGroupsSelectorStateCopyWith<_ProxiesAndGroupsSelectorState> get copyWith => __$ProxiesAndGroupsSelectorStateCopyWithImpl<_ProxiesAndGroupsSelectorState>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ProxiesAndGroupsSelectorState&&const DeepCollectionEquality().equals(other._proxies, _proxies)&&const DeepCollectionEquality().equals(other._proxyGroups, _proxyGroups));
}
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_proxies),const DeepCollectionEquality().hash(_proxyGroups));
@override
String toString() {
return 'ProxiesAndGroupsSelectorState(proxies: $proxies, proxyGroups: $proxyGroups)';
}
}
/// @nodoc
abstract mixin class _$ProxiesAndGroupsSelectorStateCopyWith<$Res> implements $ProxiesAndGroupsSelectorStateCopyWith<$Res> {
factory _$ProxiesAndGroupsSelectorStateCopyWith(_ProxiesAndGroupsSelectorState value, $Res Function(_ProxiesAndGroupsSelectorState) _then) = __$ProxiesAndGroupsSelectorStateCopyWithImpl;
@override @useResult
$Res call({
List<Proxy> proxies, List<ProxyGroup> proxyGroups
});
}
/// @nodoc
class __$ProxiesAndGroupsSelectorStateCopyWithImpl<$Res>
implements _$ProxiesAndGroupsSelectorStateCopyWith<$Res> {
__$ProxiesAndGroupsSelectorStateCopyWithImpl(this._self, this._then);
final _ProxiesAndGroupsSelectorState _self;
final $Res Function(_ProxiesAndGroupsSelectorState) _then;
/// Create a copy of ProxiesAndGroupsSelectorState
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? proxies = null,Object? proxyGroups = null,}) {
return _then(_ProxiesAndGroupsSelectorState(
proxies: null == proxies ? _self._proxies : proxies // ignore: cast_nullable_to_non_nullable
as List<Proxy>,proxyGroups: null == proxyGroups ? _self._proxyGroups : proxyGroups // ignore: cast_nullable_to_non_nullable
as List<ProxyGroup>,
));
}
}
/// @nodoc
mixin _$RuleTargetsSelectorState {
Set<String> get ruleTargets; Set<String> get subRules;
bool get loaded; Set<String> get ruleTargets; Set<String> get subRules;
/// Create a copy of RuleTargetsSelectorState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -1488,16 +1231,16 @@ $RuleTargetsSelectorStateCopyWith<RuleTargetsSelectorState> get copyWith => _$Ru
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is RuleTargetsSelectorState&&const DeepCollectionEquality().equals(other.ruleTargets, ruleTargets)&&const DeepCollectionEquality().equals(other.subRules, subRules));
return identical(this, other) || (other.runtimeType == runtimeType&&other is RuleTargetsSelectorState&&(identical(other.loaded, loaded) || other.loaded == loaded)&&const DeepCollectionEquality().equals(other.ruleTargets, ruleTargets)&&const DeepCollectionEquality().equals(other.subRules, subRules));
}
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(ruleTargets),const DeepCollectionEquality().hash(subRules));
int get hashCode => Object.hash(runtimeType,loaded,const DeepCollectionEquality().hash(ruleTargets),const DeepCollectionEquality().hash(subRules));
@override
String toString() {
return 'RuleTargetsSelectorState(ruleTargets: $ruleTargets, subRules: $subRules)';
return 'RuleTargetsSelectorState(loaded: $loaded, ruleTargets: $ruleTargets, subRules: $subRules)';
}
@@ -1508,7 +1251,7 @@ abstract mixin class $RuleTargetsSelectorStateCopyWith<$Res> {
factory $RuleTargetsSelectorStateCopyWith(RuleTargetsSelectorState value, $Res Function(RuleTargetsSelectorState) _then) = _$RuleTargetsSelectorStateCopyWithImpl;
@useResult
$Res call({
Set<String> ruleTargets, Set<String> subRules
bool loaded, Set<String> ruleTargets, Set<String> subRules
});
@@ -1525,9 +1268,10 @@ class _$RuleTargetsSelectorStateCopyWithImpl<$Res>
/// Create a copy of RuleTargetsSelectorState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? ruleTargets = null,Object? subRules = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? loaded = null,Object? ruleTargets = null,Object? subRules = null,}) {
return _then(_self.copyWith(
ruleTargets: null == ruleTargets ? _self.ruleTargets : ruleTargets // ignore: cast_nullable_to_non_nullable
loaded: null == loaded ? _self.loaded : loaded // ignore: cast_nullable_to_non_nullable
as bool,ruleTargets: null == ruleTargets ? _self.ruleTargets : ruleTargets // ignore: cast_nullable_to_non_nullable
as Set<String>,subRules: null == subRules ? _self.subRules : subRules // ignore: cast_nullable_to_non_nullable
as Set<String>,
));
@@ -1614,10 +1358,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( Set<String> ruleTargets, Set<String> subRules)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool loaded, Set<String> ruleTargets, Set<String> subRules)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _RuleTargetsSelectorState() when $default != null:
return $default(_that.ruleTargets,_that.subRules);case _:
return $default(_that.loaded,_that.ruleTargets,_that.subRules);case _:
return orElse();
}
@@ -1635,10 +1379,10 @@ return $default(_that.ruleTargets,_that.subRules);case _:
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( Set<String> ruleTargets, Set<String> subRules) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool loaded, Set<String> ruleTargets, Set<String> subRules) $default,) {final _that = this;
switch (_that) {
case _RuleTargetsSelectorState():
return $default(_that.ruleTargets,_that.subRules);case _:
return $default(_that.loaded,_that.ruleTargets,_that.subRules);case _:
throw StateError('Unexpected subclass');
}
@@ -1655,10 +1399,10 @@ return $default(_that.ruleTargets,_that.subRules);case _:
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( Set<String> ruleTargets, Set<String> subRules)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool loaded, Set<String> ruleTargets, Set<String> subRules)? $default,) {final _that = this;
switch (_that) {
case _RuleTargetsSelectorState() when $default != null:
return $default(_that.ruleTargets,_that.subRules);case _:
return $default(_that.loaded,_that.ruleTargets,_that.subRules);case _:
return null;
}
@@ -1670,9 +1414,10 @@ return $default(_that.ruleTargets,_that.subRules);case _:
class _RuleTargetsSelectorState implements RuleTargetsSelectorState {
const _RuleTargetsSelectorState({required final Set<String> ruleTargets, required final Set<String> subRules}): _ruleTargets = ruleTargets,_subRules = subRules;
const _RuleTargetsSelectorState({required this.loaded, required final Set<String> ruleTargets, required final Set<String> subRules}): _ruleTargets = ruleTargets,_subRules = subRules;
@override final bool loaded;
final Set<String> _ruleTargets;
@override Set<String> get ruleTargets {
if (_ruleTargets is EqualUnmodifiableSetView) return _ruleTargets;
@@ -1698,16 +1443,16 @@ _$RuleTargetsSelectorStateCopyWith<_RuleTargetsSelectorState> get copyWith => __
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _RuleTargetsSelectorState&&const DeepCollectionEquality().equals(other._ruleTargets, _ruleTargets)&&const DeepCollectionEquality().equals(other._subRules, _subRules));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _RuleTargetsSelectorState&&(identical(other.loaded, loaded) || other.loaded == loaded)&&const DeepCollectionEquality().equals(other._ruleTargets, _ruleTargets)&&const DeepCollectionEquality().equals(other._subRules, _subRules));
}
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_ruleTargets),const DeepCollectionEquality().hash(_subRules));
int get hashCode => Object.hash(runtimeType,loaded,const DeepCollectionEquality().hash(_ruleTargets),const DeepCollectionEquality().hash(_subRules));
@override
String toString() {
return 'RuleTargetsSelectorState(ruleTargets: $ruleTargets, subRules: $subRules)';
return 'RuleTargetsSelectorState(loaded: $loaded, ruleTargets: $ruleTargets, subRules: $subRules)';
}
@@ -1718,7 +1463,7 @@ abstract mixin class _$RuleTargetsSelectorStateCopyWith<$Res> implements $RuleTa
factory _$RuleTargetsSelectorStateCopyWith(_RuleTargetsSelectorState value, $Res Function(_RuleTargetsSelectorState) _then) = __$RuleTargetsSelectorStateCopyWithImpl;
@override @useResult
$Res call({
Set<String> ruleTargets, Set<String> subRules
bool loaded, Set<String> ruleTargets, Set<String> subRules
});
@@ -1735,9 +1480,10 @@ class __$RuleTargetsSelectorStateCopyWithImpl<$Res>
/// Create a copy of RuleTargetsSelectorState
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? ruleTargets = null,Object? subRules = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? loaded = null,Object? ruleTargets = null,Object? subRules = null,}) {
return _then(_RuleTargetsSelectorState(
ruleTargets: null == ruleTargets ? _self._ruleTargets : ruleTargets // ignore: cast_nullable_to_non_nullable
loaded: null == loaded ? _self.loaded : loaded // ignore: cast_nullable_to_non_nullable
as bool,ruleTargets: null == ruleTargets ? _self._ruleTargets : ruleTargets // ignore: cast_nullable_to_non_nullable
as Set<String>,subRules: null == subRules ? _self._subRules : subRules // ignore: cast_nullable_to_non_nullable
as Set<String>,
));
+1 -1
View File
@@ -1,6 +1,6 @@
import 'package:collection/collection.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'app.dart';
+1 -2
View File
@@ -5,7 +5,7 @@ import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/providers/app.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:re_editor/re_editor.dart';
@@ -631,7 +631,6 @@ class FindPanel extends StatelessWidget implements PreferredSizeWidget {
inputFormatters: TextInputLimits.limit(TextInputLimits.search),
style: context.textTheme.bodyMedium,
decoration: const InputDecoration(
border: OutlineInputBorder(),
contentPadding: EdgeInsets.symmetric(horizontal: 12),
),
onSubmitted: (_) {
+4 -3
View File
@@ -1,5 +1,6 @@
import 'package:fl_clash/common/color.dart';
import 'package:flutter/material.dart';
import 'package:fl_clash/common/shape.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter/services.dart';
class InitErrorScreen extends StatelessWidget {
@@ -52,7 +53,7 @@ class InitErrorScreen extends StatelessWidget {
decoration: ShapeDecoration(
color: colorScheme.errorContainer.opacity50,
shape: RoundedSuperellipseBorder(
borderRadius: BorderRadius.circular(8),
borderRadius: AppRadius.sm,
side: BorderSide(color: colorScheme.error.opacity50),
),
),
@@ -74,7 +75,7 @@ class InitErrorScreen extends StatelessWidget {
? Colors.grey[900]
: Colors.grey[200],
shape: RoundedSuperellipseBorder(
borderRadius: BorderRadius.circular(8),
borderRadius: AppRadius.sm,
side: BorderSide(color: Colors.grey.opacity50),
),
),
+2 -2
View File
@@ -4,7 +4,7 @@ import 'package:fl_clash/manager/app_manager.dart';
import 'package:fl_clash/models/common.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/intl.dart';
@@ -296,7 +296,7 @@ class _NavigationBarDefaultsM3 extends NavigationBarThemeData {
Color? get indicatorColor => _colors.secondaryContainer;
@override
ShapeBorder? get indicatorShape => const StadiumBorder();
ShapeBorder? get indicatorShape => AppShape.full;
@override
WidgetStateProperty<TextStyle?>? get labelTextStyle {
+6 -2
View File
@@ -3,9 +3,10 @@ import 'dart:math';
import 'package:fl_clash/common/color.dart';
import 'package:fl_clash/common/context.dart';
import 'package:fl_clash/common/shape.dart';
import 'package:fl_clash/providers/action.dart';
import 'package:fl_clash/widgets/activate_box.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
@@ -178,7 +179,10 @@ class _ScanPageState extends ConsumerState<ScanPage>
}
class ScannerOverlay extends CustomPainter {
const ScannerOverlay({required this.scanWindow, this.borderRadius = 12.0});
const ScannerOverlay({
required this.scanWindow,
this.borderRadius = AppCorner.md,
});
final Rect scanWindow;
final double borderRadius;
+1 -1
View File
@@ -4,7 +4,7 @@ import 'dart:io';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter/services.dart';
class App {
+1 -1
View File
@@ -12,7 +12,7 @@ import 'package:fl_clash/plugins/service.dart';
import 'package:fl_clash/providers/actions/system_exit.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:path/path.dart' show basename;
import 'package:riverpod_annotation/riverpod_annotation.dart';
+7 -7
View File
@@ -775,7 +775,7 @@ final class CustomOverwriteDateProvider
}
String _$customOverwriteDateHash() =>
r'52b7eb3ac298486467443cd941fe993f22086f27';
r'386bdd7a3bd8f48e17bfa56d9a47fb6e0f11b4cc';
final class CustomOverwriteDateFamily extends $Family
with $FunctionalFamilyOverride<CustomOverwriteDate, int> {
@@ -855,7 +855,7 @@ final class CustomOverwriteTargetIsValidProvider
}
String _$customOverwriteTargetIsValidHash() =>
r'ec4d47b2ca9522a9b183380ebd3ee483d83a0da6';
r'cafcd9915173737f36346feec28e41221ab3657e';
final class CustomOverwriteTargetIsValidFamily extends $Family
with $FunctionalFamilyOverride<bool, (int, String?)> {
@@ -939,7 +939,7 @@ final class CustomOverwriteProxyProviderIsValidProvider
}
String _$customOverwriteProxyProviderIsValidHash() =>
r'5b93515706b1c8edb078f10be4cbf8c7d73b54c1';
r'c9b9a691686fd41605cbdf4e5adceadf1245390f';
final class CustomOverwriteProxyProviderIsValidFamily extends $Family
with $FunctionalFamilyOverride<bool, (int, String?)> {
@@ -1023,7 +1023,7 @@ final class CustomOverwriteUseIsValidProvider
}
String _$customOverwriteUseIsValidHash() =>
r'a6daf410cbde076b58540b8484127c0cabc2b331';
r'acc08a9dcc3ed111a06318ce04c265a97c3a729f';
final class CustomOverwriteUseIsValidFamily extends $Family
with $FunctionalFamilyOverride<bool, (int, List<String>)> {
@@ -1106,7 +1106,7 @@ final class CustomOverwriteProxiesIsValidProvider
}
String _$customOverwriteProxiesIsValidHash() =>
r'856289220d963e12b5c62434ea80cf819b471cff';
r'578b938d0fdca614fad63bb7eb9f8669af734de1';
final class CustomOverwriteProxiesIsValidFamily extends $Family
with $FunctionalFamilyOverride<bool, (int, List<String>)> {
@@ -1189,7 +1189,7 @@ final class InvalidProxyGroupIdsProvider
}
String _$invalidProxyGroupIdsHash() =>
r'3a458a1a4f6b7c52d317f3c137114f8cf585a7e0';
r'297bc60ef354516a01f9d36913d1c1f542cbe70f';
final class InvalidProxyGroupIdsFamily extends $Family
with $FunctionalFamilyOverride<Set<int>, int> {
@@ -3139,7 +3139,7 @@ final class ClashConfigProvider
}
}
String _$clashConfigHash() => r'9cce2e682141f6d4588b2037f293611e78f80ff4';
String _$clashConfigHash() => r'd984af6731ae56dbc1f517f683a40618cdfa5129';
final class ClashConfigFamily extends $Family
with $FunctionalFamilyOverride<FutureOr<ClashConfig>, int> {
+1 -1
View File
@@ -2,7 +2,7 @@ import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/database/database.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
+36 -27
View File
@@ -4,36 +4,42 @@ part of '../state.dart';
CustomOverwriteDate customOverwriteDate(Ref ref, int profileId) {
final overwrite = ref.watch(
clashConfigProvider(profileId).select((state) {
final clashConfig = state.value;
return CustomOverwriteSelectorState(
proxies: state.value?.proxies ?? [],
subRules: state.value?.subRules ?? [],
proxyProviders: state.value?.proxyProviders ?? [],
loaded: clashConfig != null,
proxies: clashConfig?.proxies ?? const [],
subRules: clashConfig?.subRules ?? const [],
proxyProviders: clashConfig?.proxyProviders ?? const [],
);
}),
);
final proxies = overwrite.proxies;
final subRules = overwrite.subRules.toSet();
final proxyProviders = overwrite.proxyProviders.toSet();
final proxyGroups =
ref
.watch(
proxyGroupsProvider(profileId).select((state) {
return SelectValue(state.value);
}),
)
.value ??
[];
final groups = ref
.watch(
proxyGroupsProvider(profileId).select((state) {
return SelectValue(state.value);
}),
)
.value;
final proxyGroups = groups ?? const <ProxyGroup>[];
final proxyNames = <String>[];
final proxyTypes = <String, String>{};
for (final proxy in overwrite.proxies) {
proxyNames.add(proxy.name);
proxyTypes[proxy.name] = proxy.type;
}
final ruleTargets = {
...RuleTarget.baseTargets,
...proxies.map((item) => item.name),
...proxyNames,
...proxyGroups.map((item) => item.name),
};
return CustomOverwriteDate(
proxyProviders: proxyProviders,
proxies: proxies,
loaded: overwrite.loaded && groups != null,
proxyProviders: overwrite.proxyProviders.toSet(),
proxyNames: proxyNames,
proxyTypes: proxyTypes,
proxyGroups: proxyGroups,
ruleTargets: ruleTargets,
subRules: subRules,
subRules: overwrite.subRules.toSet(),
);
}
@@ -42,7 +48,7 @@ bool customOverwriteTargetIsValid(Ref ref, int profileId, String? target) {
final valid = ref.watch(
customOverwriteDateProvider(
profileId,
).select((state) => state.ruleTargets.contains(target)),
).select((state) => !state.loaded || state.ruleTargets.contains(target)),
);
return valid;
}
@@ -54,9 +60,9 @@ bool customOverwriteProxyProviderIsValid(
String? providerName,
) {
final valid = ref.watch(
customOverwriteDateProvider(
profileId,
).select((state) => state.proxyProviders.contains(providerName)),
customOverwriteDateProvider(profileId).select(
(state) => !state.loaded || state.proxyProviders.contains(providerName),
),
);
return valid;
}
@@ -66,7 +72,7 @@ bool customOverwriteUseIsValid(Ref ref, int profileId, List<String> use) {
final valid = ref.watch(
customOverwriteDateProvider(
profileId,
).select((state) => state.proxyProviders.containsAll(use)),
).select((state) => !state.loaded || state.proxyProviders.containsAll(use)),
);
return valid;
}
@@ -78,9 +84,9 @@ bool customOverwriteProxiesIsValid(
List<String> proxies,
) {
final valid = ref.watch(
customOverwriteDateProvider(
profileId,
).select((state) => state.ruleTargets.containsAll(proxies)),
customOverwriteDateProvider(profileId).select(
(state) => !state.loaded || state.ruleTargets.containsAll(proxies),
),
);
return valid;
}
@@ -88,6 +94,9 @@ bool customOverwriteProxiesIsValid(
@riverpod
Set<int> invalidProxyGroupIds(Ref ref, int profileId) {
final overwrite = ref.watch(customOverwriteDateProvider(profileId));
if (!overwrite.loaded) {
return const {};
}
return {
for (final proxyGroup in overwrite.proxyGroups)
if (!overwrite.ruleTargets.containsAll(proxyGroup.proxies ?? const []) ||
+1 -9
View File
@@ -34,15 +34,7 @@ OverwriteType overwriteType(Ref ref, int? profileId) {
@riverpod
Future<ClashConfig> clashConfig(Ref ref, int profileId) async {
final configMap = await ref.read(coreHandlerProvider).getConfig(profileId);
final clashConfig = ClashConfig.fromJson(configMap);
final Map<String, String> proxyTypeMap = {};
for (final proxy in clashConfig.proxies) {
proxyTypeMap[proxy.name] = proxy.type;
}
for (final proxyGroup in clashConfig.proxyGroups) {
proxyTypeMap[proxyGroup.name] = proxyGroup.type.value;
}
return clashConfig.copyWith(proxyTypeMap: proxyTypeMap);
return clashConfigTask(configMap);
}
@riverpod
+2 -1
View File
@@ -3,11 +3,12 @@ import 'dart:async';
import 'common/common.dart';
import 'enum/enum.dart';
import 'models/models.dart';
import 'package:fl_clash/common/theme.dart';
import 'package:fl_clash/providers/app.dart';
import 'package:fl_clash/providers/config.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:package_info_plus/package_info_plus.dart';
+1 -1
View File
@@ -7,7 +7,7 @@ import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/list.dart';
import 'package:fl_clash/widgets/scaffold.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@immutable
+2 -4
View File
@@ -7,7 +7,7 @@ import 'package:fl_clash/plugins/app.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -392,9 +392,7 @@ class _AccessViewState extends ConsumerState<AccessView> {
Card.filled(
color: context.colorScheme.primary,
elevation: 0,
shape: RoundedSuperellipseBorder(
borderRadius: BorderRadius.circular(14),
),
shape: AppShape.md,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Row(
+1 -1
View File
@@ -2,7 +2,7 @@ import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/providers/config.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
ConfigToggleItem _appSettingToggle({
+1 -4
View File
@@ -17,7 +17,7 @@ import 'package:fl_clash/widgets/list.dart';
import 'package:fl_clash/widgets/loading.dart';
import 'package:fl_clash/widgets/scaffold.dart';
import 'package:fl_clash/widgets/text.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/intl.dart';
@@ -471,7 +471,6 @@ class _WebDAVFormDialogState extends ConsumerState<WebDAVFormDialog> {
minLines: 1,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.link),
border: const OutlineInputBorder(),
labelText: appLocalizations.address,
helperText: appLocalizations.addressHelp,
),
@@ -487,7 +486,6 @@ class _WebDAVFormDialogState extends ConsumerState<WebDAVFormDialog> {
inputFormatters: TextInputLimits.limit(TextInputLimits.userName),
decoration: InputDecoration(
prefixIcon: const Icon(Icons.account_circle),
border: const OutlineInputBorder(),
labelText: appLocalizations.account,
),
validator: (String? value) {
@@ -508,7 +506,6 @@ class _WebDAVFormDialogState extends ConsumerState<WebDAVFormDialog> {
obscureText: obscure,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.password),
border: const OutlineInputBorder(),
suffixIcon: IconButton(
tooltip: obscure
? context.appLocalizations.showPassword
+1 -1
View File
@@ -7,7 +7,7 @@ import 'package:fl_clash/views/config/on_demand.dart';
import 'package:fl_clash/views/config/scripts.dart';
import 'package:fl_clash/widgets/list.dart';
import 'package:fl_clash/widgets/scaffold.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'rules.dart';
+1 -1
View File
@@ -1,7 +1,7 @@
import 'package:fl_clash/common/context.dart';
import 'package:fl_clash/views/config/general.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
class ConfigView extends StatelessWidget {
const ConfigView({super.key});
+1 -1
View File
@@ -3,7 +3,7 @@ import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/providers/config.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
typedef _DnsUpdate<T> =
+1 -1
View File
@@ -4,7 +4,7 @@ import 'package:fl_clash/l10n/l10n.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
part 'general/port_dialog.dart';
+1 -4
View File
@@ -183,10 +183,7 @@ class _PortDialogState extends ConsumerState<_PortDialog> {
onFieldSubmitted: (_) {
_handleUpdate();
},
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: field.label(appLocalizations),
),
decoration: InputDecoration(labelText: field.label(appLocalizations)),
validator: (value) => validatePort(field, value, appLocalizations),
);
}
+1 -1
View File
@@ -3,7 +3,7 @@ import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/providers/config.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/intl.dart';
+57 -27
View File
@@ -8,7 +8,7 @@ import 'package:fl_clash/providers/app.dart';
import 'package:fl_clash/providers/config.dart';
import 'package:fl_clash/views/profiles/overwrite/custom/widgets.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:wifi_ssid/wifi_ssid.dart';
@@ -203,34 +203,56 @@ class _OnDemandViewState extends ConsumerState<OnDemandView>
loadingProvider(LoadingTag.batteryOptimization),
);
final disabled = ref.watch(batteryOptimizationDisableProvider);
final content = Row(
mainAxisSize: MainAxisSize.min,
spacing: 8,
children: [
InfoMessageButton(
message: appLocalizations.batteryOptimizationStatusTip,
),
_buildAuthorizeButton(
authorized: disabled,
onPressed: _handleOpenBatteryOptimizationSettings,
),
],
);
return DecorationListItem(
minVerticalPadding: 8,
title: Text(appLocalizations.ignoreBatteryOptimization),
subtitle: Text(appLocalizations.batteryOptimizationDesc),
trailing: isLoading
? const SizedBox(
width: 100,
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: [
SizedBox.square(dimension: 32, child: CommonCircleLoading()),
],
title: Text(
appLocalizations.ignoreBatteryOptimization,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
subtitle: Text(
appLocalizations.batteryOptimizationDesc,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
trailing: Stack(
alignment: Alignment.centerRight,
children: [
// Reserves the same width as the loaded content so switching
// in/out of the loading spinner never changes the trailing
// width and reflows the title/subtitle.
Visibility(
visible: false,
maintainSize: true,
maintainAnimation: true,
maintainState: true,
child: content,
),
if (isLoading)
const Align(
alignment: Alignment.centerRight,
child: SizedBox.square(
dimension: 32,
child: CommonCircleLoading(),
),
)
: Row(
mainAxisSize: MainAxisSize.min,
spacing: 8,
children: [
InfoMessageButton(
message: appLocalizations.batteryOptimizationStatusTip,
),
_buildAuthorizeButton(
authorized: disabled,
onPressed: _handleOpenBatteryOptimizationSettings,
),
],
),
else
content,
],
),
);
}
@@ -243,8 +265,16 @@ class _OnDemandViewState extends ConsumerState<OnDemandView>
);
return DecorationListItem(
minVerticalPadding: 8,
title: Text(appLocalizations.locationPermission),
subtitle: Text(appLocalizations.locationPermissionDesc),
title: Text(
appLocalizations.locationPermission,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
subtitle: Text(
appLocalizations.locationPermissionDesc,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
trailing: _buildAuthorizeButton(
authorized: granted,
onPressed: _handleRequestLocationPermission,
+1 -1
View File
@@ -4,7 +4,7 @@ import 'package:fl_clash/features/features.dart';
import 'package:fl_clash/models/clash_config.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class AddedRulesView extends ConsumerStatefulWidget {
+1 -1
View File
@@ -8,7 +8,7 @@ import 'package:fl_clash/pages/editor.dart';
import 'package:fl_clash/providers/app.dart';
import 'package:fl_clash/providers/database.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class ScriptsView extends ConsumerStatefulWidget {
+2 -1
View File
@@ -1,11 +1,12 @@
import 'dart:async';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/core/controller.dart';
import 'package:fl_clash/core/method.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:super_sliver_list/super_sliver_list.dart';
+1 -1
View File
@@ -4,7 +4,7 @@ import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/providers/config.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class TrackerInfoItem extends ConsumerWidget {
+1 -1
View File
@@ -3,7 +3,7 @@ import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:super_sliver_list/super_sliver_list.dart';
+1 -1
View File
@@ -6,7 +6,7 @@ import 'package:fl_clash/core/core.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'widget_registry.dart';
@@ -6,7 +6,7 @@ import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class CoreStatusButton extends ConsumerStatefulWidget {
+2 -1
View File
@@ -2,7 +2,7 @@ import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/providers/app.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class IntranetIP extends StatelessWidget {
@@ -14,6 +14,7 @@ class IntranetIP extends StatelessWidget {
return SizedBox(
height: getWidgetHeight(1),
child: CommonCard(
radius: AppCorner.lg,
info: Info(label: appLocalizations.intranetIP, iconData: Icons.devices),
onPressed: () {},
child: Container(
+2 -1
View File
@@ -8,7 +8,7 @@ import 'package:fl_clash/providers/app.dart';
import 'package:fl_clash/providers/core.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class MemoryInfo extends ConsumerStatefulWidget {
@@ -73,6 +73,7 @@ class _MemoryInfoState extends ConsumerState<MemoryInfo>
height: getWidgetHeight(1),
child: RepaintBoundary(
child: CommonCard(
radius: AppCorner.lg,
info: Info(
iconData: Icons.memory,
label: appLocalizations.memoryInfo,
@@ -3,7 +3,7 @@ import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/providers/app.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class NetworkDetection extends ConsumerStatefulWidget {
@@ -40,6 +40,7 @@ class _NetworkDetectionState extends ConsumerState<NetworkDetection> {
return SizedBox(
height: getWidgetHeight(1),
child: CommonCard(
radius: AppCorner.lg,
onPressed: () {},
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -2,7 +2,7 @@ import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/providers/app.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class NetworkSpeed extends StatefulWidget {
@@ -44,6 +44,7 @@ class _NetworkSpeedState extends State<NetworkSpeed> {
height: getWidgetHeight(2),
child: RepaintBoundary(
child: CommonCard(
radius: AppCorner.lg,
onPressed: () {},
child: Consumer(
builder: (_, ref, _) {
@@ -5,7 +5,7 @@ import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/intl.dart';
@@ -34,6 +34,7 @@ class OutboundMode extends ConsumerWidget {
hoverColor: Colors.transparent,
),
child: CommonCard(
radius: AppCorner.lg,
onPressed: () {},
info: Info(
label: appLocalizations.outboundMode,
@@ -126,6 +127,7 @@ class OutboundModeV2 extends StatelessWidget {
return SizedBox(
height: height,
child: CommonCard(
radius: AppCorner.lg,
child: Consumer(
builder: (_, ref, _) {
final mode = ref.watch(
@@ -2,7 +2,7 @@ import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/providers/config.dart';
import 'package:fl_clash/views/config/network.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class _QuickSwitchCard extends StatelessWidget {
@@ -25,6 +25,7 @@ class _QuickSwitchCard extends StatelessWidget {
return SizedBox(
height: getWidgetHeight(1),
child: CommonCard(
radius: AppCorner.lg,
onPressed: () {
showSheet(
context: context,
@@ -1,7 +1,7 @@
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
const _threeDigitHourThreshold = 100 * 60 * 60 * 1000;
@@ -4,7 +4,7 @@ import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/providers/app.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class TrafficUsage extends StatelessWidget {
@@ -17,6 +17,7 @@ class TrafficUsage extends StatelessWidget {
height: getWidgetHeight(2),
child: RepaintBoundary(
child: CommonCard(
radius: AppCorner.lg,
info: Info(
label: appLocalizations.trafficUsage,
iconData: Icons.data_saver_off,
@@ -174,12 +175,7 @@ class _LegendEntry extends StatelessWidget {
Container(
width: 20,
height: 8,
decoration: ShapeDecoration(
color: color,
shape: RoundedSuperellipseBorder(
borderRadius: BorderRadius.circular(3),
),
),
decoration: ShapeDecoration(color: color, shape: AppShape.full),
),
const SizedBox(width: 4),
label,
+3 -2
View File
@@ -1,4 +1,5 @@
import 'dart:async';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/common.dart';
@@ -7,7 +8,7 @@ import 'package:fl_clash/providers/app.dart';
import 'package:fl_clash/providers/config.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class DeveloperView extends ConsumerWidget {
@@ -99,7 +100,7 @@ class DeveloperView extends ConsumerWidget {
children: [
CommonCard(
type: CommonCardType.filled,
radius: 18,
radius: AppCorner.md,
child: ListItem.toggle(
padding: const EdgeInsets.only(left: 16, right: 16),
title: Text(appLocalizations.developerMode),
+1 -1
View File
@@ -6,7 +6,7 @@ import 'package:fl_clash/widgets/card.dart';
import 'package:fl_clash/widgets/dialog.dart';
import 'package:fl_clash/widgets/list.dart';
import 'package:fl_clash/widgets/scaffold.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/intl.dart';
+2 -1
View File
@@ -1,11 +1,12 @@
import 'dart:async';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:super_sliver_list/super_sliver_list.dart';
+1 -1
View File
@@ -2,7 +2,7 @@ import 'package:fl_clash/common/app_ports.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/views/views.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
class Navigation implements NavigationPort {
static Navigation? _instance;
+3 -5
View File
@@ -1,9 +1,10 @@
import 'dart:async';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/pages/scan.dart';
import 'package:fl_clash/providers/action.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class AddProfileView extends ConsumerWidget {
@@ -131,10 +132,7 @@ class _URLFormDialogState extends State<URLFormDialog> {
},
onEditingComplete: _handleAddProfileFormURL,
controller: _urlController,
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: appLocalizations.url,
),
decoration: InputDecoration(labelText: appLocalizations.url),
),
],
),
+3 -10
View File
@@ -11,7 +11,7 @@ import 'package:fl_clash/providers/action.dart';
import 'package:fl_clash/providers/core.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class EditProfileView extends ConsumerStatefulWidget {
@@ -298,10 +298,7 @@ class _ProfileNameField extends StatelessWidget {
textInputAction: TextInputAction.next,
controller: controller,
inputFormatters: TextInputLimits.limit(TextInputLimits.name),
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: appLocalizations.name,
),
decoration: InputDecoration(labelText: appLocalizations.name),
validator: (String? value) {
if (value == null || value.isEmpty) {
return appLocalizations.profileNameNullValidationDesc;
@@ -329,10 +326,7 @@ class _ProfileUrlField extends StatelessWidget {
inputFormatters: TextInputLimits.limit(TextInputLimits.url),
maxLines: 5,
minLines: 1,
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: appLocalizations.url,
),
decoration: InputDecoration(labelText: appLocalizations.url),
validator: (String? value) {
if (value == null || value.isEmpty) {
return appLocalizations.profileUrlNullValidationDesc;
@@ -361,7 +355,6 @@ class _AutoUpdateIntervalField extends StatelessWidget {
controller: controller,
inputFormatters: TextInputLimits.digitsOnly(TextInputLimits.interval),
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: appLocalizations.autoUpdateInterval,
),
validator: (String? value) {
@@ -3,7 +3,7 @@ import 'package:fl_clash/database/database.dart';
import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'groups.dart';
@@ -109,7 +109,7 @@ class _CountBadge extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Card.filled(
shape: RoundedSuperellipseBorder(borderRadius: BorderRadius.circular(20)),
shape: AppShape.md,
child: Container(
constraints: const BoxConstraints(minWidth: 44),
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
@@ -135,11 +135,7 @@ class _QuickFillBanner extends StatelessWidget {
alignment: Alignment.bottomCenter,
child: Container(
clipBehavior: Clip.antiAlias,
decoration: ShapeDecoration(
shape: RoundedSuperellipseBorder(
borderRadius: BorderRadius.circular(16),
),
),
decoration: const ShapeDecoration(shape: AppShape.md),
margin: const EdgeInsets.all(12),
child: MaterialBanner(
elevation: 0,
@@ -9,7 +9,7 @@ import 'package:fl_clash/providers/providers.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/views/profiles/overwrite/custom/proxy_providers.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:smooth_sheets/smooth_sheets.dart';
@@ -734,7 +734,7 @@ class _NumberCard extends StatelessWidget {
Widget build(BuildContext context) {
return Card(
elevation: 0,
shape: RoundedSuperellipseBorder(borderRadius: BorderRadius.circular(14)),
shape: AppShape.md,
child: Container(
constraints: const BoxConstraints(minWidth: 32),
alignment: Alignment.center,
@@ -6,7 +6,7 @@ import 'package:fl_clash/database/database.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:material_ui/material_ui.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -269,7 +269,7 @@ class _IconPreview extends StatelessWidget {
child: file != null
? CommonCard(
type: CommonCardType.filled,
radius: 20,
radius: AppCorner.md,
padding: const EdgeInsets.all(8),
child: CommonImage(
isSvg: srcController.text.isSvg,
@@ -303,7 +303,7 @@ class _IconSrcField extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CommonCard(
radius: 20,
radius: AppCorner.md,
type: CommonCardType.filled,
child: ListTile(
minTileHeight: dimension,

Some files were not shown because too many files have changed in this diff Show More