feat: mobile-like window size and always-visible stats

- Changed window size to mobile phone format (400x800)
- Removed width condition for ActiveProxyFooter - now always visible
- Added run-umbrix.sh launch script with icon copying
- Stats cards now display on all screen sizes
This commit is contained in:
Umbrix Developer
2026-01-17 13:09:20 +03:00
parent ec5ebbd54b
commit 76a374950f
245 changed files with 7931 additions and 1315 deletions

View File

@@ -1,10 +1,10 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hiddify/core/preferences/general_preferences.dart';
import 'package:hiddify/core/router/routes.dart';
import 'package:hiddify/features/deep_link/notifier/deep_link_notifier.dart';
import 'package:hiddify/utils/utils.dart';
import 'package:umbrix/core/preferences/general_preferences.dart';
import 'package:umbrix/core/router/routes.dart';
import 'package:umbrix/features/deep_link/notifier/deep_link_notifier.dart';
import 'package:umbrix/utils/utils.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
@@ -50,22 +50,26 @@ GoRouter router(RouterRef ref) {
}
final tabLocations = [
const HomeRoute().location,
const ProxiesRoute().location,
const PerAppProxyRoute().location,
const ConfigOptionsRoute().location,
const SettingsRoute().location,
const AboutRoute().location,
const HomeRoute().location, // 0: Главная
const ProxiesRoute().location, // 1: Локации
const PerAppProxyRoute().location, // 2: Исключения
const SettingsRoute().location, // 3: Настройки
const AboutRoute().location, // 4: О программе
];
int getCurrentIndex(BuildContext context) {
final String location = GoRouterState.of(context).uri.path;
// Проверяем точное совпадение для главной
if (location == const HomeRoute().location) return 0;
var index = 0;
for (final tab in tabLocations.sublist(1)) {
index++;
if (location.startsWith(tab)) return index;
}
// Проверяем остальные маршруты по порядку
// ВАЖНО: более длинные пути проверяем раньше!
if (location.startsWith(const PerAppProxyRoute().location)) return 2; // /settings/per-app-proxy
if (location.startsWith(const ProxiesRoute().location)) return 1; // /proxies
if (location.startsWith(const SettingsRoute().location)) return 3; // /settings
if (location.startsWith(const AboutRoute().location)) return 4; // /about
return 0;
}

View File

@@ -1,21 +1,21 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hiddify/core/router/app_router.dart';
import 'package:hiddify/features/common/adaptive_root_scaffold.dart';
import 'package:hiddify/features/config_option/overview/config_options_page.dart';
import 'package:hiddify/features/config_option/widget/quick_settings_modal.dart';
import 'package:umbrix/core/router/app_router.dart';
import 'package:umbrix/features/common/adaptive_root_scaffold.dart';
import 'package:umbrix/features/config_option/overview/config_options_page.dart';
import 'package:umbrix/features/config_option/widget/quick_settings_modal.dart';
import 'package:hiddify/features/home/widget/home_page.dart';
import 'package:hiddify/features/intro/widget/intro_page.dart';
import 'package:hiddify/features/log/overview/logs_overview_page.dart';
import 'package:hiddify/features/per_app_proxy/overview/per_app_proxy_page.dart';
import 'package:hiddify/features/profile/add/add_profile_modal.dart';
import 'package:hiddify/features/profile/details/profile_details_page.dart';
import 'package:hiddify/features/profile/overview/profiles_overview_page.dart';
import 'package:hiddify/features/proxy/overview/proxies_overview_page.dart';
import 'package:hiddify/features/settings/about/about_page.dart';
import 'package:hiddify/features/settings/overview/settings_overview_page.dart';
import 'package:hiddify/utils/utils.dart';
import 'package:umbrix/features/home/widget/home_page.dart';
import 'package:umbrix/features/intro/widget/intro_page.dart';
import 'package:umbrix/features/log/overview/logs_overview_page.dart';
import 'package:umbrix/features/per_app_proxy/overview/per_app_proxy_page.dart';
import 'package:umbrix/features/profile/add/add_profile_modal.dart';
import 'package:umbrix/features/profile/details/profile_details_page.dart';
import 'package:umbrix/features/profile/overview/profiles_overview_page.dart';
import 'package:umbrix/features/proxy/overview/proxies_overview_page.dart';
import 'package:umbrix/features/settings/about/about_page.dart';
import 'package:umbrix/features/settings/overview/settings_overview_page.dart';
import 'package:umbrix/utils/utils.dart';
part 'routes.g.dart';
@@ -54,12 +54,7 @@ GlobalKey<NavigatorState>? _dynamicRootKey = useMobileRouter ? rootNavigatorKey
TypedGoRoute<SettingsRoute>(
path: "settings",
name: SettingsRoute.name,
routes: [
TypedGoRoute<PerAppProxyRoute>(
path: "per-app-proxy",
name: PerAppProxyRoute.name,
),
],
routes: [],
),
TypedGoRoute<LogsOverviewRoute>(
path: "logs",
@@ -75,6 +70,10 @@ GlobalKey<NavigatorState>? _dynamicRootKey = useMobileRouter ? rootNavigatorKey
path: "/proxies",
name: ProxiesRoute.name,
),
TypedGoRoute<PerAppProxyRoute>(
path: "/settings/per-app-proxy",
name: PerAppProxyRoute.name,
),
],
)
class MobileWrapperRoute extends ShellRouteData {
@@ -118,6 +117,10 @@ class MobileWrapperRoute extends ShellRouteData {
path: "/proxies",
name: ProxiesRoute.name,
),
TypedGoRoute<PerAppProxyRoute>(
path: "/settings/per-app-proxy",
name: PerAppProxyRoute.name,
),
TypedGoRoute<ConfigOptionsRoute>(
path: "/config-options",
name: ConfigOptionsRoute.name,
@@ -180,9 +183,18 @@ class ProxiesRoute extends GoRouteData {
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const NoTransitionPage(
final interceptBackToHome = !PlatformUtils.isDesktop;
return NoTransitionPage(
name: name,
child: ProxiesOverviewPage(),
child: PopScope<void>(
canPop: !interceptBackToHome,
onPopInvokedWithResult: (didPop, result) {
if (!didPop && interceptBackToHome) {
const HomeRoute().go(context);
}
},
child: const ProxiesOverviewPage(),
),
);
}
}
@@ -335,14 +347,20 @@ class PerAppProxyRoute extends GoRouteData {
const PerAppProxyRoute();
static const name = "Per-app Proxy";
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
@override
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const MaterialPage(
fullscreenDialog: true,
final interceptBackToHome = !PlatformUtils.isDesktop;
return NoTransitionPage(
name: name,
child: PerAppProxyPage(),
child: PopScope<void>(
canPop: !interceptBackToHome,
onPopInvokedWithResult: (didPop, result) {
if (!didPop && interceptBackToHome) {
const HomeRoute().go(context);
}
},
child: const PerAppProxyPage(),
),
);
}
}