Add Infography Screen
This commit is contained in:
parent
445b37bc91
commit
ba20b25ab0
|
|
@ -1,3 +1,3 @@
|
||||||
org.gradle.jvmargs=-Xmx1536M
|
org.gradle.jvmargs=-Xmx4608m
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ class LightThemeConfig {
|
||||||
onBackground: _white,
|
onBackground: _white,
|
||||||
onError: _white,
|
onError: _white,
|
||||||
brightness: Brightness.light,
|
brightness: Brightness.light,
|
||||||
);
|
outline: Color(0xff007EA7));
|
||||||
}
|
}
|
||||||
|
|
||||||
class DarkThemeConfig {
|
class DarkThemeConfig {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
class InfoTagModel {
|
||||||
|
final List<InTag> tags;
|
||||||
|
|
||||||
|
InfoTagModel({required this.tags});
|
||||||
|
|
||||||
|
factory InfoTagModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return InfoTagModel(
|
||||||
|
tags: List<InTag>.from(json['tags'].map((x) => InTag.fromJson(x))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class InTag {
|
||||||
|
final int id;
|
||||||
|
final String label;
|
||||||
|
|
||||||
|
InTag({required this.id, required this.label});
|
||||||
|
|
||||||
|
factory InTag.fromJson(Map<String, dynamic> json) {
|
||||||
|
return InTag(
|
||||||
|
id: json['id'],
|
||||||
|
label: json['label'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
class InfographyContent {
|
||||||
|
final List<Content> contents;
|
||||||
|
final int lastPage;
|
||||||
|
|
||||||
|
InfographyContent({required this.contents, required this.lastPage});
|
||||||
|
|
||||||
|
factory InfographyContent.fromJson(Map<String, dynamic> json) {
|
||||||
|
return InfographyContent(
|
||||||
|
contents:
|
||||||
|
List<Content>.from(json['contents'].map((x) => Content.fromJson(x))),
|
||||||
|
lastPage: json['lastPage'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Content {
|
||||||
|
final int id;
|
||||||
|
final String title;
|
||||||
|
final String image;
|
||||||
|
final String category;
|
||||||
|
final List<Tag> tags;
|
||||||
|
|
||||||
|
Content(
|
||||||
|
{required this.id,
|
||||||
|
required this.title,
|
||||||
|
required this.image,
|
||||||
|
required this.category,
|
||||||
|
required this.tags});
|
||||||
|
|
||||||
|
factory Content.fromJson(Map<String, dynamic> json) {
|
||||||
|
return Content(
|
||||||
|
id: json['id'],
|
||||||
|
title: json['title'],
|
||||||
|
image: json['image'],
|
||||||
|
category: json['category'],
|
||||||
|
tags: List<Tag>.from(json['tags'].map((x) => Tag.fromJson(x))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Tag {
|
||||||
|
final int id;
|
||||||
|
final String label;
|
||||||
|
|
||||||
|
Tag({required this.id, required this.label});
|
||||||
|
|
||||||
|
factory Tag.fromJson(Map<String, dynamic> json) {
|
||||||
|
return Tag(
|
||||||
|
id: json['id'],
|
||||||
|
label: json['label'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
class InfographyRequestArgs {
|
||||||
|
final int page;
|
||||||
|
final String? q;
|
||||||
|
final List<int>? tag;
|
||||||
|
final List<int>? categories;
|
||||||
|
|
||||||
|
const InfographyRequestArgs({
|
||||||
|
required this.page,
|
||||||
|
this.categories,
|
||||||
|
this.q,
|
||||||
|
this.tag,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,8 @@ import 'package:didvan/views/direct/direct_state.dart';
|
||||||
import 'package:didvan/views/hashtag/hashtag.dart';
|
import 'package:didvan/views/hashtag/hashtag.dart';
|
||||||
import 'package:didvan/views/hashtag/hashtag_state.dart';
|
import 'package:didvan/views/hashtag/hashtag_state.dart';
|
||||||
import 'package:didvan/views/home/home.dart';
|
import 'package:didvan/views/home/home.dart';
|
||||||
|
import 'package:didvan/views/home/infography/infography_screen.dart';
|
||||||
|
import 'package:didvan/views/home/infography/infography_screen_state.dart';
|
||||||
import 'package:didvan/views/home/main/main_page_state.dart';
|
import 'package:didvan/views/home/main/main_page_state.dart';
|
||||||
import 'package:didvan/views/home/home_state.dart';
|
import 'package:didvan/views/home/home_state.dart';
|
||||||
import 'package:didvan/views/news/news.dart';
|
import 'package:didvan/views/news/news.dart';
|
||||||
|
|
@ -111,6 +113,12 @@ class RouteGenerator {
|
||||||
child: const News(),
|
child: const News(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
case Routes.infography:
|
||||||
|
return _createRoute(ChangeNotifierProvider<InfographyScreenState>(
|
||||||
|
create: (context) => InfographyScreenState(),
|
||||||
|
child: const InfographyScreen(),
|
||||||
|
));
|
||||||
|
|
||||||
case Routes.radarDetails:
|
case Routes.radarDetails:
|
||||||
return _createRoute(
|
return _createRoute(
|
||||||
ChangeNotifierProvider<RadarDetailsState>(
|
ChangeNotifierProvider<RadarDetailsState>(
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ class Routes {
|
||||||
static const String home = '/home';
|
static const String home = '/home';
|
||||||
static const String radars = '/radars';
|
static const String radars = '/radars';
|
||||||
static const String news = '/news';
|
static const String news = '/news';
|
||||||
|
static const String infography = '/infography';
|
||||||
static const String podcasts = '/podcasts';
|
static const String podcasts = '/podcasts';
|
||||||
static const String videocasts = '/videocasts';
|
static const String videocasts = '/videocasts';
|
||||||
static const String aboutUs = '/about-us';
|
static const String aboutUs = '/about-us';
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,7 @@ class RequestService {
|
||||||
|
|
||||||
void _handleResponse(http.Response? response) {
|
void _handleResponse(http.Response? response) {
|
||||||
statusCode = response?.statusCode;
|
statusCode = response?.statusCode;
|
||||||
|
//log("Mehradad->" + response!.body.toString());
|
||||||
if (_handleError(response)) {
|
if (_handleError(response)) {
|
||||||
if (response!.body.isNotEmpty) {
|
if (response!.body.isNotEmpty) {
|
||||||
_body = json.decode(response.body);
|
_body = json.decode(response.body);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:didvan/models/requests/infography.dart';
|
||||||
import 'package:didvan/models/requests/news.dart';
|
import 'package:didvan/models/requests/news.dart';
|
||||||
import 'package:didvan/models/requests/radar.dart';
|
import 'package:didvan/models/requests/radar.dart';
|
||||||
import 'package:didvan/models/requests/studio.dart';
|
import 'package:didvan/models/requests/studio.dart';
|
||||||
|
|
@ -7,6 +8,8 @@ class RequestHelper {
|
||||||
static const String _baseUserUrl = '$baseUrl/user';
|
static const String _baseUserUrl = '$baseUrl/user';
|
||||||
static const String _baseRadarUrl = '$baseUrl/radar';
|
static const String _baseRadarUrl = '$baseUrl/radar';
|
||||||
static const String _baseNewsUrl = '$baseUrl/news';
|
static const String _baseNewsUrl = '$baseUrl/news';
|
||||||
|
static const String _baseInfographyUrl = '$baseUrl/home/infography';
|
||||||
|
static const String _baseInfoTagUrl = '$baseUrl/home/infography/tags';
|
||||||
static const String _baseStudioUrl = '$baseUrl/studio';
|
static const String _baseStudioUrl = '$baseUrl/studio';
|
||||||
static const String _baseStatisticUrl = '$baseUrl/statistic';
|
static const String _baseStatisticUrl = '$baseUrl/statistic';
|
||||||
static const String _baseDirectUrl = '$_baseUserUrl/direct';
|
static const String _baseDirectUrl = '$_baseUserUrl/direct';
|
||||||
|
|
@ -106,6 +109,17 @@ class RequestHelper {
|
||||||
MapEntry('search', args.search),
|
MapEntry('search', args.search),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
static String infographyOverviews({required InfographyRequestArgs args}) =>
|
||||||
|
_baseInfographyUrl +
|
||||||
|
_urlConcatGenerator([
|
||||||
|
MapEntry('page', args.page),
|
||||||
|
MapEntry('category', _urlListConcatGenerator(args.categories)),
|
||||||
|
MapEntry('q', args.q),
|
||||||
|
MapEntry('tag', _urlListConcatGenerator(args.tag)),
|
||||||
|
]);
|
||||||
|
|
||||||
|
static String infographyTags() => _baseInfoTagUrl;
|
||||||
|
|
||||||
static String studioSlider(String type) =>
|
static String studioSlider(String type) =>
|
||||||
'$_baseStudioUrl/slider${_urlConcatGenerator([MapEntry('type', type)])}';
|
'$_baseStudioUrl/slider${_urlConcatGenerator([MapEntry('type', type)])}';
|
||||||
static String studioDetails(int id, StudioRequestArgs args) =>
|
static String studioDetails(int id, StudioRequestArgs args) =>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,184 @@
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
|
import 'package:didvan/models/category.dart';
|
||||||
|
import 'package:didvan/models/infography/info_tag.dart';
|
||||||
|
import 'package:didvan/models/view/action_sheet_data.dart';
|
||||||
|
import 'package:didvan/utils/action_sheet.dart';
|
||||||
|
import 'package:didvan/views/home/infography/infography_screen_state.dart';
|
||||||
|
import 'package:didvan/views/home/main/widgets/infography_item.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/checkbox.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
|
import 'package:didvan/views/widgets/item_title.dart';
|
||||||
|
import 'package:didvan/views/widgets/search_field.dart';
|
||||||
|
import 'package:didvan/views/widgets/state_handlers/state_handler.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:animated_custom_dropdown/custom_dropdown.dart';
|
||||||
|
|
||||||
|
class InfographyScreen extends StatefulWidget {
|
||||||
|
const InfographyScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<InfographyScreen> createState() => _InfographyScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _InfographyScreenState extends State<InfographyScreen> {
|
||||||
|
final ScrollController _scrollController = ScrollController();
|
||||||
|
int pageNumber = 1;
|
||||||
|
Timer? _timer;
|
||||||
|
final _focusNode = FocusNode();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
context.read<InfographyScreenState>().init();
|
||||||
|
_scrollController.addListener(_onScroll);
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_scrollController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onScroll() {
|
||||||
|
if (_scrollController.position.pixels >=
|
||||||
|
_scrollController.position.maxScrollExtent) {
|
||||||
|
pageNumber++;
|
||||||
|
context
|
||||||
|
.read<InfographyScreenState>()
|
||||||
|
.getInfographyContent(page: pageNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onChanged(String value) {
|
||||||
|
final state = context.read<InfographyScreenState>();
|
||||||
|
if (value.length < 3 && value.isNotEmpty || state.lastSearch == value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_timer?.cancel();
|
||||||
|
_timer = Timer(const Duration(seconds: 1), () {
|
||||||
|
state.search = value;
|
||||||
|
state.getInfographyContent(page: 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _showFilterBottomSheet() async {
|
||||||
|
final state = context.read<InfographyScreenState>();
|
||||||
|
await ActionSheetUtils.showBottomSheet(
|
||||||
|
data: ActionSheetData(
|
||||||
|
title: 'فیلتر جستجو',
|
||||||
|
smallDismissButton: true,
|
||||||
|
titleIcon: DidvanIcons.filter_regular,
|
||||||
|
dismissTitle: 'حذف فیلتر',
|
||||||
|
confrimTitle: 'نمایش نتایج',
|
||||||
|
onDismissed: () => state.resetFilters(false),
|
||||||
|
onConfirmed: () => state.getInfographyContent(page: 1),
|
||||||
|
content: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
ItemTitle(
|
||||||
|
title: "جستجوی هشتگ",
|
||||||
|
icon: DidvanIcons.hashtag_regular,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
|
||||||
|
child: CustomDropdown<InTag>.multiSelect(
|
||||||
|
closedHeaderPadding: EdgeInsets.all(12),
|
||||||
|
items: state.tags,
|
||||||
|
decoration: CustomDropdownDecoration(
|
||||||
|
closedBorder: Border.all(color: Colors.grey),
|
||||||
|
closedFillColor: Colors.grey.shade100.withOpacity(0.1),
|
||||||
|
),
|
||||||
|
hintText: "انتخاب کنید",
|
||||||
|
onListChanged: (value) {
|
||||||
|
state.selectedTags.addAll(value);
|
||||||
|
log('changing value to: ${value.map((e) => e.label + e.id.toString())}');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ItemTitle(
|
||||||
|
title: 'دسته بندی',
|
||||||
|
icon: DidvanIcons.category_regular,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
Wrap(
|
||||||
|
children: [
|
||||||
|
for (var i = 0; i < state.categories.length; i++)
|
||||||
|
SizedBox(
|
||||||
|
width: (MediaQuery.of(context).size.width - 40) / 2,
|
||||||
|
child: DidvanCheckbox(
|
||||||
|
title: state.categories[i].label,
|
||||||
|
value: state.selectedCats.contains(state.categories[i]),
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value) {
|
||||||
|
state.selectedCats.add(state.categories[i]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state.selectedCats.remove(state.categories[i]);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return StateHandler<InfographyScreenState>(
|
||||||
|
onRetry: context.read<InfographyScreenState>().init,
|
||||||
|
state: context.watch<InfographyScreenState>(),
|
||||||
|
builder: (context, state) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
elevation: 0.0,
|
||||||
|
scrolledUnderElevation: 0.0,
|
||||||
|
title: DidvanText(
|
||||||
|
"اینفوگرافی",
|
||||||
|
style: Theme.of(context).textTheme.bodyLarge,
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: 80,
|
||||||
|
color: Colors.white,
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 16.0, vertical: 16.0),
|
||||||
|
child: SearchField(
|
||||||
|
title: "اینفوگرافی",
|
||||||
|
onChanged: _onChanged,
|
||||||
|
focusNode: _focusNode,
|
||||||
|
onFilterButtonPressed: _showFilterBottomSheet,
|
||||||
|
isFiltered: state.filtering),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: ListView.builder(
|
||||||
|
controller: _scrollController,
|
||||||
|
//physics: const ClampingScrollPhysics(),
|
||||||
|
itemCount: state.contents.length,
|
||||||
|
itemBuilder: (context, index) => InfographyItem(
|
||||||
|
image: state.contents[index].image,
|
||||||
|
category: state.contents[index].category,
|
||||||
|
title: state.contents[index].title,
|
||||||
|
tag: state.contents[index].tags,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,127 @@
|
||||||
|
import 'package:didvan/constants/assets.dart';
|
||||||
|
import 'package:didvan/models/category.dart';
|
||||||
|
import 'package:didvan/models/enums.dart';
|
||||||
|
import 'package:didvan/models/infography/info_tag.dart';
|
||||||
|
import 'package:didvan/models/infography/infography_content.dart';
|
||||||
|
import 'package:didvan/models/requests/infography.dart';
|
||||||
|
import 'package:didvan/providers/core.dart';
|
||||||
|
import 'package:didvan/services/network/request.dart';
|
||||||
|
import 'package:didvan/services/network/request_helper.dart';
|
||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
|
import 'package:didvan/views/widgets/infography_tag.dart';
|
||||||
|
|
||||||
|
class InfographyScreenState extends CoreProvier {
|
||||||
|
List<Content> contents = [];
|
||||||
|
String search = '';
|
||||||
|
String lastSearch = '';
|
||||||
|
int lastPage = 1;
|
||||||
|
int page = 1;
|
||||||
|
|
||||||
|
final List<InTag> selectedTags = [];
|
||||||
|
List<InTag> tags = [];
|
||||||
|
final List<CategoryData> selectedCats = [];
|
||||||
|
List<CategoryData> categories = [];
|
||||||
|
|
||||||
|
bool isScrolled = false;
|
||||||
|
bool shouldColapse = false;
|
||||||
|
|
||||||
|
bool get filtering => selectedCats.length > 1 && selectedTags.length > 1;
|
||||||
|
|
||||||
|
bool get searching => search.isNotEmpty;
|
||||||
|
|
||||||
|
bool get isColapsed =>
|
||||||
|
(selectedCats.length == 1 &&
|
||||||
|
selectedTags.length == 1 &&
|
||||||
|
!filtering &&
|
||||||
|
isScrolled) ||
|
||||||
|
isScrolled;
|
||||||
|
|
||||||
|
bool get isCategorySelected =>
|
||||||
|
selectedCats.length == 1 && selectedTags.length == 1 && !filtering;
|
||||||
|
|
||||||
|
Future<void> getInfographyContent({required int page}) async {
|
||||||
|
this.page = page;
|
||||||
|
lastSearch = search;
|
||||||
|
if (page == 1) {
|
||||||
|
contents.clear();
|
||||||
|
tags.clear();
|
||||||
|
appState = AppState.busy;
|
||||||
|
}
|
||||||
|
|
||||||
|
final service = RequestService(RequestHelper.infographyOverviews(
|
||||||
|
args: InfographyRequestArgs(
|
||||||
|
page: page,
|
||||||
|
tag: selectedTags.map((e) => e.id).toList(),
|
||||||
|
q: search == '' ? null : search,
|
||||||
|
categories: selectedCats.map((e) => e.id).toList())));
|
||||||
|
final service2 = RequestService(RequestHelper.infographyTags());
|
||||||
|
await service.httpGet();
|
||||||
|
await service2.httpGet();
|
||||||
|
if (service.isSuccess && service2.isSuccess) {
|
||||||
|
lastPage = service.result['lastPage'];
|
||||||
|
|
||||||
|
final content = InfographyContent.fromJson(service.result);
|
||||||
|
final content2 = InfoTagModel.fromJson(service2.result);
|
||||||
|
|
||||||
|
contents.addAll(content.contents);
|
||||||
|
tags.addAll(content2.tags);
|
||||||
|
|
||||||
|
appState = AppState.idle;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
appState = AppState.failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetFilters(bool isInit) {
|
||||||
|
selectedCats.clear();
|
||||||
|
selectedTags.clear();
|
||||||
|
search = '';
|
||||||
|
lastSearch = '';
|
||||||
|
isScrolled = false;
|
||||||
|
if (!isInit) {
|
||||||
|
getInfographyContent(page: 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
// search = '';
|
||||||
|
// lastSearch = '';
|
||||||
|
resetFilters(true);
|
||||||
|
Future.delayed(Duration.zero, () {
|
||||||
|
getInfographyContent(page: 1);
|
||||||
|
});
|
||||||
|
categories = [
|
||||||
|
CategoryData(
|
||||||
|
id: 1,
|
||||||
|
label: 'اقتصادی',
|
||||||
|
asset: Assets.economicCategoryIcon,
|
||||||
|
),
|
||||||
|
CategoryData(
|
||||||
|
id: 2,
|
||||||
|
label: 'سیاسی',
|
||||||
|
asset: Assets.politicalCategoryIcon,
|
||||||
|
),
|
||||||
|
CategoryData(
|
||||||
|
id: 3,
|
||||||
|
label: 'فناوری',
|
||||||
|
asset: Assets.techCategoryIcon,
|
||||||
|
),
|
||||||
|
CategoryData(
|
||||||
|
id: 4,
|
||||||
|
label: 'کسب و کار',
|
||||||
|
asset: Assets.businessCategoryIcon,
|
||||||
|
),
|
||||||
|
CategoryData(
|
||||||
|
id: 5,
|
||||||
|
label: 'زیست محیطی',
|
||||||
|
asset: Assets.enviromentalCategoryIcon,
|
||||||
|
),
|
||||||
|
CategoryData(
|
||||||
|
id: 6,
|
||||||
|
label: 'اجتماعی',
|
||||||
|
asset: Assets.socialCategoryIcon,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import 'package:didvan/config/theme_data.dart';
|
import 'package:didvan/config/theme_data.dart';
|
||||||
import 'package:didvan/constants/app_icons.dart';
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
import 'package:didvan/models/home_page_content/home_page_list.dart';
|
import 'package:didvan/models/home_page_content/home_page_list.dart';
|
||||||
|
import 'package:didvan/routes/routes.dart';
|
||||||
|
import 'package:didvan/views/home/infography/infography_screen.dart';
|
||||||
import 'package:didvan/views/home/main/main_page_state.dart';
|
import 'package:didvan/views/home/main/main_page_state.dart';
|
||||||
import 'package:didvan/views/home/main/widgets/banner.dart';
|
import 'package:didvan/views/home/main/widgets/banner.dart';
|
||||||
import 'package:didvan/views/home/main/widgets/general_item.dart';
|
import 'package:didvan/views/home/main/widgets/general_item.dart';
|
||||||
|
|
@ -41,11 +43,55 @@ class _MainPageState extends State<MainPage> {
|
||||||
}
|
}
|
||||||
index--;
|
index--;
|
||||||
if (index == 4) {
|
if (index == 4) {
|
||||||
return const Padding(
|
return Padding(
|
||||||
padding: EdgeInsets.only(top: 32),
|
padding: const EdgeInsets.only(top: 32),
|
||||||
child: MainPageBanner(
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left: 16,
|
||||||
|
right: 16,
|
||||||
|
bottom: 16,
|
||||||
|
top: 28,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
DidvanText(
|
||||||
|
"اینفوگرافی",
|
||||||
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
|
color: Theme.of(context).colorScheme.title,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => {
|
||||||
|
Navigator.of(context).pushNamed(Routes.infography)
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
DidvanText(
|
||||||
|
"همه",
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
Icon(
|
||||||
|
DidvanIcons.angle_left_light,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const MainPageBanner(
|
||||||
isFirst: false,
|
isFirst: false,
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (index > 3) {
|
if (index > 3) {
|
||||||
|
|
@ -162,30 +208,6 @@ class _MainPageSection extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// if (list.type == 'radar')
|
|
||||||
// DidvanSlider(
|
|
||||||
// height: 260,
|
|
||||||
// itemCount: list.contents.length,
|
|
||||||
// viewportFraction: 0.65,
|
|
||||||
// itemBuilder: (context, index, realIndex) => Padding(
|
|
||||||
// padding: const EdgeInsets.symmetric(horizontal: 4),
|
|
||||||
// child: MainPageGeneralItem(
|
|
||||||
// content: list.contents[index],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// if (list.type == 'video')
|
|
||||||
// DidvanSlider(
|
|
||||||
// height: 260,
|
|
||||||
// itemCount: list.contents.length,
|
|
||||||
// viewportFraction: 0.65,
|
|
||||||
// itemBuilder: (context, index, realIndex) => Padding(
|
|
||||||
// padding: const EdgeInsets.symmetric(horizontal: 4),
|
|
||||||
// child: MainPageGeneralItem(
|
|
||||||
// content: list.contents[index],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
if (list.type == 'podcast')
|
if (list.type == 'podcast')
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 28),
|
padding: const EdgeInsets.only(top: 28),
|
||||||
|
|
@ -206,44 +228,7 @@ class _MainPageSection extends StatelessWidget {
|
||||||
.toList(),
|
.toList(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// if (list.type != 'news' &&
|
|
||||||
// list.type != 'radar' &&
|
|
||||||
// list.type != 'video' &&
|
|
||||||
// list.type != 'podcast')
|
|
||||||
// DidvanSlider(
|
|
||||||
// itemBuilder: (context, index, realIndex) => Padding(
|
|
||||||
// padding: const EdgeInsets.symmetric(horizontal: 4),
|
|
||||||
// child: MainPageGeneralItem(
|
|
||||||
// content: list.contents[index],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// itemCount: list.contents.length,
|
|
||||||
// viewportFraction: 0.65,
|
|
||||||
// height: 260 + _maxSublistCount() * 20,
|
|
||||||
// ),
|
|
||||||
// if (!isLast) const _MainPageDivider(),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// class _MainPageDivider extends StatelessWidget {
|
|
||||||
// const _MainPageDivider();
|
|
||||||
|
|
||||||
// @override
|
|
||||||
// Widget build(BuildContext context) {
|
|
||||||
// return Container(
|
|
||||||
// height: 2,
|
|
||||||
// margin: const EdgeInsets.only(
|
|
||||||
// top: 8,
|
|
||||||
// left: 20,
|
|
||||||
// right: 20,
|
|
||||||
// ),
|
|
||||||
// width: double.infinity,
|
|
||||||
// decoration: BoxDecoration(
|
|
||||||
// borderRadius: DesignConfig.highBorderRadius,
|
|
||||||
// color: Theme.of(context).colorScheme.border,
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:didvan/models/enums.dart';
|
import 'package:didvan/models/enums.dart';
|
||||||
import 'package:didvan/models/home_page_content/home_page_content.dart';
|
import 'package:didvan/models/home_page_content/home_page_content.dart';
|
||||||
|
import 'package:didvan/models/requests/infography.dart';
|
||||||
import 'package:didvan/models/requests/news.dart';
|
import 'package:didvan/models/requests/news.dart';
|
||||||
import 'package:didvan/models/requests/radar.dart';
|
import 'package:didvan/models/requests/radar.dart';
|
||||||
import 'package:didvan/providers/core.dart';
|
import 'package:didvan/providers/core.dart';
|
||||||
|
|
@ -49,6 +50,17 @@ class MainPageState extends CoreProvier {
|
||||||
link = link ?? '';
|
link = link ?? '';
|
||||||
dynamic args;
|
dynamic args;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case 'infography':
|
||||||
|
{
|
||||||
|
link = Routes.infography;
|
||||||
|
args = {
|
||||||
|
'onMarkChanged': (id, value) => markChangeHandler(type, id, value),
|
||||||
|
'id': id,
|
||||||
|
'args': const InfographyRequestArgs(page: 0),
|
||||||
|
'hasUnmarkConfirmation': false,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'news':
|
case 'news':
|
||||||
{
|
{
|
||||||
link = Routes.newsDetails;
|
link = Routes.newsDetails;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:didvan/config/design_config.dart';
|
||||||
|
import 'package:didvan/config/theme_data.dart';
|
||||||
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
|
import 'package:didvan/models/infography/infography_content.dart';
|
||||||
|
import 'package:didvan/views/widgets/animated_visibility.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/card.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
|
import 'package:didvan/views/widgets/infography_tag.dart';
|
||||||
|
import 'package:didvan/views/widgets/ink_wrapper.dart';
|
||||||
|
import 'package:didvan/views/widgets/skeleton_image.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class _BackButton extends StatefulWidget {
|
||||||
|
const _BackButton({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
__BackButtonState createState() => __BackButtonState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class __BackButtonState extends State<_BackButton> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AnimatedVisibility(
|
||||||
|
duration: DesignConfig.lowAnimationDuration,
|
||||||
|
isVisible: true,
|
||||||
|
child: InkWrapper(
|
||||||
|
borderRadius: DesignConfig.lowBorderRadius,
|
||||||
|
onPressed: Navigator.of(context).pop,
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.splash,
|
||||||
|
border: Border.all(color: Theme.of(context).colorScheme.border),
|
||||||
|
borderRadius: DesignConfig.lowBorderRadius,
|
||||||
|
),
|
||||||
|
child: const Icon(
|
||||||
|
DidvanIcons.back_regular,
|
||||||
|
size: 32,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class InfographyItem extends StatelessWidget {
|
||||||
|
final String image;
|
||||||
|
final String title;
|
||||||
|
final String category;
|
||||||
|
final List<Tag> tag;
|
||||||
|
|
||||||
|
const InfographyItem(
|
||||||
|
{super.key,
|
||||||
|
required this.image,
|
||||||
|
required this.category,
|
||||||
|
required this.title,
|
||||||
|
required this.tag});
|
||||||
|
|
||||||
|
void _openInteractiveViewer(BuildContext context, String image) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => Stack(
|
||||||
|
children: [
|
||||||
|
Positioned.fill(
|
||||||
|
child: InteractiveViewer(
|
||||||
|
child: Center(
|
||||||
|
child: SkeletonImage(
|
||||||
|
width: min(MediaQuery.of(context).size.width,
|
||||||
|
MediaQuery.of(context).size.height),
|
||||||
|
imageUrl: image,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Positioned(
|
||||||
|
right: 24,
|
||||||
|
top: 24,
|
||||||
|
child: _BackButton(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DidvanCard(
|
||||||
|
margin: const EdgeInsets.all(12),
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
child: DidvanText(
|
||||||
|
title,
|
||||||
|
style: Theme.of(context).textTheme.bodyLarge,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () => _openInteractiveViewer(context, image),
|
||||||
|
child: SkeletonImage(
|
||||||
|
imageUrl: image,
|
||||||
|
aspectRatio: 16 / 9,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Wrap(
|
||||||
|
spacing: 4,
|
||||||
|
runSpacing: 4,
|
||||||
|
children: [
|
||||||
|
for (var i = 0; i < tag.length; i++)
|
||||||
|
InfographyTag(
|
||||||
|
tag: tag[i],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
InfoCat(category: category)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,16 +15,6 @@ class MainPageMainContent extends StatelessWidget {
|
||||||
isFirst: true,
|
isFirst: true,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 28),
|
const SizedBox(height: 28),
|
||||||
// Stack(
|
|
||||||
// children: [
|
|
||||||
// Positioned(
|
|
||||||
// bottom: 13,
|
|
||||||
// child: Container(
|
|
||||||
// width: MediaQuery.of(context).size.width,
|
|
||||||
// height: 2,
|
|
||||||
// color: Theme.of(context).colorScheme.border,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
Center(
|
Center(
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
import 'package:didvan/config/design_config.dart';
|
||||||
|
import 'package:didvan/config/theme_data.dart';
|
||||||
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
|
import 'package:didvan/models/infography/infography_content.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
|
import 'package:didvan/views/widgets/ink_wrapper.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class InfographyTag extends StatelessWidget {
|
||||||
|
final Tag tag;
|
||||||
|
|
||||||
|
const InfographyTag({
|
||||||
|
Key? key,
|
||||||
|
required this.tag,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return InkWrapper(
|
||||||
|
borderRadius: DesignConfig.lowBorderRadius,
|
||||||
|
onPressed: () => {},
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 4,
|
||||||
|
horizontal: 4,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: DesignConfig.lowBorderRadius,
|
||||||
|
border: Border.all(
|
||||||
|
color: Theme.of(context).colorScheme.focusedBorder,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
DidvanIcons.hashtag_regular,
|
||||||
|
color: Theme.of(context).colorScheme.focusedBorder,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
DidvanText(
|
||||||
|
tag.label,
|
||||||
|
color: Theme.of(context).colorScheme.focusedBorder,
|
||||||
|
style: Theme.of(context).textTheme.labelLarge,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class InfoCat extends StatelessWidget {
|
||||||
|
final String category;
|
||||||
|
|
||||||
|
const InfoCat({
|
||||||
|
Key? key,
|
||||||
|
required this.category,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return InkWrapper(
|
||||||
|
borderRadius: DesignConfig.lowBorderRadius,
|
||||||
|
onPressed: () => {},
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 4,
|
||||||
|
horizontal: 8,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: DesignConfig.lowBorderRadius,
|
||||||
|
border: Border.all(
|
||||||
|
color: Theme.of(context).colorScheme.outline,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: DidvanText(
|
||||||
|
category,
|
||||||
|
color: Theme.of(context).colorScheme.outline,
|
||||||
|
style: Theme.of(context).textTheme.labelLarge,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -31,7 +31,9 @@ class _SearchFieldState extends State<SearchField> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
widget.focusNode.addListener(() {
|
widget.focusNode.addListener(() {
|
||||||
|
if (mounted) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
48
pubspec.lock
48
pubspec.lock
|
|
@ -9,6 +9,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.7"
|
version: "1.3.7"
|
||||||
|
animated_custom_dropdown:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: animated_custom_dropdown
|
||||||
|
sha256: "9e286defa42f2e774285015d7ff29523a24260888d53f79a3635328fad5bdad7"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.0"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -134,10 +142,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
|
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.17.2"
|
version: "1.18.0"
|
||||||
cross_file:
|
cross_file:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -442,10 +450,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fwfh_text_style
|
name: fwfh_text_style
|
||||||
sha256: f0883ccb64b7bb3f2a7a091542c2e834fc3e2a6aa54158f46b3c43b55675d8f7
|
sha256: "5f8b587fd223a6bf14aad3d3da5e7ced0628becbd0768f8e7ae25ff6b9f3d2ec"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.22.8+3"
|
version: "2.23.8"
|
||||||
graphs:
|
graphs:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -598,14 +606,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.2"
|
version: "1.0.2"
|
||||||
logging:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: logging
|
|
||||||
sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -626,10 +626,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
|
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.1"
|
version: "1.10.0"
|
||||||
mime:
|
mime:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -927,18 +927,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stack_trace
|
name: stack_trace
|
||||||
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
|
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.11.0"
|
version: "1.11.1"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stream_channel
|
name: stream_channel
|
||||||
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
|
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.2"
|
||||||
string_scanner:
|
string_scanner:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -967,10 +967,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
|
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.0"
|
version: "0.6.1"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -1151,10 +1151,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web
|
name: web
|
||||||
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
|
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.4-beta"
|
version: "0.3.0"
|
||||||
webview_flutter:
|
webview_flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -1212,5 +1212,5 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.3.0"
|
version: "6.3.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.1.0 <4.0.0"
|
dart: ">=3.2.0-194.0.dev <4.0.0"
|
||||||
flutter: ">=3.13.0"
|
flutter: ">=3.14.0-0"
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ dependencies:
|
||||||
assets_audio_player: ^3.1.1
|
assets_audio_player: ^3.1.1
|
||||||
fl_chart: ^0.63.0
|
fl_chart: ^0.63.0
|
||||||
collection: ^1.17.2
|
collection: ^1.17.2
|
||||||
|
animated_custom_dropdown: ^3.0.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue