perf(android): уменьшаем вес APK на ~33% (65→43.6 МБ)

- media_kit только для десктопа — убраны ffmpeg/libass/mdk с мобилы (~10 МБ)
- google_fonts заменён бандлом Inter/Outfit/Unbounded — убран реестр всех
  шрифтов из libapp.so (22→10 МБ)
- удалена неиспользуемая зависимость camera (CameraX)
- Dart-обфускация (--obfuscate --split-debug-info) в релизных CI + выгрузка
  символов
- кастомные шрифты с Google Fonts вернулись через FontLoader + кэш, без веса
- хардкод Inter заменён наследованием шрифта из активной темы
This commit is contained in:
klockky
2026-06-25 22:51:04 +03:00
parent 0f4844bf80
commit a55ab28ede
26 changed files with 291 additions and 237 deletions
@@ -2,7 +2,6 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:komet/l10n/app_localizations.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'password_2fa_screen.dart';
import 'registration_screen.dart';
import '../../../main.dart';
@@ -234,7 +233,7 @@ class _CodeConfirmationScreenState extends State<CodeConfirmationScreen>
const SizedBox(height: 16),
Text(
widget.phoneNumber,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 22,
fontWeight: FontWeight.w500,
+22 -23
View File
@@ -2,7 +2,6 @@ import 'dart:async';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:komet/core/config/countries.dart';
import 'package:komet/l10n/app_localizations.dart';
@@ -172,7 +171,7 @@ class _LoginScreenState extends State<LoginScreen> {
padding: const EdgeInsets.only(left: 8, bottom: 8),
child: Text(
l10n.loginLanguage,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 18,
fontWeight: FontWeight.w600,
@@ -182,7 +181,7 @@ class _LoginScreenState extends State<LoginScreen> {
ListTile(
title: Text(
l10n.languageNameRu,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 16,
fontWeight: FontWeight.w500,
@@ -198,7 +197,7 @@ class _LoginScreenState extends State<LoginScreen> {
ListTile(
title: Text(
l10n.languageNameEn,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 16,
fontWeight: FontWeight.w500,
@@ -249,7 +248,7 @@ class _LoginScreenState extends State<LoginScreen> {
children: [
Text(
AppLocalizations.of(context)!.loginTermsOfUse,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 20,
fontWeight: FontWeight.w500,
@@ -420,7 +419,7 @@ class _LoginScreenState extends State<LoginScreen> {
children: [
Text(
l10n.loginConfirmPhoneTitle,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurfaceVariant,
fontSize: 14,
fontWeight: FontWeight.w500,
@@ -429,7 +428,7 @@ class _LoginScreenState extends State<LoginScreen> {
const SizedBox(height: 12),
Text(
'${_selectedCountry.phoneCode} $formattedPhone',
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 18,
fontWeight: FontWeight.w500,
@@ -445,7 +444,7 @@ class _LoginScreenState extends State<LoginScreen> {
onPressed: () => Navigator.pop(context),
child: Text(
l10n.loginEdit,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.primary,
fontSize: 15,
fontWeight: FontWeight.w500,
@@ -482,7 +481,7 @@ class _LoginScreenState extends State<LoginScreen> {
},
child: Text(
l10n.loginDone,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.primary,
fontSize: 15,
fontWeight: FontWeight.w600,
@@ -558,7 +557,7 @@ class _LoginScreenState extends State<LoginScreen> {
leading: Icon(Symbols.security, color: cs.onSurface),
title: Text(
l10n.loginSpoofRedacted,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 16,
fontWeight: FontWeight.w500,
@@ -578,7 +577,7 @@ class _LoginScreenState extends State<LoginScreen> {
leading: Icon(Symbols.vpn_lock, color: cs.onSurface),
title: Text(
l10n.loginProxy,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 16,
fontWeight: FontWeight.w500,
@@ -593,7 +592,7 @@ class _LoginScreenState extends State<LoginScreen> {
leading: Icon(Symbols.dns, color: cs.onSurface),
title: Text(
l10n.loginChangeServer,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 16,
fontWeight: FontWeight.w500,
@@ -633,7 +632,7 @@ class _LoginScreenState extends State<LoginScreen> {
leading: Icon(Symbols.qr_code_2, color: cs.onSurface),
title: Text(
l10n.loginSignInWithQr,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 16,
fontWeight: FontWeight.w500,
@@ -647,7 +646,7 @@ class _LoginScreenState extends State<LoginScreen> {
leading: Icon(Symbols.key, color: cs.onSurface),
title: Text(
l10n.loginSignInWithToken,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 16,
fontWeight: FontWeight.w500,
@@ -669,7 +668,7 @@ class _LoginScreenState extends State<LoginScreen> {
leading: Icon(Symbols.description, color: cs.onSurface),
title: Text(
l10n.loginSignInWithSessionFile,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 16,
fontWeight: FontWeight.w500,
@@ -771,7 +770,7 @@ class _LoginScreenState extends State<LoginScreen> {
const SizedBox(height: 16),
Text(
l10n.loginTitle,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 32,
fontWeight: FontWeight.w500,
@@ -801,7 +800,7 @@ class _LoginScreenState extends State<LoginScreen> {
children: [
Text(
_countryDisplayName(_selectedCountry),
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 15,
fontWeight: FontWeight.w400,
@@ -823,7 +822,7 @@ class _LoginScreenState extends State<LoginScreen> {
children: [
Text(
_selectedCountry.phoneCode,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 15,
fontWeight: FontWeight.w400,
@@ -905,7 +904,7 @@ class _LoginScreenState extends State<LoginScreen> {
onPressed: () => _showOtherLoginMethods(context),
child: Text(
l10n.loginOtherSignInMethods,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.primary,
fontSize: 14,
fontWeight: FontWeight.w400,
@@ -922,7 +921,7 @@ class _LoginScreenState extends State<LoginScreen> {
padding: const EdgeInsets.only(bottom: 24.0),
child: RichText(
text: TextSpan(
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 14,
fontWeight: FontWeight.w500,
@@ -931,7 +930,7 @@ class _LoginScreenState extends State<LoginScreen> {
children: [
TextSpan(
text: l10n.loginTermsIntro,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 14,
height: 1.4,
@@ -940,7 +939,7 @@ class _LoginScreenState extends State<LoginScreen> {
),
TextSpan(
text: l10n.loginTermsLink,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.primary,
fontSize: 14,
height: 1.4,
@@ -1016,7 +1015,7 @@ class _LoginScreenState extends State<LoginScreen> {
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Text(
label,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.primary,
fontSize: 14,
fontWeight: FontWeight.w400,
@@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../../../main.dart';
import '../../widgets/custom_notification.dart';
import '../../widgets/login_success_screen.dart';
@@ -94,7 +93,7 @@ class _Password2FAScreenState extends State<Password2FAScreen> {
const SizedBox(height: 16),
Text(
'Двухфакторная аутентификация',
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 22,
fontWeight: FontWeight.w500,
@@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:komet/backend/api.dart';
import 'package:komet/core/config/proxy_config.dart';
import 'package:komet/l10n/app_localizations.dart';
@@ -128,7 +127,7 @@ class _ProxySettingsSheetState extends State<ProxySettingsSheet> {
),
Text(
l10n.proxySettingsTitle,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 18,
fontWeight: FontWeight.w600,
@@ -230,7 +229,7 @@ class _ProxySettingsSheetState extends State<ProxySettingsSheet> {
alignment: Alignment.center,
child: Text(
labels[type]!,
style: GoogleFonts.inter(
style: TextStyle(
color: selected ? cs.onPrimary : cs.onSurfaceVariant,
fontSize: 13,
fontWeight: selected ? FontWeight.w600 : FontWeight.w500,
@@ -258,7 +257,7 @@ class _ProxySettingsSheetState extends State<ProxySettingsSheet> {
children: [
Text(
label,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurfaceVariant,
fontWeight: FontWeight.w500,
fontSize: 14,
@@ -271,10 +270,10 @@ class _ProxySettingsSheetState extends State<ProxySettingsSheet> {
inputFormatters: inputFormatters,
enabled: !_busy,
obscureText: obscureText,
style: GoogleFonts.inter(color: cs.onSurface, fontSize: 15),
style: TextStyle(color: cs.onSurface, fontSize: 15),
decoration: InputDecoration(
hintText: hintText,
hintStyle: GoogleFonts.inter(
hintStyle: TextStyle(
color: cs.onSurfaceVariant.withValues(alpha: 0.6),
fontSize: 15,
),
@@ -1,6 +1,5 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:komet/l10n/app_localizations.dart';
import '../../../backend/modules/account.dart';
@@ -134,7 +133,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
children: [
Text(
l10n.registrationTitle,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 26,
fontWeight: FontWeight.w600,
@@ -203,7 +202,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
const SizedBox(height: 28),
Text(
l10n.registrationChooseAvatar,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 16,
fontWeight: FontWeight.w600,
@@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:komet/core/config/countries.dart';
import 'package:komet/l10n/app_localizations.dart';
@@ -69,14 +68,14 @@ class _SelectCountryScreenState extends State<SelectCountryScreen> {
? TextField(
controller: _searchController,
autofocus: true,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 18,
fontWeight: FontWeight.w400,
),
decoration: InputDecoration(
hintText: l10n.selectCountrySearchHint,
hintStyle: GoogleFonts.inter(
hintStyle: TextStyle(
color: cs.onSurfaceVariant,
fontSize: 18,
fontWeight: FontWeight.w400,
@@ -87,7 +86,7 @@ class _SelectCountryScreenState extends State<SelectCountryScreen> {
)
: Text(
l10n.selectCountryTitle,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 20,
fontWeight: FontWeight.w500,
@@ -121,7 +120,7 @@ class _SelectCountryScreenState extends State<SelectCountryScreen> {
return ListTile(
leading: Text(
country.phoneCode,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurfaceVariant,
fontSize: 14,
fontWeight: FontWeight.w400,
@@ -129,7 +128,7 @@ class _SelectCountryScreenState extends State<SelectCountryScreen> {
),
title: Text(
lang == 'ru' ? country.ru : country.en,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 16,
fontWeight: isSelected ? FontWeight.w600 : FontWeight.w400,
@@ -2,7 +2,6 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:komet/backend/api.dart';
import 'package:komet/core/config/config.dart';
import 'package:komet/l10n/app_localizations.dart';
@@ -131,7 +130,7 @@ class _ServerSettingsSheetState extends State<ServerSettingsSheet> {
),
Text(
l10n.serverSettingsTitle,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 18,
fontWeight: FontWeight.w600,
@@ -184,7 +183,7 @@ class _ServerSettingsSheetState extends State<ServerSettingsSheet> {
children: [
Text(
label,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurfaceVariant,
fontWeight: FontWeight.w500,
fontSize: 14,
@@ -196,10 +195,10 @@ class _ServerSettingsSheetState extends State<ServerSettingsSheet> {
keyboardType: keyboardType,
inputFormatters: inputFormatters,
enabled: !_busy,
style: GoogleFonts.inter(color: cs.onSurface, fontSize: 15),
style: TextStyle(color: cs.onSurface, fontSize: 15),
decoration: InputDecoration(
hintText: hintText,
hintStyle: GoogleFonts.inter(
hintStyle: TextStyle(
color: cs.onSurfaceVariant.withValues(alpha: 0.6),
fontSize: 15,
),
@@ -4,7 +4,6 @@ import 'dart:math';
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:material_symbols_icons/symbols.dart';
import '../../../core/utils/format.dart';
import '../../../main.dart' show accountModule;
@@ -75,7 +74,7 @@ class _DevicesScreenState extends State<DevicesScreen>
backgroundColor: cs.surfaceContainerHigh,
title: Text(
'Ссылка из QR',
style: GoogleFonts.outfit(
style: TextStyle(fontFamily: 'Outfit',
fontWeight: FontWeight.w600,
fontSize: 18,
color: cs.onSurface,
@@ -230,7 +229,7 @@ class _DevicesScreenState extends State<DevicesScreen>
),
title: ConnectionTitleText(
'Устройства',
style: GoogleFonts.outfit(
style: TextStyle(fontFamily: 'Outfit',
fontSize: 20,
fontWeight: FontWeight.w600,
color: cs.onSurface,
@@ -280,7 +279,7 @@ class _DevicesScreenState extends State<DevicesScreen>
const SizedBox(height: 16),
Text(
'Устройства в KOMET',
style: GoogleFonts.outfit(
style: TextStyle(fontFamily: 'Outfit',
fontSize: 18,
fontWeight: FontWeight.w700,
color: cs.onSurface,
@@ -302,7 +301,7 @@ class _DevicesScreenState extends State<DevicesScreen>
icon: const Icon(Symbols.qr_code_scanner, size: 22),
label: Text(
'Сканировать QR',
style: GoogleFonts.outfit(
style: TextStyle(fontFamily: 'Outfit',
fontSize: 15,
fontWeight: FontWeight.w600,
),
@@ -473,7 +472,7 @@ class _DevicesScreenState extends State<DevicesScreen>
children: [
Text(
title,
style: GoogleFonts.outfit(
style: TextStyle(fontFamily: 'Outfit',
fontSize: 16,
fontWeight: FontWeight.w700,
color: cs.onSurface,
@@ -3,6 +3,7 @@ import 'package:m3e_collection/m3e_collection.dart';
import 'package:material_symbols_icons/symbols.dart';
import '../../../core/config/app_fonts.dart';
import '../../../core/config/custom_font_service.dart';
import '../../../core/utils/haptics.dart';
import '../../../main.dart';
import '../../widgets/connection_status.dart';
@@ -18,6 +19,7 @@ class FontSettingsScreen extends StatefulWidget {
class _FontSettingsScreenState extends State<FontSettingsScreen> {
List<String> _custom = const [];
bool _adding = false;
@override
void initState() {
@@ -26,7 +28,7 @@ class _FontSettingsScreenState extends State<FontSettingsScreen> {
}
Future<void> _reloadCustom() async {
final list = await AppFonts.loadCustomFamilies();
final list = await CustomFontService.families();
if (mounted) setState(() => _custom = list);
}
@@ -45,26 +47,26 @@ class _FontSettingsScreenState extends State<FontSettingsScreen> {
}
return;
}
final canonical = AppFonts.matchGoogleFamily(parsed);
if (canonical == null) {
if (mounted) {
showCustomNotification(
context,
'Шрифт «$parsed» не найден в Google Fonts',
);
}
setState(() => _adding = true);
final family = await CustomFontService.addFamily(parsed);
if (!mounted) return;
setState(() => _adding = false);
if (family == null) {
showCustomNotification(
context,
'Шрифт «$parsed» не найден или нет сети',
);
return;
}
await AppFonts.addCustomFamily(canonical);
await _reloadCustom();
if (!mounted) return;
KometApp.stateOf(context)?.applyAppFont(AppFonts.customId(canonical));
KometApp.stateOf(context)?.applyAppFont(AppFonts.customId(family));
Haptics.success();
showCustomNotification(context, 'Шрифт «$canonical» добавлен');
showCustomNotification(context, 'Шрифт «$family» добавлен');
}
Future<void> _removeFont(String family) async {
await AppFonts.removeCustomFamily(family);
await CustomFontService.removeFamily(family);
await _reloadCustom();
if (!mounted) return;
final app = KometApp.stateOf(context);
@@ -175,11 +177,11 @@ class _FontSettingsScreenState extends State<FontSettingsScreen> {
SizedBox(
width: double.infinity,
child: ButtonM3E(
onPressed: _showAddFontDialog,
onPressed: _adding ? null : _showAddFontDialog,
style: ButtonM3EStyle.outlined,
size: ButtonM3ESize.md,
icon: const Icon(Symbols.add),
label: const Text('Добавить шрифт'),
icon: Icon(_adding ? Symbols.hourglass_top : Symbols.add),
label: Text(_adding ? 'Загрузка…' : 'Добавить шрифт'),
),
),
const SizedBox(height: 30),
@@ -3,7 +3,6 @@ import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
@@ -72,7 +71,7 @@ class _WebQrScanScreenState extends State<WebQrScanScreen> {
),
title: Text(
'QR для веба и ПК',
style: GoogleFonts.outfit(
style: TextStyle(fontFamily: 'Outfit',
fontSize: 20,
fontWeight: FontWeight.w600,
color: Colors.white,
@@ -134,7 +133,7 @@ class _WebQrScanScreenState extends State<WebQrScanScreen> {
child: Text(
'Наведите камеру на QR-код на экране компьютера',
textAlign: TextAlign.center,
style: GoogleFonts.outfit(
style: TextStyle(fontFamily: 'Outfit',
fontSize: 15,
fontWeight: FontWeight.w500,
color: Colors.white,
@@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
const Duration _defaultNotificationDuration = Duration(milliseconds: 2600);
@@ -90,7 +89,7 @@ class _CustomNotificationState extends State<CustomNotification>
),
child: Text(
widget.message,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 14,
fontWeight: FontWeight.w500,
+5 -6
View File
@@ -1,7 +1,6 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:shared_preferences/shared_preferences.dart';
class InfoActionSheetItem {
@@ -150,7 +149,7 @@ class _InfoActionSheetState extends State<_InfoActionSheet> {
Text(
widget.title,
textAlign: TextAlign.center,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurface,
fontSize: 22,
fontWeight: FontWeight.w700,
@@ -161,7 +160,7 @@ class _InfoActionSheetState extends State<_InfoActionSheet> {
Text(
widget.subtitle!,
textAlign: TextAlign.center,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurfaceVariant,
fontSize: 13,
fontWeight: FontWeight.w400,
@@ -195,7 +194,7 @@ class _InfoActionSheetState extends State<_InfoActionSheet> {
),
child: Text(
buttonText,
style: GoogleFonts.inter(
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
@@ -248,7 +247,7 @@ class _InfoActionSheetState extends State<_InfoActionSheet> {
children: [
Text(
item.title,
style: GoogleFonts.inter(
style: TextStyle(
color: titleColor,
fontSize: 16,
fontWeight: FontWeight.w700,
@@ -258,7 +257,7 @@ class _InfoActionSheetState extends State<_InfoActionSheet> {
const SizedBox(height: 4),
Text(
item.body,
style: GoogleFonts.inter(
style: TextStyle(
color: cs.onSurfaceVariant,
fontSize: 14,
fontWeight: FontWeight.w400,
+1 -2
View File
@@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../../main.dart' show accountModule;
import 'custom_notification.dart';
@@ -25,7 +24,7 @@ Future<bool> showWebQrLoginConfirmSheet(BuildContext context) async {
const SizedBox(height: 20),
Text(
'Вход по QR',
style: GoogleFonts.outfit(
style: TextStyle(fontFamily: 'Outfit',
fontSize: 20,
fontWeight: FontWeight.w700,
color: cs.onSurface,