что-не очень
Before Width: | Height: | Size: 544 B After Width: | Height: | Size: 8.7 KiB |
Before Width: | Height: | Size: 442 B After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 721 B After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 42 KiB |
BIN
assets/launcher.png
Normal file
After Width: | Height: | Size: 202 KiB |
6
l10n.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
arb-dir: l10n
|
||||
template-arb-file: app_ru.arb
|
||||
output-localization-file: app_locale.dart
|
||||
output-dir: lib/components/locale/l10n
|
||||
output-class: AppLocale
|
||||
synthetic-package: false
|
9
l10n/app_en.arb
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"@@locale": "en",
|
||||
|
||||
"search": "Search",
|
||||
"liked": "Like :)",
|
||||
"disliked": "Dislike :(",
|
||||
|
||||
"arbEnding": ""
|
||||
}
|
9
l10n/app_ru.arb
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"@@locale": "ru",
|
||||
|
||||
"search": "Поиск",
|
||||
"liked": "Круто :)",
|
||||
"disliked": "Не круто :с",
|
||||
|
||||
"arbEnding": ""
|
||||
}
|
6
lib/components/extensions/context_x.dart
Normal file
@ -0,0 +1,6 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
import '../locale/l10n/app_locale.dart';
|
||||
|
||||
extension LocalContextX on BuildContext {
|
||||
AppLocale get locale => AppLocale.of(this)!;
|
||||
}
|
@ -11,9 +11,9 @@ class Debounce {
|
||||
static Timer? _timer;
|
||||
|
||||
static void run(
|
||||
VoidCallback action, {
|
||||
Duration delay = const Duration(milliseconds: 1000),
|
||||
}) {
|
||||
VoidCallback action, {
|
||||
Duration delay = const Duration(milliseconds: 1000),
|
||||
}) {
|
||||
_timer?.cancel();
|
||||
_timer = Timer(delay, action);
|
||||
}
|
||||
|
@ -16,8 +16,9 @@ class QuoteDataDto {
|
||||
final String? body;
|
||||
final String? author;
|
||||
final String? imageUrl;
|
||||
final String? id;
|
||||
|
||||
const QuoteDataDto({this.body, this.author, this.imageUrl});
|
||||
const QuoteDataDto({this.body, this.author, this.imageUrl, this.id});
|
||||
|
||||
factory QuoteDataDto.fromJson(Map<String, dynamic> json) => _$QuoteDataDtoFromJson(json);
|
||||
}
|
@ -2,13 +2,13 @@ import '../../domain/quote.dart';
|
||||
import '/data/dtos/quotes_dto.dart';
|
||||
import '/presentation/home_page/home_page.dart';
|
||||
|
||||
const _imagePlaceholder =
|
||||
'https://cdn-icons-png.flaticon.com/128/17818/17818874.png';
|
||||
const _imagePlaceholder = 'https://cdn-icons-png.flaticon.com/128/17818/17818874.png';
|
||||
|
||||
extension QuoteDtoToModel on QuoteDataDto {
|
||||
Quote toDomain() => Quote(
|
||||
body ?? 'Без текста',
|
||||
author ?? 'Неизвестный автор',
|
||||
imageUrl ?? _imagePlaceholder,
|
||||
);
|
||||
body ?? 'Без текста',
|
||||
author ?? 'Неизвестный автор',
|
||||
imageUrl ?? _imagePlaceholder,
|
||||
id ?? "",
|
||||
);
|
||||
}
|
@ -24,12 +24,10 @@ class QuotesRepository extends ApiInterface {
|
||||
try {
|
||||
final Map<String, dynamic> queryParams = {};
|
||||
|
||||
|
||||
if (q != null && q.isNotEmpty) {
|
||||
queryParams['filter'] = q;
|
||||
}
|
||||
|
||||
|
||||
if (author != null && author.isNotEmpty) {
|
||||
queryParams['type'] = 'author';
|
||||
queryParams['filter'] = author;
|
||||
@ -51,4 +49,3 @@ class QuotesRepository extends ApiInterface {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,13 @@ class Quote {
|
||||
final String text;
|
||||
final String author;
|
||||
final String imagePath;
|
||||
final String id;
|
||||
bool isFavorite;
|
||||
|
||||
Quote(this.text, this.author, this.imagePath, [this.isFavorite = false]);
|
||||
Quote(this.text, this.author, this.imagePath, this.id,[this.isFavorite = false]);
|
||||
|
||||
void toggleFavorite() {
|
||||
bool toggleFavorite() {
|
||||
isFavorite = !isFavorite;
|
||||
return isFavorite;
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:pmu_flutter_labs/presentation/home_page/bloc/events.dart';
|
||||
import 'package:pmu_flutter_labs/presentation/like_bloc/like_bloc.dart';
|
||||
import 'components/locale/l10n/app_locale.dart';
|
||||
import 'data/repositories/quotes_repository.dart';
|
||||
import '/presentation/home_page/bloc/bloc.dart';
|
||||
import '/presentation/home_page/home_page.dart';
|
||||
|
||||
void main() {
|
||||
runApp(const MyApp());
|
||||
}
|
||||
@ -15,6 +17,8 @@ class MyApp extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'Цитаты',
|
||||
localizationsDelegates: AppLocale.localizationsDelegates,
|
||||
supportedLocales: AppLocale.supportedLocales,
|
||||
theme: ThemeData(
|
||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
|
||||
useMaterial3: true,
|
||||
@ -22,12 +26,16 @@ class MyApp extends StatelessWidget {
|
||||
home: RepositoryProvider<QuotesRepository>(
|
||||
lazy: true,
|
||||
create: (_) => QuotesRepository(),
|
||||
child: BlocProvider<HomeBloc>(
|
||||
lazy: false,
|
||||
create: (context) => HomeBloc(context.read<QuotesRepository>()),
|
||||
child: const MyHomePage(title: "Цитаты",),
|
||||
child: BlocProvider(
|
||||
create: (context) => LikeBloc(), // Add LikeBloc here
|
||||
child: BlocProvider(
|
||||
create: (context) => HomeBloc(context.read<QuotesRepository>())
|
||||
..add(const HomeLoadDataEvent()), // Ensure initial load
|
||||
child: const MyHomePage(title: "Цитаты"),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
34
lib/presentation/common/svg_objects.dart
Normal file
@ -0,0 +1,34 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import '/components/resources.g.dart';
|
||||
|
||||
abstract class SvgObjects {
|
||||
static void init() {
|
||||
final pics = <String>[
|
||||
R.ASSETS_SVG_RU_SVG,
|
||||
R.ASSETS_SVG_US_SVG,
|
||||
];
|
||||
for (final String p in pics) {
|
||||
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_US_SVG);
|
||||
}
|
||||
}
|
@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
|
||||
import 'error_dialog.dart';
|
||||
|
||||
void showErrorDialog(
|
||||
BuildContext context, {
|
||||
required String error,
|
||||
}) {
|
||||
BuildContext context, {
|
||||
required String error,
|
||||
}) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => ErrorDialog(error),
|
||||
|
@ -24,12 +24,14 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
||||
} else {
|
||||
// Если автор указан, фильтруем данные по тексту цитаты
|
||||
try {
|
||||
final currentData = await repo.loadData(q:search, author: author,
|
||||
final currentData = await repo.loadData(
|
||||
q: search,
|
||||
author: author,
|
||||
);
|
||||
final filteredData = currentData?.where((quote) {
|
||||
final matchesAuthor = quote.author.toLowerCase().contains(author.toLowerCase());
|
||||
final matchesSearch = search.isEmpty ||
|
||||
quote.text.toLowerCase().contains(search.toLowerCase());
|
||||
final matchesSearch =
|
||||
search.isEmpty || quote.text.toLowerCase().contains(search.toLowerCase());
|
||||
return matchesAuthor && matchesSearch;
|
||||
}).toList();
|
||||
emit(state.copyWith(data: Future.value(filteredData)));
|
||||
@ -39,13 +41,8 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Future<void> _onRefreshData(HomeRefreshEvent event, Emitter<HomeState> emit) async {
|
||||
add(HomeLoadDataEvent(search: event.search, author: event.author)); // Просто перезапускаем загрузку
|
||||
add(HomeLoadDataEvent(
|
||||
search: event.search, author: event.author)); // Просто перезапускаем загрузку
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ import 'package:equatable/equatable.dart';
|
||||
import '../../../domain/quote.dart';
|
||||
import '../home_page.dart';
|
||||
|
||||
|
||||
class HomeState extends Equatable {
|
||||
final Future<List<Quote>>? data; // Изменено
|
||||
|
||||
|
@ -1,55 +1,60 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../domain/quote.dart';
|
||||
import '../like_bloc/like_bloc.dart';
|
||||
import '../like_bloc/like_state.dart';
|
||||
import 'home_page.dart';
|
||||
|
||||
class QuoteCard extends StatelessWidget {
|
||||
final Quote quote;
|
||||
final VoidCallback onFavoriteToggle;
|
||||
|
||||
const QuoteCard({
|
||||
super.key,
|
||||
required this.quote,
|
||||
required this.onFavoriteToggle,
|
||||
});
|
||||
const QuoteCard({Key? key, required this.quote, required this.onFavoriteToggle}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Card(
|
||||
margin: const EdgeInsets.symmetric(
|
||||
vertical: 8.0,
|
||||
horizontal: 10.0,
|
||||
),
|
||||
child: ListTile(
|
||||
contentPadding: const EdgeInsets.all(8.0),
|
||||
leading: SizedBox(
|
||||
width: 50.0,
|
||||
child: Image.network(
|
||||
quote.imagePath,
|
||||
fit: BoxFit.cover,
|
||||
errorBuilder: (_, __, ___) =>
|
||||
const Icon(Icons.error, color: Colors.red),
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
quote.text,
|
||||
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
|
||||
),
|
||||
subtitle: Text('- ${quote.author}'),
|
||||
trailing: IconButton(
|
||||
icon: Icon(
|
||||
quote.isFavorite ? Icons.favorite : Icons.favorite_border,
|
||||
color: quote.isFavorite ? Colors.red : null,
|
||||
),
|
||||
onPressed: onFavoriteToggle,
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => QuoteDetailScreen(quote: quote),
|
||||
margin: const EdgeInsets.all(8.0),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
quote.text,
|
||||
style: const TextStyle(fontSize: 18.0),
|
||||
),
|
||||
);
|
||||
},
|
||||
const SizedBox(height: 8.0),
|
||||
Text(
|
||||
'- ${quote.author}',
|
||||
style: const TextStyle(fontStyle: FontStyle.italic, fontSize: 16.0),
|
||||
),
|
||||
const SizedBox(height: 8.0),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ElevatedButton.icon(
|
||||
onPressed: onFavoriteToggle,
|
||||
icon: BlocBuilder<LikeBloc, LikeState>(
|
||||
builder: (context, state) {
|
||||
final isLiked = state.likedIds?.contains(quote.id) ?? false;
|
||||
return Icon(
|
||||
isLiked ? Icons.favorite : Icons.favorite_border,
|
||||
color: isLiked ? Colors.red : Colors.grey,
|
||||
);
|
||||
},
|
||||
),
|
||||
label: BlocBuilder<LikeBloc, LikeState>(
|
||||
builder: (context, state) {
|
||||
final isLiked = state.likedIds?.contains(quote.id) ?? false;
|
||||
return Text(isLiked ? 'Убрать из избранного' : 'Добавить в избранное');
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -75,8 +80,7 @@ class QuoteDetailScreen extends StatelessWidget {
|
||||
Image.network(
|
||||
quote.imagePath,
|
||||
height: 150,
|
||||
errorBuilder: (_, __, ___) =>
|
||||
const Icon(Icons.error, color: Colors.red),
|
||||
errorBuilder: (_, __, ___) => const Icon(Icons.error, color: Colors.red),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
|
@ -1,7 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:pmu_flutter_labs/components/extensions/context_x.dart';
|
||||
import '../../components/utils/debounce.dart';
|
||||
import '../../domain/quote.dart';
|
||||
import '../common/svg_objects.dart';
|
||||
import '../like_bloc/like_bloc.dart';
|
||||
import '../like_bloc/like_event.dart';
|
||||
import '/data/repositories/quotes_repository.dart';
|
||||
import '/presentation/home_page/bloc/bloc.dart';
|
||||
import '/presentation/home_page/bloc/events.dart';
|
||||
@ -40,11 +44,15 @@ class _HomePageBodyState extends State<_HomePageBody> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
SvgObjects.init();
|
||||
super.initState();
|
||||
|
||||
searchController.addListener(() {
|
||||
Debounce.run(() {
|
||||
context.read<HomeBloc>().add(HomeLoadDataEvent(search: searchController.text));
|
||||
context.read<HomeBloc>().add(HomeLoadDataEvent(
|
||||
search: searchController.text,
|
||||
author: authorController.text,
|
||||
));
|
||||
});
|
||||
});
|
||||
|
||||
@ -56,6 +64,18 @@ class _HomePageBodyState extends State<_HomePageBody> {
|
||||
));
|
||||
});
|
||||
});
|
||||
context.read<LikeBloc>().add(const LoadLikesEvent());
|
||||
|
||||
}
|
||||
|
||||
void _showSnackbar(BuildContext context, bool isLiked) {
|
||||
final message = isLiked ? context.locale.liked : context.locale.disliked;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(message),
|
||||
duration: const Duration(seconds: 2),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -119,9 +139,7 @@ class _HomePageBodyState extends State<_HomePageBody> {
|
||||
return QuoteCard(
|
||||
quote: quote,
|
||||
onFavoriteToggle: () {
|
||||
setState(() {
|
||||
quote.toggleFavorite();
|
||||
});
|
||||
context.read<LikeBloc>().add(ChangeLikeEvent(quote.id));
|
||||
},
|
||||
);
|
||||
},
|
||||
@ -136,3 +154,4 @@ class _HomePageBodyState extends State<_HomePageBody> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
36
lib/presentation/like_bloc/like_bloc.dart
Normal file
@ -0,0 +1,36 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
//import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'like_event.dart';
|
||||
import 'like_state.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));
|
||||
}
|
||||
}
|
13
lib/presentation/like_bloc/like_event.dart
Normal file
@ -0,0 +1,13 @@
|
||||
abstract class LikeEvent {
|
||||
const LikeEvent();
|
||||
}
|
||||
|
||||
class LoadLikesEvent extends LikeEvent {
|
||||
const LoadLikesEvent();
|
||||
}
|
||||
|
||||
class ChangeLikeEvent extends LikeEvent {
|
||||
final String id;
|
||||
|
||||
const ChangeLikeEvent(this.id);
|
||||
}
|
14
lib/presentation/like_bloc/like_state.dart
Normal file
@ -0,0 +1,14 @@
|
||||
import 'package:copy_with_extension/copy_with_extension.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
part 'like_state.g.dart';
|
||||
|
||||
@CopyWith()
|
||||
class LikeState extends Equatable {
|
||||
final List<String>? likedIds;
|
||||
|
||||
const LikeState({required this.likedIds});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [likedIds];
|
||||
}
|
14
makefile
Normal file
@ -0,0 +1,14 @@
|
||||
gen:
|
||||
flutter pub run build_runner build --delete-conflicting-outputs
|
||||
icon:
|
||||
flutter pub 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.g.dart --no-watch --no-preview;\
|
||||
dart format . --line-length 100
|
||||
loc:
|
||||
flutter gen-l10n
|
||||
dart format . --line-length 100
|
52
pubspec.lock
@ -26,10 +26,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: archive
|
||||
sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
|
||||
sha256: "08064924cbf0ab88280a0c3f60db9dd24fec693927e725ecb176f16c629d1cb8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.6.1"
|
||||
version: "4.0.1"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -254,6 +254,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
@ -353,10 +361,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
|
||||
sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
version: "3.2.2"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -369,10 +377,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image
|
||||
sha256: f31d52537dc417fdcde36088fdf11d191026fd5e4fae742491ebd40e5a8bea7d
|
||||
sha256: "20842a5ad1555be624c314b0c0cc0566e8ece412f61e859a42efeb6d4101a26c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.3.0"
|
||||
version: "4.5.0"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -505,10 +513,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
|
||||
sha256: "92d4488434b520a62570293fbd33bb556c7d49230791c1b4bbd973baf6d2dc67"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -541,6 +549,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.1"
|
||||
posix:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: posix
|
||||
sha256: a0117dc2167805aa9125b82eee515cc891819bac2f538c83646d355b16f58b9a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.1"
|
||||
pretty_dio_logger:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -561,10 +577,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
|
||||
sha256: "7b3cfbf654f3edd0c6298ecd5be782ce997ddf0e00531b9464b55245185bbbbd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
version: "2.1.5"
|
||||
pubspec_parse:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -606,10 +622,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_helper
|
||||
sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd"
|
||||
sha256: "86d247119aedce8e63f4751bd9626fc9613255935558447569ad42f9f5b48b3c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.4"
|
||||
version: "1.3.5"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -638,10 +654,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_transform
|
||||
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
|
||||
sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -670,10 +686,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: timing
|
||||
sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32"
|
||||
sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "1.0.2"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -726,10 +742,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: watcher
|
||||
sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
|
||||
sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
10
pubspec.yaml
@ -7,6 +7,7 @@ environment:
|
||||
sdk: ^3.5.4
|
||||
|
||||
dependencies:
|
||||
# shared_preferences: ^2.3.3
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
@ -29,9 +30,10 @@ dependencies:
|
||||
sdk: flutter
|
||||
intl: ^0.19.0
|
||||
|
||||
#shared_preferences: ^2.0.0
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
flutter_lints: ^5.0.0
|
||||
@ -41,9 +43,15 @@ dev_dependencies:
|
||||
build_runner: ^2.4.9
|
||||
json_serializable: ^6.7.1
|
||||
|
||||
flutter_icons:
|
||||
android: "ic_launcher"
|
||||
image_path: "assets/launcher.png"
|
||||
min_sdk_android: 21
|
||||
|
||||
flutter:
|
||||
generate: true
|
||||
uses-material-design: true
|
||||
|
||||
assets:
|
||||
- assets/svg/
|
||||
|
||||
|