Compare commits

..

No commits in common. "lab7" and "master" have entirely different histories.
lab7 ... master

43 changed files with 56 additions and 1758 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1016 B

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 473 B

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 392 B

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 -4 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_503_2726)">
<rect x="0.25" y="0.25" width="27.5" height="19.5" rx="1.75" fill="white" stroke="#F5F5F5" stroke-width="0.5"/>
<mask id="mask0_503_2726" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="28" height="20">
<rect x="0.25" y="0.25" width="27.5" height="19.5" rx="1.75" fill="white" stroke="white" stroke-width="0.5"/>
</mask>
<g mask="url(#mask0_503_2726)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 13.3333H28V6.66667H0V13.3333Z" fill="#0C47B7"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 20H28V13.3333H0V20Z" fill="#E53B35"/>
</g>
</g>
<defs>
<clipPath id="clip0_503_2726">
<rect width="28" height="20" rx="2" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 968 B

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 512 512" xml:space="preserve">
<path style="fill:#41479B;" d="M473.655,88.276H38.345C17.167,88.276,0,105.443,0,126.621V385.38
c0,21.177,17.167,38.345,38.345,38.345h435.31c21.177,0,38.345-17.167,38.345-38.345V126.621
C512,105.443,494.833,88.276,473.655,88.276z"/>
<path style="fill:#F5F5F5;" d="M511.469,120.282c-3.022-18.159-18.797-32.007-37.814-32.007h-9.977l-163.54,107.147V88.276h-88.276
v107.147L48.322,88.276h-9.977c-19.017,0-34.792,13.847-37.814,32.007l139.778,91.58H0v88.276h140.309L0.531,391.717
c3.022,18.159,18.797,32.007,37.814,32.007h9.977l163.54-107.147v107.147h88.276V316.577l163.54,107.147h9.977
c19.017,0,34.792-13.847,37.814-32.007l-139.778-91.58H512v-88.276H371.691L511.469,120.282z"/>
<g>
<polygon style="fill:#FF4B55;" points="282.483,88.276 229.517,88.276 229.517,229.517 0,229.517 0,282.483 229.517,282.483
229.517,423.724 282.483,423.724 282.483,282.483 512,282.483 512,229.517 282.483,229.517 "/>
<path style="fill:#FF4B55;" d="M24.793,421.252l186.583-121.114h-32.428L9.224,410.31
C13.377,415.157,18.714,418.955,24.793,421.252z"/>
<path style="fill:#FF4B55;" d="M346.388,300.138H313.96l180.716,117.305c5.057-3.321,9.277-7.807,12.287-13.075L346.388,300.138z"
/>
<path style="fill:#FF4B55;" d="M4.049,109.475l157.73,102.387h32.428L15.475,95.842C10.676,99.414,6.749,104.084,4.049,109.475z"/>
<path style="fill:#FF4B55;" d="M332.566,211.862l170.035-110.375c-4.199-4.831-9.578-8.607-15.699-10.86L300.138,211.862H332.566z"
/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

View File

@ -1,6 +0,0 @@
arb-dir: l10n
template-arb-file: app_ru.arb
output-localization-file: app_locale.dart
output-dir: lib/components/l10n
output-class: AppLocale
synthetic-package: false

View File

@ -1,7 +0,0 @@
{
"@@locale": "en",
"cardLiked": "Card added in favourite",
"cardDisliked": "Card deleted from favourite",
"searchInputPlaceholder": "Search..."
}

View File

@ -1,7 +0,0 @@
{
"@@locale": "ru",
"cardLiked": "Карточка добавлена в Избранное",
"cardDisliked": "Карточка удалена из Избранного",
"searchInputPlaceholder": "Поиск..."
}

View File

@ -1,6 +0,0 @@
import 'package:flutter/cupertino.dart';
import 'package:lab/components/l10n/app_locale.dart';
extension LocalContextX on BuildContext {
AppLocale get locale => AppLocale.of(this)!;
}

View File

@ -1,147 +0,0 @@
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart' as intl;
import 'app_locale_en.dart';
import 'app_locale_ru.dart';
// ignore_for_file: type=lint
/// Callers can lookup localized strings with an instance of AppLocale
/// returned by `AppLocale.of(context)`.
///
/// Applications need to include `AppLocale.delegate()` in their app's
/// `localizationDelegates` list, and the locales they support in the app's
/// `supportedLocales` list. For example:
///
/// ```dart
/// import 'l10n/app_locale.dart';
///
/// return MaterialApp(
/// localizationsDelegates: AppLocale.localizationsDelegates,
/// supportedLocales: AppLocale.supportedLocales,
/// home: MyApplicationHome(),
/// );
/// ```
///
/// ## Update pubspec.yaml
///
/// Please make sure to update your pubspec.yaml to include the following
/// packages:
///
/// ```yaml
/// dependencies:
/// # Internationalization support.
/// flutter_localizations:
/// sdk: flutter
/// intl: any # Use the pinned version from flutter_localizations
///
/// # Rest of dependencies
/// ```
///
/// ## iOS Applications
///
/// iOS applications define key application metadata, including supported
/// locales, in an Info.plist file that is built into the application bundle.
/// To configure the locales supported by your app, youll need to edit this
/// file.
///
/// First, open your projects ios/Runner.xcworkspace Xcode workspace file.
/// Then, in the Project Navigator, open the Info.plist file under the Runner
/// projects Runner folder.
///
/// Next, select the Information Property List item, select Add Item from the
/// Editor menu, then select Localizations from the pop-up menu.
///
/// Select and expand the newly-created Localizations item then, for each
/// locale your application supports, add a new item and select the locale
/// you wish to add from the pop-up menu in the Value field. This list should
/// be consistent with the languages listed in the AppLocale.supportedLocales
/// property.
abstract class AppLocale {
AppLocale(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString());
final String localeName;
static AppLocale? of(BuildContext context) {
return Localizations.of<AppLocale>(context, AppLocale);
}
static const LocalizationsDelegate<AppLocale> delegate = _AppLocaleDelegate();
/// A list of this localizations delegate along with the default localizations
/// delegates.
///
/// Returns a list of localizations delegates containing this delegate along with
/// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
/// and GlobalWidgetsLocalizations.delegate.
///
/// Additional delegates can be added by appending to this list in
/// MaterialApp. This list does not have to be used at all if a custom list
/// of delegates is preferred or required.
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates = <LocalizationsDelegate<dynamic>>[
delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
];
/// A list of this localizations delegate's supported locales.
static const List<Locale> supportedLocales = <Locale>[
Locale('en'),
Locale('ru')
];
/// No description provided for @cardLiked.
///
/// In ru, this message translates to:
/// **'Карточка добавлена в Избранное'**
String get cardLiked;
/// No description provided for @cardDisliked.
///
/// In ru, this message translates to:
/// **'Карточка удалена из Избранного'**
String get cardDisliked;
/// No description provided for @searchInputPlaceholder.
///
/// In ru, this message translates to:
/// **'Поиск...'**
String get searchInputPlaceholder;
}
class _AppLocaleDelegate extends LocalizationsDelegate<AppLocale> {
const _AppLocaleDelegate();
@override
Future<AppLocale> load(Locale locale) {
return SynchronousFuture<AppLocale>(lookupAppLocale(locale));
}
@override
bool isSupported(Locale locale) => <String>['en', 'ru'].contains(locale.languageCode);
@override
bool shouldReload(_AppLocaleDelegate old) => false;
}
AppLocale lookupAppLocale(Locale locale) {
// Lookup logic when only language code is specified.
switch (locale.languageCode) {
case 'en': return AppLocaleEn();
case 'ru': return AppLocaleRu();
}
throw FlutterError(
'AppLocale.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.'
);
}

View File

@ -1,17 +0,0 @@
import 'app_locale.dart';
// ignore_for_file: type=lint
/// The translations for English (`en`).
class AppLocaleEn extends AppLocale {
AppLocaleEn([String locale = 'en']) : super(locale);
@override
String get cardLiked => 'Card added in favourite';
@override
String get cardDisliked => 'Card deleted from favourite';
@override
String get searchInputPlaceholder => 'Search...';
}

View File

@ -1,17 +0,0 @@
import 'app_locale.dart';
// ignore_for_file: type=lint
/// The translations for Russian (`ru`).
class AppLocaleRu extends AppLocale {
AppLocaleRu([String locale = 'ru']) : super(locale);
@override
String get cardLiked => 'Карточка добавлена в Избранное';
@override
String get cardDisliked => 'Карточка удалена из Избранного';
@override
String get searchInputPlaceholder => 'Поиск...';
}

View File

@ -1,12 +0,0 @@
/// Generate by [asset_generator](https://github.com/fluttercandies/flutter_asset_generator) library.
/// PLEASE DO NOT EDIT MANUALLY.
// ignore_for_file: constant_identifier_names
class R {
const R._();
/// ![preview](file://C:\MyFiles\pmd\PIbd-33_Dyakonov_R_R_PMD\assets\svg\ru.svg)
static const String ASSETS_SVG_RU_SVG = 'assets/svg/ru.svg';
/// ![preview](file://C:\MyFiles\pmd\PIbd-33_Dyakonov_R_R_PMD\assets\svg\uk.svg)
static const String ASSETS_SVG_UK_SVG = 'assets/svg/uk.svg';
}

View File

@ -1,19 +0,0 @@
import 'dart:async';
import 'dart:ui';
class Debounce {
factory Debounce() => _instance;
// Приватный конструктор
Debounce._();
static final Debounce _instance = Debounce._();
static Timer? _timer;
static void run(
{required VoidCallback action, Duration delay = const Duration(milliseconds: 500)}) {
_timer?.cancel();
_timer = Timer(delay, action);
}
}

View File

@ -1,57 +0,0 @@
import 'package:json_annotation/json_annotation.dart';
part 'characters_dto.g.dart';
// dart run build_runner build --delete-conflicting-outputs
@JsonSerializable(createToJson: false)
class CharactersDto {
final List<CharacterDataDto>? data;
final MetaDto? meta;
const CharactersDto({this.data, this.meta});
factory CharactersDto.fromJson(Map<String, dynamic> json) => _$CharactersDtoFromJson(json);
}
@JsonSerializable(createToJson: false)
class MetaDto {
final PaginationDto? pagination;
const MetaDto({this.pagination});
factory MetaDto.fromJson(Map<String, dynamic> json) => _$MetaDtoFromJson(json);
}
@JsonSerializable(createToJson: false)
class PaginationDto {
final int? current;
final int? next;
final int? last;
const PaginationDto({this.current, this.last, this.next});
factory PaginationDto.fromJson(Map<String, dynamic> json) => _$PaginationDtoFromJson(json);
}
@JsonSerializable(createToJson: false)
class CharacterDataDto {
final String? id;
final CharacterAttributesDataDto? attributes;
const CharacterDataDto(this.id, this.attributes);
factory CharacterDataDto.fromJson(Map<String, dynamic> json) => _$CharacterDataDtoFromJson(json);
}
@JsonSerializable(createToJson: false)
class CharacterAttributesDataDto {
final String? name;
final String? image;
final String? species;
CharacterAttributesDataDto(this.name, this.image, this.species);
factory CharacterAttributesDataDto.fromJson(Map<String, dynamic> json) =>
_$CharacterAttributesDataDtoFromJson(json);
}

View File

@ -1,40 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'characters_dto.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
CharactersDto _$CharactersDtoFromJson(Map<String, dynamic> json) => CharactersDto(
data: (json['data'] as List<dynamic>?)
?.map((e) => CharacterDataDto.fromJson(e as Map<String, dynamic>))
.toList(),
meta: json['meta'] == null ? null : MetaDto.fromJson(json['meta'] as Map<String, dynamic>),
);
MetaDto _$MetaDtoFromJson(Map<String, dynamic> json) => MetaDto(
pagination: json['pagination'] == null
? null
: PaginationDto.fromJson(json['pagination'] as Map<String, dynamic>),
);
PaginationDto _$PaginationDtoFromJson(Map<String, dynamic> json) => PaginationDto(
current: (json['current'] as num?)?.toInt(),
last: (json['last'] as num?)?.toInt(),
next: (json['next'] as num?)?.toInt(),
);
CharacterDataDto _$CharacterDataDtoFromJson(Map<String, dynamic> json) => CharacterDataDto(
json['id'] as String?,
json['attributes'] == null
? null
: CharacterAttributesDataDto.fromJson(json['attributes'] as Map<String, dynamic>),
);
CharacterAttributesDataDto _$CharacterAttributesDataDtoFromJson(Map<String, dynamic> json) =>
CharacterAttributesDataDto(
json['name'] as String?,
json['image'] as String?,
json['species'] as String?,
);

View File

@ -1,17 +0,0 @@
import 'package:lab/data/dtos/characters_dto.dart';
import 'package:lab/domain/models/card_data.dart';
import 'package:lab/domain/models/home_data.dart';
extension CharacterDataDtoToModel on CharacterDataDto {
CardData toDomain() => CardData(
id: id,
name: attributes?.name ?? "UNKNOWN",
image: attributes?.image ??
"https://upload.wikimedia.org/wikipedia/commons/a/a2/Person_Image_Placeholder.png",
species: attributes?.species ?? "UNKNOWN");
}
extension ChatactersDtoToModel on CharactersDto {
HomeData toDomain() =>
HomeData(data: data?.map((e) => e.toDomain()).toList(), nextPage: meta?.pagination?.next);
}

View File

@ -1,7 +0,0 @@
import 'package:lab/domain/models/home_data.dart';
typedef OnErrorCallback = void Function(String? error);
abstract class ApiInterface {
Future<HomeData?> loadData({OnErrorCallback? onError});
}

View File

@ -1,23 +0,0 @@
import 'package:lab/data/repositories/api_interface.dart';
import 'package:lab/domain/models/card_data.dart';
import 'package:lab/domain/models/home_data.dart';
class MockRepository extends ApiInterface {
@override
Future<HomeData?> loadData({OnErrorCallback? onError}) async {
return HomeData(data: [
const CardData(
id: '0',
name: "test 0",
species: "Species 0",
image:
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTtAT11wKgHrJBUYzIBFogucXg0a9fE0fQXDQ&s"),
const CardData(
id: "1",
name: "test 1",
species: "Species 1",
image:
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTtAT11wKgHrJBUYzIBFogucXg0a9fE0fQXDQ&s")
]);
}
}

View File

@ -1,37 +0,0 @@
import 'dart:developer';
import 'package:dio/dio.dart';
import 'package:lab/data/dtos/characters_dto.dart';
import 'package:lab/data/mappers/characters_mapper.dart';
import 'package:lab/data/repositories/api_interface.dart';
import 'package:lab/domain/models/home_data.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
class PotterRepository extends ApiInterface {
static final Dio _dio = Dio(BaseOptions(connectTimeout: const Duration(seconds: 10)))
..interceptors.add(PrettyDioLogger(request: true, requestHeader: true, requestBody: true));
static const String _baseUrl = "https://api.potterdb.com/v1";
@override
Future<HomeData?> loadData(
{OnErrorCallback? onError, String? q, int page = 1, int pageSize = 10}) async {
try {
const String url = '$_baseUrl/characters';
final Response<dynamic> response = await _dio.get<Map<dynamic, dynamic>>(
url,
queryParameters: {'filter[name_cont]': q, 'page[number]': page, 'page[size]': pageSize},
);
final CharactersDto dto = CharactersDto.fromJson(response.data as Map<String, dynamic>);
return dto.toDomain();
} on DioException catch (e) {
log("DioException: $e");
onError?.call(e.error?.toString());
return null;
} catch (e) {
log('Unknown error: $e');
return null;
}
}
}

View File

@ -1,9 +0,0 @@
class CardData {
final String name;
final String image;
final String species;
final String? id;
const CardData(
{required this.id, required this.name, required this.image, required this.species});
}

View File

@ -1,8 +0,0 @@
import 'package:lab/domain/models/card_data.dart';
class HomeData {
final List<CardData>? data;
final int? nextPage;
HomeData({this.data, this.nextPage});
}

View File

@ -1,14 +1,4 @@
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:lab/components/l10n/app_locale.dart';
import 'package:lab/data/repositories/potter_repository.dart';
import 'package:lab/presentation/other/like_bloc/like_bloc.dart';
import 'package:lab/presentation/other/locale_bloc/locale_bloc.dart';
import 'package:lab/presentation/other/locale_bloc/locale_state.dart';
import 'package:lab/presentation/pages/home_page/home_page.dart';
import 'package:lab/presentation/pages/home_page/bloc/bloc.dart';
void main() { void main() {
runApp(const MyApp()); runApp(const MyApp());
@ -19,37 +9,60 @@ class MyApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider<LocaleBloc>( return MaterialApp(
lazy: false, title: 'Flutter Demo',
create: (context) => LocaleBloc(Locale(Platform.localeName)), theme: ThemeData(
child: BlocBuilder<LocaleBloc, LocaleState>( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
builder: (context, state) { useMaterial3: true,
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
localizationsDelegates: AppLocale.localizationsDelegates,
supportedLocales: AppLocale.supportedLocales,
locale: state.currentLocale,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.white),
useMaterial3: true,
),
home: RepositoryProvider<PotterRepository>(
lazy: true,
create: (_) => PotterRepository(),
child: BlocProvider<LikeBloc>(
lazy: false,
create: (context) => LikeBloc(),
child: BlocProvider<HomeBloc>(
lazy: false,
create: (context) => HomeBloc(context.read<PotterRepository>()),
child: const MyHomePage(title: 'Lab 7: Internationalization and other'),
),
),
),
);
},
), ),
home: const MyHomePage(title: 'Дьяконов Руслан ПИбд-33'),
); );
} }
} }
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
));
}
}

View File

@ -1,32 +0,0 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:lab/components/resources/resources.g.dart';
abstract class SvgObjects {
static void init() {
final pictures = <String>[R.ASSETS_SVG_RU_SVG, R.ASSETS_SVG_UK_SVG];
for (final String p in pictures) {
final loader = SvgAssetLoader(p);
svg.cache.putIfAbsent(loader.cacheKey(null), () => loader.loadBytes(null));
}
}
}
class SvgRu extends StatelessWidget {
const SvgRu({super.key});
@override
Widget build(BuildContext context) {
return SvgPicture.asset(R.ASSETS_SVG_RU_SVG);
}
}
class SvgUk extends StatelessWidget {
const SvgUk({super.key});
@override
Widget build(BuildContext context) {
return SvgPicture.asset(R.ASSETS_SVG_UK_SVG);
}
}

View File

@ -1,35 +0,0 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:lab/presentation/other/like_bloc/like_events.dart';
import 'package:lab/presentation/other/like_bloc/like_state.dart';
import 'package:shared_preferences/shared_preferences.dart';
const String _likedPrefsKey = "liked";
class LikeBloc extends Bloc<LikeEvent, LikeState> {
LikeBloc() : super(const LikeState(likedIds: [])) {
on<ChangeLikeEvent>(_onChangeLike);
on<LoadLikesEvent>(_onLoadLikes);
}
Future<void> _onLoadLikes(LoadLikesEvent event, Emitter<LikeState> emit) async {
final prefs = await SharedPreferences.getInstance();
final data = prefs.getStringList(_likedPrefsKey);
emit(state.copyWith(likedIds: data));
}
Future<void> _onChangeLike(ChangeLikeEvent event, Emitter<LikeState> emit) async {
final updatedList = List<String>.from(state.likedIds ?? []);
if (updatedList.contains(event.id)) {
updatedList.remove(event.id);
} else {
updatedList.add(event.id);
}
final prefs = await SharedPreferences.getInstance();
prefs.setStringList(_likedPrefsKey, updatedList);
emit(state.copyWith(likedIds: updatedList));
}
}

View File

@ -1,13 +0,0 @@
abstract class LikeEvent {
const LikeEvent();
}
class LoadLikesEvent extends LikeEvent {
const LoadLikesEvent();
}
class ChangeLikeEvent extends LikeEvent {
final String id;
const ChangeLikeEvent(this.id);
}

View File

@ -1,12 +0,0 @@
import 'package:equatable/equatable.dart';
class LikeState extends Equatable {
final List<String>? likedIds;
const LikeState({required this.likedIds});
LikeState copyWith({List<String>? likedIds}) => LikeState(likedIds: likedIds ?? this.likedIds);
@override
List<Object?> get props => [likedIds];
}

View File

@ -1,18 +0,0 @@
import 'dart:ui';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:lab/components/l10n/app_locale.dart';
import 'package:lab/presentation/other/locale_bloc/locale_events.dart';
import 'package:lab/presentation/other/locale_bloc/locale_state.dart';
class LocaleBloc extends Bloc<LocaleEvent, LocaleState> {
LocaleBloc(Locale defaultLocale) : super(LocaleState(currentLocale: defaultLocale)) {
on<ChangeLocaleEvent>(_onChangeLocale);
}
Future<void> _onChangeLocale(ChangeLocaleEvent event, Emitter<LocaleState> emit) async {
final toChange = AppLocale.supportedLocales
.firstWhere((e) => e.languageCode != state.currentLocale.languageCode);
emit(state.copyWith(currentLocale: toChange));
}
}

View File

@ -1,7 +0,0 @@
abstract class LocaleEvent {
const LocaleEvent();
}
class ChangeLocaleEvent extends LocaleEvent {
const ChangeLocaleEvent();
}

View File

@ -1,14 +0,0 @@
import 'dart:ui';
import 'package:equatable/equatable.dart';
class LocaleState extends Equatable {
final Locale currentLocale;
const LocaleState({required this.currentLocale});
LocaleState copyWith({Locale? currentLocale}) =>
LocaleState(currentLocale: currentLocale ?? this.currentLocale);
@override
List<Object?> get props => [currentLocale];
}

View File

@ -1,42 +0,0 @@
import 'package:flutter/material.dart';
import 'package:lab/domain/models/card_data.dart';
class DetailsPage extends StatelessWidget {
final CardData data;
const DetailsPage({super.key, required this.data});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Character ${data.name}'),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(30),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Image.network(
data.image,
width: 250,
height: 250,
),
),
const SizedBox(height: 20),
Text(
data.name,
style: const TextStyle(fontSize: 18),
),
const SizedBox(height: 20),
Text(
"Species: ${data.species}",
style: const TextStyle(fontSize: 25, color: Colors.orange),
),
],
),
),
);
}
}

View File

@ -1,31 +0,0 @@
import 'package:lab/data/repositories/potter_repository.dart';
import 'package:lab/presentation/pages/home_page/bloc/events.dart';
import 'package:lab/presentation/pages/home_page/bloc/state.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class HomeBloc extends Bloc<HomeEvent, HomeState> {
final PotterRepository repo;
HomeBloc(this.repo) : super(const HomeState()) {
on<HomeLoadDataEvent>(_onLoadData);
}
Future<void> _onLoadData(HomeLoadDataEvent event, Emitter<HomeState> emit) async {
if (event.nextPage == null) {
emit(state.copyWith(isLoading: true));
} else {
emit(state.copyWith(isPaginationLoading: true));
}
String? error;
final data =
await repo.loadData(q: event.search, page: event.nextPage ?? 1, onError: (e) => error = e);
if (event.nextPage != null) {
data?.data?.insertAll(0, state.data?.data ?? []);
}
emit(state.copyWith(isLoading: false, isPaginationLoading: false, data: data, error: error));
}
}

View File

@ -1,10 +0,0 @@
abstract class HomeEvent {
const HomeEvent();
}
class HomeLoadDataEvent extends HomeEvent {
final String? search;
final int? nextPage;
const HomeLoadDataEvent({this.search, this.nextPage});
}

View File

@ -1,24 +0,0 @@
import 'package:equatable/equatable.dart';
import 'package:lab/domain/models/home_data.dart';
class HomeState extends Equatable {
final HomeData? data;
final bool isLoading;
final bool isPaginationLoading;
final String? error;
const HomeState(
{this.data, this.isLoading = false, this.isPaginationLoading = false, this.error});
// Получение нового экземпляра состояния
HomeState copyWith({HomeData? data, bool? isLoading, bool? isPaginationLoading, String? error}) =>
HomeState(
data: data ?? this.data,
isLoading: isLoading ?? this.isLoading,
isPaginationLoading: isPaginationLoading ?? this.isPaginationLoading,
error: error ?? this.error);
// Поля, по которым Equatable сравнивает состояния
@override
List<Object?> get props => [data, isLoading, isPaginationLoading, error];
}

View File

@ -1,101 +0,0 @@
part of "home_page.dart";
typedef OnLikeCallback = void Function(String? id, String text, bool isLiked);
class Card extends StatelessWidget {
final String? id;
final String name;
final String image;
final String species;
final bool isLiked;
final OnLikeCallback? onLike;
final VoidCallback? onTap;
const Card({
super.key,
required this.id,
required this.name,
required this.species,
required this.image,
this.onLike,
this.onTap,
this.isLiked = false,
});
factory Card.fromData(CardData data,
{OnLikeCallback? onLike, VoidCallback? onTap, bool isLiked = false}) =>
Card(
id: data.id,
isLiked: isLiked,
name: data.name,
image: data.image,
species: data.species,
onTap: onTap,
onLike: onLike,
);
@override
Widget build(BuildContext context) {
void toggleIsFavourite() {
onLike?.call(id, !isLiked ? context.locale.cardLiked : context.locale.cardDisliked, isLiked);
}
return GestureDetector(
onTap: onTap,
child: Container(
width: double.infinity,
padding: const EdgeInsets.only(top: 15, bottom: 15, left: 30, right: 30),
decoration: BoxDecoration(
border: Border.all(color: Colors.black12, width: 2),
borderRadius: BorderRadius.circular(20)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
GestureDetector(
onTap: toggleIsFavourite,
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 200),
child: isLiked
? const Icon(
Icons.favorite,
color: Colors.red,
key: ValueKey<int>(0),
)
: const Icon(
Icons.favorite_border,
color: Colors.red,
key: ValueKey<int>(1),
),
),
)
],
),
const SizedBox(height: 20),
Center(
child: Image.network(
image,
width: 250,
height: 250,
),
),
Padding(
padding: const EdgeInsets.only(top: 50),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(name, style: const TextStyle(fontSize: 17)),
Text("Species: $species",
style: const TextStyle(fontSize: 17, color: Colors.orange))
],
),
)
],
),
),
);
}
}

View File

@ -1,190 +0,0 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:lab/components/extensions/local_context_x.dart';
import 'package:lab/components/utils/debounce.dart';
import 'package:lab/domain/models/card_data.dart';
import 'package:lab/presentation/other/common/svg_objects.dart';
import 'package:lab/presentation/other/like_bloc/like_bloc.dart';
import 'package:lab/presentation/other/like_bloc/like_events.dart';
import 'package:lab/presentation/other/like_bloc/like_state.dart';
import 'package:lab/presentation/other/locale_bloc/locale_bloc.dart';
import 'package:lab/presentation/other/locale_bloc/locale_events.dart';
import 'package:lab/presentation/other/locale_bloc/locale_state.dart';
import 'package:lab/presentation/pages/details_page/details_page.dart';
import 'package:lab/presentation/pages/home_page/bloc/bloc.dart';
import 'package:lab/presentation/pages/home_page/bloc/events.dart';
import 'package:lab/presentation/pages/home_page/bloc/state.dart';
part 'card.dart';
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final TextEditingController _searchController = TextEditingController();
final _scrollController = ScrollController();
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) {
context.read<HomeBloc>().add(const HomeLoadDataEvent());
context.read<LikeBloc>().add(const LoadLikesEvent());
});
_scrollController.addListener(_onNextPageListener);
SvgObjects.init();
super.initState();
}
@override
void dispose() {
_searchController.dispose();
_scrollController.dispose();
super.dispose();
}
void _onNextPageListener() {
if (_scrollController.offset >= _scrollController.position.maxScrollExtent) {
final bloc = context.read<HomeBloc>();
if (!bloc.state.isPaginationLoading) {
bloc.add(
HomeLoadDataEvent(search: _searchController.text, nextPage: bloc.state.data?.nextPage));
}
}
}
Future<void> _onRefresh() {
context.read<HomeBloc>().add(HomeLoadDataEvent(search: _searchController.text));
return Future.value(null);
}
void _onSearchInputChange(search) {
Debounce.run(action: () => context.read<HomeBloc>().add(HomeLoadDataEvent(search: search)));
}
void _onLike(String? id, String text, bool isLiked) {
if (id != null) {
context.read<LikeBloc>().add(ChangeLikeEvent(id));
_showSnackBar(context, id, text, isLiked);
}
}
void _showSnackBar(BuildContext context, String? id, String text, bool isLiked) {
WidgetsBinding.instance.addPostFrameCallback((_) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(text),
duration: const Duration(seconds: 2),
backgroundColor: Colors.black54,
));
});
}
void _navigateToDetailsPage(BuildContext context, CardData data) {
Navigator.push(
context,
CupertinoPageRoute(builder: (context) => DetailsPage(data: data)),
);
}
void _handleLocaleButtonTap() {
context.read<LocaleBloc>().add(const ChangeLocaleEvent());
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.only(right: 30, left: 30, top: 20, bottom: 20),
child: Row(
children: [
Expanded(
flex: 4,
child: CupertinoSearchTextField(
controller: _searchController,
placeholder: context.locale.searchInputPlaceholder,
onChanged: _onSearchInputChange,
)),
GestureDetector(
onTap: _handleLocaleButtonTap,
child: SizedBox.square(
dimension: 50,
child: Padding(
padding: const EdgeInsets.only(left: 12),
child: BlocBuilder<LocaleBloc, LocaleState>(
builder: (context, state) {
return state.currentLocale.languageCode == "ru"
? const SvgRu()
: const SvgUk();
},
),
),
),
),
],
),
),
BlocBuilder<HomeBloc, HomeState>(
builder: (context, state) => state.error != null
? Text(
state.error ?? "",
style: Theme.of(context).textTheme.headlineSmall?.copyWith(color: Colors.red),
)
: state.isLoading
? const Padding(
padding: EdgeInsets.only(top: 20),
child: CircularProgressIndicator(),
)
: BlocBuilder<LikeBloc, LikeState>(
builder: (context, likeState) {
return Expanded(
child: RefreshIndicator(
onRefresh: _onRefresh,
child: ListView.separated(
controller: _scrollController,
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 30),
separatorBuilder: (context, index) => const SizedBox(height: 20),
itemCount: state.data?.data?.length ?? 0,
itemBuilder: (context, index) {
final data = state.data?.data?[index];
return data == null
? const SizedBox.shrink()
: Card.fromData(
data,
isLiked: likeState.likedIds?.contains(data.id) == true,
onLike: (String? id, String text, bool isLiked) =>
_onLike(id, text, isLiked),
onTap: () => _navigateToDetailsPage(context, data),
);
},
),
),
);
},
),
),
BlocBuilder<HomeBloc, HomeState>(
builder: (context, state) => state.isPaginationLoading
? const CircularProgressIndicator()
: const SizedBox.shrink(),
),
],
),
);
}
}

View File

@ -1,18 +0,0 @@
gen:
dart run build_runner build --delete-conflicting-outputs
icon:
dart run flutter_launcher_icons:main
init_res:
dart pub global activate flutter_asset_generator
format:
dart format . --line-length 100
res:
fgen --output lib/components/resources/resources.g.dart --no-watch --no-preview; \
make format
locale:
flutter gen-l10n

View File

@ -1,43 +1,6 @@
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
_fe_analyzer_shared:
dependency: transitive
description:
name: _fe_analyzer_shared
sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834
url: "https://pub.dev"
source: hosted
version: "72.0.0"
_macros:
dependency: transitive
description: dart
source: sdk
version: "0.3.2"
analyzer:
dependency: transitive
description:
name: analyzer
sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139
url: "https://pub.dev"
source: hosted
version: "6.7.0"
archive:
dependency: transitive
description:
name: archive
sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
url: "https://pub.dev"
source: hosted
version: "3.6.1"
args:
dependency: transitive
description:
name: args
sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
url: "https://pub.dev"
source: hosted
version: "2.5.0"
async: async:
dependency: transitive dependency: transitive
description: description:
@ -46,14 +9,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.11.0" version: "2.11.0"
bloc:
dependency: transitive
description:
name: bloc
sha256: "106842ad6569f0b60297619e9e0b1885c2fb9bf84812935490e6c5275777804e"
url: "https://pub.dev"
source: hosted
version: "8.1.4"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
@ -62,70 +17,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.1" version: "2.1.1"
build:
dependency: transitive
description:
name: build
sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
build_config:
dependency: transitive
description:
name: build_config
sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1
url: "https://pub.dev"
source: hosted
version: "1.1.1"
build_daemon:
dependency: transitive
description:
name: build_daemon
sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
build_resolvers:
dependency: transitive
description:
name: build_resolvers
sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a"
url: "https://pub.dev"
source: hosted
version: "2.4.2"
build_runner:
dependency: "direct dev"
description:
name: build_runner
sha256: dd09dd4e2b078992f42aac7f1a622f01882a8492fef08486b27ddde929c19f04
url: "https://pub.dev"
source: hosted
version: "2.4.12"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0
url: "https://pub.dev"
source: hosted
version: "7.3.2"
built_collection:
dependency: transitive
description:
name: built_collection
sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
url: "https://pub.dev"
source: hosted
version: "5.1.1"
built_value:
dependency: transitive
description:
name: built_value
sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb
url: "https://pub.dev"
source: hosted
version: "8.9.2"
characters: characters:
dependency: transitive dependency: transitive
description: description:
@ -134,22 +25,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.0" version: "1.3.0"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
url: "https://pub.dev"
source: hosted
version: "2.0.3"
cli_util:
dependency: transitive
description:
name: cli_util
sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19
url: "https://pub.dev"
source: hosted
version: "0.4.1"
clock: clock:
dependency: transitive dependency: transitive
description: description:
@ -158,14 +33,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.1" version: "1.1.1"
code_builder:
dependency: transitive
description:
name: code_builder
sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37
url: "https://pub.dev"
source: hosted
version: "4.10.0"
collection: collection:
dependency: transitive dependency: transitive
description: description:
@ -174,22 +41,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.18.0" version: "1.18.0"
convert:
dependency: transitive
description:
name: convert
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
crypto:
dependency: transitive
description:
name: crypto
sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27
url: "https://pub.dev"
source: hosted
version: "3.0.5"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
@ -198,38 +49,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.8" version: "1.0.8"
dart_style:
dependency: transitive
description:
name: dart_style
sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab"
url: "https://pub.dev"
source: hosted
version: "2.3.7"
dio:
dependency: "direct main"
description:
name: dio
sha256: "5598aa796bbf4699afd5c67c0f5f6e2ed542afc956884b9cd58c306966efc260"
url: "https://pub.dev"
source: hosted
version: "5.7.0"
dio_web_adapter:
dependency: transitive
description:
name: dio_web_adapter
sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
equatable:
dependency: "direct main"
description:
name: equatable
sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
url: "https://pub.dev"
source: hosted
version: "2.0.5"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@ -238,51 +57,11 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.1" version: "1.3.1"
ffi:
dependency: transitive
description:
name: ffi
sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
url: "https://pub.dev"
source: hosted
version: "2.1.3"
file:
dependency: transitive
description:
name: file
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
fixnum:
dependency: transitive
description:
name: fixnum
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_bloc:
dependency: "direct main"
description:
name: flutter_bloc
sha256: b594505eac31a0518bdcb4b5b79573b8d9117b193cc80cc12e17d639b10aa27a
url: "https://pub.dev"
source: hosted
version: "8.1.6"
flutter_launcher_icons:
dependency: "direct dev"
description:
name: flutter_launcher_icons
sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea"
url: "https://pub.dev"
source: hosted
version: "0.13.1"
flutter_lints: flutter_lints:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -291,125 +70,11 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.0" version: "4.0.0"
flutter_localizations:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_svg:
dependency: "direct main"
description:
name: flutter_svg
sha256: "8c5d68a82add3ca76d792f058b186a0599414f279f00ece4830b9b231b570338"
url: "https://pub.dev"
source: hosted
version: "2.0.7"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
frontend_server_client:
dependency: transitive
description:
name: frontend_server_client
sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694
url: "https://pub.dev"
source: hosted
version: "4.0.0"
glob:
dependency: transitive
description:
name: glob
sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
graphs:
dependency: transitive
description:
name: graphs
sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
http:
dependency: transitive
description:
name: http
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
url: "https://pub.dev"
source: hosted
version: "1.2.2"
http_multi_server:
dependency: transitive
description:
name: http_multi_server
sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
url: "https://pub.dev"
source: hosted
version: "3.2.1"
http_parser:
dependency: transitive
description:
name: http_parser
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
image:
dependency: transitive
description:
name: image
sha256: "2237616a36c0d69aef7549ab439b833fb7f9fb9fc861af2cc9ac3eedddd69ca8"
url: "https://pub.dev"
source: hosted
version: "4.2.0"
intl:
dependency: "direct main"
description:
name: intl
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
url: "https://pub.dev"
source: hosted
version: "0.19.0"
io:
dependency: transitive
description:
name: io
sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e"
url: "https://pub.dev"
source: hosted
version: "1.0.4"
js:
dependency: transitive
description:
name: js
sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf
url: "https://pub.dev"
source: hosted
version: "0.7.1"
json_annotation:
dependency: "direct main"
description:
name: json_annotation
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
url: "https://pub.dev"
source: hosted
version: "4.9.0"
json_serializable:
dependency: "direct dev"
description:
name: json_serializable
sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b
url: "https://pub.dev"
source: hosted
version: "6.8.0"
leak_tracker: leak_tracker:
dependency: transitive dependency: transitive
description: description:
@ -442,22 +107,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.0" version: "4.0.0"
logging:
dependency: transitive
description:
name: logging
sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
macros:
dependency: transitive
description:
name: macros
sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536"
url: "https://pub.dev"
source: hosted
version: "0.1.2-main.4"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
@ -482,30 +131,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.15.0" version: "1.15.0"
mime:
dependency: transitive
description:
name: mime
sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a"
url: "https://pub.dev"
source: hosted
version: "1.0.6"
nested:
dependency: transitive
description:
name: nested
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
package_config:
dependency: transitive
description:
name: package_config
sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
path: path:
dependency: transitive dependency: transitive
description: description:
@ -514,195 +139,11 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.0" version: "1.9.0"
path_parsing:
dependency: transitive
description:
name: path_parsing
sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf
url: "https://pub.dev"
source: hosted
version: "1.0.1"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.dev"
source: hosted
version: "2.2.1"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
url: "https://pub.dev"
source: hosted
version: "2.3.0"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
url: "https://pub.dev"
source: hosted
version: "6.0.2"
platform:
dependency: transitive
description:
name: platform
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
url: "https://pub.dev"
source: hosted
version: "3.1.5"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://pub.dev"
source: hosted
version: "2.1.8"
pool:
dependency: transitive
description:
name: pool
sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a"
url: "https://pub.dev"
source: hosted
version: "1.5.1"
pretty_dio_logger:
dependency: "direct main"
description:
name: pretty_dio_logger
sha256: "36f2101299786d567869493e2f5731de61ce130faa14679473b26905a92b6407"
url: "https://pub.dev"
source: hosted
version: "1.4.0"
provider:
dependency: transitive
description:
name: provider
sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
url: "https://pub.dev"
source: hosted
version: "6.1.2"
pub_semver:
dependency: transitive
description:
name: pub_semver
sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
pubspec_parse:
dependency: transitive
description:
name: pubspec_parse
sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
url: "https://pub.dev"
source: hosted
version: "1.3.0"
shared_preferences:
dependency: "direct main"
description:
name: shared_preferences
sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180
url: "https://pub.dev"
source: hosted
version: "2.2.3"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
sha256: "480ba4345773f56acda9abf5f50bd966f581dac5d514e5fc4a18c62976bbba7e"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
sha256: c4b35f6cb8f63c147312c054ce7c2254c8066745125264f0c88739c417fc9d9f
url: "https://pub.dev"
source: hosted
version: "2.5.2"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
shared_preferences_platform_interface:
dependency: transitive
description:
name: shared_preferences_platform_interface
sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
shared_preferences_web:
dependency: transitive
description:
name: shared_preferences_web
sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e
url: "https://pub.dev"
source: hosted
version: "2.4.2"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
shelf:
dependency: transitive
description:
name: shelf
sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4
url: "https://pub.dev"
source: hosted
version: "1.4.1"
shelf_web_socket:
dependency: transitive
description:
name: shelf_web_socket
sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.99" version: "0.0.99"
source_gen:
dependency: transitive
description:
name: source_gen
sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832"
url: "https://pub.dev"
source: hosted
version: "1.5.0"
source_helper:
dependency: transitive
description:
name: source_helper
sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd"
url: "https://pub.dev"
source: hosted
version: "1.3.4"
source_span: source_span:
dependency: transitive dependency: transitive
description: description:
@ -727,14 +168,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.2" version: "2.1.2"
stream_transform:
dependency: transitive
description:
name: stream_transform
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
@ -759,46 +192,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.2" version: "0.7.2"
timing:
dependency: transitive
description:
name: timing
sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32"
url: "https://pub.dev"
source: hosted
version: "1.0.1"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted
version: "1.3.2"
vector_graphics:
dependency: transitive
description:
name: vector_graphics
sha256: "32c3c684e02f9bc0afb0ae0aa653337a2fe022e8ab064bcd7ffda27a74e288e3"
url: "https://pub.dev"
source: hosted
version: "1.1.11+1"
vector_graphics_codec:
dependency: transitive
description:
name: vector_graphics_codec
sha256: c86987475f162fadff579e7320c7ddda04cd2fdeffbe1129227a85d9ac9e03da
url: "https://pub.dev"
source: hosted
version: "1.1.11+1"
vector_graphics_compiler:
dependency: transitive
description:
name: vector_graphics_compiler
sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81"
url: "https://pub.dev"
source: hosted
version: "1.1.11+1"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
@ -815,62 +208,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "14.2.5" version: "14.2.5"
watcher:
dependency: transitive
description:
name: watcher
sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
web:
dependency: transitive
description:
name: web
sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062
url: "https://pub.dev"
source: hosted
version: "1.0.0"
web_socket:
dependency: transitive
description:
name: web_socket
sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83"
url: "https://pub.dev"
source: hosted
version: "0.1.6"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
url: "https://pub.dev"
source: hosted
version: "1.0.4"
xml:
dependency: transitive
description:
name: xml
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
url: "https://pub.dev"
source: hosted
version: "6.5.0"
yaml:
dependency: transitive
description:
name: yaml
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
url: "https://pub.dev"
source: hosted
version: "3.1.2"
sdks: sdks:
dart: ">=3.5.2 <4.0.0" dart: ">=3.5.2 <4.0.0"
flutter: ">=3.22.0" flutter: ">=3.18.0-18.0.pre.54"

View File

@ -31,24 +31,11 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
flutter_svg: 2.0.7
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.8 cupertino_icons: ^1.0.8
json_annotation: ^4.8.1
dio: ^5.4.2+1
pretty_dio_logger: ^1.3.1
flutter_bloc: ^8.1.5
equatable: ^2.0.5
flutter_localizations:
sdk: flutter
intl: ^0.19.0
shared_preferences: 2.2.3
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
@ -60,25 +47,11 @@ dev_dependencies:
# rules and activating additional ones. # rules and activating additional ones.
flutter_lints: ^4.0.0 flutter_lints: ^4.0.0
flutter_launcher_icons: 0.13.1
build_runner: ^2.4.9
json_serializable: ^6.7.1
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec
flutter_icons:
android: "ic_launcher"
image_path: "assets/app_icon.png"
min_sdk_android: 21
# The following section is specific to Flutter packages. # The following section is specific to Flutter packages.
flutter: flutter:
generate: true
assets:
- assets/svg/
# The following line ensures that the Material Icons font is # The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in # included with your application, so that you can use the icons in
@ -114,4 +87,4 @@ flutter:
# weight: 700 # weight: 700
# #
# For details regarding fonts from package dependencies, # For details regarding fonts from package dependencies,
# see https://flutter.dev/to/font-from-package # see https://flutter.dev/to/font-from-package