Change icons
This commit is contained in:
23
lib/core/widget/adaptive_icon.dart
Normal file
23
lib/core/widget/adaptive_icon.dart
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class AdaptiveIcon {
|
||||||
|
AdaptiveIcon(BuildContext context) : platform = Theme.of(context).platform;
|
||||||
|
|
||||||
|
final TargetPlatform platform;
|
||||||
|
|
||||||
|
IconData get more => switch (platform) {
|
||||||
|
TargetPlatform.iOS ||
|
||||||
|
TargetPlatform.macOS =>
|
||||||
|
FluentIcons.more_horizontal_24_regular,
|
||||||
|
_ => FluentIcons.more_vertical_24_regular,
|
||||||
|
};
|
||||||
|
|
||||||
|
IconData get share => switch (platform) {
|
||||||
|
TargetPlatform.android => FluentIcons.share_android_24_regular,
|
||||||
|
TargetPlatform.iOS ||
|
||||||
|
TargetPlatform.macOS =>
|
||||||
|
FluentIcons.share_ios_24_regular,
|
||||||
|
_ => FluentIcons.share_24_regular,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hiddify/utils/platform_utils.dart';
|
import 'package:hiddify/utils/platform_utils.dart';
|
||||||
@@ -120,7 +121,8 @@ class AdaptiveMenu extends HookConsumerWidget {
|
|||||||
ListTile(
|
ListTile(
|
||||||
title: Text(item.title),
|
title: Text(item.title),
|
||||||
leading: item.icon != null ? Icon(item.icon) : null,
|
leading: item.icon != null ? Icon(item.icon) : null,
|
||||||
trailing: const Icon(Icons.chevron_right),
|
trailing:
|
||||||
|
const Icon(FluentIcons.chevron_right_20_regular, size: 20),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
pageIndexNotifier.value = subSheetIndex;
|
pageIndexNotifier.value = subSheetIndex;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class TipCard extends StatelessWidget {
|
class TipCard extends StatelessWidget {
|
||||||
@@ -16,7 +17,7 @@ class TipCard extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
const Padding(
|
const Padding(
|
||||||
padding: EdgeInsets.all(8.0),
|
padding: EdgeInsets.all(8.0),
|
||||||
child: Icon(Icons.lightbulb),
|
child: Icon(FluentIcons.lightbulb_24_regular),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
@@ -12,7 +13,7 @@ Future<bool> showConfirmationDialog(
|
|||||||
builder: (context) {
|
builder: (context) {
|
||||||
final localizations = MaterialLocalizations.of(context);
|
final localizations = MaterialLocalizations.of(context);
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
icon: const Icon(Icons.delete_forever),
|
icon: const Icon(FluentIcons.delete_24_regular),
|
||||||
title: Text(title),
|
title: Text(title),
|
||||||
content: Text(message),
|
content: Text(message),
|
||||||
actions: [
|
actions: [
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hiddify/core/analytics/analytics_controller.dart';
|
import 'package:hiddify/core/analytics/analytics_controller.dart';
|
||||||
import 'package:hiddify/core/localization/locale_extensions.dart';
|
import 'package:hiddify/core/localization/locale_extensions.dart';
|
||||||
@@ -19,7 +20,7 @@ class LocalePrefTile extends HookConsumerWidget {
|
|||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(t.settings.general.locale),
|
title: Text(t.settings.general.locale),
|
||||||
subtitle: Text(locale.localeName),
|
subtitle: Text(locale.localeName),
|
||||||
leading: const Icon(Icons.language),
|
leading: const Icon(FluentIcons.local_language_24_regular),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final selectedLocale = await showDialog<AppLocale>(
|
final selectedLocale = await showDialog<AppLocale>(
|
||||||
context: context,
|
context: context,
|
||||||
@@ -61,7 +62,7 @@ class RegionPrefTile extends HookConsumerWidget {
|
|||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(t.settings.general.region),
|
title: Text(t.settings.general.region),
|
||||||
subtitle: Text(region.present(t)),
|
subtitle: Text(region.present(t)),
|
||||||
leading: const Icon(Icons.my_location),
|
leading: const Icon(FluentIcons.globe_location_24_regular),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final selectedRegion = await showDialog<Region>(
|
final selectedRegion = await showDialog<Region>(
|
||||||
context: context,
|
context: context,
|
||||||
@@ -111,7 +112,7 @@ class EnableAnalyticsPrefTile extends HookConsumerWidget {
|
|||||||
t.settings.general.enableAnalyticsMsg,
|
t.settings.general.enableAnalyticsMsg,
|
||||||
style: Theme.of(context).textTheme.bodySmall,
|
style: Theme.of(context).textTheme.bodySmall,
|
||||||
),
|
),
|
||||||
secondary: const Icon(Icons.bug_report),
|
secondary: const Icon(FluentIcons.bug_24_regular),
|
||||||
value: enabled,
|
value: enabled,
|
||||||
onChanged: (value) async {
|
onChanged: (value) async {
|
||||||
if (onChanged != null) {
|
if (onChanged != null) {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:dartx/dartx.dart';
|
import 'package:dartx/dartx.dart';
|
||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hiddify/core/localization/translations.dart';
|
import 'package:hiddify/core/localization/translations.dart';
|
||||||
@@ -46,9 +47,15 @@ class QRCodeScannerScreen extends HookConsumerWidget with PresLogger {
|
|||||||
builder: (context, state, child) {
|
builder: (context, state, child) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case TorchState.off:
|
case TorchState.off:
|
||||||
return const Icon(Icons.flash_off, color: Colors.grey);
|
return const Icon(
|
||||||
|
FluentIcons.flash_off_24_regular,
|
||||||
|
color: Colors.grey,
|
||||||
|
);
|
||||||
case TorchState.on:
|
case TorchState.on:
|
||||||
return const Icon(Icons.flash_on, color: Colors.yellow);
|
return const Icon(
|
||||||
|
FluentIcons.flash_24_regular,
|
||||||
|
color: Colors.yellow,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -56,17 +63,7 @@ class QRCodeScannerScreen extends HookConsumerWidget with PresLogger {
|
|||||||
onPressed: () => controller.toggleTorch(),
|
onPressed: () => controller.toggleTorch(),
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: ValueListenableBuilder(
|
icon: const Icon(FluentIcons.camera_switch_24_regular),
|
||||||
valueListenable: controller.cameraFacingState,
|
|
||||||
builder: (context, state, child) {
|
|
||||||
switch (state) {
|
|
||||||
case CameraFacing.front:
|
|
||||||
return const Icon(Icons.camera_front);
|
|
||||||
case CameraFacing.back:
|
|
||||||
return const Icon(Icons.camera_rear);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
tooltip: t.profile.add.qrScanner.facingSemanticLabel,
|
tooltip: t.profile.add.qrScanner.facingSemanticLabel,
|
||||||
onPressed: () => controller.switchCamera(),
|
onPressed: () => controller.switchCamera(),
|
||||||
),
|
),
|
||||||
@@ -103,7 +100,10 @@ class QRCodeScannerScreen extends HookConsumerWidget with PresLogger {
|
|||||||
children: [
|
children: [
|
||||||
const Padding(
|
const Padding(
|
||||||
padding: EdgeInsets.only(bottom: 8),
|
padding: EdgeInsets.only(bottom: 8),
|
||||||
child: Icon(Icons.error, color: Colors.white),
|
child: Icon(
|
||||||
|
FluentIcons.error_circle_24_regular,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Text(message),
|
Text(message),
|
||||||
Text(error.errorDetails?.message ?? ''),
|
Text(error.errorDetails?.message ?? ''),
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import 'package:dartx/dartx.dart';
|
import 'package:dartx/dartx.dart';
|
||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:hiddify/core/localization/translations.dart';
|
import 'package:hiddify/core/localization/translations.dart';
|
||||||
import 'package:hiddify/core/model/failures.dart';
|
import 'package:hiddify/core/model/failures.dart';
|
||||||
import 'package:hiddify/core/model/range.dart';
|
import 'package:hiddify/core/model/range.dart';
|
||||||
|
import 'package:hiddify/core/widget/adaptive_icon.dart';
|
||||||
import 'package:hiddify/core/widget/tip_card.dart';
|
import 'package:hiddify/core/widget/tip_card.dart';
|
||||||
import 'package:hiddify/features/common/nested_app_bar.dart';
|
import 'package:hiddify/features/common/nested_app_bar.dart';
|
||||||
import 'package:hiddify/features/config_option/model/config_option_entity.dart';
|
import 'package:hiddify/features/config_option/model/config_option_entity.dart';
|
||||||
@@ -45,6 +47,7 @@ class ConfigOptionsPage extends HookConsumerWidget {
|
|||||||
actions: [
|
actions: [
|
||||||
if (asyncOptions case AsyncData(value: final options))
|
if (asyncOptions case AsyncData(value: final options))
|
||||||
PopupMenuButton(
|
PopupMenuButton(
|
||||||
|
icon: Icon(AdaptiveIcon(context).more),
|
||||||
itemBuilder: (context) {
|
itemBuilder: (context) {
|
||||||
return [
|
return [
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
@@ -483,7 +486,7 @@ class ConfigOptionsPage extends HookConsumerWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
const Icon(Icons.error),
|
const Icon(FluentIcons.error_circle_24_regular),
|
||||||
const Gap(2),
|
const Gap(2),
|
||||||
Text(t.presentShortError(error)),
|
Text(t.presentShortError(error)),
|
||||||
const Gap(2),
|
const Gap(2),
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:hiddify/core/localization/translations.dart';
|
import 'package:hiddify/core/localization/translations.dart';
|
||||||
|
import 'package:hiddify/core/widget/adaptive_icon.dart';
|
||||||
|
import 'package:hiddify/core/widget/animated_visibility.dart';
|
||||||
|
import 'package:hiddify/core/widget/tip_card.dart';
|
||||||
import 'package:hiddify/features/geo_asset/overview/geo_assets_overview_notifier.dart';
|
import 'package:hiddify/features/geo_asset/overview/geo_assets_overview_notifier.dart';
|
||||||
import 'package:hiddify/features/geo_asset/widget/geo_asset_tile.dart';
|
import 'package:hiddify/features/geo_asset/widget/geo_asset_tile.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
@@ -22,6 +25,7 @@ class GeoAssetsOverviewPage extends HookConsumerWidget {
|
|||||||
pinned: true,
|
pinned: true,
|
||||||
actions: [
|
actions: [
|
||||||
PopupMenuButton(
|
PopupMenuButton(
|
||||||
|
icon: Icon(AdaptiveIcon(context).more),
|
||||||
itemBuilder: (context) {
|
itemBuilder: (context) {
|
||||||
return [
|
return [
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
@@ -39,13 +43,13 @@ class GeoAssetsOverviewPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
if (state case AsyncData(value: (:final geoip, :final geosite)))
|
if (state case AsyncData(value: (:final geoip, :final geosite)))
|
||||||
SliverPinnedHeader(
|
SliverPinnedHeader(
|
||||||
child: AnimatedSwitcher(
|
child: AnimatedVisibility(
|
||||||
duration: const Duration(milliseconds: 200),
|
visible: (geoip + geosite)
|
||||||
child: (geoip + geosite)
|
|
||||||
.where((e) => e.$1.active && e.$2 == null)
|
.where((e) => e.$1.active && e.$2 == null)
|
||||||
.isNotEmpty
|
.isNotEmpty,
|
||||||
? const MissingRoutingAssetsCard()
|
axis: Axis.vertical,
|
||||||
: const SizedBox(),
|
child:
|
||||||
|
TipCard(message: t.settings.geoAssets.missingGeoAssetsMsg),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
switch (state) {
|
switch (state) {
|
||||||
@@ -96,39 +100,3 @@ class GeoAssetsOverviewPage extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MissingRoutingAssetsCard extends HookConsumerWidget {
|
|
||||||
const MissingRoutingAssetsCard({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
|
||||||
final t = ref.watch(translationsProvider);
|
|
||||||
|
|
||||||
return Card(
|
|
||||||
margin: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 12,
|
|
||||||
vertical: 4,
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
const Padding(
|
|
||||||
padding: EdgeInsets.all(8.0),
|
|
||||||
child: Icon(Icons.lightbulb),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding:
|
|
||||||
const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
|
|
||||||
child: Text(t.settings.geoAssets.missingGeoAssetsMsg),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'package:dartx/dartx.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hiddify/core/localization/translations.dart';
|
import 'package:hiddify/core/localization/translations.dart';
|
||||||
import 'package:hiddify/core/model/failures.dart';
|
import 'package:hiddify/core/model/failures.dart';
|
||||||
|
import 'package:hiddify/core/widget/adaptive_icon.dart';
|
||||||
import 'package:hiddify/features/geo_asset/model/geo_asset_entity.dart';
|
import 'package:hiddify/features/geo_asset/model/geo_asset_entity.dart';
|
||||||
import 'package:hiddify/features/geo_asset/model/geo_asset_failure.dart';
|
import 'package:hiddify/features/geo_asset/model/geo_asset_failure.dart';
|
||||||
import 'package:hiddify/features/geo_asset/notifier/geo_asset_notifier.dart';
|
import 'package:hiddify/features/geo_asset/notifier/geo_asset_notifier.dart';
|
||||||
@@ -95,6 +96,7 @@ class GeoAssetTile extends HookConsumerWidget {
|
|||||||
selected: geoAsset.active,
|
selected: geoAsset.active,
|
||||||
onTap: onMarkAsActive,
|
onTap: onMarkAsActive,
|
||||||
trailing: PopupMenuButton(
|
trailing: PopupMenuButton(
|
||||||
|
icon: Icon(AdaptiveIcon(context).more),
|
||||||
itemBuilder: (context) {
|
itemBuilder: (context) {
|
||||||
return [
|
return [
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:hiddify/core/localization/translations.dart';
|
import 'package:hiddify/core/localization/translations.dart';
|
||||||
@@ -20,7 +21,7 @@ class EmptyProfilesHomeBody extends HookConsumerWidget {
|
|||||||
const Gap(16),
|
const Gap(16),
|
||||||
OutlinedButton.icon(
|
OutlinedButton.icon(
|
||||||
onPressed: () => const AddProfileRoute().push(context),
|
onPressed: () => const AddProfileRoute().push(context),
|
||||||
icon: const Icon(Icons.add),
|
icon: const Icon(FluentIcons.add_24_regular),
|
||||||
label: Text(t.profile.add.buttonText),
|
label: Text(t.profile.add.buttonText),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:dartx/dartx.dart';
|
import 'package:dartx/dartx.dart';
|
||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hiddify/core/app_info/app_info_provider.dart';
|
import 'package:hiddify/core/app_info/app_info_provider.dart';
|
||||||
import 'package:hiddify/core/localization/translations.dart';
|
import 'package:hiddify/core/localization/translations.dart';
|
||||||
@@ -48,7 +47,7 @@ class HomePage extends HookConsumerWidget {
|
|||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () => const AddProfileRoute().push(context),
|
onPressed: () => const AddProfileRoute().push(context),
|
||||||
icon: const Icon(Icons.add_circle),
|
icon: const Icon(FluentIcons.add_circle_24_filled),
|
||||||
tooltip: t.profile.add.buttonText,
|
tooltip: t.profile.add.buttonText,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
@@ -5,6 +6,7 @@ import 'package:gap/gap.dart';
|
|||||||
import 'package:hiddify/core/localization/translations.dart';
|
import 'package:hiddify/core/localization/translations.dart';
|
||||||
import 'package:hiddify/core/model/failures.dart';
|
import 'package:hiddify/core/model/failures.dart';
|
||||||
import 'package:hiddify/core/preferences/general_preferences.dart';
|
import 'package:hiddify/core/preferences/general_preferences.dart';
|
||||||
|
import 'package:hiddify/core/widget/adaptive_icon.dart';
|
||||||
import 'package:hiddify/features/common/nested_app_bar.dart';
|
import 'package:hiddify/features/common/nested_app_bar.dart';
|
||||||
import 'package:hiddify/features/log/data/log_data_providers.dart';
|
import 'package:hiddify/features/log/data/log_data_providers.dart';
|
||||||
import 'package:hiddify/features/log/model/log_level.dart';
|
import 'package:hiddify/features/log/model/log_level.dart';
|
||||||
@@ -65,22 +67,26 @@ class LogsOverviewPage extends HookConsumerWidget with PresLogger {
|
|||||||
if (state.paused)
|
if (state.paused)
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: notifier.resume,
|
onPressed: notifier.resume,
|
||||||
icon: const Icon(Icons.play_arrow),
|
icon: const Icon(FluentIcons.play_20_regular),
|
||||||
tooltip: t.logs.resumeTooltip,
|
tooltip: t.logs.resumeTooltip,
|
||||||
|
iconSize: 20,
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: notifier.pause,
|
onPressed: notifier.pause,
|
||||||
icon: const Icon(Icons.pause),
|
icon: const Icon(FluentIcons.pause_20_regular),
|
||||||
tooltip: t.logs.pauseTooltip,
|
tooltip: t.logs.pauseTooltip,
|
||||||
|
iconSize: 20,
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: notifier.clear,
|
onPressed: notifier.clear,
|
||||||
icon: const Icon(Icons.clear_all),
|
icon: const Icon(FluentIcons.delete_lines_20_regular),
|
||||||
tooltip: t.logs.clearTooltip,
|
tooltip: t.logs.clearTooltip,
|
||||||
|
iconSize: 20,
|
||||||
),
|
),
|
||||||
if (popupButtons.isNotEmpty)
|
if (popupButtons.isNotEmpty)
|
||||||
PopupMenuButton(
|
PopupMenuButton(
|
||||||
|
icon: Icon(AdaptiveIcon(context).more),
|
||||||
itemBuilder: (context) {
|
itemBuilder: (context) {
|
||||||
return popupButtons;
|
return popupButtons;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import 'package:dartx/dartx.dart';
|
import 'package:dartx/dartx.dart';
|
||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hiddify/core/localization/translations.dart';
|
import 'package:hiddify/core/localization/translations.dart';
|
||||||
import 'package:hiddify/core/preferences/general_preferences.dart';
|
import 'package:hiddify/core/preferences/general_preferences.dart';
|
||||||
|
import 'package:hiddify/core/widget/adaptive_icon.dart';
|
||||||
import 'package:hiddify/features/per_app_proxy/model/installed_package_info.dart';
|
import 'package:hiddify/features/per_app_proxy/model/installed_package_info.dart';
|
||||||
import 'package:hiddify/features/per_app_proxy/model/per_app_proxy_mode.dart';
|
import 'package:hiddify/features/per_app_proxy/model/per_app_proxy_mode.dart';
|
||||||
import 'package:hiddify/features/per_app_proxy/overview/per_app_proxy_notifier.dart';
|
import 'package:hiddify/features/per_app_proxy/overview/per_app_proxy_notifier.dart';
|
||||||
@@ -83,11 +85,12 @@ class PerAppProxyPage extends HookConsumerWidget with PresLogger {
|
|||||||
title: Text(t.settings.network.perAppProxyPageTitle),
|
title: Text(t.settings.network.perAppProxyPageTitle),
|
||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.search),
|
icon: const Icon(FluentIcons.search_24_regular),
|
||||||
onPressed: () => isSearching.value = true,
|
onPressed: () => isSearching.value = true,
|
||||||
tooltip: localizations.searchFieldLabel,
|
tooltip: localizations.searchFieldLabel,
|
||||||
),
|
),
|
||||||
PopupMenuButton(
|
PopupMenuButton(
|
||||||
|
icon: Icon(AdaptiveIcon(context).more),
|
||||||
itemBuilder: (context) {
|
itemBuilder: (context) {
|
||||||
return [
|
return [
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
@@ -179,7 +182,8 @@ class PerAppProxyPage extends HookConsumerWidget with PresLogger {
|
|||||||
.watch(packageIconProvider(package.packageName))
|
.watch(packageIconProvider(package.packageName))
|
||||||
.when(
|
.when(
|
||||||
data: (data) => Image(image: data),
|
data: (data) => Image(image: data),
|
||||||
error: (error, _) => const Icon(Icons.error),
|
error: (error, _) =>
|
||||||
|
const Icon(FluentIcons.error_circle_24_regular),
|
||||||
loading: () => const Center(
|
loading: () => const Center(
|
||||||
child: CircularProgressIndicator(),
|
child: CircularProgressIndicator(),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
@@ -99,7 +100,7 @@ class AddProfileModal extends HookConsumerWidget {
|
|||||||
_Button(
|
_Button(
|
||||||
key: const ValueKey("add_from_clipboard_button"),
|
key: const ValueKey("add_from_clipboard_button"),
|
||||||
label: t.profile.add.fromClipboard,
|
label: t.profile.add.fromClipboard,
|
||||||
icon: Icons.content_paste,
|
icon: FluentIcons.clipboard_paste_24_regular,
|
||||||
size: buttonWidth,
|
size: buttonWidth,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final captureResult =
|
final captureResult =
|
||||||
@@ -116,7 +117,7 @@ class AddProfileModal extends HookConsumerWidget {
|
|||||||
_Button(
|
_Button(
|
||||||
key: const ValueKey("add_by_qr_code_button"),
|
key: const ValueKey("add_by_qr_code_button"),
|
||||||
label: t.profile.add.scanQr,
|
label: t.profile.add.scanQr,
|
||||||
icon: Icons.qr_code_scanner,
|
icon: FluentIcons.qr_code_24_regular,
|
||||||
size: buttonWidth,
|
size: buttonWidth,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final captureResult =
|
final captureResult =
|
||||||
@@ -133,7 +134,7 @@ class AddProfileModal extends HookConsumerWidget {
|
|||||||
_Button(
|
_Button(
|
||||||
key: const ValueKey("add_manually_button"),
|
key: const ValueKey("add_manually_button"),
|
||||||
label: t.profile.add.manually,
|
label: t.profile.add.manually,
|
||||||
icon: Icons.add,
|
icon: FluentIcons.add_24_regular,
|
||||||
size: buttonWidth,
|
size: buttonWidth,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
context.pop();
|
context.pop();
|
||||||
@@ -170,7 +171,7 @@ class AddProfileModal extends HookConsumerWidget {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Icon(
|
Icon(
|
||||||
Icons.add,
|
FluentIcons.add_24_regular,
|
||||||
color: theme.colorScheme.primary,
|
color: theme.colorScheme.primary,
|
||||||
),
|
),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:fpdart/fpdart.dart';
|
import 'package:fpdart/fpdart.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hiddify/core/localization/translations.dart';
|
import 'package:hiddify/core/localization/translations.dart';
|
||||||
import 'package:hiddify/core/model/failures.dart';
|
import 'package:hiddify/core/model/failures.dart';
|
||||||
|
import 'package:hiddify/core/widget/adaptive_icon.dart';
|
||||||
import 'package:hiddify/features/common/confirmation_dialogs.dart';
|
import 'package:hiddify/features/common/confirmation_dialogs.dart';
|
||||||
import 'package:hiddify/features/profile/details/profile_details_notifier.dart';
|
import 'package:hiddify/features/profile/details/profile_details_notifier.dart';
|
||||||
import 'package:hiddify/features/profile/model/profile_entity.dart';
|
import 'package:hiddify/features/profile/model/profile_entity.dart';
|
||||||
@@ -95,6 +97,7 @@ class ProfileDetailsPage extends HookConsumerWidget with PresLogger {
|
|||||||
actions: [
|
actions: [
|
||||||
if (state.isEditing)
|
if (state.isEditing)
|
||||||
PopupMenuButton(
|
PopupMenuButton(
|
||||||
|
icon: Icon(AdaptiveIcon(context).more),
|
||||||
itemBuilder: (context) {
|
itemBuilder: (context) {
|
||||||
return [
|
return [
|
||||||
if (state.profile case RemoteProfileEntity())
|
if (state.profile case RemoteProfileEntity())
|
||||||
@@ -175,7 +178,8 @@ class ProfileDetailsPage extends HookConsumerWidget with PresLogger {
|
|||||||
) ??
|
) ??
|
||||||
t.general.toggle.disabled,
|
t.general.toggle.disabled,
|
||||||
),
|
),
|
||||||
leading: const Icon(Icons.update),
|
leading:
|
||||||
|
const Icon(FluentIcons.arrow_sync_24_regular),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final intervalInHours =
|
final intervalInHours =
|
||||||
await SettingsInputDialog(
|
await SettingsInputDialog(
|
||||||
@@ -185,7 +189,8 @@ class ProfileDetailsPage extends HookConsumerWidget with PresLogger {
|
|||||||
optionalAction: (
|
optionalAction: (
|
||||||
t.general.state.disable,
|
t.general.state.disable,
|
||||||
() => notifier.setField(
|
() => notifier.setField(
|
||||||
updateInterval: none()),
|
updateInterval: none(),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
validator: isPort,
|
validator: isPort,
|
||||||
mapTo: int.tryParse,
|
mapTo: int.tryParse,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hiddify/core/localization/translations.dart';
|
import 'package:hiddify/core/localization/translations.dart';
|
||||||
|
|
||||||
@@ -13,8 +14,8 @@ enum ProfilesSort {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IconData get icon => switch (this) {
|
IconData get icon => switch (this) {
|
||||||
lastUpdate => Icons.update,
|
lastUpdate => FluentIcons.history_24_regular,
|
||||||
name => Icons.sort_by_alpha,
|
name => FluentIcons.text_sort_ascending_24_regular,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:hiddify/core/localization/translations.dart';
|
import 'package:hiddify/core/localization/translations.dart';
|
||||||
@@ -79,7 +80,7 @@ class ProfilesOverviewModal extends HookConsumerWidget {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
const AddProfileRoute().push(context);
|
const AddProfileRoute().push(context);
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.add),
|
icon: const Icon(FluentIcons.add_24_filled),
|
||||||
label: Text(t.profile.add.shortBtnTxt),
|
label: Text(t.profile.add.shortBtnTxt),
|
||||||
),
|
),
|
||||||
FilledButton.icon(
|
FilledButton.icon(
|
||||||
@@ -91,7 +92,7 @@ class ProfilesOverviewModal extends HookConsumerWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.sort),
|
icon: const Icon(FluentIcons.arrow_sort_24_filled),
|
||||||
label: Text(t.general.sort),
|
label: Text(t.general.sort),
|
||||||
),
|
),
|
||||||
FilledButton.icon(
|
FilledButton.icon(
|
||||||
@@ -102,7 +103,7 @@ class ProfilesOverviewModal extends HookConsumerWidget {
|
|||||||
)
|
)
|
||||||
.trigger();
|
.trigger();
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.update),
|
icon: const Icon(FluentIcons.arrow_sync_24_filled),
|
||||||
label: Text(t.profile.update.updateSubscriptions),
|
label: Text(t.profile.update.updateSubscriptions),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -159,7 +160,7 @@ class ProfilesSortModal extends HookConsumerWidget {
|
|||||||
turns: arrowTurn,
|
turns: arrowTurn,
|
||||||
duration: const Duration(milliseconds: 100),
|
duration: const Duration(milliseconds: 100),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.arrow_upward,
|
FluentIcons.arrow_sort_up_24_regular,
|
||||||
semanticLabel: sort.mode.name,
|
semanticLabel: sort.mode.name,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
@@ -6,6 +7,7 @@ import 'package:go_router/go_router.dart';
|
|||||||
import 'package:hiddify/core/localization/translations.dart';
|
import 'package:hiddify/core/localization/translations.dart';
|
||||||
import 'package:hiddify/core/model/failures.dart';
|
import 'package:hiddify/core/model/failures.dart';
|
||||||
import 'package:hiddify/core/router/router.dart';
|
import 'package:hiddify/core/router/router.dart';
|
||||||
|
import 'package:hiddify/core/widget/adaptive_icon.dart';
|
||||||
import 'package:hiddify/core/widget/adaptive_menu.dart';
|
import 'package:hiddify/core/widget/adaptive_menu.dart';
|
||||||
import 'package:hiddify/features/common/confirmation_dialogs.dart';
|
import 'package:hiddify/features/common/confirmation_dialogs.dart';
|
||||||
import 'package:hiddify/features/common/qr_code_dialog.dart';
|
import 'package:hiddify/features/common/qr_code_dialog.dart';
|
||||||
@@ -132,7 +134,10 @@ class ProfileTile extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Icon(Icons.arrow_drop_down),
|
const Icon(
|
||||||
|
FluentIcons.caret_down_16_filled,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -196,7 +201,7 @@ class ProfileActionButton extends HookConsumerWidget {
|
|||||||
.read(updateProfileProvider(profile.id).notifier)
|
.read(updateProfileProvider(profile.id).notifier)
|
||||||
.updateProfile(profile as RemoteProfileEntity);
|
.updateProfile(profile as RemoteProfileEntity);
|
||||||
},
|
},
|
||||||
child: const Icon(Icons.update),
|
child: const Icon(FluentIcons.arrow_sync_24_filled),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -210,7 +215,7 @@ class ProfileActionButton extends HookConsumerWidget {
|
|||||||
message: MaterialLocalizations.of(context).showMenuTooltip,
|
message: MaterialLocalizations.of(context).showMenuTooltip,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: toggleVisibility,
|
onTap: toggleVisibility,
|
||||||
child: const Icon(Icons.more_vert),
|
child: Icon(AdaptiveIcon(context).more),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -248,7 +253,7 @@ class ProfileActionsMenu extends HookConsumerWidget {
|
|||||||
if (profile case RemoteProfileEntity())
|
if (profile case RemoteProfileEntity())
|
||||||
AdaptiveMenuItem(
|
AdaptiveMenuItem(
|
||||||
title: t.profile.update.buttonTxt,
|
title: t.profile.update.buttonTxt,
|
||||||
icon: Icons.update,
|
icon: FluentIcons.arrow_sync_24_regular,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (ref.read(updateProfileProvider(profile.id)).isLoading) {
|
if (ref.read(updateProfileProvider(profile.id)).isLoading) {
|
||||||
return;
|
return;
|
||||||
@@ -260,7 +265,7 @@ class ProfileActionsMenu extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
AdaptiveMenuItem(
|
AdaptiveMenuItem(
|
||||||
title: t.profile.share.buttonText,
|
title: t.profile.share.buttonText,
|
||||||
icon: Icons.share,
|
icon: AdaptiveIcon(context).share,
|
||||||
subItems: [
|
subItems: [
|
||||||
if (profile case RemoteProfileEntity(:final url, :final name)) ...[
|
if (profile case RemoteProfileEntity(:final url, :final name)) ...[
|
||||||
AdaptiveMenuItem(
|
AdaptiveMenuItem(
|
||||||
@@ -305,14 +310,14 @@ class ProfileActionsMenu extends HookConsumerWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
AdaptiveMenuItem(
|
AdaptiveMenuItem(
|
||||||
icon: Icons.edit,
|
icon: FluentIcons.edit_24_regular,
|
||||||
title: t.profile.edit.buttonTxt,
|
title: t.profile.edit.buttonTxt,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await ProfileDetailsRoute(profile.id).push(context);
|
await ProfileDetailsRoute(profile.id).push(context);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
AdaptiveMenuItem(
|
AdaptiveMenuItem(
|
||||||
icon: Icons.delete,
|
icon: FluentIcons.delete_24_regular,
|
||||||
title: t.profile.delete.buttonTxt,
|
title: t.profile.delete.buttonTxt,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (deleteProfileMutation.state.isInProgress) {
|
if (deleteProfileMutation.state.isInProgress) {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hiddify/core/localization/translations.dart';
|
import 'package:hiddify/core/localization/translations.dart';
|
||||||
import 'package:hiddify/core/model/failures.dart';
|
import 'package:hiddify/core/model/failures.dart';
|
||||||
@@ -29,7 +30,7 @@ class ProxiesOverviewPage extends HookConsumerWidget with PresLogger {
|
|||||||
PopupMenuButton<ProxiesSort>(
|
PopupMenuButton<ProxiesSort>(
|
||||||
initialValue: sortBy,
|
initialValue: sortBy,
|
||||||
onSelected: ref.read(proxiesSortNotifierProvider.notifier).update,
|
onSelected: ref.read(proxiesSortNotifierProvider.notifier).update,
|
||||||
icon: const Icon(Icons.sort),
|
icon: const Icon(FluentIcons.arrow_sort_24_regular),
|
||||||
tooltip: t.proxies.sortTooltip,
|
tooltip: t.proxies.sortTooltip,
|
||||||
itemBuilder: (context) {
|
itemBuilder: (context) {
|
||||||
return [
|
return [
|
||||||
@@ -131,7 +132,7 @@ class ProxiesOverviewPage extends HookConsumerWidget with PresLogger {
|
|||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: FloatingActionButton(
|
||||||
onPressed: () async => notifier.urlTest(group.tag),
|
onPressed: () async => notifier.urlTest(group.tag),
|
||||||
tooltip: t.proxies.delayTestTooltip,
|
tooltip: t.proxies.delayTestTooltip,
|
||||||
child: const Icon(Icons.bolt),
|
child: const Icon(FluentIcons.flash_24_filled),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
@@ -6,6 +7,7 @@ import 'package:hiddify/core/directories/directories_provider.dart';
|
|||||||
import 'package:hiddify/core/localization/translations.dart';
|
import 'package:hiddify/core/localization/translations.dart';
|
||||||
import 'package:hiddify/core/model/constants.dart';
|
import 'package:hiddify/core/model/constants.dart';
|
||||||
import 'package:hiddify/core/model/failures.dart';
|
import 'package:hiddify/core/model/failures.dart';
|
||||||
|
import 'package:hiddify/core/widget/adaptive_icon.dart';
|
||||||
import 'package:hiddify/features/app_update/notifier/app_update_notifier.dart';
|
import 'package:hiddify/features/app_update/notifier/app_update_notifier.dart';
|
||||||
import 'package:hiddify/features/app_update/notifier/app_update_state.dart';
|
import 'package:hiddify/features/app_update/notifier/app_update_state.dart';
|
||||||
import 'package:hiddify/features/app_update/widget/new_version_dialog.dart';
|
import 'package:hiddify/features/app_update/widget/new_version_dialog.dart';
|
||||||
@@ -54,7 +56,7 @@ class AboutPage extends HookConsumerWidget {
|
|||||||
height: 24,
|
height: 24,
|
||||||
child: CircularProgressIndicator(),
|
child: CircularProgressIndicator(),
|
||||||
),
|
),
|
||||||
_ => const Icon(Icons.update),
|
_ => const Icon(FluentIcons.arrow_sync_24_regular),
|
||||||
},
|
},
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await ref.read(appUpdateNotifierProvider.notifier).check();
|
await ref.read(appUpdateNotifierProvider.notifier).check();
|
||||||
@@ -63,7 +65,7 @@ class AboutPage extends HookConsumerWidget {
|
|||||||
if (PlatformUtils.isDesktop)
|
if (PlatformUtils.isDesktop)
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(t.settings.general.openWorkingDir),
|
title: Text(t.settings.general.openWorkingDir),
|
||||||
trailing: const Icon(Icons.arrow_outward_outlined),
|
trailing: const Icon(FluentIcons.open_folder_24_regular),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final path =
|
final path =
|
||||||
ref.watch(appDirectoriesProvider).requireValue.workingDir.uri;
|
ref.watch(appDirectoriesProvider).requireValue.workingDir.uri;
|
||||||
@@ -79,6 +81,7 @@ class AboutPage extends HookConsumerWidget {
|
|||||||
title: Text(t.about.pageTitle),
|
title: Text(t.about.pageTitle),
|
||||||
actions: [
|
actions: [
|
||||||
PopupMenuButton(
|
PopupMenuButton(
|
||||||
|
icon: Icon(AdaptiveIcon(context).more),
|
||||||
itemBuilder: (context) {
|
itemBuilder: (context) {
|
||||||
return [
|
return [
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
@@ -126,7 +129,7 @@ class AboutPage extends HookConsumerWidget {
|
|||||||
if (conditionalTiles.isNotEmpty) const Divider(),
|
if (conditionalTiles.isNotEmpty) const Divider(),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(t.about.sourceCode),
|
title: Text(t.about.sourceCode),
|
||||||
trailing: const Icon(Icons.open_in_new),
|
trailing: const Icon(FluentIcons.open_24_regular),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await UriUtils.tryLaunch(
|
await UriUtils.tryLaunch(
|
||||||
Uri.parse(Constants.githubUrl),
|
Uri.parse(Constants.githubUrl),
|
||||||
@@ -135,7 +138,7 @@ class AboutPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(t.about.telegramChannel),
|
title: Text(t.about.telegramChannel),
|
||||||
trailing: const Icon(Icons.open_in_new),
|
trailing: const Icon(FluentIcons.open_24_regular),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await UriUtils.tryLaunch(
|
await UriUtils.tryLaunch(
|
||||||
Uri.parse(Constants.telegramChannelUrl),
|
Uri.parse(Constants.telegramChannelUrl),
|
||||||
@@ -144,7 +147,7 @@ class AboutPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(t.about.termsAndConditions),
|
title: Text(t.about.termsAndConditions),
|
||||||
trailing: const Icon(Icons.open_in_new),
|
trailing: const Icon(FluentIcons.open_24_regular),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await UriUtils.tryLaunch(
|
await UriUtils.tryLaunch(
|
||||||
Uri.parse(Constants.termsAndConditionsUrl),
|
Uri.parse(Constants.termsAndConditionsUrl),
|
||||||
@@ -153,7 +156,7 @@ class AboutPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(t.about.privacyPolicy),
|
title: Text(t.about.privacyPolicy),
|
||||||
trailing: const Icon(Icons.open_in_new),
|
trailing: const Icon(FluentIcons.open_24_regular),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await UriUtils.tryLaunch(
|
await UriUtils.tryLaunch(
|
||||||
Uri.parse(Constants.privacyPolicyUrl),
|
Uri.parse(Constants.privacyPolicyUrl),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hiddify/core/localization/translations.dart';
|
import 'package:hiddify/core/localization/translations.dart';
|
||||||
import 'package:hiddify/core/preferences/general_preferences.dart';
|
import 'package:hiddify/core/preferences/general_preferences.dart';
|
||||||
@@ -25,7 +26,9 @@ class AdvancedSettingTiles extends HookConsumerWidget {
|
|||||||
const RegionPrefTile(),
|
const RegionPrefTile(),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(t.settings.geoAssets.pageTitle),
|
title: Text(t.settings.geoAssets.pageTitle),
|
||||||
leading: const Icon(Icons.folder),
|
leading: const Icon(
|
||||||
|
FluentIcons.arrow_routing_rectangle_multiple_24_regular,
|
||||||
|
),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await const GeoAssetsRoute().push(context);
|
await const GeoAssetsRoute().push(context);
|
||||||
},
|
},
|
||||||
@@ -33,7 +36,7 @@ class AdvancedSettingTiles extends HookConsumerWidget {
|
|||||||
if (Platform.isAndroid) ...[
|
if (Platform.isAndroid) ...[
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(t.settings.network.perAppProxyPageTitle),
|
title: Text(t.settings.network.perAppProxyPageTitle),
|
||||||
leading: const Icon(Icons.apps),
|
leading: const Icon(FluentIcons.apps_list_detail_24_regular),
|
||||||
trailing: Switch(
|
trailing: Switch(
|
||||||
value: perAppProxy,
|
value: perAppProxy,
|
||||||
onChanged: (value) async {
|
onChanged: (value) async {
|
||||||
@@ -61,7 +64,7 @@ class AdvancedSettingTiles extends HookConsumerWidget {
|
|||||||
title: Text(t.settings.advanced.memoryLimit),
|
title: Text(t.settings.advanced.memoryLimit),
|
||||||
subtitle: Text(t.settings.advanced.memoryLimitMsg),
|
subtitle: Text(t.settings.advanced.memoryLimitMsg),
|
||||||
value: !disableMemoryLimit,
|
value: !disableMemoryLimit,
|
||||||
secondary: const Icon(Icons.memory),
|
secondary: const Icon(FluentIcons.developer_board_24_regular),
|
||||||
onChanged: (value) async {
|
onChanged: (value) async {
|
||||||
await ref.read(disableMemoryLimitProvider.notifier).update(!value);
|
await ref.read(disableMemoryLimitProvider.notifier).update(!value);
|
||||||
},
|
},
|
||||||
@@ -69,7 +72,7 @@ class AdvancedSettingTiles extends HookConsumerWidget {
|
|||||||
if (Platform.isIOS)
|
if (Platform.isIOS)
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(t.settings.advanced.resetTunnel),
|
title: Text(t.settings.advanced.resetTunnel),
|
||||||
leading: const Icon(Icons.restart_alt),
|
leading: const Icon(FluentIcons.arrow_reset_24_regular),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await ref.read(resetTunnelProvider.notifier).run();
|
await ref.read(resetTunnelProvider.notifier).run();
|
||||||
},
|
},
|
||||||
@@ -77,7 +80,7 @@ class AdvancedSettingTiles extends HookConsumerWidget {
|
|||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
title: Text(t.settings.advanced.debugMode),
|
title: Text(t.settings.advanced.debugMode),
|
||||||
value: debug,
|
value: debug,
|
||||||
secondary: const Icon(Icons.bug_report),
|
secondary: const Icon(FluentIcons.window_dev_tools_24_regular),
|
||||||
onChanged: (value) async {
|
onChanged: (value) async {
|
||||||
if (value) {
|
if (value) {
|
||||||
await showDialog<bool>(
|
await showDialog<bool>(
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hiddify/core/localization/translations.dart';
|
import 'package:hiddify/core/localization/translations.dart';
|
||||||
import 'package:hiddify/core/preferences/general_preferences.dart';
|
import 'package:hiddify/core/preferences/general_preferences.dart';
|
||||||
@@ -25,7 +26,7 @@ class GeneralSettingTiles extends HookConsumerWidget {
|
|||||||
ListTile(
|
ListTile(
|
||||||
title: Text(t.settings.general.themeMode),
|
title: Text(t.settings.general.themeMode),
|
||||||
subtitle: Text(themeMode.present(t)),
|
subtitle: Text(themeMode.present(t)),
|
||||||
leading: const Icon(Icons.light_mode),
|
leading: const Icon(FluentIcons.weather_moon_20_regular),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final selectedThemeMode = await showDialog<AppThemeMode>(
|
final selectedThemeMode = await showDialog<AppThemeMode>(
|
||||||
context: context,
|
context: context,
|
||||||
@@ -56,7 +57,7 @@ class GeneralSettingTiles extends HookConsumerWidget {
|
|||||||
if (Platform.isAndroid)
|
if (Platform.isAndroid)
|
||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
title: Text(t.settings.general.dynamicNotification),
|
title: Text(t.settings.general.dynamicNotification),
|
||||||
secondary: const Icon(Icons.speed),
|
secondary: const Icon(FluentIcons.top_speed_24_regular),
|
||||||
value: ref.watch(dynamicNotificationProvider),
|
value: ref.watch(dynamicNotificationProvider),
|
||||||
onChanged: (value) async {
|
onChanged: (value) async {
|
||||||
await ref
|
await ref
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hiddify/core/localization/translations.dart';
|
import 'package:hiddify/core/localization/translations.dart';
|
||||||
import 'package:hiddify/features/settings/notifier/platform_settings_notifier.dart';
|
import 'package:hiddify/features/settings/notifier/platform_settings_notifier.dart';
|
||||||
@@ -18,7 +19,7 @@ class PlatformSettingsTiles extends HookConsumerWidget {
|
|||||||
ListTile buildIgnoreTile(bool enabled) => ListTile(
|
ListTile buildIgnoreTile(bool enabled) => ListTile(
|
||||||
title: Text(t.settings.general.ignoreBatteryOptimizations),
|
title: Text(t.settings.general.ignoreBatteryOptimizations),
|
||||||
subtitle: Text(t.settings.general.ignoreBatteryOptimizationsMsg),
|
subtitle: Text(t.settings.general.ignoreBatteryOptimizationsMsg),
|
||||||
leading: const Icon(Icons.running_with_errors),
|
leading: const Icon(FluentIcons.battery_saver_24_regular),
|
||||||
enabled: enabled,
|
enabled: enabled,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await ref
|
await ref
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:toastification/toastification.dart';
|
import 'package:toastification/toastification.dart';
|
||||||
|
|
||||||
@@ -73,13 +74,13 @@ class CustomToast extends StatelessWidget {
|
|||||||
this.message, {
|
this.message, {
|
||||||
this.duration = const Duration(seconds: 5),
|
this.duration = const Duration(seconds: 5),
|
||||||
}) : type = AlertType.error,
|
}) : type = AlertType.error,
|
||||||
icon = Icons.error;
|
icon = FluentIcons.error_circle_24_regular;
|
||||||
|
|
||||||
const CustomToast.success(
|
const CustomToast.success(
|
||||||
this.message, {
|
this.message, {
|
||||||
this.duration = const Duration(seconds: 3),
|
this.duration = const Duration(seconds: 3),
|
||||||
}) : type = AlertType.success,
|
}) : type = AlertType.success,
|
||||||
icon = Icons.check;
|
icon = FluentIcons.checkmark_24_regular;
|
||||||
|
|
||||||
final String message;
|
final String message;
|
||||||
final AlertType type;
|
final AlertType type;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
@@ -39,7 +40,7 @@ class SliverErrorBodyPlaceholder extends HookConsumerWidget {
|
|||||||
const SliverErrorBodyPlaceholder(
|
const SliverErrorBodyPlaceholder(
|
||||||
this.msg, {
|
this.msg, {
|
||||||
super.key,
|
super.key,
|
||||||
this.icon = Icons.error,
|
this.icon = FluentIcons.error_circle_24_regular,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String msg;
|
final String msg;
|
||||||
|
|||||||
Reference in New Issue
Block a user