feat(customization): font switcher with Unbounded, styled via m3e
This commit is contained in:
@@ -0,0 +1,37 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
|
||||||
|
class AppFont {
|
||||||
|
final String id;
|
||||||
|
final String label;
|
||||||
|
final String googleFamily;
|
||||||
|
|
||||||
|
const AppFont({
|
||||||
|
required this.id,
|
||||||
|
required this.label,
|
||||||
|
required this.googleFamily,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppFonts {
|
||||||
|
static const String prefKey = 'app_font';
|
||||||
|
|
||||||
|
static const List<AppFont> all = [
|
||||||
|
AppFont(id: 'inter', label: 'Inter', googleFamily: 'Inter'),
|
||||||
|
AppFont(id: 'unbounded', label: 'Unbounded', googleFamily: 'Unbounded'),
|
||||||
|
];
|
||||||
|
|
||||||
|
static AppFont get fallback => all.first;
|
||||||
|
|
||||||
|
static AppFont byId(String? id) {
|
||||||
|
return all.firstWhere((f) => f.id == id, orElse: () => fallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TextTheme textTheme(String id, TextTheme base) {
|
||||||
|
return GoogleFonts.getTextTheme(byId(id).googleFamily, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TextStyle sample(String id, {required double fontSize}) {
|
||||||
|
return GoogleFonts.getFont(byId(id).googleFamily, fontSize: fontSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:m3e_collection/m3e_collection.dart';
|
||||||
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
|
|
||||||
|
import '../../../core/config/app_fonts.dart';
|
||||||
|
import '../../../core/utils/haptics.dart';
|
||||||
|
import '../../../main.dart';
|
||||||
|
|
||||||
|
class CustomizationScreen extends StatefulWidget {
|
||||||
|
const CustomizationScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<CustomizationScreen> createState() => _CustomizationScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CustomizationScreenState extends State<CustomizationScreen> {
|
||||||
|
void _selectFont(String id) {
|
||||||
|
final app = KometApp.stateOf(context);
|
||||||
|
if (app == null || app.fontId == id) return;
|
||||||
|
Haptics.selection();
|
||||||
|
app.applyAppFont(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final cs = Theme.of(context).colorScheme;
|
||||||
|
final currentId = KometApp.stateOf(context)?.fontId ?? AppFonts.fallback.id;
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: cs.surface,
|
||||||
|
appBar: AppBarM3E(
|
||||||
|
titleText: 'Кастомизация',
|
||||||
|
backgroundColor: cs.surface,
|
||||||
|
),
|
||||||
|
body: SafeArea(
|
||||||
|
top: false,
|
||||||
|
child: ListView(
|
||||||
|
physics: const BouncingScrollPhysics(),
|
||||||
|
padding: const EdgeInsets.fromLTRB(16, 8, 16, 120),
|
||||||
|
children: [
|
||||||
|
_PreviewCard(fontId: currentId),
|
||||||
|
const SizedBox(height: 28),
|
||||||
|
const _SectionLabel(icon: Symbols.text_fields, text: 'Шрифт'),
|
||||||
|
const SizedBox(height: 14),
|
||||||
|
for (final font in AppFonts.all) ...[
|
||||||
|
_FontOption(
|
||||||
|
font: font,
|
||||||
|
selected: font.id == currentId,
|
||||||
|
onTap: () => _selectFont(font.id),
|
||||||
|
),
|
||||||
|
if (font != AppFonts.all.last) const SizedBox(height: 12),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PreviewCard extends StatelessWidget {
|
||||||
|
final String fontId;
|
||||||
|
|
||||||
|
const _PreviewCard({required this.fontId});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final cs = Theme.of(context).colorScheme;
|
||||||
|
return Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: const EdgeInsets.all(24),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: cs.surfaceContainerHigh,
|
||||||
|
borderRadius: BorderRadius.circular(28),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'ПРЕДПРОСМОТР',
|
||||||
|
style: TextStyle(
|
||||||
|
color: cs.primary,
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
letterSpacing: 1.2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Text(
|
||||||
|
'Съешь ещё этих мягких булок',
|
||||||
|
style: AppFonts.sample(fontId, fontSize: 22).copyWith(
|
||||||
|
color: cs.onSurface,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
height: 1.25,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Text(
|
||||||
|
'The quick brown fox 0123',
|
||||||
|
style: AppFonts.sample(fontId, fontSize: 15).copyWith(
|
||||||
|
color: cs.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SectionLabel extends StatelessWidget {
|
||||||
|
final IconData icon;
|
||||||
|
final String text;
|
||||||
|
|
||||||
|
const _SectionLabel({required this.icon, required this.text});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final cs = Theme.of(context).colorScheme;
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 6),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Icon(icon, size: 20, color: cs.onSurfaceVariant, weight: 500),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
text,
|
||||||
|
style: TextStyle(
|
||||||
|
color: cs.onSurfaceVariant,
|
||||||
|
fontSize: 15,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
letterSpacing: 0.3,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FontOption extends StatelessWidget {
|
||||||
|
final AppFont font;
|
||||||
|
final bool selected;
|
||||||
|
final VoidCallback onTap;
|
||||||
|
|
||||||
|
const _FontOption({
|
||||||
|
required this.font,
|
||||||
|
required this.selected,
|
||||||
|
required this.onTap,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: ButtonM3E(
|
||||||
|
onPressed: onTap,
|
||||||
|
style: selected ? ButtonM3EStyle.filled : ButtonM3EStyle.tonal,
|
||||||
|
size: ButtonM3ESize.xl,
|
||||||
|
shape: ButtonM3EShape.round,
|
||||||
|
selected: selected,
|
||||||
|
icon: Icon(
|
||||||
|
selected ? Symbols.check_circle : Symbols.font_download,
|
||||||
|
fill: selected ? 1 : 0,
|
||||||
|
),
|
||||||
|
label: Text(
|
||||||
|
font.label,
|
||||||
|
style: AppFonts.sample(font.id, fontSize: 18),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import '../../../core/utils/haptics.dart';
|
|||||||
import '../../../l10n/app_localizations.dart';
|
import '../../../l10n/app_localizations.dart';
|
||||||
import '../../../main.dart';
|
import '../../../main.dart';
|
||||||
import '../auth/proxy_settings_sheet.dart';
|
import '../auth/proxy_settings_sheet.dart';
|
||||||
|
import 'customization_screen.dart';
|
||||||
import 'debug_menu_screen.dart';
|
import 'debug_menu_screen.dart';
|
||||||
import 'devices_screen.dart';
|
import 'devices_screen.dart';
|
||||||
import 'edit_profile_screen.dart';
|
import 'edit_profile_screen.dart';
|
||||||
@@ -142,6 +143,29 @@ child: _buildSection(
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(16, 12, 16, 0),
|
||||||
|
child: _buildSection(
|
||||||
|
context,
|
||||||
|
cs,
|
||||||
|
items: [
|
||||||
|
_SettingsItem(
|
||||||
|
icon: Symbols.palette,
|
||||||
|
label: 'Кастомизация',
|
||||||
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const CustomizationScreen(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(16, 12, 16, 0),
|
padding: const EdgeInsets.fromLTRB(16, 12, 16, 0),
|
||||||
|
|||||||
+36
-11
@@ -2,11 +2,12 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:dynamic_color/dynamic_color.dart';
|
import 'package:dynamic_color/dynamic_color.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
|
||||||
import 'package:komet/l10n/app_localizations.dart';
|
import 'package:komet/l10n/app_localizations.dart';
|
||||||
|
import 'package:m3e_collection/m3e_collection.dart';
|
||||||
import 'package:package_info_plus/package_info_plus.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'backend/api.dart';
|
import 'backend/api.dart';
|
||||||
|
import 'core/config/app_fonts.dart';
|
||||||
import 'backend/modules/account.dart';
|
import 'backend/modules/account.dart';
|
||||||
import 'backend/modules/contacts.dart';
|
import 'backend/modules/contacts.dart';
|
||||||
import 'backend/modules/messages.dart';
|
import 'backend/modules/messages.dart';
|
||||||
@@ -59,11 +60,14 @@ void main() async {
|
|||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
final initialFpsOverlay = prefs.getBool('dev_fps_overlay') ?? false;
|
final initialFpsOverlay = prefs.getBool('dev_fps_overlay') ?? false;
|
||||||
final initialVpnBypass = prefs.getBool(VpnBypassService.prefKey) ?? false;
|
final initialVpnBypass = prefs.getBool(VpnBypassService.prefKey) ?? false;
|
||||||
|
final initialFontId =
|
||||||
|
prefs.getString(AppFonts.prefKey) ?? AppFonts.fallback.id;
|
||||||
runApp(
|
runApp(
|
||||||
KometApp(
|
KometApp(
|
||||||
initialLocale: initialLocale,
|
initialLocale: initialLocale,
|
||||||
initialFpsOverlay: initialFpsOverlay,
|
initialFpsOverlay: initialFpsOverlay,
|
||||||
initialVpnBypass: initialVpnBypass,
|
initialVpnBypass: initialVpnBypass,
|
||||||
|
initialFontId: initialFontId,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -74,11 +78,13 @@ class KometApp extends StatefulWidget {
|
|||||||
required this.initialLocale,
|
required this.initialLocale,
|
||||||
this.initialFpsOverlay = false,
|
this.initialFpsOverlay = false,
|
||||||
this.initialVpnBypass = false,
|
this.initialVpnBypass = false,
|
||||||
|
required this.initialFontId,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Locale initialLocale;
|
final Locale initialLocale;
|
||||||
final bool initialFpsOverlay;
|
final bool initialFpsOverlay;
|
||||||
final bool initialVpnBypass;
|
final bool initialVpnBypass;
|
||||||
|
final String initialFontId;
|
||||||
static final navigatorKey = GlobalKey<NavigatorState>();
|
static final navigatorKey = GlobalKey<NavigatorState>();
|
||||||
|
|
||||||
static KometAppState? stateOf(BuildContext context) {
|
static KometAppState? stateOf(BuildContext context) {
|
||||||
@@ -93,6 +99,7 @@ class KometAppState extends State<KometApp> {
|
|||||||
static const _fallbackSeed = Color(0xFFC1C4FF);
|
static const _fallbackSeed = Color(0xFFC1C4FF);
|
||||||
|
|
||||||
late Locale _locale;
|
late Locale _locale;
|
||||||
|
late String _fontId;
|
||||||
bool _isLoggingOut = false;
|
bool _isLoggingOut = false;
|
||||||
StreamSubscription<SessionExpiredException>? _sessionExpiredSub;
|
StreamSubscription<SessionExpiredException>? _sessionExpiredSub;
|
||||||
StreamSubscription<LoginStatus>? _loginStatusSub;
|
StreamSubscription<LoginStatus>? _loginStatusSub;
|
||||||
@@ -112,6 +119,7 @@ class KometAppState extends State<KometApp> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_locale = widget.initialLocale;
|
_locale = widget.initialLocale;
|
||||||
|
_fontId = widget.initialFontId;
|
||||||
|
|
||||||
api.setReconnectCallback(() async {
|
api.setReconnectCallback(() async {
|
||||||
try {
|
try {
|
||||||
@@ -217,6 +225,17 @@ class KometAppState extends State<KometApp> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get fontId => _fontId;
|
||||||
|
|
||||||
|
Future<void> applyAppFont(String fontId) async {
|
||||||
|
if (_fontId == fontId) return;
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.setString(AppFonts.prefKey, fontId);
|
||||||
|
if (mounted) {
|
||||||
|
setState(() => _fontId = fontId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void notifyProfileUpdate() {
|
void notifyProfileUpdate() {
|
||||||
_profileUpdateController.add(null);
|
_profileUpdateController.add(null);
|
||||||
}
|
}
|
||||||
@@ -282,18 +301,24 @@ class KometAppState extends State<KometApp> {
|
|||||||
themeMode: ThemeMode.system,
|
themeMode: ThemeMode.system,
|
||||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||||
supportedLocales: AppLocalizations.supportedLocales,
|
supportedLocales: AppLocalizations.supportedLocales,
|
||||||
theme: ThemeData(
|
theme: withM3ETheme(
|
||||||
useMaterial3: true,
|
ThemeData(
|
||||||
colorScheme: lightScheme,
|
useMaterial3: true,
|
||||||
textTheme: GoogleFonts.interTextTheme(
|
colorScheme: lightScheme,
|
||||||
ThemeData(brightness: Brightness.light).textTheme,
|
textTheme: AppFonts.textTheme(
|
||||||
|
_fontId,
|
||||||
|
ThemeData(brightness: Brightness.light).textTheme,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
darkTheme: ThemeData(
|
darkTheme: withM3ETheme(
|
||||||
useMaterial3: true,
|
ThemeData(
|
||||||
colorScheme: darkScheme,
|
useMaterial3: true,
|
||||||
textTheme: GoogleFonts.interTextTheme(
|
colorScheme: darkScheme,
|
||||||
ThemeData(brightness: Brightness.dark).textTheme,
|
textTheme: AppFonts.textTheme(
|
||||||
|
_fontId,
|
||||||
|
ThemeData(brightness: Brightness.dark).textTheme,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
navigatorKey: KometApp.navigatorKey,
|
navigatorKey: KometApp.navigatorKey,
|
||||||
|
|||||||
+128
@@ -9,6 +9,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.71"
|
version: "1.3.71"
|
||||||
|
app_bar_m3e:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: app_bar_m3e
|
||||||
|
sha256: a8cef3d2cfe8d254fac355816ede509e7b437066d9fef8e7ba779a202485bc9f
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.2"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -33,6 +41,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
version: "2.1.2"
|
||||||
|
button_group_m3e:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: button_group_m3e
|
||||||
|
sha256: bb8ce524f87e806c89abb4cd430425de22cd53feeacc122e3b5da45c76ba2246
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.1"
|
||||||
|
button_m3e:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: button_m3e
|
||||||
|
sha256: "6754ddeb9068ad2005bd26d5ceabc41268029465095686d7d228296c2e706909"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.2"
|
||||||
cached_network_image:
|
cached_network_image:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -161,6 +185,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.8"
|
version: "2.0.8"
|
||||||
|
expressive_refresh:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: expressive_refresh
|
||||||
|
sha256: "99bb70ae1719ebdedbaf3b4a49031ef7b916da157f7843b8e83efbe6633b20ad"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.2"
|
||||||
|
fab_m3e:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: fab_m3e
|
||||||
|
sha256: e4f5abfa3c8c092005449d56dcac45b85e2dbe9c32789d672c5ed71428e43b59
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.1"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -421,6 +461,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.2"
|
version: "4.1.2"
|
||||||
|
icon_button_m3e:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: icon_button_m3e
|
||||||
|
sha256: c4524d6141a468679821bbb635b833ac6831925d8a6ae4a4511430b0e4ab9c67
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.1"
|
||||||
intl:
|
intl:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -469,6 +517,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.0"
|
version: "6.1.0"
|
||||||
|
loading_indicator_m3e:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: loading_indicator_m3e
|
||||||
|
sha256: "3fe97385b4f84382c25b901abf88fcee4200e6e78fcd5ed7e037a34d7db53038"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.1"
|
||||||
logger:
|
logger:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -485,6 +541,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.3.0"
|
||||||
|
m3e_collection:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: m3e_collection
|
||||||
|
sha256: "623079bd3fe39bac1a3a10656647cdef6a8b2aa8bb8ee5ff99779facd05b18f6"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.7"
|
||||||
|
m3e_design:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: m3e_design
|
||||||
|
sha256: "15ff0ef4c43553d855c5e866a9aee8231d44919fe2bb354b1259337bdfd659b4"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.1"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -501,6 +573,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.13.0"
|
version: "0.13.0"
|
||||||
|
material_new_shapes:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: material_new_shapes
|
||||||
|
sha256: e4bc375205e187e8fb232573387112dd8c0dd45b03af8aa2b3c79eb4b9e3e0dc
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
material_symbols_icons:
|
material_symbols_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -541,6 +621,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.17.6"
|
version: "0.17.6"
|
||||||
|
navigation_bar_m3e:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: navigation_bar_m3e
|
||||||
|
sha256: "20d0ce28c783fd7b530e542e1e62c9edc402028303af08667fcbfd89162c83b2"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.1"
|
||||||
|
navigation_rail_m3e:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: navigation_rail_m3e
|
||||||
|
sha256: "029a1f556c4ecaf8318ae7d4ad09af117bdb449e483e3d9ec04085a9e341db3d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.5"
|
||||||
objective_c:
|
objective_c:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -653,6 +749,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.8"
|
version: "2.1.8"
|
||||||
|
progress_indicator_m3e:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: progress_indicator_m3e
|
||||||
|
sha256: "1a2ca029d14427d31093552a0e916b453f58643b78ef805ce6f4669845ac8f70"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.1"
|
||||||
pub_semver:
|
pub_semver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -730,6 +834,14 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
slider_m3e:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: slider_m3e
|
||||||
|
sha256: e4c25e94b46ebf3164f407e9db6cce70aa51b92db5143d720f6e55a2a709aa67
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.1"
|
||||||
source_span:
|
source_span:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -738,6 +850,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.2"
|
version: "1.10.2"
|
||||||
|
split_button_m3e:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: split_button_m3e
|
||||||
|
sha256: "8864b612e2475cf8d070783d5d834c8da98b7489365e4597e5b4f6ef85d50f66"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.1"
|
||||||
sqflite:
|
sqflite:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -850,6 +970,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.11.0"
|
version: "0.11.0"
|
||||||
|
toolbar_m3e:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: toolbar_m3e
|
||||||
|
sha256: "5a02108fc47d5b14dc645fd52d3cbdbd7cc3c2c60c8410c5a69d9cf7ac852cc9"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.1"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ dependencies:
|
|||||||
sqflite_common_ffi: ^2.4.0+2
|
sqflite_common_ffi: ^2.4.0+2
|
||||||
path: ^1.9.1
|
path: ^1.9.1
|
||||||
google_fonts: ^6.2.1
|
google_fonts: ^6.2.1
|
||||||
|
m3e_collection: ^0.3.7
|
||||||
material_symbols_icons: ^4.2906.0
|
material_symbols_icons: ^4.2906.0
|
||||||
dynamic_color: ^1.8.1
|
dynamic_color: ^1.8.1
|
||||||
shared_preferences: ^2.5.4
|
shared_preferences: ^2.5.4
|
||||||
|
|||||||
Reference in New Issue
Block a user