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:
+15
-3
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -13,7 +13,7 @@ concurrency:
|
||||
|
||||
env:
|
||||
IS_STABLE: ${{ !contains(github.ref, '-') }}
|
||||
FLUTTER_VERSION: '3.44.4'
|
||||
FLUTTER_VERSION: '3.47.1'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
|
||||
@@ -6,5 +6,11 @@ analyzer:
|
||||
- lib/l10n/intl/**
|
||||
- lib/**/generated/**
|
||||
- plugins/**
|
||||
- android/**
|
||||
- ios/**
|
||||
- web/**
|
||||
- windows/**
|
||||
- macos/**
|
||||
- linux/**
|
||||
errors:
|
||||
invalid_annotation_target: ignore
|
||||
|
||||
+11
-11
@@ -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
@@ -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,5 +1,6 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:fl_clash/l10n/l10n.dart';
|
||||
|
||||
import 'dart:ui';
|
||||
|
||||
final currentAppLocalizations = AppLocalizations.current;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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,4 +1,4 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import 'context.dart';
|
||||
|
||||
|
||||
@@ -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,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');
|
||||
|
||||
@@ -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
@@ -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
@@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,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
@@ -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}) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
@@ -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
@@ -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';
|
||||
|
||||
@@ -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
@@ -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';
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,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';
|
||||
|
||||
@@ -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,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';
|
||||
|
||||
@@ -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: (_) {
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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 []) ||
|
||||
|
||||
@@ -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
@@ -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';
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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});
|
||||
|
||||
@@ -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> =
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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,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(
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
@@ -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';
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user